diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe index 144fec91..597dc357 100644 Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ diff --git a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c index 200a8cfd..b863bb17 100644 --- a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c +++ b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c @@ -289,7 +289,7 @@ out: } -static DWORD GetVentoyVolumeName(int PhyDrive, UINT32 StartSectorId, CHAR *NameBuf, UINT32 BufLen, BOOL DelSlash) +static DWORD GetVentoyVolumeName(int PhyDrive, UINT64 StartSectorId, CHAR *NameBuf, UINT32 BufLen, BOOL DelSlash) { size_t len; BOOL bRet; @@ -304,7 +304,7 @@ static DWORD GetVentoyVolumeName(int PhyDrive, UINT32 StartSectorId, CHAR *NameB PartOffset = 512ULL * StartSectorId; - Log("GetVentoyVolumeName PhyDrive %d SectorStart:%u PartOffset:%llu", PhyDrive, StartSectorId, (ULONGLONG)PartOffset); + Log("GetVentoyVolumeName PhyDrive %d SectorStart:%llu PartOffset:%llu", PhyDrive, (ULONGLONG)StartSectorId, (ULONGLONG)PartOffset); hVolume = FindFirstVolumeA(VolumeName, sizeof(VolumeName)); if (hVolume == INVALID_HANDLE_VALUE) @@ -1401,18 +1401,18 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett goto End; } - // clear first and last 1MB space - pTmpBuf = malloc(SIZE_1MB); + // clear first and last 2MB space + pTmpBuf = malloc(SIZE_2MB); if (!pTmpBuf) { Log("Failed to alloc memory."); rc = 1; goto End; } - memset(pTmpBuf, 0, SIZE_1MB); + memset(pTmpBuf, 0, SIZE_2MB); SET_FILE_POS(512); - bRet = WriteFile(hDrive, pTmpBuf, SIZE_1MB - 512, &dwSize, NULL); + bRet = WriteFile(hDrive, pTmpBuf, SIZE_2MB - 512, &dwSize, NULL); Log("Write fisrt 1MB ret:%d size:%u err:%d", bRet, dwSize, LASTERR); if (!bRet) { @@ -1420,8 +1420,8 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett goto End; } - SET_FILE_POS(SIZE_1MB); - bRet = WriteFile(hDrive, pTmpBuf, SIZE_1MB, &dwSize, NULL); + SET_FILE_POS(pPhyDrive->SizeInBytes - SIZE_2MB); + bRet = WriteFile(hDrive, pTmpBuf, SIZE_2MB, &dwSize, NULL); Log("Write 2nd 1MB ret:%d size:%u err:%d", bRet, dwSize, LASTERR); if (!bRet) { @@ -1430,30 +1430,71 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett } SET_FILE_POS(0); - bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); - Log("Read MBR ret:%d size:%u err:%d", bRet, dwSize, LASTERR); - if (!bRet) + + if (pPhyDrive->SizeInBytes > 2199023255552ULL) { - rc = 1; - goto End; + VTOY_GPT_INFO *pGptInfo; + VTOY_GPT_HDR BackupHead; + LARGE_INTEGER liCurrentPosition; + + pGptInfo = (VTOY_GPT_INFO *)pTmpBuf; + + VentoyFillWholeGpt(pPhyDrive->SizeInBytes, pGptInfo); + + 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 ..."); } - - //clear boot code and partition table (reserved disk signature) - memset(MBR.BootCode, 0, 440); - memset(MBR.PartTbl, 0, sizeof(MBR.PartTbl)); - - VentoyFillLocation(pPhyDrive->SizeInBytes, 2048, (UINT32)(pPhyDrive->SizeInBytes / 512 - 2048), MBR.PartTbl); - - MBR.PartTbl[0].Active = 0x00; // bootable - MBR.PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS - - SET_FILE_POS(0); - bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); - Log("Write MBR ret:%d size:%u err:%d", bRet, dwSize, LASTERR); - if (!bRet) + else { - rc = 1; - goto End; + bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + Log("Read MBR ret:%d size:%u err:%d", bRet, dwSize, LASTERR); + if (!bRet) + { + rc = 1; + goto End; + } + + //clear boot code and partition table (reserved disk signature) + memset(MBR.BootCode, 0, 440); + memset(MBR.PartTbl, 0, sizeof(MBR.PartTbl)); + + VentoyFillMBRLocation(pPhyDrive->SizeInBytes, 2048, (UINT32)(pPhyDrive->SizeInBytes / 512 - 2048), MBR.PartTbl); + + MBR.PartTbl[0].Active = 0x00; // bootable + MBR.PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS + + SET_FILE_POS(0); + bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); + Log("Write MBR ret:%d size:%u err:%d", bRet, dwSize, LASTERR); + if (!bRet) + { + rc = 1; + goto End; + } } Log("Clear Ventoy successfully finished"); @@ -1490,7 +1531,7 @@ End: if (state != 1) { Log("need to mount ventoy part1..."); - if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, MBR.PartTbl[0].StartSectorId, DriveLetters, sizeof(DriveLetters), FALSE)) + if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, 2048, DriveLetters, sizeof(DriveLetters), FALSE)) { DriveName[0] = MountDrive; bRet = SetVolumeMountPointA(DriveName, DriveLetters); @@ -1528,6 +1569,10 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle) CHAR DriveLetters[MAX_PATH] = { 0 }; MBR_HEAD MBR; VTOY_GPT_INFO *pGptInfo = NULL; + UINT64 Part1StartSector = 0; + UINT64 Part1SectorCount = 0; + UINT64 Part2StartSector = 0; + Log("InstallVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>", PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, @@ -1541,10 +1586,19 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle) PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); - VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle);//also used to format 1st partition in GPT mode if (PartStyle) { VentoyFillGpt(pPhyDrive->SizeInBytes, pGptInfo); + Part1StartSector = pGptInfo->PartTbl[0].StartLBA; + Part1SectorCount = pGptInfo->PartTbl[0].LastLBA - Part1StartSector + 1; + Part2StartSector = pGptInfo->PartTbl[1].StartLBA; + } + else + { + VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle); + Part1StartSector = MBR.PartTbl[0].StartSectorId; + Part1SectorCount = MBR.PartTbl[0].SectorCount; + Part2StartSector = MBR.PartTbl[1].StartSectorId; } Log("Lock disk for clean ............................. "); @@ -1608,7 +1662,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle) //Refresh Drive Layout DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); - disk_io_set_param(hDrive, MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount); + disk_io_set_param(hDrive, Part1StartSector + Part1SectorCount);// include the 2048 sector gap PROGRESS_BAR_SET_POS(PT_FORMAT_PART1); @@ -1626,9 +1680,12 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle) goto End; } + + PROGRESS_BAR_SET_POS(PT_FORMAT_PART2); Log("Writing part2 FAT img ..."); - if (0 != FormatPart2Fat(hDrive, MBR.PartTbl[1].StartSectorId)) + + if (0 != FormatPart2Fat(hDrive, Part2StartSector)) { Log("FormatPart2Fat failed."); rc = 1; @@ -1679,7 +1736,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle) } Log("Write GPT Info OK ..."); - memcpy(&(pPhyDrive->MBR), &MBR, 512); + memcpy(&(pPhyDrive->MBR), &(pGptInfo->MBR), 512); } else { @@ -1728,7 +1785,8 @@ End: if (state != 1) { Log("need to mount ventoy part1..."); - if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, MBR.PartTbl[0].StartSectorId, DriveLetters, sizeof(DriveLetters), FALSE)) + + if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, Part1StartSector, DriveLetters, sizeof(DriveLetters), FALSE)) { DriveName[0] = MountDrive; bRet = SetVolumeMountPointA(DriveName, DriveLetters); @@ -1872,7 +1930,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) Log("Lock volume for update .......................... "); hVolume = INVALID_HANDLE_VALUE; - Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, (UINT32)StartSector, DriveLetters, sizeof(DriveLetters), TRUE); + Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, StartSector, DriveLetters, sizeof(DriveLetters), TRUE); if (ERROR_SUCCESS == Status) { Log("Now lock and dismount volume <%s>", DriveLetters); diff --git a/Ventoy2Disk/Ventoy2Disk/Utility.c b/Ventoy2Disk/Ventoy2Disk/Utility.c index ff77db55..91403bd2 100644 --- a/Ventoy2Disk/Ventoy2Disk/Utility.c +++ b/Ventoy2Disk/Ventoy2Disk/Utility.c @@ -382,7 +382,7 @@ BOOL IsVentoyLogicalDrive(CHAR DriveLetter) } -int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 SectorCount, PART_TABLE *Table) +int VentoyFillMBRLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 SectorCount, PART_TABLE *Table) { BYTE Head; BYTE Sector; @@ -473,7 +473,7 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR, int PartStyle) //Part1 PartStartSector = VENTOY_PART1_START_SECTOR; PartSectorCount = DiskSectorCount - ReservedSector - VENTOY_EFI_PART_SIZE / 512 - PartStartSector; - VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl); + VentoyFillMBRLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl); pMBR->PartTbl[0].Active = 0x80; // bootable pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS @@ -481,7 +481,7 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR, int PartStyle) //Part2 PartStartSector += PartSectorCount; PartSectorCount = VENTOY_EFI_PART_SIZE / 512; - VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl + 1); + VentoyFillMBRLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl + 1); pMBR->PartTbl[1].Active = 0x00; pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition @@ -538,6 +538,45 @@ static int VentoyFillProtectMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR) return 0; } +int VentoyFillWholeGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo) +{ + 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 } }; + + VentoyFillProtectMBR(DiskSizeBytes, &pInfo->MBR); + + Part1SectorCount = DiskSectorCount - 33 - 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"Data", 4 * 2); + + //Update CRC + Head->PartTblCrc = VentoyCrc32(Table, sizeof(pInfo->PartTbl)); + Head->Crc = VentoyCrc32(Head, Head->Length); + + return 0; +} int VentoyFillGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo) { diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c index 5fe037bb..1f206aaa 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c @@ -153,6 +153,8 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN } *Part2StartSector = pGpt->PartTbl[1].StartLBA; + + memcpy(pMBR, &(pGpt->MBR), sizeof(MBR_HEAD)); } else { @@ -188,9 +190,10 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN } *Part2StartSector = MBR.PartTbl[1].StartSectorId; + + memcpy(pMBR, &MBR, sizeof(MBR_HEAD)); } - memcpy(pMBR, &MBR, sizeof(MBR_HEAD)); Log("PhysicalDrive%d is ventoy disk", PhyDrive); return TRUE; } diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h index 0f8e76c6..8407ae14 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h @@ -24,6 +24,7 @@ #include #define SIZE_1MB (1024 * 1024) +#define SIZE_2MB (2048 * 1024) #define VENTOY_EFI_PART_SIZE (32 * SIZE_1MB) #define VENTOY_PART1_START_SECTOR 2048 @@ -208,6 +209,7 @@ int ParseCmdLineOption(LPSTR lpCmdLine); int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle); int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive); int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead); +int VentoyFillWholeGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo); void SetProgressBarPos(int Pos); int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen); int INIT unxz(unsigned char *in, int in_size, @@ -219,7 +221,7 @@ void disk_io_set_param(HANDLE Handle, UINT64 SectorCount); INT_PTR CALLBACK PartDialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); int GetReservedSpaceInMB(void); int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive); -int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 SectorCount, PART_TABLE *Table); +int VentoyFillMBRLocation(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); diff --git a/Ventoy2Disk/Ventoy2Disk/ff14/source/ff.c b/Ventoy2Disk/Ventoy2Disk/ff14/source/ff.c index 22cbac5c..c39bea6f 100644 --- a/Ventoy2Disk/Ventoy2Disk/ff14/source/ff.c +++ b/Ventoy2Disk/Ventoy2Disk/ff14/source/ff.c @@ -475,9 +475,9 @@ static const char* const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS}; /* Pre-define #endif #if FF_LBA64 -#if FF_MIN_GPT > 0x100000000 -#error Wrong FF_MIN_GPT setting -#endif +//#if FF_MIN_GPT > 0x100000000 +//#error Wrong FF_MIN_GPT setting +//#endif static const BYTE GUID_MS_Basic[16] = {0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7}; #endif @@ -5983,10 +5983,10 @@ FRESULT f_mkfs ( if (sz_vol >= 0x4000000) sz_au = 256; /* >= 64Ms */ } b_fat = b_vol + 32; /* FAT start at offset 32 */ - sz_fat = (DWORD)((sz_vol / sz_au + 2) * 4 + ss - 1) / ss; /* Number of FAT sectors */ + sz_fat = (DWORD)(((sz_vol / sz_au + 2) * 4 + ss - 1) / ss); /* Number of FAT sectors */ b_data = (b_fat + sz_fat + sz_blk - 1) & ~((LBA_t)sz_blk - 1); /* Align data area to the erase block boundary */ if (b_data - b_vol >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ - n_clst = (DWORD)(sz_vol - (b_data - b_vol)) / sz_au; /* Number of clusters */ + n_clst = (DWORD)((sz_vol - (b_data - b_vol)) / sz_au); /* Number of clusters */ if (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too few clusters? */ if (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters? */ diff --git a/Ventoy2Disk/Ventoy2Disk/ff14/source/ffconf.h b/Ventoy2Disk/Ventoy2Disk/ff14/source/ffconf.h index 229d865a..d40f8696 100644 --- a/Ventoy2Disk/Ventoy2Disk/ff14/source/ffconf.h +++ b/Ventoy2Disk/Ventoy2Disk/ff14/source/ffconf.h @@ -205,7 +205,7 @@ / To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */ -#define FF_MIN_GPT 0x100000000 +#define FF_MIN_GPT 0x10000000000000 /* Minimum number of sectors to switch GPT format to create partition in f_mkfs and / f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */