diff --git a/src/drive.c b/src/drive.c index ed7b2c5c..9bc65b4f 100644 --- a/src/drive.c +++ b/src/drive.c @@ -1507,19 +1507,24 @@ BOOL AnalyzePBR(HANDLE hLogicalVolume) /* * This call returns the offset of the first ESP partition found - * on the relevant drive, or -1 if no ESP was found. + * on the relevant drive, or 0ULL if no ESP was found. */ -int64_t GetEspOffset(HANDLE hPhysical) +uint64_t GetEspOffset(DWORD DriveIndex) { - int64_t ret = -1; + uint64_t ret = 0ULL; BOOL r; + HANDLE hPhysical; DWORD size, i; BYTE layout[4096] = { 0 }; PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; + hPhysical = GetPhysicalHandle(DriveIndex, FALSE, TRUE, TRUE); + if (hPhysical == INVALID_HANDLE_VALUE) + return FALSE; + r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0, layout, sizeof(layout), &size, NULL); if (!r || size <= 0) { - uprintf("Could not get drive layout: %s", WindowsErrorString()); + uprintf("Could not get layout for drive 0x%02x: %s", DriveIndex, WindowsErrorString()); goto out; } @@ -1532,6 +1537,7 @@ int64_t GetEspOffset(HANDLE hPhysical) } out: + safe_closehandle(hPhysical); return ret; } @@ -1725,33 +1731,10 @@ out: } // This is a crude attempt at detecting file systems through their superblock magic. +// Note that we only attempt to detect the file systems that Rufus can format as +// well as a couple other maintsream ones. const char* GetFsName(HANDLE hPhysical, LARGE_INTEGER StartingOffset) { - typedef struct { - const char* name; - const uint8_t magic[4]; - } magic_type; - const magic_type magic_types[] = { - { "SquashFS", { 'h', 's', 'q', 's' } }, - { "CramFS", { 0x45, 0x3D, 0xCD, 0x28 } }, - { "XFS", { 'X', 'F', 'S', 'B' } }, - { "LUKS", { 'L', 'U', 'K', 'S' } }, - { "MD RAID", { 0xFC, 0x4E, 0x2B, 0xA9 } }, - { "U-Boot Legacy uImage", { 0x27, 0x05, 0x19, 0x56 } }, - { "Device Tree/U-Boot FIT", { 0xD0, 0x0D, 0xFE, 0xED } }, - { "Device Tree Overlay", { 0xD7, 0xB7, 0xAB, 0x1E } }, - { "Android Sparse Image", { 0x3A, 0xFF, 0x26, 0xED } }, - { "Android Verified Boot", { 'A', 'V', 'B', '0' } }, - { "Qualcomm Device Tree", { 'Q', 'C', 'D', 'T' } }, - { "Rockchip Resource Image", { 'R', 'S', 'C', 'E' } }, - { "Rockchip Kernel Image", { 'K', 'R', 'N', 'L' } }, - { "Rockchip Parameter Image", { 'P', 'A', 'R', 'M' } }, - { "Rockchip Firmware Image", { 'R', 'K', 'F', 'W' } }, - { "Amlogic Image", { '@', 'A', 'M', 'L' } }, - { "Allwinner Image", { 'e', 'G', 'O', 'N' } }, - { "Mediatek Image", { 0x88, 0x16, 0x88, 0x58 } }, - { "Mediatek Extension", { 0x88, 0x16, 0x89, 0x58 } }, - }; typedef struct { const char* name; const uint8_t magic[8]; @@ -1776,28 +1759,23 @@ const char* GetFsName(HANDLE hPhysical, LARGE_INTEGER StartingOffset) { 0x00000013, 0x0000004C, 0x0003F780 } }; const char* ext_names[] = { "ext", "ext2", "ext3", "ext4" }; - const uint8_t erofs_magic[4] = { 0xE2, 0xE1, 0xF5, 0xE0 }; - const uint8_t f2fs_magic[4] = { 0x10, 0x20, 0xF5, 0xF2 }; const char* ret = "(Unrecognized)"; DWORD i, j, offset, size, sector_size = 512; uint8_t* buf = calloc(sector_size, 1); if (buf == NULL) goto out; - // 1. Detect magic-based file systems through the 512 bytes superblock at offset 0 + // 1. Try to detect ISO9660/FAT/exFAT/NTFS/ReFS/SquashFS through the 512 bytes superblock at offset 0 if (!SetFilePointerEx(hPhysical, StartingOffset, NULL, FILE_BEGIN)) goto out; if (!ReadFile(hPhysical, buf, sector_size, &size, NULL) || size != sector_size) goto out; - if (strncmp("CD001", &buf[0x01], 5) == 0) { - ret = "ISO9660"; + if (memcmp("hsqs", buf, 4) == 0) { + ret = "SquashFS"; goto out; } - for (i = 0; i < ARRAYSIZE(magic_types); i++) - if (memcmp(buf, magic_types[i].magic, 4) == 0) - break; - if (i < ARRAYSIZE(magic_types)) { - ret = magic_types[i].name; + if (strncmp("CD001", &buf[0x01], 5) == 0) { + ret = "ISO9660"; goto out; } @@ -1847,8 +1825,8 @@ const char* GetFsName(HANDLE hPhysical, LARGE_INTEGER StartingOffset) goto out; } - // 3. Try to detect ext2/ext3/ext4/EROFS/F2FS through the 512 bytes superblock at - // offset 1024 (which StartingOffset already points to) + // 3. Try to detect ext2/ext3/ext4 through the 512 bytes superblock at offset 1024 + // We're already at the right offset if (!SetFilePointerEx(hPhysical, StartingOffset, NULL, FILE_BEGIN)) goto out; if (!ReadFile(hPhysical, buf, sector_size, &size, NULL) || size != sector_size) @@ -1867,14 +1845,6 @@ const char* GetFsName(HANDLE hPhysical, LARGE_INTEGER StartingOffset) ret = ext_names[rev]; goto out; } - if (memcmp(buf, erofs_magic, 4) == 0) { - ret = "EROFS"; - goto out; - } - if (memcmp(buf, f2fs_magic, 4) == 0) { - ret = "F2FS"; - goto out; - } // 4. Try to detect UDF through by looking for a "BEA01\0" string at offset 0xC001 // NB: This is not thorough UDF detection but good enough for our purpose. diff --git a/src/drive.h b/src/drive.h index d20cc49b..8dc0f7aa 100644 --- a/src/drive.h +++ b/src/drive.h @@ -408,8 +408,7 @@ BOOL CyclePort(int index); int CycleDevice(int index); BOOL RefreshLayout(DWORD DriveIndex); BOOL GetOpticalMedia(IMG_SAVE* img_save); -int64_t GetEspOffset(HANDLE hPhysical); +uint64_t GetEspOffset(DWORD DriveIndex); BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset); -const char* GetFsName(HANDLE hPhysical, LARGE_INTEGER StartingOffset); BOOL IsMsDevDrive(DWORD DriveIndex); BOOL IsFilteredDrive(DWORD DriveIndex); diff --git a/src/format.c b/src/format.c index bcad042e..c13f253c 100644 --- a/src/format.c +++ b/src/format.c @@ -1444,7 +1444,7 @@ out: */ DWORD WINAPI FormatThread(void* param) { - int i, r; + int r; BOOL ret, windows_to_go, actual_lock_drive = lock_drive, write_as_ext = FALSE; // Windows 11 and VDS (which I suspect is what fmifs.dll's FormatEx() is now calling behind the scenes) // require us to unlock the physical drive to format the drive, else access denied is returned. @@ -1517,9 +1517,7 @@ DWORD WINAPI FormatThread(void* param) } // Unassign all drives letters - // For raw images, keep the primary partition on the earliest prior letter - // so we don't steal the secondary partition's former mountpoint. - drive_name[0] = RemoveDriveLetters(DriveIndex, !((boot_type == BT_IMAGE) && write_as_image), FALSE); + drive_name[0] = RemoveDriveLetters(DriveIndex, TRUE, FALSE); if (drive_name[0] == 0) { uprintf("Unable to find a drive letter to use"); ErrorStatus = RUFUS_ERROR(APPERR(ERROR_CANT_ASSIGN_LETTER)); @@ -2044,25 +2042,18 @@ out: PrintInfo(0, MSG_320, lmprintf(MSG_307)); Sleep(200); VdsRescan(VDS_RESCAN_REFRESH, 0, TRUE); - // Try to remount the first non ESP partition we see with a file system that Windows supports - hPhysicalDrive = GetPhysicalHandle(DriveIndex, FALSE, TRUE, TRUE); - if (hPhysicalDrive != INVALID_HANDLE_VALUE) { - int64_t esp_offset = GetEspOffset(hPhysicalDrive); - for (i = 0; i < SelectedDrive.nPartitions; i++) { - LARGE_INTEGER li = { .QuadPart = SelectedDrive.Partition[partition_index[i]].Offset }; - if (li.QuadPart == esp_offset) // Skip any ESP - continue; - const char* fs = GetFsName(hPhysicalDrive, li); - if (fs != NULL && (strcmp(fs, "NTFS") == 0 || strcmp(fs, "exFAT") == 0 || - strcmp(fs, "ReFS") == 0 || strncmp(fs, "FAT", 3) == 0)) { - WaitForLogical(DriveIndex, li.QuadPart); - volume_name = GetLogicalName(DriveIndex, li.QuadPart, TRUE, TRUE); - if ((volume_name != NULL) && (MountVolume(drive_name, volume_name))) - uprintf("Remounted %s as %c:", volume_name, toupper(drive_name[0])); - break; - } + // Trying to mount accessible partitions after writing an image leads to the + // creation of the infamous 'System Volume Information' folder on ESPs, which + // in turn leads to checksum errors for Ubuntu's boot/grub/efi.img (that maps + // to the Ubuntu ESP). So we only call the code below if there are no ESPs or + // if we're running a Ventoy image. + if ((GetEspOffset(DriveIndex) == 0) || (img_report.compression_type == BLED_COMPRESSION_VTSI)) { + WaitForLogical(DriveIndex, 0); + if (GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_name, sizeof(fs_name), TRUE)) { + volume_name = GetLogicalName(DriveIndex, 0, TRUE, TRUE); + if ((volume_name != NULL) && (MountVolume(drive_name, volume_name))) + uprintf("Remounted %s as %c:", volume_name, toupper(drive_name[0])); } - safe_closehandle(hPhysicalDrive); } } if (IS_ERROR(ErrorStatus)) { diff --git a/src/rufus.rc b/src/rufus.rc index 27ac0fb0..f15ce6ca 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.15.2409" +CAPTION "Rufus 4.15.2407" 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,15,2409,0 - PRODUCTVERSION 4,15,2409,0 + FILEVERSION 4,15,2407,0 + PRODUCTVERSION 4,15,2407,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.15.2409" + VALUE "FileVersion", "4.15.2407" 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.15.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.15.2409" + VALUE "ProductVersion", "4.15.2407" END END BLOCK "VarFileInfo"