From eb7b6843eee395ea1d286d82297a599c65035ce6 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Tue, 3 Mar 2026 16:20:00 +0000 Subject: [PATCH 01/80] [core] improve GPT partition type reporting * Rather than waste our time reimplementing the wheel, use the descriptions from gdisk. * Also update the DB SHA-266 entries to latest. * Also set version to rufus-next and update GitHub Actions to latest (Closes #2929). --- .github/workflows/coverity.yml | 2 +- .github/workflows/mingw.yml | 4 +- .github/workflows/setup.yml | 4 +- .github/workflows/vs2022.yml | 4 +- configure | 20 +- configure.ac | 2 +- src/db.h | 11 +- src/drive.c | 21 +- src/gpt_types.h | 736 +++++++++++++++++++++++---------- src/license.h | 8 +- src/rufus.h | 4 +- src/rufus.rc | 12 +- src/stdio.c | 31 +- 13 files changed, 582 insertions(+), 277 deletions(-) diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index a34ebb9c..ecfa023a 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -53,7 +53,7 @@ jobs: cov-build.exe --dir cov-int msbuild ${{ env.SOLUTION_FILE_PATH }} /m /p:Configuration=${{ env.BUILD_CONFIGURATION }},Platform=${{ env.TARGET_PLATFORM }} - name: Publish Coverity artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: cov-int path: cov-int/ diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 74b788a1..8e1df007 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -114,7 +114,7 @@ jobs: - name: Upload artifacts if: ${{ github.event_name == 'push' }} - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ${{ matrix.sys }} path: ./*.exe @@ -124,7 +124,7 @@ jobs: needs: MinGW-Build steps: - name: Merge Artifacts - uses: actions/upload-artifact/merge@v6 + uses: actions/upload-artifact/merge@v7 if: ${{ github.event_name == 'push' }} with: name: MinGW diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index d737d74f..83ba9e24 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -36,7 +36,7 @@ jobs: run: sha256sum ./setup_${{ matrix.TARGET_PLATFORM }}.exe - name: Upload artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ${{ matrix.TARGET_PLATFORM }} path: ./*.exe @@ -46,7 +46,7 @@ jobs: needs: VS2022-Build steps: - name: Merge Artifacts - uses: actions/upload-artifact/merge@v5 + uses: actions/upload-artifact/merge@v7 with: name: setup delete-merged: true diff --git a/.github/workflows/vs2022.yml b/.github/workflows/vs2022.yml index ac7b41fa..228a11aa 100644 --- a/.github/workflows/vs2022.yml +++ b/.github/workflows/vs2022.yml @@ -126,7 +126,7 @@ jobs: curl --request POST --url https://www.virustotal.com/api/v3/monitor/items --header 'x-apikey: ${{ secrets.VIRUSTOTAL_API_KEY }}' --form path='/rufus_${{ matrix.TARGET_PLATFORM }}.exe' --form file=@./rufus_${{ matrix.TARGET_PLATFORM }}.exe - name: Upload artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: ${{ github.event_name == 'push' }} with: name: ${{ matrix.TARGET_PLATFORM }} @@ -139,7 +139,7 @@ jobs: needs: VS2022-Build steps: - name: Merge Artifacts - uses: actions/upload-artifact/merge@v6 + uses: actions/upload-artifact/merge@v7 if: ${{ github.event_name == 'push' }} with: name: VS2022 diff --git a/configure b/configure index 06fae879..8f8dcb92 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for rufus 4.13. +# Generated by GNU Autoconf 2.71 for rufus 4.14. # # Report bugs to . # @@ -611,8 +611,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='rufus' PACKAGE_TARNAME='rufus' -PACKAGE_VERSION='4.13' -PACKAGE_STRING='rufus 4.13' +PACKAGE_VERSION='4.14' +PACKAGE_STRING='rufus 4.14' PACKAGE_BUGREPORT='https://github.com/pbatard/rufus/issues' PACKAGE_URL='https://rufus.ie' @@ -1269,7 +1269,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures rufus 4.13 to adapt to many kinds of systems. +\`configure' configures rufus 4.14 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1336,7 +1336,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of rufus 4.13:";; + short | recursive ) echo "Configuration of rufus 4.14:";; esac cat <<\_ACEOF @@ -1428,7 +1428,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -rufus configure 4.13 +rufus configure 4.14 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1504,7 +1504,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by rufus $as_me 4.13, which was +It was created by rufus $as_me 4.14, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -2767,7 +2767,7 @@ fi # Define the identity of the package. PACKAGE='rufus' - VERSION='4.13' + VERSION='4.14' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -5313,7 +5313,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by rufus $as_me 4.13, which was +This file was extended by rufus $as_me 4.14, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5369,7 +5369,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -rufus config.status 4.13 +rufus config.status 4.14 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 2179a531..94f0e09b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([rufus], [4.13], [https://github.com/pbatard/rufus/issues], [rufus], [https://rufus.ie]) +AC_INIT([rufus], [4.14], [https://github.com/pbatard/rufus/issues], [rufus], [https://rufus.ie]) AM_INIT_AUTOMAKE([-Wno-portability foreign no-dist no-dependencies]) AC_CONFIG_SRCDIR([src/rufus.c]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/src/db.h b/src/db.h index 2be05621..c3197e9f 100644 --- a/src/db.h +++ b/src/db.h @@ -1,8 +1,8 @@ /* * Rufus: The Reliable USB Formatting Utility * DB of the known SHA256 hash values for Rufus downloadable content (GRUB, Syslinux, etc.) - * as well PE256 hash values for UEFI revoked content (DBX, SkuSiPolicy.p7b) - * Copyright © 2016-2025 Pete Batard + * as well other data for UEFI revoked content (SBAT, certs). + * Copyright © 2016-2026 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 @@ -31,6 +31,8 @@ static uint8_t sha256db[] = { 0x11, 0x0c, 0x50, 0x1b, 0xfa, 0x9e, 0x72, 0xa8, 0x8c, 0xdb, 0xb8, 0xba, 0x11, 0xe1, 0xf0, 0x76, 0x1a, 0xec, 0x28, 0xbf, 0x04, 0x44, 0x67, 0xff, 0x38, 0x2c, 0x06, 0x95, 0xd5, 0x1f, 0x8a, 0x83, // grub-2.04-nonstandard/core.img 0x12, 0xbd, 0x22, 0xd2, 0xb3, 0x69, 0x56, 0x0f, 0x89, 0xb8, 0x50, 0x7e, 0x7e, 0x74, 0xeb, 0xc5, 0xea, 0x44, 0x91, 0x48, 0x75, 0xf0, 0xa4, 0xcb, 0x1e, 0xa6, 0xfb, 0x4e, 0xc9, 0x89, 0x58, 0x17, // syslinux-6.03/pre6/ldlinux.sys 0x15, 0x5f, 0x36, 0x7b, 0xb1, 0x30, 0xfe, 0x05, 0x5c, 0x79, 0x9f, 0x88, 0xb3, 0xc0, 0xc1, 0xa0, 0x0a, 0x18, 0x05, 0x78, 0x22, 0x69, 0xcf, 0x7e, 0x54, 0xaa, 0x61, 0xbd, 0xe3, 0x8e, 0x05, 0x92, // syslinux-6.03/pre3/ldlinux.bss + 0x15, 0x90, 0x28, 0x95, 0x48, 0x7c, 0x08, 0x4c, 0x8f, 0x57, 0x46, 0x66, 0xc3, 0x1e, 0x7f, 0xa3, 0x99, 0xd0, 0x5b, 0x83, 0x1f, 0xd6, 0x1c, 0x1e, 0x3c, 0x3e, 0xee, 0x69, 0xd6, 0x57, 0x69, 0x24, // grub-2.12/core.img + 0x19, 0xba, 0x57, 0x32, 0x9b, 0xe7, 0x45, 0xce, 0xae, 0x46, 0x35, 0x4c, 0x5d, 0x41, 0x1b, 0x7d, 0x8e, 0xfe, 0xc6, 0x80, 0x2c, 0xfd, 0x7f, 0x6f, 0xee, 0x98, 0x6d, 0xf4, 0xb7, 0x63, 0xf6, 0xfe, // grub4dos-0.4.6a/grldr 0x1c, 0xb7, 0x8b, 0x98, 0xbc, 0xd6, 0x76, 0x7b, 0x01, 0x44, 0xf5, 0x00, 0xaf, 0x81, 0xef, 0x4f, 0x3c, 0x54, 0xea, 0xaf, 0xe3, 0xc9, 0x4e, 0x1f, 0xd6, 0x24, 0x68, 0x41, 0x4e, 0x98, 0x92, 0x25, // syslinux-6.03/pre20/ldlinux.bss 0x1c, 0xc6, 0x32, 0x21, 0xfd, 0xf4, 0x46, 0xfc, 0xda, 0xc6, 0xc0, 0x56, 0x35, 0x79, 0x54, 0xc1, 0x5b, 0x61, 0x75, 0xca, 0x1b, 0xc2, 0xa4, 0x9f, 0x85, 0x52, 0xec, 0xca, 0x28, 0xac, 0x3e, 0x51, // syslinux-6.02/ldlinux.bss 0x22, 0x96, 0x82, 0xac, 0x61, 0xb8, 0x8b, 0x11, 0x25, 0xfc, 0xd7, 0xe6, 0x9f, 0x4e, 0x7f, 0x46, 0x7f, 0x68, 0xc5, 0x14, 0x9e, 0xb9, 0x37, 0x1a, 0x98, 0xd8, 0xf2, 0x78, 0x41, 0x40, 0xad, 0x88, // syslinux-5.00/ldlinux.sys @@ -88,7 +90,9 @@ static uint8_t sha256db[] = { 0x8e, 0xc8, 0x42, 0x06, 0x94, 0x4c, 0xd4, 0x3d, 0xf6, 0xba, 0x83, 0x63, 0xc0, 0x81, 0xe4, 0xa0, 0x82, 0x9e, 0x71, 0x9a, 0xbf, 0x5a, 0x46, 0x6d, 0x7c, 0x81, 0x0c, 0x2f, 0x5b, 0x6d, 0x13, 0x75, // syslinux-6.03/pre5/ldlinux.sys 0x95, 0x8d, 0x10, 0xbb, 0x87, 0x28, 0xcc, 0x1f, 0xf1, 0x6a, 0x12, 0xee, 0x6a, 0x60, 0x62, 0x40, 0xa6, 0xb7, 0x4d, 0xab, 0xa0, 0x2b, 0x8c, 0xb8, 0xed, 0x2a, 0xe8, 0x1c, 0x2f, 0xb2, 0x5b, 0x97, // syslinux-6.00/ldlinux.bss 0x9a, 0x0b, 0xc4, 0x1b, 0xd7, 0x95, 0xed, 0xb0, 0x83, 0x0f, 0x1c, 0xc4, 0x82, 0x4b, 0xfa, 0x9d, 0xe0, 0x9d, 0x68, 0x63, 0x92, 0x09, 0x4f, 0x5a, 0xe7, 0xfb, 0xac, 0xfb, 0xb0, 0x17, 0x9d, 0xa6, // syslinux-6.03/pre1/ldlinux.bss + 0x9a, 0x2c, 0x94, 0x67, 0x04, 0x01, 0x7f, 0xa8, 0xdc, 0x4e, 0x03, 0xa8, 0xa5, 0x8d, 0x75, 0x4d, 0x2d, 0x16, 0x07, 0xc2, 0xd2, 0xcd, 0x74, 0xf0, 0xe2, 0x92, 0x01, 0x33, 0xf1, 0x19, 0x28, 0x09, // grub-2.14/core.img 0x9b, 0xcc, 0x65, 0x92, 0xa7, 0xba, 0x7e, 0x73, 0x38, 0xf4, 0xbb, 0xba, 0x27, 0xc6, 0x30, 0x16, 0xb9, 0x5e, 0xcb, 0x1e, 0xc6, 0x8c, 0x0b, 0xe9, 0xb6, 0x99, 0xb2, 0xea, 0x69, 0xcb, 0xab, 0xb2, // syslinux-5.00/ldlinux.c32 + 0xa2, 0xa8, 0x76, 0x93, 0x71, 0xeb, 0x57, 0xc5, 0xe7, 0x9b, 0x3c, 0xea, 0x4a, 0x91, 0x12, 0x75, 0xaf, 0x47, 0x43, 0xf1, 0x0f, 0x42, 0x0e, 0xd6, 0xd2, 0x6e, 0x4e, 0xec, 0x5c, 0x86, 0x50, 0x59, // grub4dos-0.4.6a/grldr.mbr 0xa6, 0x82, 0x43, 0xa0, 0xf2, 0xe5, 0x90, 0xb8, 0x14, 0x02, 0xd6, 0xfa, 0x62, 0xd4, 0xfd, 0x30, 0x94, 0x8c, 0x00, 0x3d, 0xa1, 0x2b, 0xfe, 0xeb, 0x69, 0xba, 0x20, 0x34, 0x17, 0x27, 0x09, 0x4c, // syslinux-6.03/pre14/ldlinux.sys 0xa9, 0x4a, 0x99, 0xe6, 0xde, 0x68, 0x81, 0x44, 0x49, 0x2b, 0x38, 0xdb, 0xee, 0x09, 0xde, 0x07, 0x30, 0xe3, 0x2e, 0x1c, 0xfd, 0x0a, 0xb2, 0x54, 0x99, 0x22, 0xff, 0xa8, 0x04, 0x01, 0xad, 0x49, // syslinux-6.03/pre2/ldlinux.bss 0xa9, 0x95, 0x68, 0x57, 0x9c, 0xd2, 0x51, 0xaf, 0xf1, 0x34, 0xfc, 0xaa, 0xa8, 0x09, 0x91, 0x60, 0x5e, 0x8f, 0xb1, 0x19, 0x74, 0x51, 0xf7, 0x51, 0xaa, 0x4d, 0x6c, 0x84, 0xbf, 0x65, 0xf4, 0xe3, // syslinux-6.03/pre15/ldlinux.sys @@ -100,6 +104,7 @@ static uint8_t sha256db[] = { 0xb3, 0xdc, 0x31, 0x79, 0xf6, 0x2b, 0x20, 0x51, 0xc9, 0x43, 0xe5, 0x2e, 0xeb, 0xf2, 0x29, 0x8a, 0xa4, 0x7e, 0x7c, 0x0a, 0x97, 0x78, 0xe8, 0x62, 0x77, 0xa7, 0x48, 0x2a, 0x27, 0x0a, 0x7a, 0x8e, // syslinux-6.01/ldlinux.bss 0xb4, 0x6a, 0xf2, 0x09, 0x19, 0xe9, 0xf2, 0x1f, 0xa1, 0x52, 0x37, 0x5d, 0xda, 0xc4, 0x58, 0x87, 0x08, 0xc1, 0x22, 0xb3, 0x65, 0x7f, 0x09, 0x01, 0x31, 0x4e, 0x83, 0x45, 0x49, 0xa9, 0x6c, 0xe7, // syslinux-4.07/menu.c32 0xbc, 0x3f, 0xb7, 0x6d, 0xbc, 0xd6, 0x32, 0x37, 0xc3, 0x68, 0x8d, 0x3b, 0x55, 0x3c, 0x99, 0x41, 0x0e, 0x8f, 0xb3, 0x9e, 0x52, 0x00, 0x9d, 0xdc, 0xeb, 0xb8, 0x8e, 0xe7, 0xd2, 0x5a, 0xec, 0xa8, // grub-2.03.5/core.img + 0xbf, 0x05, 0x9b, 0x7f, 0x9d, 0xc5, 0x1d, 0x08, 0xb7, 0xa9, 0x36, 0x81, 0xcc, 0xc7, 0x82, 0xdc, 0x46, 0x4e, 0x43, 0xe6, 0x0d, 0xa4, 0xfb, 0xb6, 0xa1, 0xf5, 0x62, 0xea, 0x0e, 0x2d, 0xd3, 0x1a, // grub-2.14~rc1/core.img 0xbf, 0xf9, 0xc5, 0x89, 0x59, 0x70, 0x4d, 0x1e, 0xbe, 0x25, 0xb4, 0x43, 0xc8, 0x92, 0x3a, 0x42, 0xed, 0x89, 0xaf, 0x8b, 0xd2, 0x92, 0xe7, 0xd7, 0xcb, 0xeb, 0xca, 0xcc, 0xc0, 0x7c, 0xc7, 0x19, // syslinux-5.11/ldlinux.sys 0xc3, 0x3b, 0x31, 0x5f, 0xec, 0xe4, 0xad, 0xc4, 0xc3, 0xb2, 0x75, 0x13, 0x22, 0x84, 0x66, 0xe4, 0x44, 0x99, 0xcd, 0xa7, 0xfd, 0x63, 0x97, 0xc5, 0xab, 0xe0, 0xf8, 0xce, 0x4f, 0xe3, 0x45, 0x39, // syslinux-5.10/ldlinux.c32 0xcc, 0x40, 0xba, 0x03, 0x49, 0x78, 0x2c, 0xb4, 0xc9, 0x02, 0x1e, 0x54, 0xdc, 0xc0, 0xa4, 0x54, 0x0c, 0x3a, 0x8b, 0x96, 0x08, 0x8b, 0x3a, 0x56, 0x48, 0x67, 0x19, 0x26, 0xef, 0x44, 0xd2, 0xf0, // syslinux-6.04/ldlinux.bss @@ -108,7 +113,6 @@ static uint8_t sha256db[] = { 0xd2, 0xc6, 0x93, 0x8d, 0xae, 0x5a, 0xd7, 0x16, 0x0e, 0x9e, 0x6c, 0x61, 0xef, 0x46, 0xb7, 0xfd, 0x14, 0x6e, 0x30, 0xc0, 0x3f, 0xdc, 0x8f, 0x5c, 0x6d, 0xbd, 0xeb, 0x86, 0x22, 0xc8, 0xa7, 0xbd, // syslinux-5.00/ldlinux.bss 0xd3, 0x47, 0x2c, 0x02, 0x26, 0x3a, 0xcf, 0x9c, 0xd1, 0xda, 0x5d, 0xb5, 0x1e, 0x26, 0x3c, 0x54, 0x84, 0xba, 0xd1, 0x3e, 0xa6, 0x86, 0x18, 0xc4, 0x03, 0xd9, 0xcb, 0x01, 0xca, 0x07, 0x0a, 0xee, // syslinux-6.04/ldlinux.c32 0xd5, 0x50, 0x39, 0xef, 0xb6, 0x8d, 0x6e, 0xec, 0xde, 0x68, 0x61, 0xc9, 0x0b, 0xa9, 0xb7, 0x99, 0x44, 0xd1, 0xaa, 0x8b, 0xc3, 0xd6, 0x01, 0xfb, 0x80, 0xfd, 0x08, 0x7b, 0xc6, 0x13, 0x63, 0xf8, // syslinux-6.02/ldlinux.sys - 0xd6, 0xa7, 0x0c, 0xe1, 0x90, 0x2b, 0x22, 0x1a, 0xcb, 0xc1, 0xd5, 0xf5, 0x94, 0x24, 0xa8, 0x22, 0x7b, 0x62, 0xfe, 0x6d, 0x85, 0x34, 0x86, 0x0e, 0x2b, 0x6e, 0x75, 0x7e, 0x01, 0x02, 0xc5, 0x6f, // grub4dos-0.4.6a/grldr 0xd9, 0x1c, 0xbd, 0xf9, 0x01, 0x79, 0x5e, 0x98, 0x19, 0x84, 0x9c, 0x75, 0x3e, 0xa5, 0x3a, 0xd8, 0x59, 0xc6, 0xf2, 0x5d, 0x59, 0x17, 0xa6, 0x75, 0x92, 0x58, 0x3f, 0xd6, 0x5e, 0x6d, 0x00, 0xf0, // syslinux-6.03/pre18/ldlinux.bss 0xda, 0xa3, 0x06, 0xa9, 0x97, 0x0e, 0x37, 0x7d, 0xb4, 0x4c, 0xe7, 0xfa, 0xd8, 0xdd, 0x01, 0xe9, 0xe8, 0x53, 0xc6, 0x8b, 0x1e, 0x3d, 0x84, 0xf3, 0x2a, 0xaf, 0x42, 0x24, 0x6f, 0x77, 0xae, 0x3d, // grub-2.02/core.img 0xe7, 0x87, 0x08, 0xc7, 0x2c, 0x49, 0x8e, 0xcc, 0x14, 0x9e, 0x30, 0xf0, 0xa9, 0x85, 0xd3, 0x73, 0xa3, 0x00, 0xad, 0x5c, 0xf7, 0xd2, 0x88, 0xc7, 0x7d, 0xe8, 0x05, 0x5e, 0x25, 0x66, 0x28, 0x1f, // syslinux-6.03/pre18/ldlinux.sys @@ -118,7 +122,6 @@ static uint8_t sha256db[] = { 0xec, 0xfd, 0xbc, 0x3f, 0x4f, 0x2e, 0x4d, 0x99, 0x16, 0x9c, 0xdd, 0xfb, 0x15, 0x2d, 0x92, 0x4d, 0x7d, 0xe6, 0x8a, 0xb6, 0x7f, 0x4d, 0x12, 0x54, 0x40, 0xfa, 0xbc, 0x9f, 0x00, 0x46, 0xd5, 0xbc, // syslinux-6.03/pre5/ldlinux.bss 0xee, 0xed, 0xc0, 0x4c, 0x13, 0x73, 0xb5, 0xc4, 0x04, 0x4d, 0x1f, 0xde, 0x0d, 0x2f, 0xb8, 0xe2, 0x8c, 0x74, 0xb1, 0x02, 0x9c, 0x99, 0xed, 0x67, 0x0a, 0x15, 0x98, 0x3f, 0x18, 0xa0, 0x4d, 0x36, // syslinux-6.02/ldlinux.c32 0xf5, 0x40, 0x26, 0x1c, 0x09, 0x7d, 0xbd, 0x8a, 0x8a, 0x12, 0x9b, 0x68, 0x99, 0x5f, 0x33, 0xab, 0xe7, 0x1c, 0x29, 0x40, 0xf8, 0x87, 0xc6, 0x68, 0x9b, 0xf8, 0xdc, 0x3f, 0x1a, 0xcf, 0x0b, 0x44, // syslinux-6.03/pre17/ldlinux.bss - 0xf5, 0xc6, 0xe8, 0xe2, 0xc1, 0xeb, 0x73, 0x80, 0x28, 0x5f, 0xa9, 0xcb, 0x1c, 0x91, 0x68, 0xe9, 0x2d, 0x5b, 0x3b, 0x55, 0xcd, 0xe0, 0x52, 0xc0, 0x43, 0xba, 0x81, 0xed, 0x17, 0xb9, 0xac, 0xef, // grub4dos-0.4.6a/grldr.mbr 0xfb, 0x0a, 0x23, 0xca, 0x4d, 0x22, 0xfd, 0xd2, 0xad, 0x4e, 0xfa, 0x1b, 0x21, 0x08, 0xb6, 0x60, 0xd2, 0xff, 0xa3, 0xf2, 0xfb, 0xdd, 0x25, 0x32, 0xdc, 0xf1, 0x3f, 0x49, 0x33, 0x28, 0x46, 0x7b, // syslinux-6.03/pre11/ldlinux.bss 0xfb, 0x49, 0xfd, 0x45, 0x8c, 0xaf, 0x47, 0x5a, 0x16, 0x05, 0x5e, 0x4a, 0x75, 0x5a, 0xc3, 0xe3, 0x95, 0x52, 0xf4, 0xe9, 0x6c, 0xa2, 0x0d, 0xea, 0x53, 0xf5, 0xc4, 0x09, 0x2b, 0x68, 0xfd, 0x4f, // syslinux-6.00/ldlinux.sys }; diff --git a/src/drive.c b/src/drive.c index fbce1bc8..798db108 100644 --- a/src/drive.c +++ b/src/drive.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Drive access function calls - * Copyright © 2011-2025 Pete Batard + * Copyright © 2011-2026 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 @@ -1546,7 +1546,7 @@ static BOOL StoreEspInfo(GUID* guid) return WriteSettingStr(key_name[1], GuidToString(guid, TRUE)); } -static GUID* GetEspGuid(uint8_t index) +static GUID GetEspGuid(uint8_t index) { char key_name[16]; @@ -1574,7 +1574,7 @@ BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset) HANDLE hPhysical; DWORD dl_size, size, offset; BYTE layout[4096] = { 0 }, buf[512]; - GUID *guid = NULL, *stored_guid = NULL, mbr_guid; + GUID *guid = NULL, stored_guid = { 0 }, mbr_guid; PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; typedef struct { const uint8_t mbr_type; @@ -1650,7 +1650,7 @@ BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset) // Basic Data -> ESP for (i = 1; i <= MAX_ESP_TOGGLE && esp_index < 0; i++) { stored_guid = GetEspGuid((uint8_t)i); - if (stored_guid != NULL) { + if (!CompareGUID(&stored_guid, &GUID_NULL)) { for (j = 0; j < (int)DriveLayout->PartitionCount && esp_index < 0; j++) { if (DriveLayout->PartitionStyle == PARTITION_STYLE_GPT) { guid = &DriveLayout->PartitionEntry[j].Gpt.PartitionId; @@ -1660,7 +1660,7 @@ BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset) *((uint64_t*)&mbr_guid.Data4) = DriveLayout->PartitionEntry[j].StartingOffset.QuadPart; guid = &mbr_guid; } - if (CompareGUID(stored_guid, guid)) { + if (CompareGUID(&stored_guid, guid)) { esp_index = j; delete_data = TRUE; if (DriveLayout->PartitionStyle == PARTITION_STYLE_GPT) @@ -2606,9 +2606,8 @@ const char* GetMBRPartitionType(const uint8_t type) const char* GetGPTPartitionType(const GUID* guid) { - int i; - for (i = 0; (i < ARRAYSIZE(gpt_type)) && !CompareGUID(guid, gpt_type[i].guid); i++); - return (i < ARRAYSIZE(gpt_type)) ? gpt_type[i].name : GuidToString(guid, TRUE); + const char* desc = gpt_type_desc(guid); + return desc != NULL ? desc : GuidToString(guid, TRUE); } /* @@ -2653,7 +2652,7 @@ BOOL IsFilteredDrive(DWORD DriveIndex) HANDLE hPhysical = INVALID_HANDLE_VALUE; BYTE layout[4096] = { 0 }; PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; - GUID* DiskGuid; + GUID DiskGuid; hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE, TRUE); if (hPhysical == INVALID_HANDLE_VALUE) @@ -2669,8 +2668,8 @@ BOOL IsFilteredDrive(DWORD DriveIndex) for (i = 1; i <= MAX_IGNORE_USB; i++) { static_sprintf(setting_name, "IgnoreDisk%02d", i); DiskGuid = StringToGuid(ReadSettingStr(setting_name)); - if (CompareGUID(&DriveLayout->Gpt.DiskId, DiskGuid)) { - uprintf("Device eliminated because it matches Disk GUID %s", GuidToString(DiskGuid, TRUE)); + if (CompareGUID(&DriveLayout->Gpt.DiskId, &DiskGuid)) { + uprintf("Device eliminated because it matches Disk GUID %s", GuidToString(&DiskGuid, TRUE)); ret = TRUE; goto out; } diff --git a/src/gpt_types.h b/src/gpt_types.h index 926056cc..128123aa 100644 --- a/src/gpt_types.h +++ b/src/gpt_types.h @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * GPT Partition Types - * Copyright © 2020 Pete Batard + * Copyright © 2020-2026 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 @@ -24,226 +24,520 @@ #pragma once -/* - * From https://en.wikipedia.org/wiki/GUID_Partition_Table - */ -DEFINE_GUID(PARTITION_ANDROID_BOOT, 0x49A4D17F, 0x93A3, 0x45C1, 0xA0, 0xDE, 0xF5, 0x0B, 0x2E, 0xBE, 0x25, 0x99); -DEFINE_GUID(PARTITION_ANDROID_BOOTLOADER1, 0x2568845D, 0x2332, 0x4675, 0xBC, 0x39, 0x8F, 0xA5, 0xA4, 0x74, 0x8D, 0x15); -DEFINE_GUID(PARTITION_ANDROID_BOOTLOADER2, 0x114EAFFE, 0x1552, 0x4022, 0xB2, 0x6E, 0x9B, 0x05, 0x36, 0x04, 0xCF, 0x84); -DEFINE_GUID(PARTITION_ANDROID_CACHE, 0xA893EF21, 0xE428, 0x470A, 0x9E, 0x55, 0x06, 0x68, 0xFD, 0x91, 0xA2, 0xD9); -DEFINE_GUID(PARTITION_ANDROID_CONFIG, 0xBD59408B, 0x4514, 0x490D, 0xBF, 0x12, 0x98, 0x78, 0xD9, 0x63, 0xF3, 0x78); -DEFINE_GUID(PARTITION_ANDROID_DATA, 0xDC76DDA9, 0x5AC1, 0x491C, 0xAF, 0x42, 0xA8, 0x25, 0x91, 0x58, 0x0C, 0x0D); -DEFINE_GUID(PARTITION_ANDROID_EXT, 0x193D1EA4, 0xB3CA, 0x11E4, 0xB0, 0x75, 0x10, 0x60, 0x4B, 0x88, 0x9D, 0xCF); -DEFINE_GUID(PARTITION_ANDROID_FACTORY1, 0x8F68CC74, 0xC5E5, 0x48DA, 0xBE, 0x91, 0xA0, 0xC8, 0xC1, 0x5E, 0x9C, 0x80); -DEFINE_GUID(PARTITION_ANDROID_FACTORY2, 0x9FDAA6EF, 0x4B3F, 0x40D2, 0xBA, 0x8D, 0xBF, 0xF1, 0x6B, 0xFB, 0x88, 0x7B); -DEFINE_GUID(PARTITION_ANDROID_FASTBOOT, 0x767941D0, 0x2085, 0x11E3, 0xAD, 0x3B, 0x6C, 0xFD, 0xB9, 0x47, 0x11, 0xE9); -DEFINE_GUID(PARTITION_ANDROID_METADATA1, 0x20AC26BE, 0x20B7, 0x11E3, 0x84, 0xC5, 0x6C, 0xFD, 0xB9, 0x47, 0x11, 0xE9); -DEFINE_GUID(PARTITION_ANDROID_METADATA2, 0x19A710A2, 0xB3CA, 0x11E4, 0xB0, 0x26, 0x10, 0x60, 0x4B, 0x88, 0x9D, 0xCF); -DEFINE_GUID(PARTITION_ANDROID_MISC, 0xEF32A33B, 0xA409, 0x486C, 0x91, 0x41, 0x9F, 0xFB, 0x71, 0x1F, 0x62, 0x66); -DEFINE_GUID(PARTITION_ANDROID_OEM, 0xAC6D7924, 0xEB71, 0x4DF8, 0xB4, 0x8D, 0xE2, 0x67, 0xB2, 0x71, 0x48, 0xFF); -DEFINE_GUID(PARTITION_ANDROID_PERSISTENCE, 0xEBC597D0, 0x2053, 0x4B15, 0x8B, 0x64, 0xE0, 0xAA, 0xC7, 0x5F, 0x4D, 0xB1); -DEFINE_GUID(PARTITION_ANDROID_RECOVERY, 0x4177C722, 0x9E92, 0x4AAB, 0x86, 0x44, 0x43, 0x50, 0x2B, 0xFD, 0x55, 0x06); -DEFINE_GUID(PARTITION_ANDROID_SYSTEM, 0x38F428E6, 0xD326, 0x425D, 0x91, 0x40, 0x6E, 0x0E, 0xA1, 0x33, 0x64, 0x7C); -DEFINE_GUID(PARTITION_ANDROID_VENDOR, 0xC5A0AEEC, 0x13EA, 0x11E5, 0xA1, 0xB1, 0x00, 0x1E, 0x67, 0xCA, 0x0C, 0x3C); -DEFINE_GUID(PARTITION_APPLE_APFS, 0x7C3457EF, 0x0000, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -DEFINE_GUID(PARTITION_APPLE_BOOT, 0x426F6F74, 0x0000, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -DEFINE_GUID(PARTITION_APPLE_FILEVAULT, 0x53746F72, 0x6167, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -DEFINE_GUID(PARTITION_APPLE_HFS, 0x48465300, 0x0000, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -DEFINE_GUID(PARTITION_APPLE_LABEL, 0x4C616265, 0x6C00, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -DEFINE_GUID(PARTITION_APPLE_OFFLINE_RAID, 0x52414944, 0x5F4F, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -DEFINE_GUID(PARTITION_APPLE_RAID, 0x52414944, 0x0000, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -DEFINE_GUID(PARTITION_APPLE_RAID_CACHE, 0xBBBA6DF5, 0xF46F, 0x4A89, 0x8F, 0x59, 0x87, 0x65, 0xB2, 0x72, 0x75, 0x03); -DEFINE_GUID(PARTITION_APPLE_RAID_SCRATCH, 0x2E313465, 0x19B9, 0x463F, 0x81, 0x26, 0x8A, 0x79, 0x93, 0x77, 0x38, 0x01); -DEFINE_GUID(PARTITION_APPLE_RAID_STATUS, 0xB6FA30DA, 0x92D2, 0x4A9A, 0x96, 0xF1, 0x87, 0x1E, 0xC6, 0x48, 0x62, 0x00); -DEFINE_GUID(PARTITION_APPLE_RAID_VOLUME, 0xFA709C7E, 0x65B1, 0x4593, 0xBF, 0xD5, 0xE7, 0x1D, 0x61, 0xDE, 0x9B, 0x02); -DEFINE_GUID(PARTITION_APPLE_RECOVERY, 0x5265636F, 0x7665, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -DEFINE_GUID(PARTITION_APPLE_UFS, 0x55465300, 0x0000, 0x11AA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC); -// Stolen from Solaris below. Great job here, Apple! Then again, Oracle can and *should* go to hell, so who cares... -DEFINE_GUID(PARTITION_APPLE_ZFS, 0x6A898CC3, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_ATARI_DATA, 0x734E5AFE, 0xF61A, 0x11E6, 0xBC, 0x64, 0x92, 0x36, 0x1F, 0x00, 0x26, 0x71); -DEFINE_GUID(PARTITION_BEOS_BFS, 0x42465331, 0x3BA3, 0x10F1, 0x80, 0x2A, 0x48, 0x61, 0x69, 0x6B, 0x75, 0x21); -DEFINE_GUID(PARTITION_CHROMEOS_KERNEL, 0xFE3A2A5D, 0x4F32, 0x41A7, 0xB7, 0x25, 0xAC, 0xCC, 0x32, 0x85, 0xA3, 0x09); -DEFINE_GUID(PARTITION_CHROMEOS_RESERVED, 0x2E0A753D, 0x9E48, 0x43B0, 0x83, 0x37, 0xB1, 0x51, 0x92, 0xCB, 0x1B, 0x5E); -DEFINE_GUID(PARTITION_CHROMEOS_ROOT, 0x3CB8E202, 0x3B7E, 0x47DD, 0x8A, 0x3C, 0x7F, 0xF2, 0xA1, 0x3C, 0xFC, 0xEC); -DEFINE_GUID(PARTITION_COREOS_RAID, 0xBE9067B9, 0xEA49, 0x4F15, 0xB4, 0xF6, 0xF3, 0x6F, 0x8C, 0x9E, 0x18, 0x18); -DEFINE_GUID(PARTITION_COREOS_RESERVED, 0xC95DC21A, 0xDF0E, 0x4340, 0x8D, 0x7B, 0x26, 0xCB, 0xFA, 0x9A, 0x03, 0xE0); -DEFINE_GUID(PARTITION_COREOS_ROOT, 0x3884DD41, 0x8582, 0x4404, 0xB9, 0xA8, 0xE9, 0xB8, 0x4F, 0x2D, 0xF5, 0x0E); -DEFINE_GUID(PARTITION_COREOS_USR, 0x5DFBF5F4, 0x2848, 0x4BAC, 0xAA, 0x5E, 0x0D, 0x9A, 0x20, 0xB7, 0x45, 0xA6); -DEFINE_GUID(PARTITION_FREEBSD_BOOT, 0x83BD6B9D, 0x7F41, 0x11DC, 0xBE, 0x0B, 0x00, 0x15, 0x60, 0xB8, 0x4F, 0x0F); -DEFINE_GUID(PARTITION_FREEBSD_DATA, 0x516E7CB4, 0x6ECF, 0x11D6, 0x8F, 0xF8, 0x00, 0x02, 0x2D, 0x09, 0x71, 0x2B); -DEFINE_GUID(PARTITION_FREEBSD_LVM, 0x516E7CB8, 0x6ECF, 0x11D6, 0x8F, 0xF8, 0x00, 0x02, 0x2D, 0x09, 0x71, 0x2B); -DEFINE_GUID(PARTITION_FREEBSD_SWAP, 0x516E7CB5, 0x6ECF, 0x11D6, 0x8F, 0xF8, 0x00, 0x02, 0x2D, 0x09, 0x71, 0x2B); -DEFINE_GUID(PARTITION_FREEBSD_UFS, 0x516E7CB6, 0x6ECF, 0x11D6, 0x8F, 0xF8, 0x00, 0x02, 0x2D, 0x09, 0x71, 0x2B); -DEFINE_GUID(PARTITION_FREEBSD_ZFS, 0x516E7CBA, 0x6ECF, 0x11D6, 0x8F, 0xF8, 0x00, 0x02, 0x2D, 0x09, 0x71, 0x2B); -DEFINE_GUID(PARTITION_GENERIC_BIOS_BOOT, 0x21686148, 0x6449, 0x6E6F, 0x74, 0x4E, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49); -DEFINE_GUID(PARTITION_GENERIC_XBOOTLDR, 0xBC13C2FF, 0x59E6, 0x4262, 0xA3, 0x52, 0xB2, 0x75, 0xFD, 0x6F, 0x71, 0x72); -DEFINE_GUID(PARTITION_GENERIC_ESP, 0xC12A7328, 0xF81F, 0x11D2, 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B); -DEFINE_GUID(PARTITION_GENERIC_MBR, 0x024DEE41, 0x33E7, 0x11D3, 0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F); -DEFINE_GUID(PARTITION_GENERIC_UNUSED, 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -DEFINE_GUID(PARTITION_HPUX_DATA, 0x75894C1E, 0x3AEB, 0x11D3, 0xB7, 0xC1, 0x7B, 0x03, 0xA0, 0x00, 0x00, 0x00); -DEFINE_GUID(PARTITION_HPUX_SERVICE, 0xE2A1E728, 0x32E3, 0x11D6, 0xA6, 0x82, 0x7B, 0x03, 0xA0, 0x00, 0x00, 0x00); -DEFINE_GUID(PARTITION_IBM_GPFS, 0x37AFFC90, 0xEF7D, 0x4E96, 0x91, 0xC3, 0x2D, 0x7A, 0xE0, 0x55, 0xB1, 0x74); -DEFINE_GUID(PARTITION_INTEL_IFF, 0xD3BFE2DE, 0x3DAF, 0x11DF, 0xBA, 0x40, 0xE3, 0xA5, 0x56, 0xD8, 0x95, 0x93); -DEFINE_GUID(PARTITION_LENOVO_BOOT, 0xBFBFAFE7, 0xA34F, 0x448A, 0x9A, 0x5B, 0x62, 0x13, 0xEB, 0x73, 0x6C, 0x22); -DEFINE_GUID(PARTITION_LINUX_BOOT, 0xBC13C2FF, 0x59E6, 0x4262, 0xA3, 0x52, 0xB2, 0x75, 0xFD, 0x6F, 0x71, 0x72); -DEFINE_GUID(PARTITION_LINUX_DATA, 0x0FC63DAF, 0x8483, 0x4772, 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4); -DEFINE_GUID(PARTITION_LINUX_ENCRYPTED, 0x7FFEC5C9, 0x2D00, 0x49B7, 0x89, 0x41, 0x3E, 0xA1, 0x0A, 0x55, 0x86, 0xB7); -DEFINE_GUID(PARTITION_LINUX_HOME, 0x933AC7E1, 0x2EB4, 0x4F13, 0xB8, 0x44, 0x0E, 0x14, 0xE2, 0xAE, 0xF9, 0x15); -DEFINE_GUID(PARTITION_LINUX_LUKS, 0xCA7D7CCB, 0x63ED, 0x4C53, 0x86, 0x1C, 0x17, 0x42, 0x53, 0x60, 0x59, 0xCC); -DEFINE_GUID(PARTITION_LINUX_LVM, 0xE6D6D379, 0xF507, 0x44C2, 0xA2, 0x3C, 0x23, 0x8F, 0x2A, 0x3D, 0xF9, 0x28); -DEFINE_GUID(PARTITION_LINUX_RAID, 0xA19D880F, 0x05FC, 0x4D3B, 0xA0, 0x06, 0x74, 0x3F, 0x0F, 0x84, 0x91, 0x1E); -DEFINE_GUID(PARTITION_LINUX_RESERVED, 0x8DA63339, 0x0007, 0x60C0, 0xC4, 0x36, 0x08, 0x3A, 0xC8, 0x23, 0x09, 0x08); -DEFINE_GUID(PARTITION_LINUX_ROOT_ARM_32, 0x69DAD710, 0x2CE4, 0x4E3C, 0xB1, 0x6C, 0x21, 0xA1, 0xD4, 0x9A, 0xBE, 0xD3); -DEFINE_GUID(PARTITION_LINUX_ROOT_ARM_64, 0xB921B045, 0x1DF0, 0x41C3, 0xAF, 0x44, 0x4C, 0x6F, 0x28, 0x0D, 0x3F, 0xAE); -DEFINE_GUID(PARTITION_LINUX_ROOT_X86_32, 0x44479540, 0xF297, 0x41B2, 0x9A, 0xF7, 0xD1, 0x31, 0xD5, 0xF0, 0x45, 0x8A); -DEFINE_GUID(PARTITION_LINUX_ROOT_X86_64, 0x4F68BCE3, 0xE8CD, 0x4DB1, 0x96, 0xE7, 0xFB, 0xCA, 0xF9, 0x84, 0xB7, 0x09); -DEFINE_GUID(PARTITION_LINUX_SRV, 0x3B8F8425, 0x20E0, 0x4F3B, 0x90, 0x7F, 0x1A, 0x25, 0xA7, 0x6F, 0x98, 0xE8); -DEFINE_GUID(PARTITION_LINUX_SWAP, 0x0657FD6D, 0xA4AB, 0x43C4, 0x84, 0xE5, 0x09, 0x33, 0xC8, 0x4B, 0x4F, 0x4F); -DEFINE_GUID(PARTITION_MICROSOFT_DATA, 0xEBD0A0A2, 0xB9E5, 0x4433, 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7); -DEFINE_GUID(PARTITION_MICROSOFT_LDM_DATA, 0xAF9B60A0, 0x1431, 0x4F62, 0xBC, 0x68, 0x33, 0x11, 0x71, 0x4A, 0x69, 0xAD); -DEFINE_GUID(PARTITION_MICROSOFT_LDM_META, 0x5808C8AA, 0x7E8F, 0x42E0, 0x85, 0xD2, 0xE1, 0xE9, 0x04, 0x34, 0xCF, 0xB3); -DEFINE_GUID(PARTITION_MICROSOFT_RECOVERY, 0xDE94BBA4, 0x06D1, 0x4D40, 0xA1, 0x6A, 0xBF, 0xD5, 0x01, 0x79, 0xD6, 0xAC); -DEFINE_GUID(PARTITION_MICROSOFT_RESERVED, 0xE3C9E316, 0x0B5C, 0x4DB8, 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE); -DEFINE_GUID(PARTITION_MICROSOFT_STORAGE_SPACES, 0xE75CAF8F, 0xF680, 0x4CEE, 0xAF, 0xA3, 0xB0, 0x01, 0xE5, 0x6E, 0xFC, 0x2D); -DEFINE_GUID(PARTITION_NETBSD_CONCAT, 0x2DB519C4, 0xB10F, 0x11DC, 0xB9, 0x9B, 0x00, 0x19, 0xD1, 0x87, 0x96, 0x48); -DEFINE_GUID(PARTITION_NETBSD_ENCRYPTED, 0x2DB519EC, 0xB10F, 0x11DC, 0xB9, 0x9B, 0x00, 0x19, 0xD1, 0x87, 0x96, 0x48); -DEFINE_GUID(PARTITION_NETBSD_FFS, 0x49F48D5A, 0xB10E, 0x11DC, 0xB9, 0x9B, 0x00, 0x19, 0xD1, 0x87, 0x96, 0x48); -DEFINE_GUID(PARTITION_NETBSD_LFS, 0x49F48D82, 0xB10E, 0x11DC, 0xB9, 0x9B, 0x00, 0x19, 0xD1, 0x87, 0x96, 0x48); -DEFINE_GUID(PARTITION_NETBSD_RAID, 0x49F48DAA, 0xB10E, 0x11DC, 0xB9, 0x9B, 0x00, 0x19, 0xD1, 0x87, 0x96, 0x48); -DEFINE_GUID(PARTITION_NETBSD_SWAP, 0x49F48D32, 0xB10E, 0x11DC, 0xB9, 0x9B, 0x00, 0x19, 0xD1, 0x87, 0x96, 0x48); -DEFINE_GUID(PARTITION_OPENBSD_DATA, 0x824CC7A0, 0x36A8, 0x11E3, 0x89, 0x0A, 0x95, 0x25, 0x19, 0xAD, 0x3F, 0x61); -DEFINE_GUID(PARTITION_PLAN9_DATA, 0xC91818F9, 0x8025, 0x47AF, 0x89, 0xD2, 0xF0, 0x30, 0xD7, 0x00, 0x0C, 0x2C); -DEFINE_GUID(PARTITION_PREP_BOOT, 0x9E1A2D38, 0xC612, 0x4316, 0xAA, 0x26, 0x8B, 0x49, 0x52, 0x1E, 0x5A, 0x8B); -DEFINE_GUID(PARTITION_QNX_DATA, 0xCEF5A9AD, 0x73BC, 0x4601, 0x89, 0xF3, 0xCD, 0xEE, 0xEE, 0xE3, 0x21, 0xA1); -DEFINE_GUID(PARTITION_SOLARIS_ALT, 0x6A9283A5, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_BACKUP, 0x6A8B642B, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_BOOT, 0x6A82CB45, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_HOME, 0x6A90BA39, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_RESERVED1, 0x6A945A3B, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_RESERVED2, 0x6A9630D1, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_RESERVED3, 0x6A980767, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_RESERVED4, 0x6A96237F, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_RESERVED5, 0x6A8D2AC7, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -// You sure you don't need a couple more reserved partition GUIDs here, Solaris? -DEFINE_GUID(PARTITION_SOLARIS_ROOT, 0x6A85CF4D, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_SWAP, 0x6A87C46F, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -//DEFINE_GUID(PARTITION_SOLARIS_USR, 0x6A898CC3, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SOLARIS_VAR, 0x6A8EF2E9, 0x1DD2, 0x11B2, 0x99, 0xA6, 0x08, 0x00, 0x20, 0x73, 0x66, 0x31); -DEFINE_GUID(PARTITION_SONY_BOOT, 0xF4019732, 0x066E, 0x4E12, 0x82, 0x73, 0x34, 0x6C, 0x56, 0x41, 0x49, 0x4F); -DEFINE_GUID(PARTITION_VERACRYPT_DATA, 0x8C8F8EFF, 0xAC95, 0x4770, 0x81, 0x4A, 0x21, 0x99, 0x4F, 0x2D, 0xBC, 0x8F); -DEFINE_GUID(PARTITION_VMWARE_COREDUMP, 0x9D275380, 0x40AD, 0x11DB, 0xBF, 0x97, 0x00, 0x0C, 0x29, 0x11, 0xD1, 0xB8); -DEFINE_GUID(PARTITION_VMWARE_RESERVED, 0x9198EFFC, 0x31C0, 0x11DB, 0x8F, 0x78, 0x00, 0x0C, 0x29, 0x11, 0xD1, 0xB8); -DEFINE_GUID(PARTITION_VMWARE_VMFS, 0xAA31E02A, 0x400F, 0x11DB, 0x95, 0x90, 0x00, 0x0C, 0x29, 0x11, 0xD1, 0xB8); - typedef struct { - const GUID* guid; - const char* name; -} gpt_type_t; + uint16_t code; + const char* guid_str; + const char* description; +} gpt_type_entry_t; -gpt_type_t gpt_type[] = { - { &PARTITION_ANDROID_BOOT, "Android Boot Partition" }, - { &PARTITION_ANDROID_BOOTLOADER1, "Android Bootloader Partition" }, - { &PARTITION_ANDROID_BOOTLOADER2, "Android Bootloader Partition" }, - { &PARTITION_ANDROID_CACHE, "Android Cache Partition" }, - { &PARTITION_ANDROID_CONFIG, "Android Config Partition" }, - { &PARTITION_ANDROID_DATA, "Android Data Partition" }, - { &PARTITION_ANDROID_EXT, "Android Ext Partition" }, - { &PARTITION_ANDROID_FACTORY1, "Android Factory Partition" }, - { &PARTITION_ANDROID_FACTORY2, "Android Factory Partition" }, - { &PARTITION_ANDROID_FASTBOOT, "Android Fastboot Partition" }, - { &PARTITION_ANDROID_METADATA1, "Android Metadata Partition" }, - { &PARTITION_ANDROID_METADATA2, "Android Metadata Partition" }, - { &PARTITION_ANDROID_MISC, "Android Misc Partition" }, - { &PARTITION_ANDROID_OEM, "Android OEM Partition" }, - { &PARTITION_ANDROID_PERSISTENCE, "Android Persistent Partition" }, - { &PARTITION_ANDROID_RECOVERY, "Android Recovery Partition" }, - { &PARTITION_ANDROID_SYSTEM, "Android System Partition" }, - { &PARTITION_ANDROID_VENDOR, "Android Vendor Partition" }, - { &PARTITION_APPLE_APFS, "Apple APFS Partition" }, - { &PARTITION_APPLE_BOOT, "Apple Boot Partition" }, - { &PARTITION_APPLE_FILEVAULT, "Apple Filevault Partition" }, - { &PARTITION_APPLE_HFS, "Apple HFS+ Partition" }, - { &PARTITION_APPLE_LABEL, "Apple Label Partition" }, - { &PARTITION_APPLE_OFFLINE_RAID, "Apple RAID Partition (Offline)" }, - { &PARTITION_APPLE_RAID, "Apple RAID Partition" }, - { &PARTITION_APPLE_RAID_CACHE, "Apple RAID Cache Partition" }, - { &PARTITION_APPLE_RAID_SCRATCH, "Apple RAID Scratch Partition" }, - { &PARTITION_APPLE_RAID_STATUS, "Apple RAID Status Partition" }, - { &PARTITION_APPLE_RAID_VOLUME, "Apple RAID Volume Partition" }, - { &PARTITION_APPLE_RECOVERY, "Apple Recovery Partition" }, - { &PARTITION_APPLE_UFS, "Apple UFS Partition" }, - { &PARTITION_APPLE_ZFS, "Apple ZFS Partition" }, - { &PARTITION_ATARI_DATA, "Atari Data Partition" }, - { &PARTITION_BEOS_BFS, "BeOS BFS Partition" }, - { &PARTITION_CHROMEOS_KERNEL, "Chrome OS Kernel Partition" }, - { &PARTITION_CHROMEOS_RESERVED, "Chrome OS Reserved Partition" }, - { &PARTITION_CHROMEOS_ROOT, "Chrome OS Root Partition" }, - { &PARTITION_COREOS_RAID, "CoreOS Raid Partition" }, - { &PARTITION_COREOS_RESERVED, "CoreOS Reserved Partition" }, - { &PARTITION_COREOS_ROOT, "CoreOS Root Partition" }, - { &PARTITION_COREOS_USR, "CoreOS Usr Partition" }, - { &PARTITION_FREEBSD_BOOT, "FreeBSD Boot Partition" }, - { &PARTITION_FREEBSD_DATA, "FreeBSD Data Partition" }, - { &PARTITION_FREEBSD_LVM, "FreeBSD LVM Partition" }, - { &PARTITION_FREEBSD_SWAP, "FreeBSD Swap Partition" }, - { &PARTITION_FREEBSD_UFS, "FreeBSD UFS Partition" }, - { &PARTITION_FREEBSD_ZFS, "FreeBSD ZFS Partition" }, - { &PARTITION_GENERIC_BIOS_BOOT, "BIOS Boot Partition" }, - { &PARTITION_GENERIC_XBOOTLDR, "Extended Boot Loader Partition" }, - { &PARTITION_GENERIC_ESP, "EFI System Partition" }, - { &PARTITION_GENERIC_MBR, "MBR Partition" }, - { &PARTITION_GENERIC_UNUSED, "Unused Partition" }, - { &PARTITION_HPUX_DATA, "HP-UX Data Partition" }, - { &PARTITION_HPUX_SERVICE, "HP-UX Service Partition" }, - { &PARTITION_IBM_GPFS, "IBM GPFS Partition" }, - { &PARTITION_INTEL_IFF, "Intel Fast Flash Partition" }, - { &PARTITION_LENOVO_BOOT, "Lenovo Boot Partition" }, - { &PARTITION_LINUX_BOOT, "Linux Boot Partition" }, - { &PARTITION_LINUX_DATA, "Linux Data Partition" }, - { &PARTITION_LINUX_ENCRYPTED, "Linux Encrypted Partition" }, - { &PARTITION_LINUX_HOME, "Linux Home Partition" }, - { &PARTITION_LINUX_LUKS, "Linux LUKS Partition" }, - { &PARTITION_LINUX_LVM, "Linux LVM Partition" }, - { &PARTITION_LINUX_RAID, "Linux RAID Partition" }, - { &PARTITION_LINUX_RESERVED, "Linux Reserved Partition" }, - { &PARTITION_LINUX_ROOT_ARM_32, "Linux Boot Partition (ARM)" }, - { &PARTITION_LINUX_ROOT_ARM_64, "Linux Boot Partition (ARM64)" }, - { &PARTITION_LINUX_ROOT_X86_32, "Linux Boot Partition (x86-32)" }, - { &PARTITION_LINUX_ROOT_X86_64, "Linux Boot Partition (x86-64)" }, - { &PARTITION_LINUX_SRV, "Linux Srv Partition" }, - { &PARTITION_LINUX_SWAP, "Linux Swap Partition" }, - { &PARTITION_MICROSOFT_DATA, "Microsoft Basic Data Partition" }, - { &PARTITION_MICROSOFT_LDM_DATA, "Microsoft LDM Data Partition" }, - { &PARTITION_MICROSOFT_LDM_META, "Microsoft LDM Metadata Partition" }, - { &PARTITION_MICROSOFT_RECOVERY, "Microsoft Recovery Partition" }, - { &PARTITION_MICROSOFT_RESERVED, "Microsoft System Reserved Partition" }, - { &PARTITION_MICROSOFT_STORAGE_SPACES, "Microsoft Storage Spaces Partition" }, - { &PARTITION_NETBSD_CONCAT, "NetBSD Concatenated Partition" }, - { &PARTITION_NETBSD_ENCRYPTED, "NetBSD Encrypted Partition" }, - { &PARTITION_NETBSD_FFS, "NetBSD FFS Partition" }, - { &PARTITION_NETBSD_LFS, "NetBSD LFS Partition" }, - { &PARTITION_NETBSD_RAID, "NetBSD RAID Partition" }, - { &PARTITION_NETBSD_SWAP, "NetBSD Swap Partition" }, - { &PARTITION_OPENBSD_DATA, "OpenBSD Data Partition" }, - { &PARTITION_PLAN9_DATA, "Plan 9 Data Partition" }, - { &PARTITION_PREP_BOOT, "PReP Boot Partition" }, - { &PARTITION_QNX_DATA, "QNX Data Partition" }, - { &PARTITION_SOLARIS_ALT, "Solaris Alternate Sector Partition" }, - { &PARTITION_SOLARIS_BACKUP, "Solaris Backup Partition" }, - { &PARTITION_SOLARIS_BOOT, "Solaris Boot Partition" }, - { &PARTITION_SOLARIS_HOME, "Solaris Home Partition" }, - { &PARTITION_SOLARIS_RESERVED1, "Solaris Reserved Partition" }, - { &PARTITION_SOLARIS_RESERVED2, "Solaris Reserved Partition" }, - { &PARTITION_SOLARIS_RESERVED3, "Solaris Reserved Partition" }, - { &PARTITION_SOLARIS_RESERVED4, "Solaris Reserved Partition" }, - { &PARTITION_SOLARIS_RESERVED5, "Solaris Reserved Partition" }, - { &PARTITION_SOLARIS_ROOT, "Solaris Root Partition" }, - { &PARTITION_SOLARIS_SWAP, "Solaris Swap Partition" }, -// { &PARTITION_SOLARIS_USR, "Solaris Usr Partition" }, - { &PARTITION_SOLARIS_VAR, "Solaris Var Partition" }, - { &PARTITION_SONY_BOOT, "Sony Boot Partition" }, - { &PARTITION_VERACRYPT_DATA, "VeraCrypt Data Partition" }, - { &PARTITION_VMWARE_COREDUMP, "VMware Coredump Partition" }, - { &PARTITION_VMWARE_RESERVED, "VMware Reserved Partition" }, - { &PARTITION_VMWARE_VMFS, "VMware VMFS Partition" }, +#define AddType(code, guid, desc, ...) { code, guid, desc }, + +/* + * Because we value our sanity, we build our GPT entries from code lifted + * verbatim from Debian's gdisk's parttypes.cc and use AddType() as a macro + * to create a static table. + */ +static const gpt_type_entry_t gpt_type_table[] = { + // From https://salsa.debian.org/debian/gdisk/-/blob/master/parttypes.cc + // Semicolons after Addtype() *MUST* be removed. + + // Start with the "unused entry," which should normally appear only + // on empty partition table entries.... + AddType(0x0000, "00000000-0000-0000-0000-000000000000", "Unused entry", 0) + + // DOS/Windows partition types, most of which are hidden from the "L" listing + // (they're available mainly for MBR-to-GPT conversions). + AddType(0x0100, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // FAT-12 + AddType(0x0400, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // FAT-16 < 32M + AddType(0x0600, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // FAT-16 + AddType(0x0700, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 1) // NTFS (or HPFS) + AddType(0x0701, "558D43C5-A1AC-43C0-AAC8-D1472B2923D1", "Microsoft Storage Replica", 1) + AddType(0x0702, "90B6FF38-B98F-4358-A21F-48F35B4A8AD3", "ArcaOS Type 1", 1) + AddType(0x0b00, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // FAT-32 + AddType(0x0c00, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // FAT-32 LBA + AddType(0x0c01, "E3C9E316-0B5C-4DB8-817D-F92DF00215AE", "Microsoft reserved") + AddType(0x0e00, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // FAT-16 LBA + AddType(0x1100, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // Hidden FAT-12 + AddType(0x1400, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // Hidden FAT-16 < 32M + AddType(0x1600, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // Hidden FAT-16 + AddType(0x1700, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // Hidden NTFS (or HPFS) + AddType(0x1b00, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // Hidden FAT-32 + AddType(0x1c00, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // Hidden FAT-32 LBA + AddType(0x1e00, "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "Microsoft basic data", 0) // Hidden FAT-16 LBA + AddType(0x2700, "DE94BBA4-06D1-4D40-A16A-BFD50179D6AC", "Windows RE") + + // Open Network Install Environment (ONIE) specific types. + // See http://www.onie.org/ and + // https://github.com/opencomputeproject/onie/blob/master/patches/gptfdisk/add-onie-partition-types.patch + AddType(0x3000, "7412F7D5-A156-4B13-81DC-867174929325", "ONIE boot") + AddType(0x3001, "D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149", "ONIE config") + + // Plan 9; see http://man.cat-v.org/9front/8/prep + AddType(0x3900, "C91818F9-8025-47AF-89D2-F030D7000C2C", "Plan 9") + + // PowerPC reference platform boot partition + AddType(0x4100, "9E1A2D38-C612-4316-AA26-8B49521E5A8B", "PowerPC PReP boot") + + // Windows LDM ("dynamic disk") types + AddType(0x4200, "AF9B60A0-1431-4F62-BC68-3311714A69AD", "Windows LDM data") // Logical disk manager + AddType(0x4201, "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3", "Windows LDM metadata") // Logical disk manager + AddType(0x4202, "E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D", "Windows Storage Spaces") // A newer LDM-type setup + + // An oddball IBM filesystem.... + AddType(0x7501, "37AFFC90-EF7D-4E96-91C3-2D7AE055B174", "IBM GPFS") // General Parallel File System (GPFS) + + // ChromeOS-specific partition types... + // Values taken from vboot_reference/firmware/lib/cgptlib/include/gpt.h in + // ChromeOS source code, retrieved 12/23/2010. They're also at + // http://www.chromium.org/chromium-os/chromiumos-design-docs/disk-format. + // These have no MBR equivalents, AFAIK, so I'm using 0x7Fxx values, since they're close + // to the Linux values. + AddType(0x7f00, "FE3A2A5D-4F32-41A7-B725-ACCC3285A309", "ChromeOS kernel") + AddType(0x7f01, "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC", "ChromeOS root") + AddType(0x7f02, "2E0A753D-9E48-43B0-8337-B15192CB1B5E", "ChromeOS reserved") + AddType(0x7f03, "CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3", "ChromeOS firmware") + AddType(0x7f04, "09845860-705F-4BB5-B16C-8A8A099CAF52", "ChromeOS mini-OS") + AddType(0x7f05, "3F0F8318-F146-4E6B-8222-C28C8F02E0D5", "ChromeOS hibernate") + + // Linux-specific partition types.... + AddType(0x8200, "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F", "Linux swap") // Linux swap (or Solaris on MBR) + AddType(0x8300, "0FC63DAF-8483-4772-8E79-3D69D8477DE4", "Linux filesystem") // Linux native + AddType(0x8301, "8DA63339-0007-60C0-C436-083AC8230908", "Linux reserved") + // See https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html + // and https://systemd.io/DISCOVERABLE_PARTITIONS + AddType(0x8302, "933AC7E1-2EB4-4F13-B844-0E14E2AEF915", "Linux /home") // Linux /home (auto-mounted by systemd) + AddType(0x8303, "44479540-F297-41B2-9AF7-D131D5F0458A", "Linux x86 root (/)") // Linux / on x86 (auto-mounted by systemd) + AddType(0x8304, "4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709", "Linux x86-64 root (/)") // Linux / on x86-64 (auto-mounted by systemd) + AddType(0x8305, "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", "Linux ARM64 root (/)") // Linux / on 64-bit ARM (auto-mounted by systemd) + AddType(0x8306, "3B8F8425-20E0-4F3B-907F-1A25A76F98E8", "Linux /srv") // Linux /srv (auto-mounted by systemd) + AddType(0x8307, "69DAD710-2CE4-4E3C-B16C-21A1D49ABED3", "Linux ARM32 root (/)") // Linux / on 32-bit ARM (auto-mounted by systemd) + AddType(0x8308, "7FFEC5C9-2D00-49B7-8941-3EA10A5586B7", "Linux dm-crypt") + AddType(0x8309, "CA7D7CCB-63ED-4C53-861C-1742536059CC", "Linux LUKS") + AddType(0x830A, "993D8D3D-F80E-4225-855A-9DAF8ED7EA97", "Linux IA-64 root (/)") // Linux / on Itanium (auto-mounted by systemd) + AddType(0x830B, "D13C5D3B-B5D1-422A-B29F-9454FDC89D76", "Linux x86 root verity") + AddType(0x830C, "2C7357ED-EBD2-46D9-AEC1-23D437EC2BF5", "Linux x86-64 root verity") + AddType(0x830D, "7386CDF2-203C-47A9-A498-F2ECCE45A2D6", "Linux ARM32 root verity") + AddType(0x830E, "DF3300CE-D69F-4C92-978C-9BFB0F38D820", "Linux ARM64 root verity") + AddType(0x830F, "86ED10D5-B607-45BB-8957-D350F23D0571", "Linux IA-64 root verity") + AddType(0x8310, "4D21B016-B534-45C2-A9FB-5C16E091FD2D", "Linux /var") // Linux /var (auto-mounted by systemd) + AddType(0x8311, "7EC6F557-3BC5-4ACA-B293-16EF5DF639D1", "Linux /var/tmp") // Linux /var/tmp (auto-mounted by systemd) + // https://systemd.io/HOME_DIRECTORY/ + AddType(0x8312, "773F91EF-66D4-49B5-BD83-D683BF40AD16", "Linux user's home") // used by systemd-homed + AddType(0x8313, "75250D76-8CC6-458E-BD66-BD47CC81A812", "Linux x86 /usr ") // Linux /usr on x86 (auto-mounted by systemd) + AddType(0x8314, "8484680C-9521-48C6-9C11-B0720656F69E", "Linux x86-64 /usr") // Linux /usr on x86-64 (auto-mounted by systemd) + AddType(0x8315, "7D0359A3-02B3-4F0A-865C-654403E70625", "Linux ARM32 /usr") // Linux /usr on 32-bit ARM (auto-mounted by systemd) + AddType(0x8316, "B0E01050-EE5F-4390-949A-9101B17104E9", "Linux ARM64 /usr") // Linux /usr on 64-bit ARM (auto-mounted by systemd) + AddType(0x8317, "4301D2A6-4E3B-4B2A-BB94-9E0B2C4225EA", "Linux IA-64 /usr") // Linux /usr on Itanium (auto-mounted by systemd) + AddType(0x8318, "8F461B0D-14EE-4E81-9AA9-049B6FB97ABD", "Linux x86 /usr verity") + AddType(0x8319, "77FF5F63-E7B6-4633-ACF4-1565B864C0E6", "Linux x86-64 /usr verity") + AddType(0x831A, "C215D751-7BCD-4649-BE90-6627490A4C05", "Linux ARM32 /usr verity") + AddType(0x831B, "6E11A4E7-FBCA-4DED-B9E9-E1A512BB664E", "Linux ARM64 /usr verity") + AddType(0x831C, "6A491E03-3BE7-4545-8E38-83320E0EA880", "Linux IA-64 /usr verity") + AddType(0x831D, "6523F8AE-3EB1-4E2A-A05A-18B695AE656F", "Linux Alpha root (/)") + AddType(0x831E, "D27F46ED-2919-4CB8-BD25-9531F3C16534", "Linux ARC root (/)") + AddType(0x831F, "77055800-792C-4F94-B39A-98C91B762BB6", "Linux LoongArch root (/)") + AddType(0x8320, "E9434544-6E2C-47CC-BAE2-12D6DEAFB44C", "Linux MIPS-32 BE root (/)") + AddType(0x8321, "D113AF76-80EF-41B4-BDB6-0CFF4D3D4A25", "Linux MIPS-64 BE root (/)") + AddType(0x8322, "37C58C8A-D913-4156-A25F-48B1B64E07F0", "Linux MIPS-32 LE root (/)") + AddType(0x8323, "700BDA43-7A34-4507-B179-EEB93D7A7CA3", "Linux MIPS-64 LE root (/)") + AddType(0x8324, "1AACDB3B-5444-4138-BD9E-E5C2239B2346", "Linux PA-RISC root (/)") + AddType(0x8325, "1DE3F1EF-FA98-47B5-8DCD-4A860A654D78", "Linux PowerPC-32 root (/)") + AddType(0x8326, "912ADE1D-A839-4913-8964-A10EEE08FBD2", "Linux PowerPC-64 BE root (/)") + AddType(0x8327, "C31C45E6-3F39-412E-80FB-4809C4980599", "Linux PowerPC-64 LE root (/)") + AddType(0x8328, "60D5A7FE-8E7D-435C-B714-3DD8162144E1", "Linux RISC-V-32 root (/)") + AddType(0x8329, "72EC70A6-CF74-40E6-BD49-4BDA08E8F224", "Linux RISC-V-64 root (/)") + AddType(0x832A, "08A7ACEA-624C-4A20-91E8-6E0FA67D23F9", "Linux s390 root (/)") + AddType(0x832B, "5EEAD9A9-FE09-4A1E-A1D7-520D00531306", "Linux s390x root (/)") + AddType(0x832C, "C50CDD70-3862-4CC3-90E1-809A8C93EE2C", "Linux TILE-Gx root (/)") + AddType(0x832D, "E18CF08C-33EC-4C0D-8246-C6C6FB3DA024", "Linux Alpha /usr") + AddType(0x832E, "7978A683-6316-4922-BBEE-38BFF5A2FECC", "Linux ARC /usr") + AddType(0x832F, "E611C702-575C-4CBE-9A46-434FA0BF7E3F", "Linux LoongArch /usr") + AddType(0x8330, "773B2ABC-2A99-4398-8BF5-03BAAC40D02B", "Linux MIPS-32 BE /usr") + AddType(0x8331, "57E13958-7331-4365-8E6E-35EEEE17C61B", "Linux MIPS-64 BE /usr") + AddType(0x8332, "0F4868E9-9952-4706-979F-3ED3A473E947", "Linux MIPS-32 LE /usr") + AddType(0x8333, "C97C1F32-BA06-40B4-9F22-236061B08AA8", "Linux MIPS-64 LE /usr") + AddType(0x8334, "DC4A4480-6917-4262-A4EC-DB9384949F25", "Linux PA-RISC /usr") + AddType(0x8335, "7D14FEC5-CC71-415D-9D6C-06BF0B3C3EAF", "Linux PowerPC-32 /usr") + AddType(0x8336, "2C9739E2-F068-46B3-9FD0-01C5A9AFBCCA", "Linux PowerPC-64 BE /usr") + AddType(0x8337, "15BB03AF-77E7-4D4A-B12B-C0D084F7491C", "Linux PowerPC-64 LE /usr") + AddType(0x8338, "B933FB22-5C3F-4F91-AF90-E2BB0FA50702", "Linux RISC-V-32 /usr") + AddType(0x8339, "BEAEC34B-8442-439B-A40B-984381ED097D", "Linux RISC-V-64 /usr") + AddType(0x833A, "CD0F869B-D0FB-4CA0-B141-9EA87CC78D66", "Linux s390 /usr") + AddType(0x833B, "8A4F5770-50AA-4ED3-874A-99B710DB6FEA", "Linux s390x /usr") + AddType(0x833C, "55497029-C7C1-44CC-AA39-815ED1558630", "Linux TILE-Gx /usr") + AddType(0x833D, "FC56D9E9-E6E5-4C06-BE32-E74407CE09A5", "Linux Alpha root verity") + AddType(0x833E, "24B2D975-0F97-4521-AFA1-CD531E421B8D", "Linux ARC root verity") + AddType(0x833F, "F3393B22-E9AF-4613-A948-9D3BFBD0C535", "Linux LoongArch root verity") + AddType(0x8340, "7A430799-F711-4C7E-8E5B-1D685BD48607", "Linux MIPS-32 BE root verity") + AddType(0x8341, "579536F8-6A33-4055-A95A-DF2D5E2C42A8", "Linux MIPS-64 BE root verity") + AddType(0x8342, "D7D150D2-2A04-4A33-8F12-16651205FF7B", "Linux MIPS-32 LE root verity") + AddType(0x8343, "16B417F8-3E06-4F57-8DD2-9B5232F41AA6", "Linux MIPS-64 LE root verity") + AddType(0x8344, "D212A430-FBC5-49F9-A983-A7FEEF2B8D0E", "Linux PA-RISC root verity") + AddType(0x8345, "906BD944-4589-4AAE-A4E4-DD983917446A", "Linux PowerPC-64 LE root verity") + AddType(0x8346, "9225A9A3-3C19-4D89-B4F6-EEFF88F17631", "Linux PowerPC-64 BE root verity") + AddType(0x8347, "98CFE649-1588-46DC-B2F0-ADD147424925", "Linux PowerPC-32 root verity") + AddType(0x8348, "AE0253BE-1167-4007-AC68-43926C14C5DE", "Linux RISC-V-32 root verity") + AddType(0x8349, "B6ED5582-440B-4209-B8DA-5FF7C419EA3D", "Linux RISC-V-64 root verity") + AddType(0x834A, "7AC63B47-B25C-463B-8DF8-B4A94E6C90E1", "Linux s390 root verity") + AddType(0x834B, "B325BFBE-C7BE-4AB8-8357-139E652D2F6B", "Linux s390x root verity") + AddType(0x834C, "966061EC-28E4-4B2E-B4A5-1F0A825A1D84", "Linux TILE-Gx root verity") + AddType(0x834D, "8CCE0D25-C0D0-4A44-BD87-46331BF1DF67", "Linux Alpha /usr verity") + AddType(0x834E, "FCA0598C-D880-4591-8C16-4EDA05C7347C", "Linux ARC /usr verity") + AddType(0x834F, "F46B2C26-59AE-48F0-9106-C50ED47F673D", "Linux LoongArch /usr verity") + AddType(0x8350, "6E5A1BC8-D223-49B7-BCA8-37A5FCCEB996", "Linux MIPS-32 BE /usr verity") + AddType(0x8351, "81CF9D90-7458-4DF4-8DCF-C8A3A404F09B", "Linux MIPS-64 BE /usr verity") + AddType(0x8352, "46B98D8D-B55C-4E8F-AAB3-37FCA7F80752", "Linux MIPS-32 LE /usr verity") + AddType(0x8353, "3C3D61FE-B5F3-414D-BB71-8739A694A4EF", "Linux MIPS-64 LE /usr verity") + AddType(0x8354, "5843D618-EC37-48D7-9F12-CEA8E08768B2", "Linux PA-RISC /usr verity") + AddType(0x8355, "EE2B9983-21E8-4153-86D9-B6901A54D1CE", "Linux PowerPC-64 LE /usr verity") + AddType(0x8356, "BDB528A5-A259-475F-A87D-DA53FA736A07", "Linux PowerPC-64 BE /usr verity") + AddType(0x8357, "DF765D00-270E-49E5-BC75-F47BB2118B09", "Linux PowerPC-32 /usr verity") + AddType(0x8358, "CB1EE4E3-8CD0-4136-A0A4-AA61A32E8730", "Linux RISC-V-32 /usr verity") + AddType(0x8359, "8F1056BE-9B05-47C4-81D6-BE53128E5B54", "Linux RISC-V-64 /usr verity") + AddType(0x835A, "B663C618-E7BC-4D6D-90AA-11B756BB1797", "Linux s390 /usr verity") + AddType(0x835B, "31741CC4-1A2A-4111-A581-E00B447D2D06", "Linux s390x /usr verity") + AddType(0x835C, "2FB4BF56-07FA-42DA-8132-6B139F2026AE", "Linux TILE-Gx /usr verity") + AddType(0x835D, "D46495B7-A053-414F-80F7-700C99921EF8", "Linux Alpha root verity signature") + AddType(0x835E, "143A70BA-CBD3-4F06-919F-6C05683A78BC", "Linux ARC root verity signature") + AddType(0x835F, "42B0455F-EB11-491D-98D3-56145BA9D037", "Linux ARM32 root verity signature") + AddType(0x8360, "6DB69DE6-29F4-4758-A7A5-962190F00CE3", "Linux ARM64 root verity signature") + AddType(0x8361, "E98B36EE-32BA-4882-9B12-0CE14655F46A", "Linux IA-64 root verity signature") + AddType(0x8362, "5AFB67EB-ECC8-4F85-AE8E-AC1E7C50E7D0", "Linux LoongArch root verity signature") + AddType(0x8363, "BBA210A2-9C5D-45EE-9E87-FF2CCBD002D0", "Linux MIPS-32 BE root verity signature") + AddType(0x8364, "43CE94D4-0F3D-4999-8250-B9DEAFD98E6E", "Linux MIPS-64 BE root verity signature") + AddType(0x8365, "C919CC1F-4456-4EFF-918C-F75E94525CA5", "Linux MIPS-32 LE root verity signature") + AddType(0x8366, "904E58EF-5C65-4A31-9C57-6AF5FC7C5DE7", "Linux MIPS-64 LE root verity signature") + AddType(0x8367, "15DE6170-65D3-431C-916E-B0DCD8393F25", "Linux PA-RISC root verity signature") + AddType(0x8368, "D4A236E7-E873-4C07-BF1D-BF6CF7F1C3C6", "Linux PowerPC-64 LE root verity signature") + AddType(0x8369, "F5E2C20C-45B2-4FFA-BCE9-2A60737E1AAF", "Linux PowerPC-64 BE root verity signature") + AddType(0x836A, "1B31B5AA-ADD9-463A-B2ED-BD467FC857E7", "Linux PowerPC-32 root verity signature") + AddType(0x836B, "3A112A75-8729-4380-B4CF-764D79934448", "Linux RISC-V-32 root verity signature") + AddType(0x836C, "EFE0F087-EA8D-4469-821A-4C2A96A8386A", "Linux RISC-V-64 root verity signature") + AddType(0x836D, "3482388E-4254-435A-A241-766A065F9960", "Linux s390 root verity signature") + AddType(0x836E, "C80187A5-73A3-491A-901A-017C3FA953E9", "Linux s390x root verity signature") + AddType(0x836F, "B3671439-97B0-4A53-90F7-2D5A8F3AD47B", "Linux TILE-Gx root verity signature") + AddType(0x8370, "41092B05-9FC8-4523-994F-2DEF0408B176", "Linux x86-64 root verity signature") + AddType(0x8371, "5996FC05-109C-48DE-808B-23FA0830B676", "Linux x86 root verity signature") + AddType(0x8372, "5C6E1C76-076A-457A-A0FE-F3B4CD21CE6E", "Linux Alpha /usr verity signature") + AddType(0x8373, "94F9A9A1-9971-427A-A400-50CB297F0F35", "Linux ARC /usr verity signature") + AddType(0x8374, "D7FF812F-37D1-4902-A810-D76BA57B975A", "Linux ARM32 /usr verity signature") + AddType(0x8375, "C23CE4FF-44BD-4B00-B2D4-B41B3419E02A", "Linux ARM64 /usr verity signature") + AddType(0x8376, "8DE58BC2-2A43-460D-B14E-A76E4A17B47F", "Linux IA-64 /usr verity signature") + AddType(0x8377, "B024F315-D330-444C-8461-44BBDE524E99", "Linux LoongArch /usr verity signature") + AddType(0x8378, "97AE158D-F216-497B-8057-F7F905770F54", "Linux MIPS-32 BE /usr verity signature") + AddType(0x8379, "05816CE2-DD40-4AC6-A61D-37D32DC1BA7D", "Linux MIPS-64 BE /usr verity signature") + AddType(0x837A, "3E23CA0B-A4BC-4B4E-8087-5AB6A26AA8A9", "Linux MIPS-32 LE /usr verity signature") + AddType(0x837B, "F2C2C7EE-ADCC-4351-B5C6-EE9816B66E16", "Linux MIPS-64 LE /usr verity signature") + AddType(0x837C, "450DD7D1-3224-45EC-9CF2-A43A346D71EE", "Linux PA-RISC /usr verity signature") + AddType(0x837D, "C8BFBD1E-268E-4521-8BBA-BF314C399557", "Linux PowerPC-64 LE /usr verity signature") + AddType(0x837E, "0B888863-D7F8-4D9E-9766-239FCE4D58AF", "Linux PowerPC-64 BE /usr verity signature") + AddType(0x837F, "7007891D-D371-4A80-86A4-5CB875B9302E", "Linux PowerPC-32 /usr verity signature") + AddType(0x8380, "C3836A13-3137-45BA-B583-B16C50FE5EB4", "Linux RISC-V-32 /usr verity signature") + AddType(0x8381, "D2F9000A-7A18-453F-B5CD-4D32F77A7B32", "Linux RISC-V-64 /usr verity signature") + AddType(0x8382, "17440E4F-A8D0-467F-A46E-3912AE6EF2C5", "Linux s390 /usr verity signature") + AddType(0x8383, "3F324816-667B-46AE-86EE-9B0C0C6C11B4", "Linux s390x /usr verity signature") + AddType(0x8384, "4EDE75E2-6CCC-4CC8-B9C7-70334B087510", "Linux TILE-Gx /usr verity signature") + AddType(0x8385, "E7BB33FB-06CF-4E81-8273-E543B413E2E2", "Linux x86-64 /usr verity signature") + AddType(0x8386, "974A71C0-DE41-43C3-BE5D-5C5CCD1AD2C0", "Linux x86 /usr verity signature") + + // Used by Intel Rapid Start technology + AddType(0x8400, "D3BFE2DE-3DAF-11DF-BA40-E3A556D89593", "Intel Rapid Start") + // This is another Intel-associated technology, so I'm keeping it close to the previous one.... + AddType(0x8401, "7C5222BD-8F5D-4087-9C00-BF9843C7B58C", "SPDK block device") + + // Type codes for Container Linux (formerly CoreOS; https://coreos.com) + AddType(0x8500, "5DFBF5F4-2848-4BAC-AA5E-0D9A20B745A6", "Container Linux /usr") + AddType(0x8501, "3884DD41-8582-4404-B9A8-E9B84F2DF50E", "Container Linux resizable rootfs") + AddType(0x8502, "C95DC21A-DF0E-4340-8D7B-26CBFA9A03E0", "Container Linux /OEM customizations") + AddType(0x8503, "BE9067B9-EA49-4F15-B4F6-F36F8C9E1818", "Container Linux root on RAID") + + // Another Linux type code.... + AddType(0x8e00, "E6D6D379-F507-44C2-A23C-238F2A3DF928", "Linux LVM") + + // Android type codes.... + // from Wikipedia, https://gist.github.com/culots/704afd126dec2f45c22d0c9d42cb7fab, + // and my own Android devices' partition tables + AddType(0xa000, "2568845D-2332-4675-BC39-8FA5A4748D15", "Android bootloader") + AddType(0xa001, "114EAFFE-1552-4022-B26E-9B053604CF84", "Android bootloader 2") + AddType(0xa002, "49A4D17F-93A3-45C1-A0DE-F50B2EBE2599", "Android boot 1") + AddType(0xa003, "4177C722-9E92-4AAB-8644-43502BFD5506", "Android recovery 1") + AddType(0xa004, "EF32A33B-A409-486C-9141-9FFB711F6266", "Android misc") + AddType(0xa005, "20AC26BE-20B7-11E3-84C5-6CFDB94711E9", "Android metadata") + AddType(0xa006, "38F428E6-D326-425D-9140-6E0EA133647C", "Android system 1") + AddType(0xa007, "A893EF21-E428-470A-9E55-0668FD91A2D9", "Android cache") + AddType(0xa008, "DC76DDA9-5AC1-491C-AF42-A82591580C0D", "Android data") + AddType(0xa009, "EBC597D0-2053-4B15-8B64-E0AAC75F4DB1", "Android persistent") + AddType(0xa00a, "8F68CC74-C5E5-48DA-BE91-A0C8C15E9C80", "Android factory") + AddType(0xa00b, "767941D0-2085-11E3-AD3B-6CFDB94711E9", "Android fastboot/tertiary") + AddType(0xa00c, "AC6D7924-EB71-4DF8-B48D-E267B27148FF", "Android OEM") + AddType(0xa00d, "C5A0AEEC-13EA-11E5-A1B1-001E67CA0C3C", "Android vendor") + AddType(0xa00e, "BD59408B-4514-490D-BF12-9878D963F378", "Android config") + AddType(0xa00f, "9FDAA6EF-4B3F-40D2-BA8D-BFF16BFB887B", "Android factory (alt)") + AddType(0xa010, "19A710A2-B3CA-11E4-B026-10604B889DCF", "Android meta") + AddType(0xa011, "193D1EA4-B3CA-11E4-B075-10604B889DCF", "Android EXT") + AddType(0xa012, "DEA0BA2C-CBDD-4805-B4F9-F428251C3E98", "Android SBL1") + AddType(0xa013, "8C6B52AD-8A9E-4398-AD09-AE916E53AE2D", "Android SBL2") + AddType(0xa014, "05E044DF-92F1-4325-B69E-374A82E97D6E", "Android SBL3") + AddType(0xa015, "400FFDCD-22E0-47E7-9A23-F16ED9382388", "Android APPSBL") + AddType(0xa016, "A053AA7F-40B8-4B1C-BA08-2F68AC71A4F4", "Android QSEE/tz") + AddType(0xa017, "E1A6A689-0C8D-4CC6-B4E8-55A4320FBD8A", "Android QHEE/hyp") + AddType(0xa018, "098DF793-D712-413D-9D4E-89D711772228", "Android RPM") + AddType(0xa019, "D4E0D938-B7FA-48C1-9D21-BC5ED5C4B203", "Android WDOG debug/sdi") + AddType(0xa01a, "20A0C19C-286A-42FA-9CE7-F64C3226A794", "Android DDR") + AddType(0xa01b, "A19F205F-CCD8-4B6D-8F1E-2D9BC24CFFB1", "Android CDT") + AddType(0xa01c, "66C9B323-F7FC-48B6-BF96-6F32E335A428", "Android RAM dump") + AddType(0xa01d, "303E6AC3-AF15-4C54-9E9B-D9A8FBECF401", "Android SEC") + AddType(0xa01e, "C00EEF24-7709-43D6-9799-DD2B411E7A3C", "Android PMIC") + AddType(0xa01f, "82ACC91F-357C-4A68-9C8F-689E1B1A23A1", "Android misc 1") + AddType(0xa020, "E2802D54-0545-E8A1-A1E8-C7A3E245ACD4", "Android misc 2") + AddType(0xa021, "65ADDCF4-0C5C-4D9A-AC2D-D90B5CBFCD03", "Android device info") + AddType(0xa022, "E6E98DA2-E22A-4D12-AB33-169E7DEAA507", "Android APDP") + AddType(0xa023, "ED9E8101-05FA-46B7-82AA-8D58770D200B", "Android MSADP") + AddType(0xa024, "11406F35-1173-4869-807B-27DF71802812", "Android DPO") + AddType(0xa025, "9D72D4E4-9958-42DA-AC26-BEA7A90B0434", "Android recovery 2") + AddType(0xa026, "6C95E238-E343-4BA8-B489-8681ED22AD0B", "Android persist") + AddType(0xa027, "EBBEADAF-22C9-E33B-8F5D-0E81686A68CB", "Android modem ST1") + AddType(0xa028, "0A288B1F-22C9-E33B-8F5D-0E81686A68CB", "Android modem ST2") + AddType(0xa029, "57B90A16-22C9-E33B-8F5D-0E81686A68CB", "Android FSC") + AddType(0xa02a, "638FF8E2-22C9-E33B-8F5D-0E81686A68CB", "Android FSG 1") + AddType(0xa02b, "2013373E-1AC4-4131-BFD8-B6A7AC638772", "Android FSG 2") + AddType(0xa02c, "2C86E742-745E-4FDD-BFD8-B6A7AC638772", "Android SSD") + AddType(0xa02d, "DE7D4029-0F5B-41C8-AE7E-F6C023A02B33", "Android keystore") + AddType(0xa02e, "323EF595-AF7A-4AFA-8060-97BE72841BB9", "Android encrypt") + AddType(0xa02f, "45864011-CF89-46E6-A445-85262E065604", "Android EKSST") + AddType(0xa030, "8ED8AE95-597F-4C8A-A5BD-A7FF8E4DFAA9", "Android RCT") + AddType(0xa031, "DF24E5ED-8C96-4B86-B00B-79667DC6DE11", "Android spare1") + AddType(0xa032, "7C29D3AD-78B9-452E-9DEB-D098D542F092", "Android spare2") + AddType(0xa033, "379D107E-229E-499D-AD4F-61F5BCF87BD4", "Android spare3") + AddType(0xa034, "0DEA65E5-A676-4CDF-823C-77568B577ED5", "Android spare4") + AddType(0xa035, "4627AE27-CFEF-48A1-88FE-99C3509ADE26", "Android raw resources") + AddType(0xa036, "20117F86-E985-4357-B9EE-374BC1D8487D", "Android boot 2") + AddType(0xa037, "86A7CB80-84E1-408C-99AB-694F1A410FC7", "Android FOTA") + AddType(0xa038, "97D7B011-54DA-4835-B3C4-917AD6E73D74", "Android system 2") + AddType(0xa039, "5594C694-C871-4B5F-90B1-690A6F68E0F7", "Android cache") + AddType(0xa03a, "1B81E7E6-F50D-419B-A739-2AEEF8DA3335", "Android user data") + AddType(0xa03b, "98523EC6-90FE-4C67-B50A-0FC59ED6F56D", "LG (Android) advanced flasher") + AddType(0xa03c, "2644BCC0-F36A-4792-9533-1738BED53EE3", "Android PG1FS") + AddType(0xa03d, "DD7C91E9-38C9-45C5-8A12-4A80F7E14057", "Android PG2FS") + AddType(0xa03e, "7696D5B6-43FD-4664-A228-C563C4A1E8CC", "Android board info") + AddType(0xa03f, "0D802D54-058D-4A20-AD2D-C7A362CEACD4", "Android MFG") + AddType(0xa040, "10A0C19C-516A-5444-5CE3-664C3226A794", "Android limits") + + // Atari TOS partition type + AddType(0xa200, "734E5AFE-F61A-11E6-BC64-92361F002671", "Atari TOS basic data") + + // FreeBSD partition types.... + // Note: Rather than extract FreeBSD disklabel data, convert FreeBSD + // partitions in-place, and let FreeBSD sort out the details.... + AddType(0xa500, "516E7CB4-6ECF-11D6-8FF8-00022D09712B", "FreeBSD disklabel") + AddType(0xa501, "83BD6B9D-7F41-11DC-BE0B-001560B84F0F", "FreeBSD boot") + AddType(0xa502, "516E7CB5-6ECF-11D6-8FF8-00022D09712B", "FreeBSD swap") + AddType(0xa503, "516E7CB6-6ECF-11D6-8FF8-00022D09712B", "FreeBSD UFS") + AddType(0xa504, "516E7CBA-6ECF-11D6-8FF8-00022D09712B", "FreeBSD ZFS") + AddType(0xa505, "516E7CB8-6ECF-11D6-8FF8-00022D09712B", "FreeBSD Vinum/RAID") + AddType(0xa506, "74BA7DD9-A689-11E1-BD04-00E081286ACF", "FreeBSD nandfs") + + // Midnight BSD partition types.... + AddType(0xa580, "85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7", "Midnight BSD data") + AddType(0xa581, "85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7", "Midnight BSD boot") + AddType(0xa582, "85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7", "Midnight BSD swap") + AddType(0xa583, "0394Ef8B-237E-11E1-B4B3-E89A8F7FC3A7", "Midnight BSD UFS") + AddType(0xa584, "85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7", "Midnight BSD ZFS") + AddType(0xa585, "85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7", "Midnight BSD Vinum") + + // OpenBSD partition type.... + AddType(0xa600, "824CC7A0-36A8-11E3-890A-952519AD3F61", "OpenBSD disklabel") + + // A MacOS partition type, separated from others by NetBSD partition types... + AddType(0xa800, "55465300-0000-11AA-AA11-00306543ECAC", "Apple UFS") // Mac OS X + + // NetBSD partition types. Note that the main entry sets it up as a + // FreeBSD disklabel. I'm not 100% certain this is the correct behavior. + AddType(0xa900, "516E7CB4-6ECF-11D6-8FF8-00022D09712B", "FreeBSD disklabel", 0) // NetBSD disklabel + AddType(0xa901, "49F48D32-B10E-11DC-B99B-0019D1879648", "NetBSD swap") + AddType(0xa902, "49F48D5A-B10E-11DC-B99B-0019D1879648", "NetBSD FFS") + AddType(0xa903, "49F48D82-B10E-11DC-B99B-0019D1879648", "NetBSD LFS") + AddType(0xa904, "2DB519C4-B10F-11DC-B99B-0019D1879648", "NetBSD concatenated") + AddType(0xa905, "2DB519EC-B10F-11DC-B99B-0019D1879648", "NetBSD encrypted") + AddType(0xa906, "49F48DAA-B10E-11DC-B99B-0019D1879648", "NetBSD RAID") + + // Mac OS partition types (See also 0xa800, above).... + AddType(0xab00, "426F6F74-0000-11AA-AA11-00306543ECAC", "Recovery HD") + AddType(0xaf00, "48465300-0000-11AA-AA11-00306543ECAC", "Apple HFS/HFS+") + AddType(0xaf01, "52414944-0000-11AA-AA11-00306543ECAC", "Apple RAID") + AddType(0xaf02, "52414944-5F4F-11AA-AA11-00306543ECAC", "Apple RAID offline") + AddType(0xaf03, "4C616265-6C00-11AA-AA11-00306543ECAC", "Apple label") + AddType(0xaf04, "5265636F-7665-11AA-AA11-00306543ECAC", "AppleTV recovery") + AddType(0xaf05, "53746F72-6167-11AA-AA11-00306543ECAC", "Apple Core Storage") + AddType(0xaf06, "B6FA30DA-92D2-4A9A-96F1-871EC6486200", "Apple SoftRAID Status") + AddType(0xaf07, "2E313465-19B9-463F-8126-8A7993773801", "Apple SoftRAID Scratch") + AddType(0xaf08, "FA709C7E-65B1-4593-BFD5-E71D61DE9B02", "Apple SoftRAID Volume") + AddType(0xaf09, "BBBA6DF5-F46F-4A89-8F59-8765B2727503", "Apple SoftRAID Cache") + AddType(0xaf0a, "7C3457EF-0000-11AA-AA11-00306543ECAC", "Apple APFS") + AddType(0xaf0b, "69646961-6700-11AA-AA11-00306543ECAC", "Apple APFS Pre-Boot") + AddType(0xaf0c, "52637672-7900-11AA-AA11-00306543ECAC", "Apple APFS Recovery") + + // U-Boot boot loader; see https://lists.denx.de/pipermail/u-boot/2020-November/432928.html + // and https://source.denx.de/u-boot/u-boot/-/blob/v2021.07/include/part_efi.h#L59-61 + AddType(0xb000, "3DE21764-95BD-54BD-A5C3-4ABE786F38A8", "U-Boot boot loader") + + // QNX Power-Safe (QNX6) + AddType(0xb300, "CEF5A9AD-73BC-4601-89F3-CDEEEEE321A1", "QNX6 Power-Safe") + + // Barebox boot loader; see https://barebox.org/doc/latest/user/state.html?highlight=guid#sd-emmc-and-ata + AddType(0xbb00, "4778ED65-BF42-45FA-9C5B-287A1DC4AAB1", "Barebox boot loader") + + // Acronis Secure Zone + AddType(0xbc00, "0311FC50-01CA-4725-AD77-9ADBB20ACE98", "Acronis Secure Zone") + + // Solaris partition types (one of which is shared with MacOS) + AddType(0xbe00, "6A82CB45-1DD2-11B2-99A6-080020736631", "Solaris boot") + AddType(0xbf00, "6A85CF4D-1DD2-11B2-99A6-080020736631", "Solaris root") + AddType(0xbf01, "6A898CC3-1DD2-11B2-99A6-080020736631", "Solaris /usr & Mac ZFS") // Solaris/MacOS + AddType(0xbf02, "6A87C46F-1DD2-11B2-99A6-080020736631", "Solaris swap") + AddType(0xbf03, "6A8B642B-1DD2-11B2-99A6-080020736631", "Solaris backup") + AddType(0xbf04, "6A8EF2E9-1DD2-11B2-99A6-080020736631", "Solaris /var") + AddType(0xbf05, "6A90BA39-1DD2-11B2-99A6-080020736631", "Solaris /home") + AddType(0xbf06, "6A9283A5-1DD2-11B2-99A6-080020736631", "Solaris alternate sector") + AddType(0xbf07, "6A945A3B-1DD2-11B2-99A6-080020736631", "Solaris Reserved 1") + AddType(0xbf08, "6A9630D1-1DD2-11B2-99A6-080020736631", "Solaris Reserved 2") + AddType(0xbf09, "6A980767-1DD2-11B2-99A6-080020736631", "Solaris Reserved 3") + AddType(0xbf0a, "6A96237F-1DD2-11B2-99A6-080020736631", "Solaris Reserved 4") + AddType(0xbf0b, "6A8D2AC7-1DD2-11B2-99A6-080020736631", "Solaris Reserved 5") + + // I can find no MBR equivalents for these, but they're on the + // Wikipedia page for GPT, so here we go.... + AddType(0xc001, "75894C1E-3AEB-11D3-B7C1-7B03A0000000", "HP-UX data") + AddType(0xc002, "E2A1E728-32E3-11D6-A682-7B03A0000000", "HP-UX service") + + // Open Network Install Environment (ONIE) partitions.... + AddType(0xe100, "7412F7D5-A156-4B13-81DC-867174929325", "ONIE boot") + AddType(0xe101, "D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149", "ONIE config") + + // Veracrypt (https://www.veracrypt.fr/en/Home.html) encrypted partition + AddType(0xe900, "8C8F8EFF-AC95-4770-814A-21994F2DBC8F", "Veracrypt data") + + // See https://systemd.io/BOOT_LOADER_SPECIFICATION/ + AddType(0xea00, "BC13C2FF-59E6-4262-A352-B275FD6F7172", "XBOOTLDR partition") + + // Type code for Haiku; uses BeOS MBR code as hex code base + AddType(0xeb00, "42465331-3BA3-10F1-802A-4861696B7521", "Haiku BFS") + + // Manufacturer-specific ESP-like partitions (in order in which they were added) + AddType(0xed00, "F4019732-066E-4E12-8273-346C5641494F", "Sony system partition") + AddType(0xed01, "BFBFAFE7-A34F-448A-9A5B-6213EB736C22", "Lenovo system partition") + + // EFI system and related partitions + AddType(0xef00, "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", "EFI system partition") // Parted identifies these as having the "boot flag" set + AddType(0xef01, "024DEE41-33E7-11D3-9D69-0008C781F39F", "MBR partition scheme") // Used to nest MBR in GPT + AddType(0xef02, "21686148-6449-6E6F-744E-656564454649", "BIOS boot partition") // Used by GRUB + + // Fuscia OS codes; see https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/system/public/zircon/hw/gpt.h + AddType(0xf100, "FE8A2634-5E2E-46BA-99E3-3A192091A350", "Fuchsia boot loader (slot A/B/R)") + AddType(0xf101, "D9FD4535-106C-4CEC-8D37-DFC020CA87CB", "Fuchsia durable mutable encrypted system data") + AddType(0xf102, "A409E16B-78AA-4ACC-995C-302352621A41", "Fuchsia durable mutable boot loader") + AddType(0xf103, "F95D940E-CABA-4578-9B93-BB6C90F29D3E", "Fuchsia factory ro system data") + AddType(0xf104, "10B8DBAA-D2BF-42A9-98C6-A7C5DB3701E7", "Fuchsia factory ro bootloader data") + AddType(0xf105, "49FD7CB8-DF15-4E73-B9D9-992070127F0F", "Fuchsia Volume Manager") + AddType(0xf106, "421A8BFC-85D9-4D85-ACDA-B64EEC0133E9", "Fuchsia verified boot metadata (slot A/B/R)") + AddType(0xf107, "9B37FFF6-2E58-466A-983A-F7926D0B04E0", "Fuchsia Zircon boot image (slot A/B/R)") + AddType(0xf108, "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", "Fuchsia ESP") + AddType(0xf109, "606B000B-B7C7-4653-A7D5-B737332C899D", "Fuchsia System") + AddType(0xf10a, "08185F0C-892D-428A-A789-DBEEC8F55E6A", "Fuchsia Data") + AddType(0xf10b, "48435546-4953-2041-494E-5354414C4C52", "Fuchsia Install") + AddType(0xf10c, "2967380E-134C-4CBB-B6DA-17E7CE1CA45D", "Fuchsia Blob") + AddType(0xf10d, "41D0E340-57E3-954E-8C1E-17ECAC44CFF5", "Fuchsia FVM") + AddType(0xf10e, "DE30CC86-1F4A-4A31-93C4-66F147D33E05", "Fuchsia Zircon boot image (slot A)") + AddType(0xf10f, "23CC04DF-C278-4CE7-8471-897D1A4BCDF7", "Fuchsia Zircon boot image (slot B)") + AddType(0xf110, "A0E5CF57-2DEF-46BE-A80C-A2067C37CD49", "Fuchsia Zircon boot image (slot R)") + AddType(0xf111, "4E5E989E-4C86-11E8-A15B-480FCF35F8E6", "Fuchsia sys-config") + AddType(0xf112, "5A3A90BE-4C86-11E8-A15B-480FCF35F8E6", "Fuchsia factory-config") + AddType(0xf113, "5ECE94FE-4C86-11E8-A15B-480FCF35F8E6", "Fuchsia bootloader") + AddType(0xf114, "8B94D043-30BE-4871-9DFA-D69556E8C1F3", "Fuchsia guid-test") + AddType(0xf115, "A13B4D9A-EC5F-11E8-97D8-6C3BE52705BF", "Fuchsia verified boot metadata (A)") + AddType(0xf116, "A288ABF2-EC5F-11E8-97D8-6C3BE52705BF", "Fuchsia verified boot metadata (B)") + AddType(0xf117, "6A2460C3-CD11-4E8B-80A8-12CCE268ED0A", "Fuchsia verified boot metadata (R)") + AddType(0xf118, "1D75395D-F2C6-476B-A8B7-45CC1C97B476", "Fuchsia misc") + AddType(0xf119, "900B0FC5-90CD-4D4F-84F9-9F8ED579DB88", "Fuchsia emmc-boot1") + AddType(0xf11a, "B2B2E8D1-7C10-4EBC-A2D0-4614568260AD", "Fuchsia emmc-boot2") + + // Ceph type codes; see https://github.com/ceph/ceph/blob/9bcc42a3e6b08521694b5c0228b2c6ed7b3d312e/src/ceph-disk#L76-L81 + // and Wikipedia + AddType(0xf800, "4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D", "Ceph OSD") // Ceph Object Storage Daemon + AddType(0xf801, "4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D", "Ceph dm-crypt OSD") // Ceph Object Storage Daemon (encrypted) + AddType(0xf802, "45B0969E-9B03-4F30-B4C6-B4B80CEFF106", "Ceph journal") + AddType(0xf803, "45B0969E-9B03-4F30-B4C6-5EC00CEFF106", "Ceph dm-crypt journal") + AddType(0xf804, "89C57F98-2FE5-4DC0-89C1-F3AD0CEFF2BE", "Ceph disk in creation") + AddType(0xf805, "89C57F98-2FE5-4DC0-89C1-5EC00CEFF2BE", "Ceph dm-crypt disk in creation") + AddType(0xf806, "CAFECAFE-9B03-4F30-B4C6-B4B80CEFF106", "Ceph block") + AddType(0xf807, "30CD0809-C2B2-499C-8879-2D6B78529876", "Ceph block DB") + AddType(0xf808, "5CE17FCE-4087-4169-B7FF-056CC58473F9", "Ceph block write-ahead log") + AddType(0xf809, "FB3AABF9-D25F-47CC-BF5E-721D1816496B", "Ceph lockbox for dm-crypt keys") + AddType(0xf80a, "4FBD7E29-8AE0-4982-BF9D-5A8D867AF560", "Ceph multipath OSD") + AddType(0xf80b, "45B0969E-8AE0-4982-BF9D-5A8D867AF560", "Ceph multipath journal") + AddType(0xf80c, "CAFECAFE-8AE0-4982-BF9D-5A8D867AF560", "Ceph multipath block 1") + AddType(0xf80d, "7F4A666A-16F3-47A2-8445-152EF4D03F6C", "Ceph multipath block 2") + AddType(0xf80e, "EC6D6385-E346-45DC-BE91-DA2A7C8B3261", "Ceph multipath block DB") + AddType(0xf80f, "01B41E1B-002A-453C-9F17-88793989FF8F", "Ceph multipath block write-ahead log") + AddType(0xf810, "CAFECAFE-9B03-4F30-B4C6-5EC00CEFF106", "Ceph dm-crypt block") + AddType(0xf811, "93B0052D-02D9-4D8A-A43B-33A3EE4DFBC3", "Ceph dm-crypt block DB") + AddType(0xf812, "306E8683-4FE2-4330-B7C0-00A917C16966", "Ceph dm-crypt block write-ahead log") + AddType(0xf813, "45B0969E-9B03-4F30-B4C6-35865CEFF106", "Ceph dm-crypt LUKS journal") + AddType(0xf814, "CAFECAFE-9B03-4F30-B4C6-35865CEFF106", "Ceph dm-crypt LUKS block") + AddType(0xf815, "166418DA-C469-4022-ADF4-B30AFD37F176", "Ceph dm-crypt LUKS block DB") + AddType(0xf816, "86A32090-3647-40B9-BBBD-38D8C573AA86", "Ceph dm-crypt LUKS block write-ahead log") + AddType(0xf817, "4FBD7E29-9D25-41B8-AFD0-35865CEFF05D", "Ceph dm-crypt LUKS OSD") + + // VMWare ESX partition types codes + AddType(0xfb00, "AA31E02A-400F-11DB-9590-000C2911D1B8", "VMWare VMFS") + AddType(0xfb01, "9198EFFC-31C0-11DB-8F78-000C2911D1B8", "VMWare reserved") + AddType(0xfc00, "9D275380-40AD-11DB-BF97-000C2911D1B8", "VMWare kcore crash protection") + + // A straggler Linux partition type.... + AddType(0xfd00, "A19D880F-05FC-4D3B-A006-743F0F84911E", "Linux RAID") }; +#undef AddType + +static inline const gpt_type_entry_t* gpt_type_lookup(uint16_t code) +{ + for (int i = 0; i < ARRAYSIZE(gpt_type_table); i++) { + if (gpt_type_table[i].code == code) + return &gpt_type_table[i]; + } + return NULL; +} + +static inline const char* gpt_type_desc(const GUID* guid) +{ + const char* guid_str = GuidToString(guid, TRUE); + if (guid_str == NULL) + return NULL; + for (int i = 0; i < ARRAYSIZE(gpt_type_table); i++) { + if (_strnicmp(&guid_str[1], gpt_type_table[i].guid_str, 36) == 0) + return gpt_type_table[i].description; + } + return NULL; +} + +static inline const char* gpt_type_guid_str(uint16_t code) +{ + const gpt_type_entry_t* e = gpt_type_lookup(code); + return (e != NULL) ? e->guid_str : NULL; +} + +static inline const char* gpt_type_description(uint16_t code) +{ + const gpt_type_entry_t* e = gpt_type_lookup(code); + return (e != NULL) ? e->description : NULL; +} + +static inline GUID gpt_type_guid(uint16_t code) +{ + return StringToGuid(gpt_type_guid_str(code)); +} + +// Also redefine the constant GUIDs we use in the application +DEFINE_GUID(PARTITION_GENERIC_ESP, 0xC12A7328, 0xF81F, 0x11D2, 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B); +DEFINE_GUID(PARTITION_LINUX_DATA, 0x0FC63DAF, 0x8483, 0x4772, 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4); +DEFINE_GUID(PARTITION_MICROSOFT_DATA, 0xEBD0A0A2, 0xB9E5, 0x4433, 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7); +DEFINE_GUID(PARTITION_MICROSOFT_RESERVED, 0xE3C9E316, 0x0B5C, 0x4DB8, 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE); diff --git a/src/license.h b/src/license.h index 4ddeae4c..a7781b49 100644 --- a/src/license.h +++ b/src/license.h @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Licensing Data - * Copyright © 2011-2025 Pete Batard + * Copyright © 2011-2026 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 @@ -110,9 +110,11 @@ const char* additional_copyrights = "https://sourceforge.net/projects/smartmontools\\line\n" "GNU General Public License (GPL) v2 or later\\line\n" "\\line\n" -"FS Type description from GNU fdisk:\\line\n" +"Partition and FS Type identification from GNU fdisk and GPT fdisk:\\line\n" "https://www.gnu.org/software/fdisk\\line\n" -"GNU General Public License (GPL) v3 or later\\line\n" +"https://www.rodsbooks.com/gdisk\\line\n" +"https://salsa.debian.org/debian/gdisk\\line\n" +"GNU General Public License (GPL) v2 or later\\line\n" "\\line\n" "Speed/ETA computation from GNU wget:\\line\n" "https://www.gnu.org/software/wget\\line\n" diff --git a/src/rufus.h b/src/rufus.h index 1f011224..14723810 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -1,6 +1,6 @@ /* * Rufus: The Reliable USB Formatting Utility - * Copyright © 2011-2025 Pete Batard + * Copyright © 2011-2026 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 @@ -784,7 +784,7 @@ extern void _UpdateProgressWithInfo(int op, int msg, uint64_t processed, uint64_ #define UpdateProgressWithInfoInit(hProgressDialog, bNoAltMode) UpdateProgressWithInfo(OP_INIT, (int)bNoAltMode, (uint64_t)(uintptr_t)hProgressDialog, 0); extern const char* StrError(DWORD error_code, BOOL use_default_locale); extern char* GuidToString(const GUID* guid, BOOL bDecorated); -extern GUID* StringToGuid(const char* str); +extern GUID StringToGuid(const char* str); extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units); extern char* TimestampToHumanReadable(uint64_t ts); extern HWND MyCreateDialog(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc); diff --git a/src/rufus.rc b/src/rufus.rc index 6ea3e295..ecc30772 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 4.13.2316" +CAPTION "Rufus 4.14.2317" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -408,8 +408,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,13,2316,0 - PRODUCTVERSION 4,13,2316,0 + FILEVERSION 4,14,2317,0 + PRODUCTVERSION 4,14,2317,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -427,13 +427,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.13.2316" + VALUE "FileVersion", "4.14.2317" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2026 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" - VALUE "OriginalFilename", "rufus-4.13.exe" + VALUE "OriginalFilename", "rufus-4.14.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.13.2316" + VALUE "ProductVersion", "4.14.2317" END END BLOCK "VarFileInfo" diff --git a/src/stdio.c b/src/stdio.c index 8726b0d1..042622d3 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Standard User I/O Routines (logging, status, error, etc.) - * Copyright © 2011-2025 Pete Batard + * Copyright © 2011-2026 Pete Batard * Copyright © 2020 Mattiwatti * * This program is free software: you can redistribute it and/or modify @@ -365,18 +365,25 @@ char* GuidToString(const GUID* guid, BOOL bDecorated) return guid_string; } -GUID* StringToGuid(const char* str) +GUID StringToGuid(const char* str) { - static GUID guid; - - if (str == NULL) return NULL; - if (sscanf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", - (uint32_t*)&guid.Data1, (uint32_t*)&guid.Data2, (uint32_t*)&guid.Data3, - (uint32_t*)&guid.Data4[0], (uint32_t*)&guid.Data4[1], (uint32_t*)&guid.Data4[2], - (uint32_t*)&guid.Data4[3], (uint32_t*)&guid.Data4[4], (uint32_t*)&guid.Data4[5], - (uint32_t*)&guid.Data4[6], (uint32_t*)&guid.Data4[7]) != 11) - return NULL; - return &guid; + GUID guid = { 0 }; + uint32_t d1, d2, d3, b0, b1, b2, b3, b4, b5, b6, b7; + if (str != NULL && sscanf(str[0] == '{' ? &str[1] : str, "%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x", + &d1, &d2, &d3, &b0, &b1, &b2, &b3, &b4, &b5, &b6, &b7) == 11) { + guid.Data1 = d1; + guid.Data2 = (uint16_t)d2; + guid.Data3 = (uint16_t)d3; + guid.Data4[0] = (uint8_t)b0; + guid.Data4[1] = (uint8_t)b1; + guid.Data4[2] = (uint8_t)b2; + guid.Data4[3] = (uint8_t)b3; + guid.Data4[4] = (uint8_t)b4; + guid.Data4[5] = (uint8_t)b5; + guid.Data4[6] = (uint8_t)b6; + guid.Data4[7] = (uint8_t)b7; + } + return guid; } // Find upper power of 2 From 073a100c8e0bfaf496f1374114cc39e15d28918f Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Fri, 6 Mar 2026 17:36:44 +0000 Subject: [PATCH 02/80] [wue] add an option to copy SkuSiPolicy.p7b to the ESP on install * This basically accomplishes the steps described in https://support.microsoft.com/kb/5042562 on first logon. * Note that we use the installed system's SkuSiPolicy.p7b rather than the host system's, even if the latter is usually more up to date, because otherwise, the user may run into Error code: 0xc0000428 on first reboot. * Likewise, we do not provide this option for Windows To Go, as it could prevent the existing Windows install from booting, and we'd have to extract SkuSiPolicy.p7b from `install.wim` to do so. * Also remove dead code related to SkuSiPolicy.p7b hash parsing (which Microsoft no longer uses). * Closes #2919 (though it doesn't actually address the issue reported there, which we couldn't replicate). --- res/loc/rufus.loc | 3 +- src/format.c | 1 - src/license.h | 5 -- src/pki.c | 121 +--------------------------------------------- src/rufus.c | 5 +- src/rufus.h | 7 ++- src/rufus.rc | 10 ++-- src/wue.c | 77 ++++++++++++++--------------- 8 files changed, 50 insertions(+), 179 deletions(-) diff --git a/res/loc/rufus.loc b/res/loc/rufus.loc index 1eef1169..c2ea67a9 100644 --- a/res/loc/rufus.loc +++ b/res/loc/rufus.loc @@ -577,6 +577,7 @@ t MSG_320 "Refreshing partition layout (%s)..." t MSG_321 "The image you have selected is an ISOHybrid, but its creators have not made it compatible with ISO/File " "copy mode.\nAs a result, DD image writing mode will be enforced." t MSG_322 "Unable to open or read '%s'" +t MSG_324 "Apply SkuSiPolicy.p7b on installation (See KB5042562)" t MSG_325 "Applying Windows customization: %s" t MSG_326 "Applying user options..." t MSG_327 "Windows User Experience" @@ -609,7 +610,7 @@ t MSG_346 "Restrict Windows to S-Mode (INCOMPATIBLE with online account bypass)" t MSG_347 "Expert Mode" t MSG_348 "Extracting archive files: %s" t MSG_349 "Use Rufus MBR" -t MSG_350 "Use 'Windows CA 2023' signed bootloaders (requires a compatible target PC)" +t MSG_350 "Use 'Windows CA 2023' signed bootloaders (Requires a compatible target PC)" t MSG_351 "Checking for UEFI bootloader revocation..." t MSG_352 "Checking for UEFI DBX updates..." t MSG_353 "DBX update available" diff --git a/src/format.c b/src/format.c index 8bbe644c..621a40c1 100644 --- a/src/format.c +++ b/src/format.c @@ -1979,7 +1979,6 @@ try_clear: } } } - CopySKUSiPolicy(drive_name); if ( (target_type == TT_BIOS) && HAS_WINPE(img_report) ) { // Apply WinPE fixup if (!SetupWinPE(drive_name[0])) diff --git a/src/license.h b/src/license.h index a7781b49..f107aaec 100644 --- a/src/license.h +++ b/src/license.h @@ -144,11 +144,6 @@ const char* additional_copyrights = "https://github.com/u-boot/u-boot\\line\n" "GNU General Public License (GPL) v2 or later\\line\n" "\\line\n" -"SkuSiPolicy.p7b parsing derived from:\\line\n" -"https://gist.github.com/mattifestation/92e545bf1ee5b68eeb71d254cec2f78e\\line\n" -"by Matthew Graeber, with contributions by James Forshaw\\line\n" -"BSD 3-Clause\\line\n" -"\\line\n" "About and License dialogs inspired by WinSCP by Martin Prikryl\\line\n" "https://winscp.net/\\line\n" "GNU General Public License (GPL) v3 or later\\line\n" diff --git a/src/pki.c b/src/pki.c index 7ebef247..bc39c703 100644 --- a/src/pki.c +++ b/src/pki.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * PKI functions (code signing, etc.) - * Copyright © 2015-2024 Pete Batard + * Copyright © 2015-2026 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 @@ -260,7 +260,7 @@ const char* WinPKIErrorString(void) } } -// Mostly from https://support.microsoft.com/en-us/kb/323809 +// Mostly from https://support.microsoft.com/kb/323809 char* GetSignatureName(const char* path, const char* country_code, uint8_t* thumbprint, BOOL bSilent) { static char szSubjectName[128]; @@ -900,120 +900,3 @@ out: CryptReleaseContext(hProv, 0); return r; } - -// The following SkuSiPolicy.p7b parsing code is derived from: -// https://gist.github.com/mattifestation/92e545bf1ee5b68eeb71d254cec2f78e -// by Matthew Graeber, with contributions by James Forshaw. -BOOL ParseSKUSiPolicy(void) -{ - char path[MAX_PATH]; - wchar_t* wpath = NULL; - BOOL r = FALSE; - DWORD i, dwEncoding, dwContentType, dwFormatType; - DWORD dwPolicySize = 0, dwBaseIndex = 0, dwSizeCount; - HCRYPTMSG hMsg = NULL; - CRYPT_DATA_BLOB pkcsData = { 0 }; - DWORD* pdwEkuRules; - BYTE* pbRule; - CIHeader* Header; - CIFileRuleHeader* FileRuleHeader; - CIFileRuleData* FileRuleData; - - pe256ssp_size = 0; - safe_free(pe256ssp); - // Must use sysnative for WOW - static_sprintf(path, "%s\\SecureBootUpdates\\SKUSiPolicy.p7b", sysnative_dir); - wpath = utf8_to_wchar(path); - if (wpath == NULL) - goto out; - - r = CryptQueryObject(CERT_QUERY_OBJECT_FILE, wpath, CERT_QUERY_CONTENT_FLAG_ALL, - CERT_QUERY_FORMAT_FLAG_ALL, 0, &dwEncoding, &dwContentType, &dwFormatType, NULL, - &hMsg, NULL); - if (!r || dwContentType != CERT_QUERY_CONTENT_PKCS7_SIGNED) - goto out; - - r = CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0, NULL, &pkcsData.cbData); - if (!r || pkcsData.cbData == 0) { - uprintf("ParseSKUSiPolicy: Failed to retreive CMSG_CONTENT_PARAM size: %s", WindowsErrorString()); - goto out; - } - pkcsData.pbData = malloc(pkcsData.cbData); - if (pkcsData.pbData == NULL) - goto out; - r = CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0, pkcsData.pbData, &pkcsData.cbData); - if (!r) { - uprintf("ParseSKUSiPolicy: Failed to retreive CMSG_CONTENT_PARAM: %s", WindowsErrorString()); - goto out; - } - - // Now process the actual Security Policy content - if (pkcsData.pbData[0] == 4) { - dwPolicySize = pkcsData.pbData[1]; - dwBaseIndex = 2; - if ((dwPolicySize & 0x80) == 0x80) { - dwSizeCount = dwPolicySize & 0x7F; - dwBaseIndex += dwSizeCount; - dwPolicySize = 0; - for (i = 0; i < dwSizeCount; i++) { - dwPolicySize = dwPolicySize << 8; - dwPolicySize = dwPolicySize | pkcsData.pbData[2 + i]; - } - } - } - - // Sanity checks - Header = (CIHeader*)&pkcsData.pbData[dwBaseIndex]; - if (Header->HeaderLength + sizeof(uint32_t) != sizeof(CIHeader)) { - uprintf("ParseSKUSiPolicy: Unexpected Code Integrity Header size (0x%02x)", Header->HeaderLength); - goto out; - } - if (!CompareGUID(&Header->PolicyTypeGUID, &SKU_CODE_INTEGRITY_POLICY)) { - uprintf("ParseSKUSiPolicy: Unexpected Policy Type GUID %s", GuidToString(&Header->PolicyTypeGUID, TRUE)); - goto out; - } - - // Skip the EKU Rules - pdwEkuRules = (DWORD*) &pkcsData.pbData[dwBaseIndex + sizeof(CIHeader)]; - for (i = 0; i < Header->EKURuleEntryCount; i++) - pdwEkuRules = &pdwEkuRules[(*pdwEkuRules + (2 * sizeof(DWORD) - 1)) / sizeof(DWORD)]; - - // Process the Files Rules - pbRule = (BYTE*)pdwEkuRules; - pe256ssp = malloc(Header->FileRuleEntryCount * PE256_HASHSIZE); - if (pe256ssp == NULL) - goto out; - for (i = 0; i < Header->FileRuleEntryCount; i++) { - FileRuleHeader = (CIFileRuleHeader*)pbRule; - pbRule = &pbRule[sizeof(CIFileRuleHeader)]; - if (FileRuleHeader->FileNameLength != 0) { -// uprintf("%S", FileRuleHeader->FileName); - pbRule = &pbRule[((FileRuleHeader->FileNameLength + sizeof(DWORD) - 1) / sizeof(DWORD)) * sizeof(DWORD)]; - } - FileRuleData = (CIFileRuleData*)pbRule; - if (FileRuleData->HashLength > 0x80) { - uprintf("ParseSKUSiPolicy: Unexpected hash length for entry %d (0x%02x)", i, FileRuleData->HashLength); - // We're probably screwed, so bail out - break; - } - // We are only interested in 'DENY' type with PE256 hashes - if (FileRuleHeader->Type == CI_DENY && FileRuleData->HashLength == PE256_HASHSIZE) { - // Microsoft has the bad habit of duplicating entries - only add a hash if it's different from previous entry - if ((pe256ssp_size == 0) || - (memcmp(&pe256ssp[(pe256ssp_size - 1) * PE256_HASHSIZE], FileRuleData->Hash, PE256_HASHSIZE) != 0)) { - memcpy(&pe256ssp[pe256ssp_size * PE256_HASHSIZE], FileRuleData->Hash, PE256_HASHSIZE); - pe256ssp_size++; - } - } - pbRule = &pbRule[sizeof(CIFileRuleData) + ((FileRuleData->HashLength + sizeof(DWORD) - 1) / sizeof(DWORD)) * sizeof(DWORD)]; - } - - r = TRUE; - -out: - if (hMsg != NULL) - CryptMsgClose(hMsg); - free(pkcsData.pbData); - free(wpath); - return r; -} diff --git a/src/rufus.c b/src/rufus.c index 543a8ac4..dd3636af 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -93,7 +93,7 @@ static char uppercase_select[2][64], uppercase_start[64], uppercase_close[64], u extern HANDLE update_check_thread; extern HIMAGELIST hUpImageList, hDownImageList; -extern BOOL enable_iso, enable_joliet, enable_rockridge, enable_extra_hashes, is_bootloader_revoked; +extern BOOL enable_iso, enable_joliet, enable_rockridge, enable_extra_hashes; extern BOOL validate_md5sum, cpu_has_sha1_accel, cpu_has_sha256_accel, toggle_dark_mode; extern BYTE* fido_script; extern HWND hFidoDlg; @@ -1505,7 +1505,6 @@ static DWORD WINAPI BootCheckThread(LPVOID param) char tmp[MAX_PATH], tmp2[MAX_PATH], c; syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0; - is_bootloader_revoked = FALSE; safe_free(grub2_buf); if (ComboBox_GetCurSel(hDeviceList) == CB_ERR) @@ -1688,6 +1687,8 @@ static DWORD WINAPI BootCheckThread(LPVOID param) if (img_report.win_version.build >= 26200) { StrArrayAdd(&options, lmprintf(MSG_350), TRUE); MAP_BIT(UNATTEND_USE_MS2023_BOOTLOADERS); + StrArrayAdd(&options, lmprintf(MSG_324), TRUE); + MAP_BIT(UNATTEND_APPLY_SKUSIPOLICY); } if (expert_mode) { StrArrayAdd(&options, lmprintf(MSG_346), TRUE); diff --git a/src/rufus.h b/src/rufus.h index 14723810..4c9e71b8 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -685,8 +685,9 @@ typedef struct { #define UNATTEND_DISABLE_BITLOCKER 0x00080 #define UNATTEND_FORCE_S_MODE 0x00100 #define UNATTEND_USE_MS2023_BOOTLOADERS 0x00200 -#define UNATTEND_FULL_MASK 0x003FF -#define UNATTEND_DEFAULT_MASK 0x002FF // Mask of values that are persisted +#define UNATTEND_APPLY_SKUSIPOLICY 0x00400 +#define UNATTEND_FULL_MASK 0x007FF +#define UNATTEND_DEFAULT_MASK 0x006FF // Mask of values that are persisted #define UNATTEND_WINDOWS_TO_GO 0x10000 // Special flag for Windows To Go #define UNATTEND_WINPE_SETUP_MASK (UNATTEND_SECUREBOOT_TPM_MINRAM) @@ -815,7 +816,6 @@ extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan); extern BOOL ExtractZip(const char* src_zip, const char* dest_dir); extern int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes); extern uint32_t ReadISOFileToBuffer(const char* iso, const char* iso_file, uint8_t** buf); -extern BOOL CopySKUSiPolicy(const char* drive_name); extern BOOL HasEfiImgBootLoaders(void); extern BOOL DumpFatDir(const char* path, int32_t cluster); extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs); @@ -866,7 +866,6 @@ extern int GetIssuerCertificateInfo(uint8_t* cert, cert_info_t* info); extern uint64_t GetSignatureTimeStamp(const char* path); extern LONG ValidateSignature(HWND hDlg, const char* path); extern BOOL ValidateOpensslSignature(BYTE* pbBuffer, DWORD dwBufferLen, BYTE* pbSignature, DWORD dwSigLen); -extern BOOL ParseSKUSiPolicy(void); extern BOOL IsFontAvailable(const char* font_name); extern BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries); diff --git a/src/rufus.rc b/src/rufus.rc index ecc30772..3fc39d57 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 4.14.2317" +CAPTION "Rufus 4.14.2318" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -408,8 +408,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,14,2317,0 - PRODUCTVERSION 4,14,2317,0 + FILEVERSION 4,14,2318,0 + PRODUCTVERSION 4,14,2318,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -427,13 +427,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.14.2317" + VALUE "FileVersion", "4.14.2318" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2026 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.14.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.14.2317" + VALUE "ProductVersion", "4.14.2318" END END BLOCK "VarFileInfo" diff --git a/src/wue.c b/src/wue.c index 3e0f382d..5c10c957 100644 --- a/src/wue.c +++ b/src/wue.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Windows User Experience - * Copyright © 2022-2025 Pete Batard + * Copyright © 2022-2026 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 @@ -47,7 +47,6 @@ const char* bypass_name[] = { "BypassTPMCheck", "BypassSecureBootCheck", "Bypass int unattend_xml_flags = 0, wintogo_index = -1, wininst_index = 0; int unattend_xml_mask = UNATTEND_DEFAULT_SELECTION_MASK; char *unattend_xml_path = NULL, unattend_username[MAX_USERNAME_LENGTH]; -BOOL is_bootloader_revoked = FALSE; extern BOOL validate_md5sum; extern uint64_t md5sum_totalbytes; @@ -65,7 +64,7 @@ char* CreateUnattendXml(int arch, int flags) { const static char* xml_arch_names[5] = { "x86", "amd64", "arm", "arm64" }; const static char* unallowed_account_names[] = { "Administrator", "Guest", "KRBTGT", "Local", "NONE" }; - static char path[MAX_PATH]; + static char path[MAX_PATH], tmp[MAX_PATH]; char* tzstr; FILE* fd; TIME_ZONE_INFORMATION tz_info; @@ -140,7 +139,8 @@ char* CreateUnattendXml(int arch, int flags) } if (flags & UNATTEND_OOBE_MASK) { - order = 1; + StrArray first_logon_commands = STRARRAY_EMPTY; + StrArrayCreate(&first_logon_commands, 8); fprintf(fd, " \n"); if (flags & UNATTEND_OOBE_SHELL_SETUP_MASK) { fprintf(fd, " sections in unattend.xml. Don't ask me how I know... :( - fprintf(fd, " \n"); - fprintf(fd, " \n"); - fprintf(fd, " %d\n", order++); - fprintf(fd, " net user "%s" /logonpasswordchg:yes\n", unattend_username); - fprintf(fd, " \n"); - // Some people report that using the `net user` command above might reset the password expiration to 90 days... + static_sprintf(tmp, "net user "%s" /logonpasswordchg:yes", unattend_username); + StrArrayAdd(&first_logon_commands, tmp, TRUE); + // The `net user` command above might reset the password expiration to 90 days... // To alleviate that, blanket set passwords on the target machine to never expire. - fprintf(fd, " \n"); - fprintf(fd, " %d\n", order++); - fprintf(fd, " net accounts /maxpwage:unlimited\n"); - fprintf(fd, " \n"); - fprintf(fd, " \n"); + StrArrayAdd(&first_logon_commands, "net accounts /maxpwage:unlimited", TRUE); } } + + // Apply SkuSiPolicy.p7b, if the user requested it and we're not creating a Windows To Go drive. + // See https://support.microsoft.com/kb/5042562. We do it post install, on first logon, because + // we'd have to patch tons of files otherwise. And we *ALWAYS* use the installed system's + // SkuSiPolicy.p7b instead of the host system's, even if the latter might be more recent, on + // account that the bootloaders from the installed system might be trailing behind, and wills + // produce the 0xc0000428 signature validation error on (re)boot if the system hasn't gone + // through a full Windows Update cycle. + if (flags & UNATTEND_APPLY_SKUSIPOLICY) { + StrArrayAdd(&first_logon_commands, "cmd /c mountvol S: /S && " + "copy %WINDIR%\\system32\\SecureBootUpdates\\SkuSiPolicy.p7b S:\\EFI\\Microsoft\\Boot && " + "mountvol S: /D", TRUE); + } + + // Now that we have all the commands to run, create the FirstLogonCommands section. + for (order = 1; order <= (int)first_logon_commands.Index; order++) { + if (order == 1) + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " %d\n", order); + fprintf(fd, " %s\n", first_logon_commands.String[order - 1]); + fprintf(fd, " \n"); + if (order == first_logon_commands.Index) + fprintf(fd, " \n"); + } + StrArrayDestroy(&first_logon_commands); + fprintf(fd, " \n"); } if (flags & UNATTEND_OOBE_INTERNATIONAL_MASK) { @@ -510,31 +530,6 @@ out: return ((img_report.win_version.major != 0) && (img_report.win_version.build != 0)); } -// Copy this system's SkuSiPolicy.p7b to the target drive so that UEFI bootloaders -// revoked by Windows through WDAC policy do get flagged as revoked. -BOOL CopySKUSiPolicy(const char* drive_name) -{ - BOOL r = FALSE; - char src[MAX_PATH], dst[MAX_PATH]; - struct __stat64 stat64 = { 0 }; - - // Only copy SkuPolicy if we warned about the bootloader being revoked. - if ((target_type != TT_UEFI) || !IS_WINDOWS_1X(img_report) || - (pe256ssp_size == 0) || !is_bootloader_revoked) - return r; - - static_sprintf(src, "%s\\SecureBootUpdates\\SKUSiPolicy.p7b", system_dir); - static_sprintf(dst, "%s\\EFI\\Microsoft\\Boot\\SKUSiPolicy.p7b", drive_name); - if ((_stat64U(dst, &stat64) != 0) && (_stat64U(src, &stat64) == 0)) { - uprintf("Copying: %s (%s) (from %s)", dst, SizeToHumanReadable(stat64.st_size, FALSE, FALSE), src); - r = CopyFileU(src, dst, TRUE); - if (!r) - uprintf(" Error writing file: %s", WindowsErrorString()); - } - - return r; -} - /// /// Checks which versions of Windows are available in an install image /// to set our extraction index. Asks the user to select one if needed. @@ -739,8 +734,6 @@ BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp) ErrorStatus = RUFUS_ERROR(APPERR(ERROR_ISO_EXTRACT)); } - CopySKUSiPolicy((use_esp) ? ms_efi : drive_name); - UpdateProgressWithInfo(OP_FILE_COPY, MSG_267, 99, 100); // Setting internal drives offline for Windows To Go is crucial if, for instance, you are using ReFS From 1d4c62ba0d0a30f6fe218f1b288dac4eccf884e8 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 11 Mar 2026 10:55:04 +0000 Subject: [PATCH 03/80] [wue] add an option to perform a fully unattended/silent install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Note that this will completely repartition and erase the first disk available on the target system ⚠WITHOUT ANY PROMPT⚠. * Also, this is dependent on the local account name and duplicate regional WUE options to be selected. * With a special mention to Claude AI, that said that detecting whether a one or multiple disks were available was impossible to accomplish using only unattend XML commands... which we therefore promptly managed to disprove. Please wake me up when there is any semblance of "intelligence" in the LLMs that are currently destroying our planet... --- res/loc/rufus.loc | 3 +- src/resource.h | 39 +++--- src/rufus.c | 27 ++-- src/rufus.h | 22 +++- src/rufus.rc | 11 +- src/stdfn.c | 185 ++++++++++++++------------- src/stdlg.c | 129 +++++++++++++++---- src/wue.c | 310 ++++++++++++++++++++++++++++++++++++++++------ 8 files changed, 533 insertions(+), 193 deletions(-) diff --git a/res/loc/rufus.loc b/res/loc/rufus.loc index c2ea67a9..8c04063f 100644 --- a/res/loc/rufus.loc +++ b/res/loc/rufus.loc @@ -577,7 +577,8 @@ t MSG_320 "Refreshing partition layout (%s)..." t MSG_321 "The image you have selected is an ISOHybrid, but its creators have not made it compatible with ISO/File " "copy mode.\nAs a result, DD image writing mode will be enforced." t MSG_322 "Unable to open or read '%s'" -t MSG_324 "Apply SkuSiPolicy.p7b on installation (See KB5042562)" +t MSG_323 "Apply SkuSiPolicy.p7b on installation (See KB5042562)" +t MSG_324 "⚠SILENTLY⚠ erase disk and install:" t MSG_325 "Applying Windows customization: %s" t MSG_326 "Applying user options..." t MSG_327 "Windows User Experience" diff --git a/src/resource.h b/src/resource.h index 9be19993..5b8b4d9f 100644 --- a/src/resource.h +++ b/src/resource.h @@ -173,25 +173,26 @@ #define IDC_SELECTION_CHOICE15 1092 #define IDC_SELECTION_CHOICEMAX 1093 #define IDC_SELECTION_USERNAME 1094 -#define IDC_LIST_ICON 1095 -#define IDC_LIST_TEXT 1096 -#define IDC_LIST_LINE 1097 -#define IDC_LIST_ITEM1 1098 -#define IDC_LIST_ITEM2 1099 -#define IDC_LIST_ITEM3 1100 -#define IDC_LIST_ITEM4 1101 -#define IDC_LIST_ITEM5 1102 -#define IDC_LIST_ITEM6 1103 -#define IDC_LIST_ITEM7 1104 -#define IDC_LIST_ITEM8 1105 -#define IDC_LIST_ITEM9 1106 -#define IDC_LIST_ITEM10 1107 -#define IDC_LIST_ITEM11 1108 -#define IDC_LIST_ITEM12 1109 -#define IDC_LIST_ITEM13 1110 -#define IDC_LIST_ITEM14 1111 -#define IDC_LIST_ITEM15 1112 -#define IDC_LIST_ITEMMAX 1113 +#define IDC_SELECTION_EDITION 1095 +#define IDC_LIST_ICON 1100 +#define IDC_LIST_TEXT 1101 +#define IDC_LIST_LINE 1102 +#define IDC_LIST_ITEM1 1103 +#define IDC_LIST_ITEM2 1104 +#define IDC_LIST_ITEM3 1105 +#define IDC_LIST_ITEM4 1106 +#define IDC_LIST_ITEM5 1107 +#define IDC_LIST_ITEM6 1108 +#define IDC_LIST_ITEM7 1109 +#define IDC_LIST_ITEM8 1110 +#define IDC_LIST_ITEM9 1111 +#define IDC_LIST_ITEM10 1112 +#define IDC_LIST_ITEM11 1113 +#define IDC_LIST_ITEM12 1114 +#define IDC_LIST_ITEM13 1115 +#define IDC_LIST_ITEM14 1116 +#define IDC_LIST_ITEM15 1117 +#define IDC_LIST_ITEMMAX 1118 #define IDS_DEVICE_TXT 2000 #define IDS_PARTITION_TYPE_TXT 2001 #define IDS_FILE_SYSTEM_TXT 2002 diff --git a/src/rufus.c b/src/rufus.c index dd3636af..790da244 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -1490,7 +1490,7 @@ out: // Likewise, boot check will block message processing => use a thread static DWORD WINAPI BootCheckThread(LPVOID param) { - int i, r, username_index = -1; + int i, r; FILE *fd; uint32_t len; WPARAM ret = BOOTCHECK_CANCEL; @@ -1503,6 +1503,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param) const char* syslinux = "syslinux"; const char* ldlinux_ext[3] = { "sys", "bss", "c32" }; char tmp[MAX_PATH], tmp2[MAX_PATH], c; + selection_dialog_options_t selection_options = { 0, -1, -1, -1 }; syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0; safe_free(grub2_buf); @@ -1610,7 +1611,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param) MAP_BIT(UNATTEND_NO_ONLINE_ACCOUNT); } StrArrayAdd(&options, lmprintf(MSG_333), TRUE); - username_index = _log2(b); + selection_options.username_index = _log2(b); MAP_BIT(UNATTEND_SET_USER); StrArrayAdd(&options, lmprintf(MSG_334), TRUE); MAP_BIT(UNATTEND_DUPLICATE_LOCALE); @@ -1620,8 +1621,9 @@ static DWORD WINAPI BootCheckThread(LPVOID param) StrArrayAdd(&options, lmprintf(MSG_346), TRUE); MAP_BIT(UNATTEND_FORCE_S_MODE); } + selection_options.mask = remap16(unattend_xml_mask, map, FALSE); i = CustomSelectionDialog(BS_AUTOCHECKBOX, lmprintf(MSG_327), lmprintf(MSG_328), - options.String, options.Index, remap16(unattend_xml_mask, map, FALSE), username_index); + options.String, options.Index, &selection_options); StrArrayDestroy(&options); if (i < 0) goto out; @@ -1676,26 +1678,35 @@ static DWORD WINAPI BootCheckThread(LPVOID param) MAP_BIT(UNATTEND_NO_ONLINE_ACCOUNT); } StrArrayAdd(&options, lmprintf(MSG_333), TRUE); - username_index = _log2(b); + selection_options.username_index = _log2(b); MAP_BIT(UNATTEND_SET_USER); StrArrayAdd(&options, lmprintf(MSG_334), TRUE); + selection_options.regional_index = _log2(b); MAP_BIT(UNATTEND_DUPLICATE_LOCALE); StrArrayAdd(&options, lmprintf(MSG_331), TRUE); MAP_BIT(UNATTEND_NO_DATA_COLLECTION); - StrArrayAdd(&options, lmprintf(MSG_335), TRUE); - MAP_BIT(UNATTEND_DISABLE_BITLOCKER); + if (IS_WINDOWS_11(img_report)) { + StrArrayAdd(&options, lmprintf(MSG_335), TRUE); + MAP_BIT(UNATTEND_DISABLE_BITLOCKER); + } if (img_report.win_version.build >= 26200) { StrArrayAdd(&options, lmprintf(MSG_350), TRUE); MAP_BIT(UNATTEND_USE_MS2023_BOOTLOADERS); - StrArrayAdd(&options, lmprintf(MSG_324), TRUE); + StrArrayAdd(&options, lmprintf(MSG_323), TRUE); MAP_BIT(UNATTEND_APPLY_SKUSIPOLICY); } + if (IS_WINDOWS_11(img_report)) { + StrArrayAdd(&options, lmprintf(MSG_324), TRUE); + selection_options.edition_index = _log2(b); + MAP_BIT(UNATTEND_SILENT_INSTALL); + } if (expert_mode) { StrArrayAdd(&options, lmprintf(MSG_346), TRUE); MAP_BIT(UNATTEND_FORCE_S_MODE); } + selection_options.mask = remap16(unattend_xml_mask, map, FALSE); i = CustomSelectionDialog(BS_AUTOCHECKBOX, lmprintf(MSG_327), lmprintf(MSG_328), - options.String, options.Index, remap16(unattend_xml_mask, map, FALSE), username_index); + options.String, options.Index, &selection_options); StrArrayDestroy(&options); if (i < 0) goto out; diff --git a/src/rufus.h b/src/rufus.h index 4c9e71b8..401769eb 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -507,6 +507,14 @@ typedef struct { char* Label; } IMG_SAVE; +// Options for the custom selection dialog +typedef struct { + int mask; + int username_index; + int edition_index; + int regional_index; +} selection_dialog_options_t; + /* * Structure and macros used for the extensions specification of FileDialog() * You can use: @@ -686,15 +694,17 @@ typedef struct { #define UNATTEND_FORCE_S_MODE 0x00100 #define UNATTEND_USE_MS2023_BOOTLOADERS 0x00200 #define UNATTEND_APPLY_SKUSIPOLICY 0x00400 -#define UNATTEND_FULL_MASK 0x007FF +#define UNATTEND_SILENT_INSTALL 0x00800 +#define UNATTEND_FULL_MASK 0x00FFF #define UNATTEND_DEFAULT_MASK 0x006FF // Mask of values that are persisted #define UNATTEND_WINDOWS_TO_GO 0x10000 // Special flag for Windows To Go -#define UNATTEND_WINPE_SETUP_MASK (UNATTEND_SECUREBOOT_TPM_MINRAM) +#define UNATTEND_WINPE_SETUP_MASK (UNATTEND_SECUREBOOT_TPM_MINRAM | UNATTEND_SILENT_INSTALL) #define UNATTEND_SPECIALIZE_DEPLOYMENT_MASK (UNATTEND_NO_ONLINE_ACCOUNT) #define UNATTEND_OOBE_SHELL_SETUP_MASK (UNATTEND_NO_DATA_COLLECTION | UNATTEND_SET_USER | UNATTEND_DUPLICATE_LOCALE) #define UNATTEND_OOBE_INTERNATIONAL_MASK (UNATTEND_DUPLICATE_LOCALE) -#define UNATTEND_OOBE_MASK (UNATTEND_OOBE_SHELL_SETUP_MASK | UNATTEND_OOBE_INTERNATIONAL_MASK | UNATTEND_DISABLE_BITLOCKER | UNATTEND_USE_MS2023_BOOTLOADERS) +#define UNATTEND_OOBE_MASK (UNATTEND_OOBE_SHELL_SETUP_MASK | UNATTEND_OOBE_INTERNATIONAL_MASK | UNATTEND_DISABLE_BITLOCKER | \ + UNATTEND_USE_MS2023_BOOTLOADERS | UNATTEND_APPLY_SKUSIPOLICY) #define UNATTEND_OFFLINE_SERVICING_MASK (UNATTEND_OFFLINE_INTERNAL_DRIVES | UNATTEND_FORCE_S_MODE) #define UNATTEND_DEFAULT_SELECTION_MASK (UNATTEND_SECUREBOOT_TPM_MINRAM | UNATTEND_NO_ONLINE_ACCOUNT | UNATTEND_OFFLINE_INTERNAL_DRIVES) @@ -769,6 +779,8 @@ extern StrArray modified_files; * Shared prototypes */ extern void GetWindowsVersion(windows_version_t* WindowsVersion); +extern const char* GetEditionName(DWORD ProductType); +extern int GetEditions(StrArray* version_name, StrArray* version_index); extern version_t* GetExecutableVersion(const char* path); extern const char* WindowsErrorString(void); extern void DumpBufferHex(void *buf, size_t size); @@ -806,8 +818,8 @@ extern void DestroyTooltip(HWND hWnd); extern void DestroyAllTooltips(void); extern int NotificationEx(int type, const char* dont_display_setting, const notification_info* more_info, const char* title, const char* format, ...); #define Notification(type, title, ...) NotificationEx(type, NULL, NULL, title, __VA_ARGS__) -extern int CustomSelectionDialog(int style, char* title, char* message, char** choices, int size, int mask, int username_index); -#define SelectionDialog(title, message, choices, size) CustomSelectionDialog(BS_AUTORADIOBUTTON, title, message, choices, size, 1, -1) +extern int CustomSelectionDialog(int style, char* title, char* message, char** choices, int size, selection_dialog_options_t* options); +#define SelectionDialog(title, message, choices, size) CustomSelectionDialog(BS_AUTORADIOBUTTON, title, message, choices, size, NULL) extern void ListDialog(char* title, char* message, char** items, int size); extern SIZE GetTextSize(HWND hCtrl, char* txt); extern BOOL ExtractAppIcon(const char* filename, BOOL bSilent); diff --git a/src/rufus.rc b/src/rufus.rc index 3fc39d57..967272f0 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 4.14.2318" +CAPTION "Rufus 4.14.2319" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -176,6 +176,7 @@ BEGIN CONTROL "Choice 15",IDC_SELECTION_CHOICE15,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,35,200,269,10,WS_EX_TRANSPARENT CONTROL "Choice 16",IDC_SELECTION_CHOICEMAX,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,35,213,269,10,WS_EX_TRANSPARENT EDITTEXT IDC_SELECTION_USERNAME,197,57,0,9,ES_AUTOHSCROLL | NOT WS_VISIBLE | WS_TABSTOP | WS_BORDER + COMBOBOX IDC_SELECTION_EDITION,197,57,0,9,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_LIST DIALOGEX 0, 0, 312, 59 @@ -408,8 +409,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,14,2318,0 - PRODUCTVERSION 4,14,2318,0 + FILEVERSION 4,14,2319,0 + PRODUCTVERSION 4,14,2319,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -427,13 +428,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.14.2318" + VALUE "FileVersion", "4.14.2319" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2026 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.14.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.14.2318" + VALUE "ProductVersion", "4.14.2319" END END BLOCK "VarFileInfo" diff --git a/src/stdfn.c b/src/stdfn.c index 43819d4b..4014f777 100644 --- a/src/stdfn.c +++ b/src/stdfn.c @@ -216,109 +216,109 @@ uint32_t htab_hash(char* str, htab_table* htab) return idx; } -static const char* GetEdition(DWORD ProductType) +const char* GetEditionName(DWORD ProductType) { - static char unknown_edition_str[64]; + static char unknown_edition_str[64] = ""; // From: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo // These values can be found in the winnt.h header. switch (ProductType) { case 0x00000000: return ""; // Undefined - case 0x00000001: return "Ultimate"; - case 0x00000002: return "Home Basic"; - case 0x00000003: return "Home Premium"; - case 0x00000004: return "Enterprise"; - case 0x00000005: return "Home Basic N"; - case 0x00000006: return "Business"; - case 0x00000007: return "Server Standard"; - case 0x00000008: return "Server Datacenter"; - case 0x00000009: return "Smallbusiness Server"; - case 0x0000000A: return "Server Enterprise"; - case 0x0000000B: return "Starter"; - case 0x0000000C: return "Server Datacenter (Core)"; - case 0x0000000D: return "Server Standard (Core)"; - case 0x0000000E: return "Server Enterprise (Core)"; - case 0x00000010: return "Business N"; - case 0x00000011: return "Web Server"; - case 0x00000012: return "HPC Edition"; - case 0x00000013: return "Storage Server (Essentials)"; - case 0x0000001A: return "Home Premium N"; - case 0x0000001B: return "Enterprise N"; - case 0x0000001C: return "Ultimate N"; - case 0x00000022: return "Home Server"; - case 0x00000024: return "Server Standard without Hyper-V"; - case 0x00000025: return "Server Datacenter without Hyper-V"; - case 0x00000026: return "Server Enterprise without Hyper-V"; - case 0x00000027: return "Server Datacenter without Hyper-V (Core)"; - case 0x00000028: return "Server Standard without Hyper-V (Core)"; - case 0x00000029: return "Server Enterprise without Hyper-V (Core)"; - case 0x0000002A: return "Hyper-V Server"; - case 0x0000002F: return "Starter N"; - case 0x00000030: return "Pro"; - case 0x00000031: return "Pro N"; - case 0x00000034: return "Server Solutions Premium"; - case 0x00000035: return "Server Solutions Premium (Core)"; - case 0x00000040: return "Server Hyper Core V"; - case 0x00000042: return "Starter E"; - case 0x00000043: return "Home Basic E"; - case 0x00000044: return "Premium E"; - case 0x00000045: return "Pro E"; - case 0x00000046: return "Enterprise E"; - case 0x00000047: return "Ultimate E"; - case 0x00000048: return "Enterprise (Eval)"; - case 0x0000004F: return "Server Standard (Eval)"; - case 0x00000050: return "Server Datacenter (Eval)"; - case 0x00000054: return "Enterprise N (Eval)"; - case 0x00000057: return "Thin PC"; + case 0x00000001: return " Ultimate"; + case 0x00000002: return " Home Basic"; + case 0x00000003: return " Home Premium"; + case 0x00000004: return " Enterprise"; + case 0x00000005: return " Home Basic N"; + case 0x00000006: return " Business"; + case 0x00000007: return " Server Standard"; + case 0x00000008: return " Server Datacenter"; + case 0x00000009: return " Smallbusiness Server"; + case 0x0000000A: return " Server Enterprise"; + case 0x0000000B: return " Starter"; + case 0x0000000C: return " Server Datacenter (Core)"; + case 0x0000000D: return " Server Standard (Core)"; + case 0x0000000E: return " Server Enterprise (Core)"; + case 0x00000010: return " Business N"; + case 0x00000011: return " Web Server"; + case 0x00000012: return " HPC Edition"; + case 0x00000013: return " Storage Server (Essentials)"; + case 0x0000001A: return " Home Premium N"; + case 0x0000001B: return " Enterprise N"; + case 0x0000001C: return " Ultimate N"; + case 0x00000022: return " Home Server"; + case 0x00000024: return " Server Standard without Hyper-V"; + case 0x00000025: return " Server Datacenter without Hyper-V"; + case 0x00000026: return " Server Enterprise without Hyper-V"; + case 0x00000027: return " Server Datacenter without Hyper-V (Core)"; + case 0x00000028: return " Server Standard without Hyper-V (Core)"; + case 0x00000029: return " Server Enterprise without Hyper-V (Core)"; + case 0x0000002A: return " Hyper-V Server"; + case 0x0000002F: return " Starter N"; + case 0x00000030: return " Pro"; + case 0x00000031: return " Pro N"; + case 0x00000034: return " Server Solutions Premium"; + case 0x00000035: return " Server Solutions Premium (Core)"; + case 0x00000040: return " Server Hyper Core V"; + case 0x00000042: return " Starter E"; + case 0x00000043: return " Home Basic E"; + case 0x00000044: return " Premium E"; + case 0x00000045: return " Pro E"; + case 0x00000046: return " Enterprise E"; + case 0x00000047: return " Ultimate E"; + case 0x00000048: return " Enterprise (Eval)"; + case 0x0000004F: return " Server Standard (Eval)"; + case 0x00000050: return " Server Datacenter (Eval)"; + case 0x00000054: return " Enterprise N (Eval)"; + case 0x00000057: return " Thin PC"; case 0x00000058: case 0x00000059: case 0x0000005A: case 0x0000005B: case 0x0000005C: return "Embedded"; - case 0x00000062: return "Home N"; - case 0x00000063: return "Home China"; - case 0x00000064: return "Home Single Language"; - case 0x00000065: return "Home"; - case 0x00000067: return "Pro with Media Center"; + case 0x00000062: return " Home N"; + case 0x00000063: return " Home China"; + case 0x00000064: return " Home Single Language"; + case 0x00000065: return " Home"; + case 0x00000067: return " Pro with Media Center"; case 0x00000069: case 0x0000006A: case 0x0000006B: case 0x0000006C: return "Embedded"; - case 0x0000006F: return "Home Connected"; - case 0x00000070: return "Pro Student"; - case 0x00000071: return "Home Connected N"; - case 0x00000072: return "Pro Student N"; - case 0x00000073: return "Home Connected Single Language"; - case 0x00000074: return "Home Connected China"; - case 0x00000079: return "Education"; - case 0x0000007A: return "Education N"; - case 0x0000007D: return "Enterprise LTSB"; - case 0x0000007E: return "Enterprise LTSB N"; - case 0x0000007F: return "Pro S"; - case 0x00000080: return "Pro S N"; - case 0x00000081: return "Enterprise LTSB (Eval)"; - case 0x00000082: return "Enterprise LTSB N (Eval)"; - case 0x0000008A: return "Pro Single Language"; - case 0x0000008B: return "Pro China"; - case 0x0000008C: return "Enterprise Subscription"; - case 0x0000008D: return "Enterprise Subscription N"; - case 0x00000091: return "Server Datacenter SA (Core)"; - case 0x00000092: return "Server Standard SA (Core)"; - case 0x00000095: return "Utility VM"; - case 0x000000A1: return "Pro for Workstations"; - case 0x000000A2: return "Pro for Workstations N"; - case 0x000000A4: return "Pro for Education"; - case 0x000000A5: return "Pro for Education N"; - case 0x000000AB: return "Enterprise G"; // I swear Microsoft are just making up editions... - case 0x000000AC: return "Enterprise G N"; - case 0x000000B2: return "Cloud"; - case 0x000000B3: return "Cloud N"; - case 0x000000B6: return "Home OS"; + case 0x0000006F: return " Home Connected"; + case 0x00000070: return " Pro Student"; + case 0x00000071: return " Home Connected N"; + case 0x00000072: return " Pro Student N"; + case 0x00000073: return " Home Connected Single Language"; + case 0x00000074: return " Home Connected China"; + case 0x00000079: return " Education"; + case 0x0000007A: return " Education N"; + case 0x0000007D: return " Enterprise LTSB"; + case 0x0000007E: return " Enterprise LTSB N"; + case 0x0000007F: return " Pro S"; + case 0x00000080: return " Pro S N"; + case 0x00000081: return " Enterprise LTSB (Eval)"; + case 0x00000082: return " Enterprise LTSB N (Eval)"; + case 0x0000008A: return " Pro Single Language"; + case 0x0000008B: return " Pro China"; + case 0x0000008C: return " Enterprise Subscription"; + case 0x0000008D: return " Enterprise Subscription N"; + case 0x00000091: return " Server Datacenter SA (Core)"; + case 0x00000092: return " Server Standard SA (Core)"; + case 0x00000095: return " Utility VM"; + case 0x000000A1: return " Pro for Workstations"; + case 0x000000A2: return " Pro for Workstations N"; + case 0x000000A4: return " Pro for Education"; + case 0x000000A5: return " Pro for Education N"; + case 0x000000AB: return " Enterprise G"; // I swear Microsoft are just making up editions... + case 0x000000AC: return " Enterprise G N"; + case 0x000000B2: return " Cloud"; + case 0x000000B3: return " Cloud N"; + case 0x000000B6: return " Home OS"; case 0x000000B7: case 0x000000CB: return "Cloud E"; - case 0x000000B9: return "IoT OS"; + case 0x000000B9: return " IoT OS"; case 0x000000BA: case 0x000000CA: return "Cloud E N"; - case 0x000000BB: return "IoT Edge OS"; - case 0x000000BC: return "IoT Enterprise"; - case 0x000000BD: return "Lite"; - case 0x000000BF: return "IoT Enterprise S"; + case 0x000000BB: return " IoT Edge OS"; + case 0x000000BC: return " IoT Enterprise"; + case 0x000000BD: return " Lite"; + case 0x000000BF: return " IoT Enterprise S"; case 0x000000C0: case 0x000000C2: case 0x000000C3: case 0x000000C4: case 0x000000C5: case 0x000000C6: return "XBox"; case 0x000000C7: case 0x000000C8: case 0x00000196: case 0x00000197: case 0x00000198: return "Azure Server"; - case 0xABCDABCD: return "(Unlicensed)"; + case 0xABCDABCD: return " (Unlicensed)"; default: - static_sprintf(unknown_edition_str, "(Unknown Edition 0x%02X)", (uint32_t)ProductType); + static_sprintf(unknown_edition_str, " (Unknown Edition 0x%02X)", (uint32_t)ProductType); return unknown_edition_str; } } @@ -475,10 +475,9 @@ void GetWindowsVersion(windows_version_t* windows_version) else if (vi.wServicePackMajor) safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, arch_name); else - safe_sprintf(vptr, vlen, "%s%s%s %s", - w, (dwProductType != 0) ? " " : "", GetEdition(dwProductType), arch_name); + safe_sprintf(vptr, vlen, "%s%s %s", w, GetEditionName(dwProductType), arch_name); - windows_version->Edition = (int)dwProductType; + windows_version->Edition = dwProductType; // Add the build number (including UBR if available) windows_version->BuildNumber = vi.dwBuildNumber; diff --git a/src/stdlg.c b/src/stdlg.c index 57ae3200..38bd7cb3 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Standard Dialog Routines (Browse for folder, About, etc) - * Copyright © 2011-2025 Pete Batard + * Copyright © 2011-2026 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 @@ -48,6 +48,7 @@ /* Globals */ extern BOOL is_x86_64, appstore_version; extern char unattend_username[MAX_USERNAME_LENGTH], *sbat_level_txt, *sb_active_txt, *sb_revoked_txt; +extern int unattend_edition_index; extern HICON hSmallIcon, hBigIcon; static HICON hMessageIcon = (HICON)INVALID_HANDLE_VALUE; static char* szMessageText = NULL; @@ -787,8 +788,39 @@ int NotificationEx(int type, const char* dont_display_setting, const notificatio return (int)ret; } +static int GetComboBoxMinWidth(HWND hCtrl, StrArray* array) +{ + HDC hDC = GetDC(hCtrl); + HFONT hFont = (HFONT)SendMessage(hCtrl, WM_GETFONT, 0, 0); + HFONT hOldFont = (HFONT)SelectObject(hDC, hFont); + SIZE size; + uint32_t i; + int max_width = 0, arrow_width, padding; + + if (array == NULL || array->String == NULL) { + ReleaseDC(hCtrl, hDC); + return 0; + } + + for (i = 0; i < array->Index; i++) { + GetTextExtentPoint32A(hDC, array->String[i], (int)strlen(array->String[i]), &size); + if (size.cx > max_width) + max_width = size.cx; + } + SelectObject(hDC, hOldFont); + ReleaseDC(hCtrl, hDC); + + // Add the dropdown arrow button width + some padding + arrow_width = GetSystemMetrics(SM_CXVSCROLL); + padding = GetSystemMetrics(SM_CXEDGE) * 4 + 8; + + return max_width + arrow_width + padding; +} + // We only ever display one selection dialog, so set some params as globals -static int selection_dialog_style, selection_dialog_mask, selection_dialog_username_index; +static int selection_dialog_style; +static selection_dialog_options_t* selection_options = NULL; +static BOOL silent_install_checked = FALSE; /* * Custom dialog for radio button selection dialog @@ -803,19 +835,22 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM static LRESULT disabled[9] = { HTLEFT, HTRIGHT, HTTOP, HTBOTTOM, HTSIZE, HTTOPLEFT, HTTOPRIGHT, HTBOTTOMLEFT, HTBOTTOMRIGHT }; static HBRUSH background_brush, separator_brush; - char username[128] = { 0 }; + static HFONT hDlgFont = NULL; + char username[128] = { 0 }, str[MAX_PATH]; int i, m, dw, dh, r = -1, mw; DWORD size = sizeof(username); LRESULT loc; // To use the system message font NONCLIENTMETRICS ncm; RECT rc, rc2; - static HFONT hDlgFont = NULL; HWND hCtrl; HDC hDC; switch (message) { case WM_INITDIALOG: + StrArray version_name = { 0 }, version_index = { 0 }; + StrArrayCreate(&version_name, 16); + StrArrayCreate(&version_index, 16); SetDarkModeForDlg(hDlg); // Don't overflow our max radio button if (nDialogItems > (IDC_SELECTION_CHOICEMAX - IDC_SELECTION_CHOICE1 + 1)) { @@ -852,23 +887,27 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM mw = rc.right - rc.left - ddw; // ddw seems to work okay as a fudge dw = mw; + r = GetEditions(&version_name, &version_index); + // Change the default icon and set the text Static_SetIcon(GetDlgItem(hDlg, IDC_SELECTION_ICON), LoadIcon(NULL, IDI_QUESTION)); SetWindowTextU(hDlg, szMessageTitle); SetWindowTextU(GetDlgItem(hDlg, IDCANCEL), lmprintf(MSG_007)); SetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_TEXT), szMessageText); for (i = 0; i < nDialogItems; i++) { - char* str = szDialogItem[i]; + static_strcpy(str, szDialogItem[i]); SetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), str); ShowWindow(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), SW_SHOW); - // Compute the maximum line's width (with some extra for the username field if needed) - if (i == selection_dialog_username_index) { - str = calloc(strlen(szDialogItem[i]) + strlen(base_username) + 8, 1); - sprintf(str, "%s __%s__", szDialogItem[i], base_username); + // Compute the maximum line's width (with some extra for the username and edition fields) + if (selection_options != NULL && i == selection_options->username_index) { + static_sprintf(str, "%s __%s__", szDialogItem[i], base_username); + mw = max(mw, GetTextSize(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), str).cx); + } else if (selection_options != NULL && i == selection_options->edition_index) { + mw = max(mw, GetTextSize(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), str).cx + + GetComboBoxMinWidth(GetDlgItem(hDlg, IDC_SELECTION_EDITION), &version_name)); + } else { + mw = max(mw, GetTextSize(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), str).cx); } - mw = max(mw, GetTextSize(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), str).cx); - if (i == selection_dialog_username_index) - free(str); } // If our maximum line's width is greater than the default, set a nonzero delta width dw = (mw <= dw) ? 0 : mw - dw; @@ -887,12 +926,12 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), 0, dh, dw, 0, 1.0f); // If required, set up the the username edit box - if (selection_dialog_username_index != -1) { + if (selection_options != NULL && selection_options->username_index != -1) { unattend_username[0] = 0; - hCtrl = GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_dialog_username_index); + hCtrl = GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->username_index); GetClientRect(hCtrl, &rc); ResizeMoveCtrl(hDlg, hCtrl, 0, 0, - (rc.left - rc.right) + GetTextSize(hCtrl, szDialogItem[selection_dialog_username_index]).cx + ddw, 0, 1.0f); + (rc.left - rc.right) + GetTextSize(hCtrl, szDialogItem[selection_options->username_index]).cx + ddw, 0, 1.0f); GetWindowRect(hCtrl, &rc); SetWindowPos(GetDlgItem(hDlg, IDC_SELECTION_USERNAME), hCtrl, rc.left, rc.top, 0, 0, SWP_NOMOVE | SWP_NOSIZE); hCtrl = GetDlgItem(hDlg, IDC_SELECTION_USERNAME); @@ -905,6 +944,25 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM ShowWindow(hCtrl, SW_SHOW); } + // If required, set up the the edition combo box + if (selection_options != NULL && selection_options->edition_index != -1 && version_name.String != NULL && version_name.Index > 0) { + hCtrl = GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->edition_index); + GetClientRect(hCtrl, &rc); + ResizeMoveCtrl(hDlg, hCtrl, 0, 0, + (rc.left - rc.right) + GetTextSize(hCtrl, szDialogItem[selection_options->edition_index]).cx + ddw, 0, 1.0f); + GetWindowRect(hCtrl, &rc); + SetWindowPos(GetDlgItem(hDlg, IDC_SELECTION_EDITION), hCtrl, rc.left, rc.top, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hCtrl = GetDlgItem(hDlg, IDC_SELECTION_EDITION); + GetWindowRect(hCtrl, &rc2); + ResizeMoveCtrl(hDlg, hCtrl, right_to_left_mode ? rc2.right - rc.left : rc.right - rc2.left, rc.top - rc2.top, + GetComboBoxMinWidth(hCtrl, &version_name), 0, 1.0f); + for (i = 0; i < (int)version_name.Index; i++) + IGNORE_RETVAL(ComboBox_SetItemData(hCtrl, ComboBox_AddStringU(hCtrl, version_name.String[i]), + (LPARAM)atoi(version_index.String[i]))); + IGNORE_RETVAL(ComboBox_SetCurSel(hCtrl, unattend_edition_index)); + ShowWindow(hCtrl, SW_SHOW); + } + if (nDialogItems > 2) { GetWindowRect(GetDlgItem(hDlg, IDC_SELECTION_CHOICE2), &rc); GetWindowRect(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + nDialogItems - 1), &rc2); @@ -922,8 +980,17 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM // Set the default selection for (i = 0, m = 1; i < nDialogItems; i++, m <<= 1) - Button_SetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), (m & selection_dialog_mask) ? BST_CHECKED : BST_UNCHECKED); + Button_SetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), + ((selection_options == NULL && i == 0) || (selection_options != NULL && (m & selection_options->mask))) ? BST_CHECKED : BST_UNCHECKED); + if (selection_options != NULL && selection_options->username_index > 0 && selection_options->edition_index > 0) { + BOOL enable = Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->username_index)); + EnableWindow(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->edition_index), enable); + EnableWindow(GetDlgItem(hDlg, IDC_SELECTION_EDITION), enable); + } + SetDarkModeForChild(hDlg); + StrArrayDestroy(&version_name); + StrArrayDestroy(&version_index); return (INT_PTR)TRUE; case WM_CTLCOLORSTATIC: // Change the background colour for static text and icon @@ -945,12 +1012,29 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM safe_delete_object(hDlgFont); break; case WM_COMMAND: - switch (LOWORD(wParam)) { + WORD command = LOWORD(wParam); + if (command >= IDC_SELECTION_CHOICE1 && command < IDC_SELECTION_CHOICEMAX) { + // Check if the local account name or regional settings checkbox was clicked and enable/disable the silent install option + if (selection_options != NULL && selection_options->username_index > 0 && selection_options->edition_index > 0 && selection_options->regional_index > 0 && + (command - IDC_SELECTION_CHOICE1 == selection_options->username_index || command - IDC_SELECTION_CHOICE1 == selection_options->regional_index)) { + BOOL enable = Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->username_index)) && + Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->regional_index)); + hCtrl = GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->edition_index); + if (!enable && IsWindowEnabled(hCtrl)) { + silent_install_checked = (Button_GetCheck(hCtrl) == BST_CHECKED); + Button_SetCheck(hCtrl, FALSE); + } else if (enable && !IsWindowEnabled(hCtrl)) { + Button_SetCheck(hCtrl, silent_install_checked); + } + EnableWindow(hCtrl, enable); + EnableWindow(GetDlgItem(hDlg, IDC_SELECTION_EDITION), enable); + } + } else switch (LOWORD(wParam)) { case IDOK: for (r = 0, i = 0, m = 1; i < nDialogItems; i++, m <<= 1) if (Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i)) == BST_CHECKED) r += m; - if (selection_dialog_username_index != -1) { + if (selection_options != NULL && selection_options->username_index != -1) { GetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_USERNAME), unattend_username, MAX_USERNAME_LENGTH); // Perform string sanitization (NB: GetWindowTextU always terminates the string) for (i = 0; unattend_username[i] != 0; i++) { @@ -958,6 +1042,8 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM unattend_username[i] = '_'; } } + if (selection_options != NULL && selection_options->edition_index != -1) + unattend_edition_index = (int)ComboBox_GetCurItemData(GetDlgItem(hDlg, IDC_SELECTION_EDITION)); // Fall through case IDNO: case IDCANCEL: @@ -972,7 +1058,7 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM /* * Display an item selection dialog */ -int CustomSelectionDialog(int style, char* title, char* message, char** choices, int size, int mask, int username_index) +int CustomSelectionDialog(int style, char* title, char* message, char** choices, int size, selection_dialog_options_t* options) { int ret; @@ -981,10 +1067,9 @@ int CustomSelectionDialog(int style, char* title, char* message, char** choices, szMessageText = message; szDialogItem = choices; nDialogItems = size; + selection_options = options; selection_dialog_style = style; - selection_dialog_mask = mask; - selection_dialog_username_index = username_index; - assert(selection_dialog_style == BS_AUTORADIOBUTTON || selection_dialog_style == BS_AUTOCHECKBOX); + assert(style == BS_AUTORADIOBUTTON || style == BS_AUTOCHECKBOX); ret = (int)MyDialogBox(hMainInstance, IDD_SELECTION, hMainDialog, CustomSelectionCallback); dialog_showing--; diff --git a/src/wue.c b/src/wue.c index 5c10c957..6e8d68c4 100644 --- a/src/wue.c +++ b/src/wue.c @@ -46,13 +46,58 @@ const char* bypass_name[] = { "BypassTPMCheck", "BypassSecureBootCheck", "Bypass int unattend_xml_flags = 0, wintogo_index = -1, wininst_index = 0; int unattend_xml_mask = UNATTEND_DEFAULT_SELECTION_MASK; +int unattend_edition_index = 1; char *unattend_xml_path = NULL, unattend_username[MAX_USERNAME_LENGTH]; +uint32_t removable_section[2] = { 0, 0 }; extern BOOL validate_md5sum; extern uint64_t md5sum_totalbytes; extern StrArray modified_files; extern const char* efi_archname[ARCH_MAX]; +// Get the UI language provided by the ISO's boot.wim +char* GetUILanguage(void) +{ + static char ui_language[8]; + int r; + char wim_path[4 * MAX_PATH] = ""; + wchar_t* xml = NULL; + ezxml_t pxml = NULL; + size_t xml_len; + WIMStruct* wim = NULL; + + assert(safe_strlen(image_path) + 32 < ARRAYSIZE(wim_path)); + static_strcpy(ui_language, "en-US"); + static_strcpy(wim_path, image_path); + static_strcat(wim_path, "|sources/boot.wim"); + + r = wimlib_open_wimU(wim_path, 0, &wim); + if (r != 0) { + uprintf("Could not open WIM: Error %d", r); + goto out; + } + + r = wimlib_get_xml_data(wim, (void**)&xml, &xml_len); + if (r != 0) { + uprintf("Could not read WIM XML index: Error %d", r); + goto out; + } + + pxml = ezxml_parse_str((char*)xml, xml_len); + if (pxml == NULL) + goto out; + + char* lang = ezxml_get_val(pxml, "IMAGE", 1, "WINDOWS", 0, "LANGUAGES", 0, "LANGUAGE", -1); + if (lang != NULL) + static_strcpy(ui_language, lang); + +out: + ezxml_free(pxml); + free(xml); + wimlib_free(wim); + return ui_language; +} + /// /// Create an installation answer file containing the sections specified by the flags. /// @@ -70,6 +115,8 @@ char* CreateUnattendXml(int arch, int flags) TIME_ZONE_INFORMATION tz_info; int i, order; unattend_xml_flags = flags; + StrArray commands = STRARRAY_EMPTY; + StrArrayCreate(&commands, 8); if (arch < ARCH_X86_32 || arch > ARCH_ARM_64 || flags == 0) { uprintf("Note: No Windows User Experience options selected"); return NULL; @@ -86,24 +133,104 @@ char* CreateUnattendXml(int arch, int flags) fprintf(fd, "\n"); fprintf(fd, "\n"); - // This part produces the unbecoming display of a command prompt window during initial setup as well - // as alters the layout and options of the initial Windows installer screens, which may scare users. - // So, in format.c, we'll try to insert the registry keys directly and drop this section. However, - // because Microsoft prevents Store apps from editing an offline registry, we do need this fallback. if (flags & UNATTEND_WINPE_SETUP_MASK) { - order = 1; fprintf(fd, " \n"); fprintf(fd, " \n", xml_arch_names[arch]); // WinPE will complain if we don't provide a product key. *Any* product key. This is soooo idiotic... fprintf(fd, " \n"); + fprintf(fd, " true\n"); fprintf(fd, " \n"); fprintf(fd, " \n"); fprintf(fd, " \n"); fprintf(fd, " \n"); + if (flags & UNATTEND_SILENT_INSTALL) { + uprintf("• Silent Install"); + // Automatically partition the disk and set the installation target + fprintf(fd, " \n"); + fprintf(fd, " OnError\n"); + if (flags & UNATTEND_DISABLE_BITLOCKER) + fprintf(fd, " true\n"); + // The following ensures that we display the disk selection screen if only the boot media is + // available (i.e. if the system does not see any target for installation). In that case the + // letter assignment below fails and the UI is displayed allowing the user to provide drivers. + // This also prevents the install media from being scratched, when it's the only disk. + // With a special mention to Claude AI, that explicitly said this could not be accomplished... + fprintf(fd, " \n"); + fprintf(fd, " 1 \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " 1\n"); + fprintf(fd, " 1\n"); + // You REALLY don't want to use 'U' for the drive letter below. Don't ask me how I know!!! + fprintf(fd, " D\n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " 0 \n"); + fprintf(fd, " true \n"); + fprintf(fd, " \n"); + // NB: Don't bother creating a recovery partition. Windows setup will do it for us. + fprintf(fd, " \n"); + fprintf(fd, " 1\n"); + fprintf(fd, " EFI\n"); + fprintf(fd, " 260\n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " 2\n"); + fprintf(fd, " MSR\n"); + fprintf(fd, " 16\n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " 3\n"); + fprintf(fd, " Primary\n"); + fprintf(fd, " true\n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " 1\n"); + fprintf(fd, " 1\n"); + fprintf(fd, " \n"); + fprintf(fd, " FAT32\n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " 2\n"); + fprintf(fd, " 3\n"); + fprintf(fd, " \n"); + fprintf(fd, " C\n"); + fprintf(fd, " NTFS\n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " OnError\n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " /IMAGE/INDEX\n"); + fprintf(fd, " %d\n", unattend_edition_index); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " 0\n"); + fprintf(fd, " 3\n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " \n"); + } if (flags & UNATTEND_SECUREBOOT_TPM_MINRAM) { + // This part produces the unbecoming display of a command prompt window during initial setup as well + // as alters the layout and options of the initial Windows installer screens, which may scare users. + // So, in format.c, we'll try to insert the registry keys directly and drop this section. However, + // because Microsoft prevents Store apps from editing an offline registry, we do need this fallback. + // NB: We could probably avoid this by running powershell with -WindowStyle "Hidden" but hey... uprintf("• Bypass SB/TPM/RAM"); + order = 1; + removable_section[0] = (uint32_t)ftell(fd); fprintf(fd, " \n"); for (i = 0; i < ARRAYSIZE(bypass_name); i++) { fprintf(fd, " \n"); @@ -112,46 +239,60 @@ char* CreateUnattendXml(int arch, int flags) fprintf(fd, " \n"); } fprintf(fd, " \n"); + removable_section[1] = (uint32_t)ftell(fd); } fprintf(fd, " \n"); + if (flags & UNATTEND_SILENT_INSTALL) { + fprintf(fd, " \n", xml_arch_names[arch]); + // Set the language from the tag of the boot.wim index + fprintf(fd, " %s\n", GetUILanguage()); + fprintf(fd, " \n"); + } fprintf(fd, " \n"); } if (flags & UNATTEND_SPECIALIZE_DEPLOYMENT_MASK) { - order = 1; fprintf(fd, " \n"); fprintf(fd, " \n", xml_arch_names[arch]); - fprintf(fd, " \n"); // This part was picked from https://github.com/AveYo/MediaCreationTool.bat/blob/main/bypass11/AutoUnattend.xml // NB: This is INCOMPATIBLE with S-Mode below if (flags & UNATTEND_NO_ONLINE_ACCOUNT) { + StrArrayAdd(&commands, "reg add \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE\" /v BypassNRO /t REG_DWORD /d 1 /f", TRUE); uprintf("• Bypass online account requirement"); - fprintf(fd, " \n"); - fprintf(fd, " %d\n", order++); - fprintf(fd, " reg add HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE /v BypassNRO /t REG_DWORD /d 1 /f\n"); - fprintf(fd, " \n"); } - fprintf(fd, " \n"); + // Now that we have all the commands to run, create the RunSynchronous section. + for (order = 1; order <= (int)commands.Index; order++) { + if (order == 1) + fprintf(fd, " \n"); + fprintf(fd, " \n"); + fprintf(fd, " %d\n", order); + fprintf(fd, " %s\n", commands.String[order - 1]); + fprintf(fd, " \n"); + if (order == commands.Index) + fprintf(fd, " \n"); + } fprintf(fd, " \n"); fprintf(fd, " \n"); + StrArrayClear(&commands); } if (flags & UNATTEND_OOBE_MASK) { - StrArray first_logon_commands = STRARRAY_EMPTY; - StrArrayCreate(&first_logon_commands, 8); fprintf(fd, " \n"); if (flags & UNATTEND_OOBE_SHELL_SETUP_MASK) { fprintf(fd, " \n", xml_arch_names[arch]); // https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-oobe-protectyourpc - // It is really super insidous of Microsoft to call this option "ProtectYourPC", when it's really only about + // It is really super disingenuous of Microsoft to call this option "ProtectYourPC", when it's really only about // data collection. But of course, if it was called "AllowDataCollection", everyone would turn it off... if (flags & UNATTEND_NO_DATA_COLLECTION) { uprintf("• Disable data collection"); fprintf(fd, " \n"); + fprintf(fd, " true\n"); fprintf(fd, " 3\n"); fprintf(fd, " \n"); } @@ -200,14 +341,13 @@ char* CreateUnattendXml(int arch, int flags) // Since we set a blank password, we'll ask the user to change it at next logon. // NB: In case you wanna try, please be aware that Microsoft doesn't let you have multiple // sections in unattend.xml. Don't ask me how I know... :( - static_sprintf(tmp, "net user "%s" /logonpasswordchg:yes", unattend_username); - StrArrayAdd(&first_logon_commands, tmp, TRUE); + static_sprintf(tmp, "net user \"%s\" /logonpasswordchg:yes", unattend_username); + StrArrayAdd(&commands, tmp, TRUE); // The `net user` command above might reset the password expiration to 90 days... // To alleviate that, blanket set passwords on the target machine to never expire. - StrArrayAdd(&first_logon_commands, "net accounts /maxpwage:unlimited", TRUE); + StrArrayAdd(&commands, "net accounts /maxpwage:unlimited", TRUE); } } - // Apply SkuSiPolicy.p7b, if the user requested it and we're not creating a Windows To Go drive. // See https://support.microsoft.com/kb/5042562. We do it post install, on first logon, because // we'd have to patch tons of files otherwise. And we *ALWAYS* use the installed system's @@ -216,25 +356,25 @@ char* CreateUnattendXml(int arch, int flags) // produce the 0xc0000428 signature validation error on (re)boot if the system hasn't gone // through a full Windows Update cycle. if (flags & UNATTEND_APPLY_SKUSIPOLICY) { - StrArrayAdd(&first_logon_commands, "cmd /c mountvol S: /S && " + uprintf("• Apply SkuSiPolicy.p7b"); + // TODO: Could we hide this using PowerShell? + StrArrayAdd(&commands, "cmd /c mountvol S: /S && " "copy %WINDIR%\\system32\\SecureBootUpdates\\SkuSiPolicy.p7b S:\\EFI\\Microsoft\\Boot && " "mountvol S: /D", TRUE); } - // Now that we have all the commands to run, create the FirstLogonCommands section. - for (order = 1; order <= (int)first_logon_commands.Index; order++) { + for (order = 1; order <= (int)commands.Index; order++) { if (order == 1) fprintf(fd, " \n"); fprintf(fd, " \n"); fprintf(fd, " %d\n", order); - fprintf(fd, " %s\n", first_logon_commands.String[order - 1]); + fprintf(fd, " %s\n", commands.String[order - 1]); fprintf(fd, " \n"); - if (order == first_logon_commands.Index) + if (order == commands.Index) fprintf(fd, " \n"); } - StrArrayDestroy(&first_logon_commands); - fprintf(fd, " \n"); + StrArrayClear(&commands); } if (flags & UNATTEND_OOBE_INTERNATIONAL_MASK) { uprintf("• Use the same regional options as this user's"); @@ -294,6 +434,7 @@ char* CreateUnattendXml(int arch, int flags) if (flags & UNATTEND_USE_MS2023_BOOTLOADERS) uprintf("• Use 'Windows CA 2023' signed bootloaders"); + StrArrayDestroy(&commands); fprintf(fd, "\n"); fclose(fd); return path; @@ -530,6 +671,86 @@ out: return ((img_report.win_version.major != 0) && (img_report.win_version.build != 0)); } +int GetEditions(StrArray* version_name, StrArray* version_index) +{ + int i, r, n = -1; + WIMStruct* wim = NULL; + const char* edition_suffix; + char *install_names[MAX_WININST], *edition_name; + wchar_t wim_path[4 * MAX_PATH] = L"", * xml = NULL; + size_t xml_len; + BOOL bNonStandard = FALSE; + ezxml_t index = NULL, image = NULL; + + // If we have multiple windows install images, ask the user the one to use + if (img_report.wininst_index > 1) { + for (i = 0; i < img_report.wininst_index; i++) + install_names[i] = &img_report.wininst_path[i][2]; + wininst_index = _log2(SelectionDialog(lmprintf(MSG_130), lmprintf(MSG_131), install_names, img_report.wininst_index)); + if (wininst_index < 0) + return -2; + if (wininst_index >= MAX_WININST) + wininst_index = 0; + } + + assert(utf8_to_wchar_get_size(image_path) <= ARRAYSIZE(wim_path)); + utf8_to_wchar_no_alloc(image_path, wim_path, ARRAYSIZE(wim_path)); + if (!img_report.is_windows_img) { + wcscat(wim_path, L"|"); + assert(utf8_to_wchar_get_size(image_path) + utf8_to_wchar_get_size(&img_report.wininst_path[wininst_index][2]) <= ARRAYSIZE(wim_path)); + utf8_to_wchar_no_alloc(&img_report.wininst_path[wininst_index][2], + &wim_path[wcslen(wim_path)], (int)ARRAYSIZE(wim_path) - wcslen(wim_path)); + } + + r = wimlib_open_wim(wim_path, 0, &wim); + if (r != 0) { + uprintf("Could not open WIM: %d", r); + goto out; + } + r = wimlib_get_xml_data(wim, (void**)&xml, &xml_len); + if (r != 0) { + uprintf("Could not read WIM XML index: %d", r); + goto out; + } + + index = ezxml_parse_str((char*)xml, xml_len); + if (index == NULL) { + uprintf("Could not parse WIM XML"); + goto out; + } + + edition_suffix = GetEditionName(WindowsVersion.Edition); + unattend_edition_index = 1; + for (n = 0, image = ezxml_child(index, "IMAGE"); + StrArrayAdd(version_index, ezxml_attr(image, "INDEX"), TRUE) >= 0; + image = image->next, n++) { + // Try to match this host's edition with an index from the image + edition_name = ezxml_child_val(image, "NAME"); + if (edition_name != NULL) { + if (strlen(edition_name) > safe_strlen(edition_suffix) && + stricmp(&edition_name[strlen(edition_name) - safe_strlen(edition_suffix)], edition_suffix) == 0) + unattend_edition_index = atoi(ezxml_attr(image, "INDEX")) - 1; + } + // Some people are apparently creating *unofficial* Windows ISOs that don't have DISPLAYNAME elements. + // If we are parsing such an ISO, try to fall back to using DESCRIPTION. + if (StrArrayAdd(version_name, ezxml_child_val(image, "DISPLAYNAME"), TRUE) < 0) { + if (StrArrayAdd(version_name, ezxml_child_val(image, "DESCRIPTION"), TRUE) < 0) { + uprintf("WARNING: Could not find a description for image index %d", n + 1); + StrArrayAdd(version_name, "Unknown Windows Version", TRUE); + } + bNonStandard = TRUE; + } + } + if (bNonStandard) + uprintf("WARNING: Nonstandard Windows image (missing entries)"); + +out: + free(xml); + ezxml_free(index); + wimlib_free(wim); + return n; +} + /// /// Checks which versions of Windows are available in an install image /// to set our extraction index. Asks the user to select one if needed. @@ -773,7 +994,7 @@ BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp) /// A bitmap of unattend flags to apply. /// TRUE on success, FALSE on error. BOOL ApplyWindowsCustomization(char drive_letter, int flags) -// NB: Work with a copy of unattend_xml_flags as a paremeter since we will modify it. +// NB: Work with a copy of unattend_xml_flags as a parameter since we will modify it. { BOOL r = FALSE, is_hive_mounted = FALSE, update_boot_wim = FALSE; int i, wim_index = 2, wuc_index = 0, num_replaced = 0; @@ -791,12 +1012,12 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags) char path[MAX_PATH], *rep, *tmp_dir_end; uint8_t* buf = NULL; uint16_t setup_arch; - size_t len; + uint32_t len; HKEY hKey = NULL, hSubKey = NULL; LSTATUS status; DWORD dwDisp, dwVal = 1, dwSize; FILE* fd_md5sum; - WIMStruct* wim; + WIMStruct* wim = NULL; StrArray files; struct wimlib_update_command wuc[2] = { 0 }; @@ -845,7 +1066,7 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags) dwSize = read_file(setup_exe, &buf); if (dwSize != 0) { setup_arch = GetPeArch(buf); - free(buf); + safe_free(buf); if (setup_arch != IMAGE_FILE_MACHINE_AMD64 && setup_arch != IMAGE_FILE_MACHINE_ARM64) { uprintf("WARNING: Unsupported arch 0x%x -- in-place upgrade wrapper will not be added", setup_arch); } else if (!MoveFileExU(setup_exe, setup_dll, 0)) { @@ -870,6 +1091,7 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags) } else { uprintf("Could not create '%s' bypass wrapper", setup_exe); } + buf = NULL; } } } @@ -948,19 +1170,27 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags) wuc[wuc_index].add.wim_target_path = L"Windows\\System32\\config\\SYSTEM"; wuc_index++; - // We were successfull in creating the keys so disable the windowsPE section from unattend.xml - // We do this by replacing '' with '' - // (provided that the registry key creation was the only item for this pass) + // We were successfull in creating the keys so remove this part from unattend.xml if ((flags & UNATTEND_WINPE_SETUP_MASK) == UNATTEND_SECUREBOOT_TPM_MINRAM) { + // If this is all we used the WindowsPE pass for, then we just replace + // '' with '' if (replace_in_token_data(unattend_xml_path, " entries from windowsPE (and only windowsPE). - assert(FALSE); + // Otherwise, remove the relevant section from our temporary unattend.xml + len = read_file(unattend_xml_path, &buf); + if (len != 0 && removable_section[0] != 0 && removable_section[0] < len && removable_section[1] < len) { + memmove(&buf[removable_section[0]], &buf[removable_section[1]], len - removable_section[1]); + len -= removable_section[1] - removable_section[0]; + if (write_file(unattend_xml_path, buf, len) != len) + uprintf("Failed to remove 'WindowsPE' section from unattend.xml"); + } else { + uprintf("Failed to remove 'WindowsPE' section from unattend.xml"); + } + safe_free(buf); } + // Remove the flags, since we accomplished the registry creation outside of unattend. + flags &= ~UNATTEND_SECUREBOOT_TPM_MINRAM; UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 102, PATCH_PROGRESS_TOTAL); } @@ -1016,7 +1246,7 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags) WIMLIB_EXTRACT_FLAG_NO_ACLS | WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE) != 0) { uprintf("Could not extract 2023 signed UEFI bootloaders - Ignoring option"); } else { - len = strlen(tmp_path[1]); + len = (uint32_t)strlen(tmp_path[1]); tmp_dir_end = &tmp_path[1][len]; // Copy/override the Font files From d4d537fc5baf5ae7dd51d7971f1466907e90c9bd Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 11 Mar 2026 15:47:06 +0000 Subject: [PATCH 04/80] [uefi] change the name of the UEFI:NTFS partition to RUFUS_BOOT * This should make it more explicit to Windows users to identify the installation media. * Also update crazy-max/ghaction-upx to latest (Closes #2936). * Also fix a Coverity warning and use improve StrArray handling/init. --- .github/workflows/vs2022.yml | 2 +- res/uefi/readme.txt | 8 +++++--- res/uefi/uefi-ntfs.img | Bin 1048576 -> 1048576 bytes src/dev.c | 2 +- src/drive.c | 2 +- src/rufus.h | 1 - src/rufus.rc | 10 +++++----- src/wue.c | 6 +++--- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/vs2022.yml b/.github/workflows/vs2022.yml index 228a11aa..f19f80d3 100644 --- a/.github/workflows/vs2022.yml +++ b/.github/workflows/vs2022.yml @@ -51,7 +51,7 @@ jobs: msbuild-architecture: x64 - name: Install UPX - uses: crazy-max/ghaction-upx@v3 + uses: crazy-max/ghaction-upx@v4 with: install-only: true diff --git a/res/uefi/readme.txt b/res/uefi/readme.txt index 76fb335d..bf8f3f26 100644 --- a/res/uefi/readme.txt +++ b/res/uefi/readme.txt @@ -25,10 +25,12 @@ o Secure Boot signed UEFI:NTFS bootloader binaries [3]. The above means that, if booting an NTFS partition on an x86_32, x86_64 or ARM64 system, Secure Boot does not need to be disabled. -The FAT partition was created on Debian GNU/Linux using the following commands +The FAT partition was created on Debian GNU/Linux using the following commands: dd if=/dev/zero of=uefi-ntfs.img bs=512 count=2048 - mkfs.vfat -n UEFI_NTFS uefi-ntfs.img -and then mounting the uefi-ntfs.img image and copying the relevant files. + chown 1000:100 uefi-ntfs.img + mkfs.vfat -n RUFUS_BOOT uefi-ntfs.img + mount -t vfat uefi-ntfs.img /mnt/hd -o rw,uid=1000,gid=100 +and then copying the relevant files. [1] https://github.com/pbatard/ntfs-3g [2] https://github.com/pbatard/efifs diff --git a/res/uefi/uefi-ntfs.img b/res/uefi/uefi-ntfs.img index 57deaef7e4ff03874ee4f014797b66e45f7e3f5f..d9ff7dc606ea992c208a9676ec1c763d63eca084 100644 GIT binary patch delta 505 zcmZo@aA;_7n4r!#_1YPUpisBa;CLs0|B#KQr#TG~Tm=pWhEqK0G3hZ7ngI-4-8>bb zK!CyQCQtfgLoOSES#Mwp6Kn%^Gj816$W`w?@dC@FAYL7iBCsJKni*_}o*v8$1&ARq z`N@_+CTtK5lZ%6__$*+0PbHQ_I|EI1Wydg*g^-a^2qUAc*v!F3PTq`QevYydgj*Cf zF)+rM!J!6d*CDp1q-{xzydQMnvLLfl zZX660hq8-7Y-@=4W+e7!5ZeZ-K7`3i2*L)&hHdzdumZ*lVN5_rHnO%wF||c8w?(nE lMFH7tZBguPQ5Z2ykCf0u);>u)0~C~t^x-G1Mlp>n7|ka%>V{K)e2A` zz#t+tJ8-fgmyJNHDpcXA1lxe!j2kyMa@D&}yudOkh*t-s2y6(5W(FIgrw21b0b&SD zezIkd37aTb!{p*1E53TTxrrsw&OlRL*+E7^Q~=!tQptj8B(nTu%P54AQC4g0sIu#1t{n?dYmi1=qDws8oPl~4;<9O!G?@E>6Xj2FU~ zfR1crZHr=Ri(+nzVrh#4vf0|A*xRBw+M+nyqPW_kxZ9$5+M;;dqWG3Y@h<}a%=nIZ diff --git a/src/dev.c b/src/dev.c index f5d5ece6..c8bee183 100644 --- a/src/dev.c +++ b/src/dev.c @@ -476,7 +476,7 @@ BOOL GetDevices(DWORD devnum) const char* bitdefender_label = "Bitdefender Partition"; // Hash table and String Array used to match a Device ID with the parent hub's Device Interface Path htab_table htab_devid = HTAB_EMPTY; - StrArray dev_if_path = STRARRAY_EMPTY; + StrArray dev_if_path = { 0 }; char letter_name[] = " (?:)"; char drive_name[] = "?:\\"; char setting_name[32]; diff --git a/src/drive.c b/src/drive.c index 798db108..8c398ab1 100644 --- a/src/drive.c +++ b/src/drive.c @@ -1944,7 +1944,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys if (buf != NULL) { if (SetFilePointerEx(hPhysical, DriveLayout->PartitionEntry[i].StartingOffset, NULL, FILE_BEGIN) && ReadFile(hPhysical, buf, SelectedDrive.SectorSize, &size, NULL)) { - isUefiNtfs = (strncmp(&buf[0x2B], "UEFI_NTFS", 9) == 0); + isUefiNtfs = (strncmp(&buf[0x2B], "UEFI_NTFS", 9) == 0) || (strncmp(&buf[0x2B], "RUFUS_BOOT", 10) == 0); } free(buf); } diff --git a/src/rufus.h b/src/rufus.h index 401769eb..b86c5757 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -735,7 +735,6 @@ typedef struct { uint32_t Index; // Current array size uint32_t Max; // Maximum array size } StrArray; -#define STRARRAY_EMPTY { NULL, 0, 0 }; extern void StrArrayCreate(StrArray* arr, uint32_t initial_size); extern int32_t StrArrayAdd(StrArray* arr, const char* str, BOOL); extern int32_t StrArrayAddUnique(StrArray* arr, const char* str, BOOL); diff --git a/src/rufus.rc b/src/rufus.rc index 967272f0..b867f998 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 4.14.2319" +CAPTION "Rufus 4.14.2320" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -409,8 +409,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,14,2319,0 - PRODUCTVERSION 4,14,2319,0 + FILEVERSION 4,14,2320,0 + PRODUCTVERSION 4,14,2320,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -428,13 +428,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.14.2319" + VALUE "FileVersion", "4.14.2320" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2026 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.14.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.14.2319" + VALUE "ProductVersion", "4.14.2320" END END BLOCK "VarFileInfo" diff --git a/src/wue.c b/src/wue.c index 6e8d68c4..9d7d6c0b 100644 --- a/src/wue.c +++ b/src/wue.c @@ -115,8 +115,7 @@ char* CreateUnattendXml(int arch, int flags) TIME_ZONE_INFORMATION tz_info; int i, order; unattend_xml_flags = flags; - StrArray commands = STRARRAY_EMPTY; - StrArrayCreate(&commands, 8); + StrArray commands = { 0 }; if (arch < ARCH_X86_32 || arch > ARCH_ARM_64 || flags == 0) { uprintf("Note: No Windows User Experience options selected"); return NULL; @@ -133,6 +132,7 @@ char* CreateUnattendXml(int arch, int flags) fprintf(fd, "\n"); fprintf(fd, "\n"); + StrArrayCreate(&commands, 8); if (flags & UNATTEND_WINPE_SETUP_MASK) { fprintf(fd, " \n"); fprintf(fd, " Date: Fri, 13 Mar 2026 23:15:27 +0000 Subject: [PATCH 05/80] [wue] add a new 'QoL Enhancements' option * This option disables most of the unwanted crap that Microsoft tries to push onto users by default. * Also make sure the Silent Install option is only enabled if the 'Disable data collection' check box is checked. * Also add a big scary warning for the Silent Install option. --- res/loc/rufus.loc | 7 ++++- src/rufus.c | 19 +++++++------- src/rufus.h | 10 +++++--- src/rufus.rc | 10 ++++---- src/stdlg.c | 13 +++++++--- src/wue.c | 65 ++++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 99 insertions(+), 25 deletions(-) diff --git a/res/loc/rufus.loc b/res/loc/rufus.loc index 8c04063f..58ffc1f2 100644 --- a/res/loc/rufus.loc +++ b/res/loc/rufus.loc @@ -578,7 +578,7 @@ t MSG_321 "The image you have selected is an ISOHybrid, but its creators have no "copy mode.\nAs a result, DD image writing mode will be enforced." t MSG_322 "Unable to open or read '%s'" t MSG_323 "Apply SkuSiPolicy.p7b on installation (See KB5042562)" -t MSG_324 "⚠SILENTLY⚠ erase disk and install:" +t MSG_324 "QoL Improvements (Don't force Copilot, OneDrive, Outlook, Fast Startup, etc.)" t MSG_325 "Applying Windows customization: %s" t MSG_326 "Applying user options..." t MSG_327 "Windows User Experience" @@ -619,6 +619,11 @@ t MSG_354 "Rufus has found an updated version of the DBX files used to perform U "- Select 'Yes' to connect to the Internet and download this content\n" "- Select 'No' to cancel the operation\n\n" "Note: The files will be downloaded in the application's directory and will be reused automatically if present." +t MSG_355 "⚠SILENTLY⚠ erase disk and install:" +t MSG_356 "You have selected to use the \"silent\" Windows installation option.\n\n" + "This is an advanced option, reserved for people who want to create media that does not prompt the user during Windows installation and therefore UNCONDITIONALLY ERASES the " + "first detected disk on the target system, without asking. If you are not careful, using this option can result in IRREVERSIBLE DATA LOSS!\n\nIf this is not what you want, " + "please select 'No' to go back and uncheck the option.\nOtherwise, if you agree that the whole responsibility for any data loss will be entirely with YOU, select 'Yes'." # The following messages are for the Windows Store listing only and are not used by the application t MSG_900 "Rufus is a utility that helps format and create bootable USB flash drives, such as USB keys/pendrives, memory sticks, etc." t MSG_901 "Official site: %s" diff --git a/src/rufus.c b/src/rufus.c index 790da244..67409f95 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -1503,7 +1503,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param) const char* syslinux = "syslinux"; const char* ldlinux_ext[3] = { "sys", "bss", "c32" }; char tmp[MAX_PATH], tmp2[MAX_PATH], c; - selection_dialog_options_t selection_options = { 0, -1, -1, -1 }; + selection_dialog_options_t selection_options = { 0, -1, -1, -1, -1 }; syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0; safe_free(grub2_buf); @@ -1684,21 +1684,22 @@ static DWORD WINAPI BootCheckThread(LPVOID param) selection_options.regional_index = _log2(b); MAP_BIT(UNATTEND_DUPLICATE_LOCALE); StrArrayAdd(&options, lmprintf(MSG_331), TRUE); + selection_options.privacy_index = _log2(b); MAP_BIT(UNATTEND_NO_DATA_COLLECTION); if (IS_WINDOWS_11(img_report)) { StrArrayAdd(&options, lmprintf(MSG_335), TRUE); MAP_BIT(UNATTEND_DISABLE_BITLOCKER); - } - if (img_report.win_version.build >= 26200) { - StrArrayAdd(&options, lmprintf(MSG_350), TRUE); - MAP_BIT(UNATTEND_USE_MS2023_BOOTLOADERS); - StrArrayAdd(&options, lmprintf(MSG_323), TRUE); - MAP_BIT(UNATTEND_APPLY_SKUSIPOLICY); - } - if (IS_WINDOWS_11(img_report)) { StrArrayAdd(&options, lmprintf(MSG_324), TRUE); + MAP_BIT(UNATTEND_QOL_ENHANCEMENTS); + StrArrayAdd(&options, lmprintf(MSG_355), TRUE); selection_options.edition_index = _log2(b); MAP_BIT(UNATTEND_SILENT_INSTALL); + if (img_report.win_version.build >= 26200) { + StrArrayAdd(&options, lmprintf(MSG_350), TRUE); + MAP_BIT(UNATTEND_USE_MS2023_BOOTLOADERS); + StrArrayAdd(&options, lmprintf(MSG_323), TRUE); + MAP_BIT(UNATTEND_APPLY_SKUSIPOLICY); + } } if (expert_mode) { StrArrayAdd(&options, lmprintf(MSG_346), TRUE); diff --git a/src/rufus.h b/src/rufus.h index b86c5757..8a730fbf 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -513,6 +513,7 @@ typedef struct { int username_index; int edition_index; int regional_index; + int privacy_index; } selection_dialog_options_t; /* @@ -695,16 +696,17 @@ typedef struct { #define UNATTEND_USE_MS2023_BOOTLOADERS 0x00200 #define UNATTEND_APPLY_SKUSIPOLICY 0x00400 #define UNATTEND_SILENT_INSTALL 0x00800 -#define UNATTEND_FULL_MASK 0x00FFF -#define UNATTEND_DEFAULT_MASK 0x006FF // Mask of values that are persisted +#define UNATTEND_QOL_ENHANCEMENTS 0x01000 +#define UNATTEND_FULL_MASK 0x01FFF +#define UNATTEND_DEFAULT_MASK 0x016FF // Mask of values that are persisted #define UNATTEND_WINDOWS_TO_GO 0x10000 // Special flag for Windows To Go #define UNATTEND_WINPE_SETUP_MASK (UNATTEND_SECUREBOOT_TPM_MINRAM | UNATTEND_SILENT_INSTALL) -#define UNATTEND_SPECIALIZE_DEPLOYMENT_MASK (UNATTEND_NO_ONLINE_ACCOUNT) +#define UNATTEND_SPECIALIZE_DEPLOYMENT_MASK (UNATTEND_NO_ONLINE_ACCOUNT | UNATTEND_QOL_ENHANCEMENTS) #define UNATTEND_OOBE_SHELL_SETUP_MASK (UNATTEND_NO_DATA_COLLECTION | UNATTEND_SET_USER | UNATTEND_DUPLICATE_LOCALE) #define UNATTEND_OOBE_INTERNATIONAL_MASK (UNATTEND_DUPLICATE_LOCALE) #define UNATTEND_OOBE_MASK (UNATTEND_OOBE_SHELL_SETUP_MASK | UNATTEND_OOBE_INTERNATIONAL_MASK | UNATTEND_DISABLE_BITLOCKER | \ - UNATTEND_USE_MS2023_BOOTLOADERS | UNATTEND_APPLY_SKUSIPOLICY) + UNATTEND_USE_MS2023_BOOTLOADERS | UNATTEND_APPLY_SKUSIPOLICY | UNATTEND_QOL_ENHANCEMENTS) #define UNATTEND_OFFLINE_SERVICING_MASK (UNATTEND_OFFLINE_INTERNAL_DRIVES | UNATTEND_FORCE_S_MODE) #define UNATTEND_DEFAULT_SELECTION_MASK (UNATTEND_SECUREBOOT_TPM_MINRAM | UNATTEND_NO_ONLINE_ACCOUNT | UNATTEND_OFFLINE_INTERNAL_DRIVES) diff --git a/src/rufus.rc b/src/rufus.rc index b867f998..7afe85db 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 4.14.2320" +CAPTION "Rufus 4.14.2321" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -409,8 +409,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,14,2320,0 - PRODUCTVERSION 4,14,2320,0 + FILEVERSION 4,14,2321,0 + PRODUCTVERSION 4,14,2321,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -428,13 +428,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.14.2320" + VALUE "FileVersion", "4.14.2321" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2026 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.14.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.14.2320" + VALUE "ProductVersion", "4.14.2321" END END BLOCK "VarFileInfo" diff --git a/src/stdlg.c b/src/stdlg.c index 38bd7cb3..76fe3193 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -1014,11 +1014,13 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM case WM_COMMAND: WORD command = LOWORD(wParam); if (command >= IDC_SELECTION_CHOICE1 && command < IDC_SELECTION_CHOICEMAX) { - // Check if the local account name or regional settings checkbox was clicked and enable/disable the silent install option + // Check if local account + regional settings + data collection checkboxes are clicked and enable/disable the silent install option if (selection_options != NULL && selection_options->username_index > 0 && selection_options->edition_index > 0 && selection_options->regional_index > 0 && - (command - IDC_SELECTION_CHOICE1 == selection_options->username_index || command - IDC_SELECTION_CHOICE1 == selection_options->regional_index)) { + (command - IDC_SELECTION_CHOICE1 == selection_options->username_index || command - IDC_SELECTION_CHOICE1 == selection_options->regional_index || + command - IDC_SELECTION_CHOICE1 == selection_options->privacy_index)) { BOOL enable = Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->username_index)) && - Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->regional_index)); + Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->regional_index)) && + Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->privacy_index)); hCtrl = GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->edition_index); if (!enable && IsWindowEnabled(hCtrl)) { silent_install_checked = (Button_GetCheck(hCtrl) == BST_CHECKED); @@ -1031,6 +1033,11 @@ static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM } } else switch (LOWORD(wParam)) { case IDOK: + // Produce a big scary warning if the silent install option was selected + if (selection_options != NULL && selection_options->edition_index >= 0 && + Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_options->edition_index)) && + Notification(MB_YESNO | MB_ICONWARNING, APPLICATION_NAME, lmprintf(MSG_356)) != IDYES) + break; for (r = 0, i = 0, m = 1; i < nDialogItems; i++, m <<= 1) if (Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i)) == BST_CHECKED) r += m; diff --git a/src/wue.c b/src/wue.c index 9d7d6c0b..e9e5f995 100644 --- a/src/wue.c +++ b/src/wue.c @@ -132,7 +132,7 @@ char* CreateUnattendXml(int arch, int flags) fprintf(fd, "\n"); fprintf(fd, "\n"); - StrArrayCreate(&commands, 8); + StrArrayCreate(&commands, 16); if (flags & UNATTEND_WINPE_SETUP_MASK) { fprintf(fd, " \n"); fprintf(fd, "