diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe
index 1539d7b0..f8b662d8 100644
Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ
diff --git a/INSTALL/tool/VentoyWorker.sh b/INSTALL/tool/VentoyWorker.sh
index 9c6967b9..099b2d55 100644
--- a/INSTALL/tool/VentoyWorker.sh
+++ b/INSTALL/tool/VentoyWorker.sh
@@ -12,6 +12,7 @@ print_usage() {
echo ' OPTION: (optional)'
echo ' -r SIZE_MB preserve some space at the bottom of the disk (only for install)'
echo ' -s enable secure boot support (default is disabled)'
+ echo ' -g use GPT partition style, default is MBR (only for install)'
echo ''
}
@@ -27,6 +28,8 @@ while [ -n "$1" ]; do
MODE="update"
elif [ "$1" = "-s" ]; then
SECUREBOOT="YES"
+ elif [ "$1" = "-g" ]; then
+ VTGPT="YES"
elif [ "$1" = "-r" ]; then
RESERVE_SPACE="YES"
shift
@@ -110,13 +113,22 @@ fi
if [ "$MODE" = "install" ]; then
vtdebug "install ventoy ..."
- if parted -v > /dev/null 2>&1; then
- PARTTOOL='parted'
- elif fdisk -v >/dev/null 2>&1; then
- PARTTOOL='fdisk'
+ if [ -n "$VTGPT" ]; then
+ if parted -v > /dev/null 2>&1; then
+ PARTTOOL='parted'
+ else
+ vterr "parted is not found in the sysstem, Ventoy can't create new partition."
+ exit 1
+ fi
else
- vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition."
- exit 1
+ if parted -v > /dev/null 2>&1; then
+ PARTTOOL='parted'
+ elif fdisk -v >/dev/null 2>&1; then
+ PARTTOOL='fdisk'
+ else
+ vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition."
+ exit 1
+ fi
fi
version=$(get_disk_ventoy_version $DISK)
@@ -148,11 +160,15 @@ if [ "$MODE" = "install" ]; then
fi
fi
-
#Print disk info
echo "Disk : $DISK"
parted -s $DISK p 2>&1 | grep Model
- echo "Size : $disk_size_gb GB"
+ echo "Size : $disk_size_gb GB"
+ if [ -n "$VTGPT" ]; then
+ echo "Style: GPT"
+ else
+ echo "Style: MBR"
+ fi
echo ''
if [ -n "$RESERVE_SPACE" ]; then
@@ -192,7 +208,13 @@ if [ "$MODE" = "install" ]; then
exit 1
fi
- format_ventoy_disk $RESERVE_SIZE_MB $DISK $PARTTOOL
+ if [ -n "$VTGPT" ]; then
+ vtdebug "format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL ..."
+ format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL
+ else
+ vtdebug "format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL ..."
+ format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL
+ fi
# format part1
if ventoy_is_linux64; then
@@ -216,8 +238,17 @@ if [ "$MODE" = "install" ]; then
chmod +x ./tool/vtoy_gen_uuid
vtinfo "writing data to disk ..."
+
dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446
- ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
+
+ if [ -n "$VTGPT" ]; then
+ echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92
+ ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
+ echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
+ else
+ ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
+ fi
+
./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector
#disk uuid
@@ -307,8 +338,11 @@ else
echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none
echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none
fi
-
- ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
+
+
+ ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
+
+
./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start
sync
diff --git a/INSTALL/tool/ventoy_lib.sh b/INSTALL/tool/ventoy_lib.sh
index 6fa869ae..9e4d45d8 100644
--- a/INSTALL/tool/ventoy_lib.sh
+++ b/INSTALL/tool/ventoy_lib.sh
@@ -103,7 +103,7 @@ get_ventoy_version_from_cfg() {
}
is_disk_contains_ventoy() {
- DISK=$1
+ DISK=$1
PART1=$(get_disk_part_name $1 1)
PART2=$(get_disk_part_name $1 2)
@@ -126,11 +126,15 @@ is_disk_contains_ventoy() {
return
fi
+ PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"')
PART2_TYPE=$(dd if=$DISK bs=1 count=1 skip=466 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"')
- if [ "$PART2_TYPE" != "EF" ]; then
- vtdebug "part2 type is $PART2_TYPE not EF"
- ventoy_false
- return
+
+ if [ "$PART1_TYPE" != "EE" ]; then
+ if [ "$PART2_TYPE" != "EF" ]; then
+ vtdebug "part2 type is $PART2_TYPE not EF"
+ ventoy_false
+ return
+ fi
fi
# PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"')
@@ -185,7 +189,7 @@ get_disk_ventoy_version() {
ventoy_false
}
-format_ventoy_disk() {
+format_ventoy_disk_mbr() {
reserve_mb=$1
DISK=$2
PARTTOOL=$3
@@ -218,7 +222,7 @@ format_ventoy_disk() {
fi
echo ""
- echo "Create partitions on $DISK by $PARTTOOL ..."
+ echo "Create partitions on $DISK by $PARTTOOL in MBR style ..."
if [ "$PARTTOOL" = "parted" ]; then
vtdebug "format disk by parted ..."
@@ -300,5 +304,95 @@ EOF
}
+format_ventoy_disk_gpt() {
+ reserve_mb=$1
+ DISK=$2
+ PARTTOOL=$3
+
+ PART1=$(get_disk_part_name $DISK 1)
+ PART2=$(get_disk_part_name $DISK 2)
+
+ sector_num=$(cat /sys/block/${DISK#/dev/}/size)
+
+ part1_start_sector=2048
+
+ if [ $reserve_mb -gt 0 ]; then
+ reserve_sector_num=$(expr $reserve_mb \* 2048 + 33)
+ part1_end_sector=$(expr $sector_num - $reserve_sector_num - $VENTOY_SECTOR_NUM - 1)
+ else
+ part1_end_sector=$(expr $sector_num - $VENTOY_SECTOR_NUM - 34)
+ fi
+
+ part2_start_sector=$(expr $part1_end_sector + 1)
+ part2_end_sector=$(expr $part2_start_sector + $VENTOY_SECTOR_NUM - 1)
+
+ export part2_start_sector
+
+ vtdebug "part1_start_sector=$part1_start_sector part1_end_sector=$part1_end_sector"
+ vtdebug "part2_start_sector=$part2_start_sector part2_end_sector=$part2_end_sector"
+
+ if [ -e $PART2 ]; then
+ echo "delete $PART2"
+ rm -f $PART2
+ fi
+
+ echo ""
+ echo "Create partitions on $DISK by $PARTTOOL in GPT style ..."
+
+ vtdebug "format disk by parted ..."
+ parted -a none --script $DISK \
+ mklabel gpt \
+ unit s \
+ mkpart Ventoy ntfs $part1_start_sector $part1_end_sector \
+ mkpart VTOYEFI fat16 $part2_start_sector $part2_end_sector \
+ set 2 boot on \
+ set 2 esp on \
+ set 2 hidden on \
+ quit
+
+ sync
+
+ udevadm trigger >/dev/null 2>&1
+ partprobe >/dev/null 2>&1
+ sleep 3
+ echo "Done"
+
+ echo 'mkfs on disk partitions ...'
+ for i in 1 2 3 4 5 6 7; do
+ if [ -b $PART2 ]; then
+ break
+ else
+ echo "wait $PART2 ..."
+ sleep 1
+ fi
+ done
+
+
+ if ! [ -b $PART2 ]; then
+ MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev)
+ echo "mknod -m 0660 $PART2 b $MajorMinor ..."
+ mknod -m 0660 $PART2 b $MajorMinor
+
+ if ! [ -b $PART1 ]; then
+ MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART1#/dev/}/dev)
+ echo "mknod -m 0660 $PART1 b $MajorMinor ..."
+ mknod -m 0660 $PART1 b $MajorMinor
+ fi
+ fi
+
+ echo "create efi fat fs $PART2 ..."
+ for i in 0 1 2 3 4 5 6 7 8 9; do
+ if mkfs.vfat -F 16 -n VTOYEFI $PART2; then
+ echo 'success'
+ break
+ else
+ echo "$? retry ..."
+ sleep 2
+ fi
+ done
+}
+
+
+
diff --git a/INSTALL/ventoy_pack.sh b/INSTALL/ventoy_pack.sh
index 1660a50b..9f21bbfa 100644
--- a/INSTALL/ventoy_pack.sh
+++ b/INSTALL/ventoy_pack.sh
@@ -31,7 +31,7 @@ while ! grep -q 524288 /sys/block/${LOOP#/dev/}/size 2>/dev/null; do
sleep 1
done
-format_ventoy_disk 0 $LOOP fdisk
+format_ventoy_disk_mbr 0 $LOOP fdisk
$GRUB_DIR/sbin/grub-bios-setup --skip-fs-probe --directory="./grub/i386-pc" $LOOP
diff --git a/LANGUAGES/languages.ini b/LANGUAGES/languages.ini
index 926f4765..c85501af 100644
Binary files a/LANGUAGES/languages.ini and b/LANGUAGES/languages.ini differ
diff --git a/Ventoy2Disk/Ventoy2Disk/Language.h b/Ventoy2Disk/Ventoy2Disk/Language.h
index 6705b86f..b365481f 100644
--- a/Ventoy2Disk/Ventoy2Disk/Language.h
+++ b/Ventoy2Disk/Ventoy2Disk/Language.h
@@ -60,6 +60,9 @@ typedef enum STR_ID
STR_MENU_CLEAR, //26
STR_CLEAR_SUCCESS, //27
STR_CLEAR_FAILED, //28
+ STR_MENU_PART_STYLE, //29
+ STR_DISK_2TB_MBR_ERROR,//30
+
STR_ID_MAX
}STR_ID;
@@ -69,6 +72,22 @@ extern BOOL g_SecureBoot;
#define VTOY_MENU_SECURE_BOOT 0xA000
#define VTOY_MENU_PART_CFG 0xA001
#define VTOY_MENU_CLEAN 0xA002
+#define VTOY_MENU_PART_STYLE 0xA003
+#define VTOY_MENU_PART_MBR 0xA004
+#define VTOY_MENU_PART_GPT 0xA005
+
+
+typedef enum OPT_SUBMENU
+{
+ OPT_SUBMENU_SECURE_BOOT = 0,
+ OPT_SUBMENU_PART_STYLE,
+ OPT_SUBMENU_PART_CFG,
+ OPT_SUBMENU_CLEAR,
+
+ OPT_SUBMENU_MAX
+}OPT_SUBMENU;
+
+
#define VTOY_MENU_LANGUAGE_BEGIN 0xB000
diff --git a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c
index 7dde3154..572aeb87 100644
--- a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c
+++ b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c
@@ -798,7 +798,7 @@ static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
}
-int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, MBR_HEAD *pMBR, CHAR *VerBuf, size_t BufLen)
+int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, UINT64 Part2StartSector, CHAR *VerBuf, size_t BufLen)
{
int rc = 0;
HANDLE hDrive;
@@ -810,7 +810,7 @@ int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, MBR_HEAD *pMBR, CHA
}
g_FatPhyDrive = hDrive;
- g_Part2StartSec = pMBR->PartTbl[1].StartSectorId;
+ g_Part2StartSec = Part2StartSector;
Log("Parse FAT fs...");
@@ -1154,7 +1154,7 @@ End:
return rc;
}
-static int WriteGrubStage1ToPhyDrive(HANDLE hDrive)
+static int WriteGrubStage1ToPhyDrive(HANDLE hDrive, int PartStyle)
{
int Len = 0;
int readLen = 0;
@@ -1180,9 +1180,20 @@ static int WriteGrubStage1ToPhyDrive(HANDLE hDrive)
unxz(ImgBuf, Len, NULL, NULL, RawBuf, &readLen, unxz_error);
- SetFilePointer(hDrive, 512, NULL, FILE_BEGIN);
+ if (PartStyle)
+ {
+ Log("Write GPT stage1 ...");
+ RawBuf[500] = 35;//update blocklist
+ SetFilePointer(hDrive, 512 * 34, NULL, FILE_BEGIN);
+ bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512 * 34, &dwSize, NULL);
+ }
+ else
+ {
+ Log("Write MBR stage1 ...");
+ SetFilePointer(hDrive, 512, NULL, FILE_BEGIN);
+ bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512, &dwSize, NULL);
+ }
- bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512, &dwSize, NULL);
Log("WriteFile Ret:%u dwSize:%u ErrCode:%u", bRet, dwSize, GetLastError());
free(RawBuf);
@@ -1372,7 +1383,7 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett
VentoyFillLocation(pPhyDrive->SizeInBytes, 2048, (UINT32)(pPhyDrive->SizeInBytes / 512 - 2048), MBR.PartTbl);
- MBR.PartTbl[0].Active = 0x80; // bootable
+ MBR.PartTbl[0].Active = 0x00; // bootable
MBR.PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS
SET_FILE_POS(0);
@@ -1386,6 +1397,9 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett
Log("Clear Ventoy successfully finished");
+ //Refresh Drive Layout
+ DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);
+
End:
PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME);
@@ -1436,14 +1450,11 @@ End:
FindProcessOccupyDisk(hDrive, pPhyDrive);
}
- //Refresh Drive Layout
- DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);
-
CHECK_CLOSE_HANDLE(hDrive);
return rc;
}
-int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
+int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)
{
int i;
int rc = 0;
@@ -1455,14 +1466,25 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
CHAR DriveName[] = "?:\\";
CHAR DriveLetters[MAX_PATH] = { 0 };
MBR_HEAD MBR;
+ VTOY_GPT_INFO *pGptInfo = NULL;
- Log("InstallVentoy2PhyDrive PhyDrive%d <<%s %s %dGB>>",
- pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,
+ Log("InstallVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>",
+ PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,
GetHumanReadableGBSize(pPhyDrive->SizeInBytes));
+ if (PartStyle)
+ {
+ pGptInfo = malloc(sizeof(VTOY_GPT_INFO));
+ memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));
+ }
+
PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);
- VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR);
+ VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle);//also used to format 1st partition in GPT mode
+ if (PartStyle)
+ {
+ VentoyFillGpt(pPhyDrive->SizeInBytes, pGptInfo);
+ }
Log("Lock disk for clean ............................. ");
@@ -1470,6 +1492,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
if (hDrive == INVALID_HANDLE_VALUE)
{
Log("Failed to open physical disk");
+ free(pGptInfo);
return 1;
}
@@ -1531,7 +1554,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
Log("Formatting part1 exFAT ...");
if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes))
{
- log("FormatPart1exFAT failed.");
+ Log("FormatPart1exFAT failed.");
rc = 1;
goto End;
}
@@ -1540,16 +1563,16 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
Log("Writing part2 FAT img ...");
if (0 != FormatPart2Fat(hDrive, MBR.PartTbl[1].StartSectorId))
{
- log("FormatPart2Fat failed.");
+ Log("FormatPart2Fat failed.");
rc = 1;
goto End;
}
PROGRESS_BAR_SET_POS(PT_WRITE_STG1_IMG);
Log("Writting Boot Image ............................. ");
- if (WriteGrubStage1ToPhyDrive(hDrive) != 0)
+ if (WriteGrubStage1ToPhyDrive(hDrive, PartStyle) != 0)
{
- log("WriteGrubStage1ToPhyDrive failed.");
+ Log("WriteGrubStage1ToPhyDrive failed.");
rc = 1;
goto End;
}
@@ -1557,14 +1580,50 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
PROGRESS_BAR_SET_POS(PT_WRITE_PART_TABLE);
Log("Writting Partition Table ........................ ");
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
- if (!WriteFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL))
- {
- rc = 1;
- Log("Write MBR Failed, dwSize:%u ErrCode:%u", dwSize, GetLastError());
- goto End;
- }
- Log("Write MBR OK ...");
+ if (PartStyle)
+ {
+ VTOY_GPT_HDR BackupHead;
+ LARGE_INTEGER liCurrentPosition;
+
+ SET_FILE_POS(pPhyDrive->SizeInBytes - 512);
+ VentoyFillBackupGptHead(pGptInfo, &BackupHead);
+ if (!WriteFile(hDrive, &BackupHead, sizeof(VTOY_GPT_HDR), &dwSize, NULL))
+ {
+ rc = 1;
+ Log("Write GPT Backup Head Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError());
+ goto End;
+ }
+
+ SET_FILE_POS(pPhyDrive->SizeInBytes - 512 * 33);
+ if (!WriteFile(hDrive, pGptInfo->PartTbl, sizeof(pGptInfo->PartTbl), &dwSize, NULL))
+ {
+ rc = 1;
+ Log("Write GPT Backup Part Table Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError());
+ goto End;
+ }
+
+ SET_FILE_POS(0);
+ if (!WriteFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL))
+ {
+ rc = 1;
+ Log("Write GPT Info Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError());
+ goto End;
+ }
+
+ Log("Write GPT Info OK ...");
+ }
+ else
+ {
+ if (!WriteFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL))
+ {
+ rc = 1;
+ Log("Write MBR Failed, dwSize:%u ErrCode:%u", dwSize, GetLastError());
+ goto End;
+ }
+ Log("Write MBR OK ...");
+ }
+
//Refresh Drive Layout
DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);
@@ -1619,6 +1678,11 @@ End:
FindProcessOccupyDisk(hDrive, pPhyDrive);
}
+ if (pGptInfo)
+ {
+ free(pGptInfo);
+ }
+
CHECK_CLOSE_HANDLE(hDrive);
return rc;
}
@@ -1635,13 +1699,14 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
BOOL bRet;
CHAR DriveName[] = "?:\\";
CHAR DriveLetters[MAX_PATH] = { 0 };
- UINT32 StartSector;
+ UINT64 StartSector;
UINT64 ReservedMB = 0;
MBR_HEAD BootImg;
MBR_HEAD MBR;
+ VTOY_GPT_INFO *pGptInfo = NULL;
- Log("UpdateVentoy2PhyDrive PhyDrive%d <<%s %s %dGB>>",
- pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,
+ Log("UpdateVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>",
+ pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,
GetHumanReadableGBSize(pPhyDrive->SizeInBytes));
PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);
@@ -1655,15 +1720,38 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
return 1;
}
- // Read MBR
- SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
- ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
+ if (pPhyDrive->PartStyle)
+ {
+ pGptInfo = malloc(sizeof(VTOY_GPT_INFO));
+ if (!pGptInfo)
+ {
+ return 1;
+ }
- StartSector = MBR.PartTbl[1].StartSectorId;
- Log("StartSector in PartTbl:%u", StartSector);
+ memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));
- ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048;
- Log("Reserved Disk Space:%u MB", ReservedMB);
+ // Read GPT Info
+ SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
+ ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL);
+
+ StartSector = pGptInfo->PartTbl[1].StartLBA;
+ Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector);
+
+ ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048;
+ Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);
+ }
+ else
+ {
+ // Read MBR
+ SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
+ ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
+
+ StartSector = MBR.PartTbl[1].StartSectorId;
+ Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector);
+
+ ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048;
+ Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);
+ }
GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));
@@ -1781,7 +1869,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
}
Log("Updating Boot Image ............................. ");
- if (WriteGrubStage1ToPhyDrive(hDrive) != 0)
+ if (WriteGrubStage1ToPhyDrive(hDrive, pPhyDrive->PartStyle) != 0)
{
rc = 1;
goto End;
@@ -1792,6 +1880,10 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
// Use Old UUID
memcpy(BootImg.BootCode + 0x180, MBR.BootCode + 0x180, 16);
+ if (pPhyDrive->PartStyle)
+ {
+ BootImg.BootCode[92] = 0x22;
+ }
if (ForceMBR == FALSE && memcmp(BootImg.BootCode, MBR.BootCode, 440) == 0)
{
@@ -1808,16 +1900,19 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
Log("Write Boot Image ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR);
}
- if (0x00 == MBR.PartTbl[0].Active && 0x80 == MBR.PartTbl[1].Active)
+ if (pPhyDrive->PartStyle == 0)
{
- Log("Need to chage 1st partition active and 2nd partition inactive.");
+ if (0x00 == MBR.PartTbl[0].Active && 0x80 == MBR.PartTbl[1].Active)
+ {
+ Log("Need to chage 1st partition active and 2nd partition inactive.");
- MBR.PartTbl[0].Active = 0x80;
- MBR.PartTbl[1].Active = 0x00;
+ MBR.PartTbl[0].Active = 0x80;
+ MBR.PartTbl[1].Active = 0x00;
- SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
- bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL);
- Log("Write NEW MBR ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR);
+ SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
+ bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL);
+ Log("Write NEW MBR ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR);
+ }
}
//Refresh Drive Layout
@@ -1836,6 +1931,11 @@ End:
CHECK_CLOSE_HANDLE(hDrive);
+ if (pGptInfo)
+ {
+ free(pGptInfo);
+ }
+
return rc;
}
diff --git a/Ventoy2Disk/Ventoy2Disk/Utility.c b/Ventoy2Disk/Ventoy2Disk/Utility.c
index e7df557b..dc8491db 100644
--- a/Ventoy2Disk/Ventoy2Disk/Utility.c
+++ b/Ventoy2Disk/Ventoy2Disk/Utility.c
@@ -424,7 +424,7 @@ int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 Sect
return 0;
}
-int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR)
+int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR, int PartStyle)
{
GUID Guid;
int ReservedValue;
@@ -444,7 +444,14 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR)
*((UINT32 *)(pMBR->BootCode + 0x1B8)) = DiskSignature;
- DiskSectorCount = (UINT32)(DiskSizeBytes / 512);
+ if (DiskSizeBytes / 512 > 0xFFFFFFFF)
+ {
+ DiskSectorCount = 0xFFFFFFFF;
+ }
+ else
+ {
+ DiskSectorCount = (UINT32)(DiskSizeBytes / 512);
+ }
ReservedValue = GetReservedSpaceInMB();
if (ReservedValue <= 0)
@@ -456,6 +463,11 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR)
ReservedSector = (UINT32)(ReservedValue * 2048);
}
+ if (PartStyle)
+ {
+ ReservedSector += 33; // backup GPT part table
+ }
+
Log("ReservedSector: %u", ReservedSector);
//Part1
@@ -480,6 +492,129 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR)
return 0;
}
+
+static int VentoyFillProtectMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR)
+{
+ GUID Guid;
+ UINT32 DiskSignature;
+ UINT64 DiskSectorCount;
+
+ VentoyGetLocalBootImg(pMBR);
+
+ CoCreateGuid(&Guid);
+
+ memcpy(&DiskSignature, &Guid, sizeof(UINT32));
+
+ Log("Disk signature: 0x%08x", DiskSignature);
+
+ *((UINT32 *)(pMBR->BootCode + 0x1B8)) = DiskSignature;
+
+ DiskSectorCount = DiskSizeBytes / 512 - 1;
+ if (DiskSectorCount > 0xFFFFFFFF)
+ {
+ DiskSectorCount = 0xFFFFFFFF;
+ }
+
+ memset(pMBR->PartTbl, 0, sizeof(pMBR->PartTbl));
+
+ pMBR->PartTbl[0].Active = 0x00;
+ pMBR->PartTbl[0].FsFlag = 0xee; // EE
+
+ pMBR->PartTbl[0].StartHead = 0;
+ pMBR->PartTbl[0].StartSector = 1;
+ pMBR->PartTbl[0].StartCylinder = 0;
+ pMBR->PartTbl[0].EndHead = 254;
+ pMBR->PartTbl[0].EndSector = 63;
+ pMBR->PartTbl[0].EndCylinder = 1023;
+
+ pMBR->PartTbl[0].StartSectorId = 1;
+ pMBR->PartTbl[0].SectorCount = (UINT32)DiskSectorCount;
+
+ pMBR->Byte55 = 0x55;
+ pMBR->ByteAA = 0xAA;
+
+ pMBR->BootCode[92] = 0x22;
+
+ return 0;
+}
+
+
+int VentoyFillGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo)
+{
+ INT64 ReservedValue = 0;
+ UINT64 ReservedSector = 33;
+ UINT64 Part1SectorCount = 0;
+ UINT64 DiskSectorCount = DiskSizeBytes / 512;
+ VTOY_GPT_HDR *Head = &pInfo->Head;
+ VTOY_GPT_PART_TBL *Table = pInfo->PartTbl;
+ static GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };
+ static GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };
+
+ VentoyFillProtectMBR(DiskSizeBytes, &pInfo->MBR);
+
+ ReservedValue = GetReservedSpaceInMB();
+ if (ReservedValue > 0)
+ {
+ ReservedSector += ReservedValue * 2048;
+ }
+
+ Part1SectorCount = DiskSectorCount - ReservedSector - (VENTOY_EFI_PART_SIZE / 512) - 2048;
+
+ memcpy(Head->Signature, "EFI PART", 8);
+ Head->Version[2] = 0x01;
+ Head->Length = 92;
+ Head->Crc = 0;
+ Head->EfiStartLBA = 1;
+ Head->EfiBackupLBA = DiskSectorCount - 1;
+ Head->PartAreaStartLBA = 34;
+ Head->PartAreaEndLBA = DiskSectorCount - 34;
+ CoCreateGuid(&Head->DiskGuid);
+ Head->PartTblStartLBA = 2;
+ Head->PartTblTotNum = 128;
+ Head->PartTblEntryLen = 128;
+
+
+ memcpy(&(Table[0].PartType), &WindowsDataPartType, sizeof(GUID));
+ CoCreateGuid(&(Table[0].PartGuid));
+ Table[0].StartLBA = 2048;
+ Table[0].LastLBA = 2048 + Part1SectorCount - 1;
+ Table[0].Attr = 0;
+ memcpy(Table[0].Name, L"Ventoy", 6 * 2);
+
+ memcpy(&(Table[1].PartType), &EspPartType, sizeof(GUID));
+ CoCreateGuid(&(Table[1].PartGuid));
+ Table[1].StartLBA = Table[0].LastLBA + 1;
+ Table[1].LastLBA = Table[1].StartLBA + VENTOY_EFI_PART_SIZE / 512 - 1;
+ Table[1].Attr = 1;
+ memcpy(Table[1].Name, L"VTOYEFI", 7 * 2);
+
+ //Update CRC
+ Head->PartTblCrc = VentoyCrc32(Table, sizeof(pInfo->PartTbl));
+ Head->Crc = VentoyCrc32(Head, Head->Length);
+
+ return 0;
+}
+
+int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead)
+{
+ UINT64 LBA;
+ UINT64 BackupLBA;
+
+ memcpy(pHead, &pInfo->Head, sizeof(VTOY_GPT_HDR));
+
+ LBA = pHead->EfiStartLBA;
+ BackupLBA = pHead->EfiBackupLBA;
+
+ pHead->EfiStartLBA = BackupLBA;
+ pHead->EfiBackupLBA = LBA;
+ pHead->PartTblStartLBA = BackupLBA + 1 - 33;
+
+ pHead->Crc = 0;
+ pHead->Crc = VentoyCrc32(pHead, pHead->Length);
+
+ return 0;
+}
+
CHAR GetFirstUnusedDriveLetter(void)
{
CHAR Letter = 'D';
diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c
index 59ca86c0..f8d709f5 100644
--- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c
+++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c
@@ -70,7 +70,7 @@ int ParseCmdLineOption(LPSTR lpCmdLine)
return 0;
}
-static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR)
+static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector)
{
int i;
BOOL bRet;
@@ -80,6 +80,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR)
UINT32 PartStartSector;
UINT32 PartSectorCount;
CHAR PhyDrivePath[128];
+ VTOY_GPT_INFO *pGpt = NULL;
safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive);
hDrive = CreateFileA(PhyDrivePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
@@ -90,63 +91,101 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR)
return FALSE;
}
- bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
- CHECK_CLOSE_HANDLE(hDrive);
-
- Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);
+ bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
+ Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);
if ((!bRet) || (dwSize != sizeof(MBR)))
{
+ CHECK_CLOSE_HANDLE(hDrive);
return FALSE;
}
if (MBR.Byte55 != 0x55 || MBR.ByteAA != 0xAA)
{
Log("Byte55 ByteAA not match 0x%x 0x%x", MBR.Byte55, MBR.ByteAA);
+ CHECK_CLOSE_HANDLE(hDrive);
return FALSE;
}
- for (i = 0; i < 4; i++)
- {
- Log("=========== Partition Table %d ============", i + 1);
- Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active);
- Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag);
- Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId);
- Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount);
- Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead);
- Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector);
- Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder);
- Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead);
- Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector);
- Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder);
- }
+ if (MBR.PartTbl[1].FsFlag == 0xEE)
+ {
+ pGpt = malloc(sizeof(VTOY_GPT_INFO));
+ if (!pGpt)
+ {
+ CHECK_CLOSE_HANDLE(hDrive);
+ return FALSE;
+ }
+ SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
+ bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL);
+ CHECK_CLOSE_HANDLE(hDrive);
+ if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO)))
+ {
+ Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR);
+ return FALSE;
+ }
- if (MBR.PartTbl[0].StartSectorId != 2048)
- {
- Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId);
- return FALSE;
- }
+ if (memcmp(pGpt->Head.Signature, "EFI PART", 8))
+ {
+ Log("Invalid GPT signature");
+ return FALSE;
+ }
- PartStartSector = MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount;
- PartSectorCount = VENTOY_EFI_PART_SIZE / 512;
+ if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2))
+ {
+ Log("Invalid ventoy efi part name");
+ return FALSE;
+ }
- if (MBR.PartTbl[1].FsFlag != 0xEF ||
- MBR.PartTbl[1].StartSectorId != PartStartSector ||
- MBR.PartTbl[1].SectorCount != PartSectorCount)
- {
- Log("Part2 not match [0x%x 0x%x] [%u %u] [%u %u]",
- MBR.PartTbl[1].FsFlag, 0xEF,
- MBR.PartTbl[1].StartSectorId, PartStartSector,
- MBR.PartTbl[1].SectorCount, PartSectorCount);
- return FALSE;
- }
+ *Part2StartSector = pGpt->PartTbl[1].StartLBA;
+ }
+ else
+ {
+ CHECK_CLOSE_HANDLE(hDrive);
- if (MBR.PartTbl[0].Active != 0x80 && MBR.PartTbl[1].Active != 0x80)
- {
- Log("Part1 and Part2 are both NOT active 0x%x 0x%x", MBR.PartTbl[0].Active, MBR.PartTbl[1].Active);
- return FALSE;
- }
+ for (i = 0; i < 4; i++)
+ {
+ Log("=========== Partition Table %d ============", i + 1);
+ Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active);
+ Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag);
+ Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId);
+ Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount);
+ Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead);
+ Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector);
+ Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder);
+ Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead);
+ Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector);
+ Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder);
+ }
+
+ if (MBR.PartTbl[0].StartSectorId != 2048)
+ {
+ Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId);
+ return FALSE;
+ }
+
+ PartStartSector = MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount;
+ PartSectorCount = VENTOY_EFI_PART_SIZE / 512;
+
+ if (MBR.PartTbl[1].FsFlag != 0xEF ||
+ MBR.PartTbl[1].StartSectorId != PartStartSector ||
+ MBR.PartTbl[1].SectorCount != PartSectorCount)
+ {
+ Log("Part2 not match [0x%x 0x%x] [%u %u] [%u %u]",
+ MBR.PartTbl[1].FsFlag, 0xEF,
+ MBR.PartTbl[1].StartSectorId, PartStartSector,
+ MBR.PartTbl[1].SectorCount, PartSectorCount);
+ return FALSE;
+ }
+
+ if (MBR.PartTbl[0].Active != 0x80 && MBR.PartTbl[1].Active != 0x80)
+ {
+ Log("Part1 and Part2 are both NOT active 0x%x 0x%x", MBR.PartTbl[0].Active, MBR.PartTbl[1].Active);
+ return FALSE;
+ }
+
+ *Part2StartSector = MBR.PartTbl[1].StartSectorId;
+ }
memcpy(pMBR, &MBR, sizeof(MBR_HEAD));
Log("PhysicalDrive%d is ventoy disk", PhyDrive);
@@ -161,6 +200,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
int Letter = 'A';
int Id = 0;
int LetterCount = 0;
+ UINT64 Part2StartSector = 0;
PHY_DRIVE_INFO *CurDrive;
MBR_HEAD MBR;
int LogLetter[VENTOY_MAX_PHY_DRIVE];
@@ -217,9 +257,10 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
}
}
- if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR))
+ if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector))
{
- GetVentoyVerInPhyDrive(CurDrive, &MBR, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion));
+ CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0;
+ GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion));
}
}
diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h
index 13b71f76..dd426179 100644
--- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h
+++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h
@@ -79,6 +79,43 @@ typedef struct MBR_HEAD
UINT8 Byte55;
UINT8 ByteAA;
}MBR_HEAD;
+
+typedef struct VTOY_GPT_HDR
+{
+ CHAR Signature[8]; /* EFI PART */
+ UINT8 Version[4];
+ UINT32 Length;
+ UINT32 Crc;
+ UINT8 Reserved1[4];
+ UINT64 EfiStartLBA;
+ UINT64 EfiBackupLBA;
+ UINT64 PartAreaStartLBA;
+ UINT64 PartAreaEndLBA;
+ GUID DiskGuid;
+ UINT64 PartTblStartLBA;
+ UINT32 PartTblTotNum;
+ UINT32 PartTblEntryLen;
+ UINT32 PartTblCrc;
+ UINT8 Reserved2[420];
+}VTOY_GPT_HDR;
+
+typedef struct VTOY_GPT_PART_TBL
+{
+ GUID PartType;
+ GUID PartGuid;
+ UINT64 StartLBA;
+ UINT64 LastLBA;
+ UINT64 Attr;
+ UINT16 Name[36];
+}VTOY_GPT_PART_TBL;
+
+typedef struct VTOY_GPT_INFO
+{
+ MBR_HEAD MBR;
+ VTOY_GPT_HDR Head;
+ VTOY_GPT_PART_TBL PartTbl[128];
+}VTOY_GPT_INFO;
+
#pragma pack()
#define VENTOY_MAX_PHY_DRIVE 128
@@ -87,6 +124,7 @@ typedef struct PHY_DRIVE_INFO
{
int Id;
int PhyDrive;
+ int PartStyle;//0:MBR 1:GPT
UINT64 SizeInBytes;
BYTE DeviceType;
BOOL RemovableMedia;
@@ -138,19 +176,21 @@ const CHAR * GetBusTypeString(STORAGE_BUS_TYPE Type);
int VentoyGetLocalBootImg(MBR_HEAD *pMBR);
int GetHumanReadableGBSize(UINT64 SizeBytes);
void TrimString(CHAR *String);
-int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR);
+int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR, int PartStyle);
+int VentoyFillGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo);
BOOL IsVentoyLogicalDrive(CHAR DriveLetter);
int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue);
int GetPhysicalDriveCount(void);
int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO *pDriveList, DWORD *pDriveCount);
int GetPhyDriveByLogicalDrive(int DriveLetter);
-int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, MBR_HEAD *pMBR, CHAR *VerBuf, size_t BufLen);
+int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, UINT64 Part2StartSector, CHAR *VerBuf, size_t BufLen);
int Ventoy2DiskInit(void);
int Ventoy2DiskDestroy(void);
PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id);
int ParseCmdLineOption(LPSTR lpCmdLine);
-int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive);
+int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle);
int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive);
+int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead);
void SetProgressBarPos(int Pos);
int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen);
int INIT unxz(unsigned char *in, int in_size,
@@ -164,6 +204,7 @@ int GetReservedSpaceInMB(void);
int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive);
int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 SectorCount, PART_TABLE *Table);
int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLetter);
+UINT32 VentoyCrc32(void *Buffer, UINT32 Length);
#define SET_FILE_POS(pos) \
liCurrentPosition.QuadPart = pos; \
diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc
index 43075fb6..03a4a003 100644
Binary files a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc and b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc differ
diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj
index f82d5fcf..821d13e5 100644
--- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj
+++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj
@@ -91,6 +91,7 @@
+
diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters
index 9c74bea8..1eac7fbb 100644
--- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters
+++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters
@@ -75,6 +75,9 @@
源文件
+
+ 源文件
+
diff --git a/Ventoy2Disk/Ventoy2Disk/WinDialog.c b/Ventoy2Disk/Ventoy2Disk/WinDialog.c
index 42bda379..814ba277 100644
Binary files a/Ventoy2Disk/Ventoy2Disk/WinDialog.c and b/Ventoy2Disk/Ventoy2Disk/WinDialog.c differ
diff --git a/Ventoy2Disk/Ventoy2Disk/crc32.c b/Ventoy2Disk/Ventoy2Disk/crc32.c
new file mode 100644
index 00000000..3af9d20a
--- /dev/null
+++ b/Ventoy2Disk/Ventoy2Disk/crc32.c
@@ -0,0 +1,275 @@
+#include
+
+static UINT32 g_CrcTable[256] = {
+ 0x00000000,
+ 0x77073096,
+ 0xEE0E612C,
+ 0x990951BA,
+ 0x076DC419,
+ 0x706AF48F,
+ 0xE963A535,
+ 0x9E6495A3,
+ 0x0EDB8832,
+ 0x79DCB8A4,
+ 0xE0D5E91E,
+ 0x97D2D988,
+ 0x09B64C2B,
+ 0x7EB17CBD,
+ 0xE7B82D07,
+ 0x90BF1D91,
+ 0x1DB71064,
+ 0x6AB020F2,
+ 0xF3B97148,
+ 0x84BE41DE,
+ 0x1ADAD47D,
+ 0x6DDDE4EB,
+ 0xF4D4B551,
+ 0x83D385C7,
+ 0x136C9856,
+ 0x646BA8C0,
+ 0xFD62F97A,
+ 0x8A65C9EC,
+ 0x14015C4F,
+ 0x63066CD9,
+ 0xFA0F3D63,
+ 0x8D080DF5,
+ 0x3B6E20C8,
+ 0x4C69105E,
+ 0xD56041E4,
+ 0xA2677172,
+ 0x3C03E4D1,
+ 0x4B04D447,
+ 0xD20D85FD,
+ 0xA50AB56B,
+ 0x35B5A8FA,
+ 0x42B2986C,
+ 0xDBBBC9D6,
+ 0xACBCF940,
+ 0x32D86CE3,
+ 0x45DF5C75,
+ 0xDCD60DCF,
+ 0xABD13D59,
+ 0x26D930AC,
+ 0x51DE003A,
+ 0xC8D75180,
+ 0xBFD06116,
+ 0x21B4F4B5,
+ 0x56B3C423,
+ 0xCFBA9599,
+ 0xB8BDA50F,
+ 0x2802B89E,
+ 0x5F058808,
+ 0xC60CD9B2,
+ 0xB10BE924,
+ 0x2F6F7C87,
+ 0x58684C11,
+ 0xC1611DAB,
+ 0xB6662D3D,
+ 0x76DC4190,
+ 0x01DB7106,
+ 0x98D220BC,
+ 0xEFD5102A,
+ 0x71B18589,
+ 0x06B6B51F,
+ 0x9FBFE4A5,
+ 0xE8B8D433,
+ 0x7807C9A2,
+ 0x0F00F934,
+ 0x9609A88E,
+ 0xE10E9818,
+ 0x7F6A0DBB,
+ 0x086D3D2D,
+ 0x91646C97,
+ 0xE6635C01,
+ 0x6B6B51F4,
+ 0x1C6C6162,
+ 0x856530D8,
+ 0xF262004E,
+ 0x6C0695ED,
+ 0x1B01A57B,
+ 0x8208F4C1,
+ 0xF50FC457,
+ 0x65B0D9C6,
+ 0x12B7E950,
+ 0x8BBEB8EA,
+ 0xFCB9887C,
+ 0x62DD1DDF,
+ 0x15DA2D49,
+ 0x8CD37CF3,
+ 0xFBD44C65,
+ 0x4DB26158,
+ 0x3AB551CE,
+ 0xA3BC0074,
+ 0xD4BB30E2,
+ 0x4ADFA541,
+ 0x3DD895D7,
+ 0xA4D1C46D,
+ 0xD3D6F4FB,
+ 0x4369E96A,
+ 0x346ED9FC,
+ 0xAD678846,
+ 0xDA60B8D0,
+ 0x44042D73,
+ 0x33031DE5,
+ 0xAA0A4C5F,
+ 0xDD0D7CC9,
+ 0x5005713C,
+ 0x270241AA,
+ 0xBE0B1010,
+ 0xC90C2086,
+ 0x5768B525,
+ 0x206F85B3,
+ 0xB966D409,
+ 0xCE61E49F,
+ 0x5EDEF90E,
+ 0x29D9C998,
+ 0xB0D09822,
+ 0xC7D7A8B4,
+ 0x59B33D17,
+ 0x2EB40D81,
+ 0xB7BD5C3B,
+ 0xC0BA6CAD,
+ 0xEDB88320,
+ 0x9ABFB3B6,
+ 0x03B6E20C,
+ 0x74B1D29A,
+ 0xEAD54739,
+ 0x9DD277AF,
+ 0x04DB2615,
+ 0x73DC1683,
+ 0xE3630B12,
+ 0x94643B84,
+ 0x0D6D6A3E,
+ 0x7A6A5AA8,
+ 0xE40ECF0B,
+ 0x9309FF9D,
+ 0x0A00AE27,
+ 0x7D079EB1,
+ 0xF00F9344,
+ 0x8708A3D2,
+ 0x1E01F268,
+ 0x6906C2FE,
+ 0xF762575D,
+ 0x806567CB,
+ 0x196C3671,
+ 0x6E6B06E7,
+ 0xFED41B76,
+ 0x89D32BE0,
+ 0x10DA7A5A,
+ 0x67DD4ACC,
+ 0xF9B9DF6F,
+ 0x8EBEEFF9,
+ 0x17B7BE43,
+ 0x60B08ED5,
+ 0xD6D6A3E8,
+ 0xA1D1937E,
+ 0x38D8C2C4,
+ 0x4FDFF252,
+ 0xD1BB67F1,
+ 0xA6BC5767,
+ 0x3FB506DD,
+ 0x48B2364B,
+ 0xD80D2BDA,
+ 0xAF0A1B4C,
+ 0x36034AF6,
+ 0x41047A60,
+ 0xDF60EFC3,
+ 0xA867DF55,
+ 0x316E8EEF,
+ 0x4669BE79,
+ 0xCB61B38C,
+ 0xBC66831A,
+ 0x256FD2A0,
+ 0x5268E236,
+ 0xCC0C7795,
+ 0xBB0B4703,
+ 0x220216B9,
+ 0x5505262F,
+ 0xC5BA3BBE,
+ 0xB2BD0B28,
+ 0x2BB45A92,
+ 0x5CB36A04,
+ 0xC2D7FFA7,
+ 0xB5D0CF31,
+ 0x2CD99E8B,
+ 0x5BDEAE1D,
+ 0x9B64C2B0,
+ 0xEC63F226,
+ 0x756AA39C,
+ 0x026D930A,
+ 0x9C0906A9,
+ 0xEB0E363F,
+ 0x72076785,
+ 0x05005713,
+ 0x95BF4A82,
+ 0xE2B87A14,
+ 0x7BB12BAE,
+ 0x0CB61B38,
+ 0x92D28E9B,
+ 0xE5D5BE0D,
+ 0x7CDCEFB7,
+ 0x0BDBDF21,
+ 0x86D3D2D4,
+ 0xF1D4E242,
+ 0x68DDB3F8,
+ 0x1FDA836E,
+ 0x81BE16CD,
+ 0xF6B9265B,
+ 0x6FB077E1,
+ 0x18B74777,
+ 0x88085AE6,
+ 0xFF0F6A70,
+ 0x66063BCA,
+ 0x11010B5C,
+ 0x8F659EFF,
+ 0xF862AE69,
+ 0x616BFFD3,
+ 0x166CCF45,
+ 0xA00AE278,
+ 0xD70DD2EE,
+ 0x4E048354,
+ 0x3903B3C2,
+ 0xA7672661,
+ 0xD06016F7,
+ 0x4969474D,
+ 0x3E6E77DB,
+ 0xAED16A4A,
+ 0xD9D65ADC,
+ 0x40DF0B66,
+ 0x37D83BF0,
+ 0xA9BCAE53,
+ 0xDEBB9EC5,
+ 0x47B2CF7F,
+ 0x30B5FFE9,
+ 0xBDBDF21C,
+ 0xCABAC28A,
+ 0x53B39330,
+ 0x24B4A3A6,
+ 0xBAD03605,
+ 0xCDD70693,
+ 0x54DE5729,
+ 0x23D967BF,
+ 0xB3667A2E,
+ 0xC4614AB8,
+ 0x5D681B02,
+ 0x2A6F2B94,
+ 0xB40BBE37,
+ 0xC30C8EA1,
+ 0x5A05DF1B,
+ 0x2D02EF8D
+};
+
+UINT32 VentoyCrc32(void *Buffer, UINT32 Length)
+{
+ UINT32 Index;
+ UINT32 Crc;
+ UINT8 *Byte = Buffer;
+
+ Crc = 0xffffffff;
+ for (Index = 0; Index < Length; Index++, Byte++)
+ {
+ Crc = (Crc >> 8) ^ g_CrcTable[(UINT8)Crc ^ *Byte];
+ }
+
+ return Crc ^ 0xffffffff;
+}
diff --git a/Ventoy2Disk/Ventoy2Disk/resource.h b/Ventoy2Disk/Ventoy2Disk/resource.h
index 9de7e743..fa0b4ab1 100644
Binary files a/Ventoy2Disk/Ventoy2Disk/resource.h and b/Ventoy2Disk/Ventoy2Disk/resource.h differ