mirror of
https://github.com/pbatard/rufus.git
synced 2026-10-22 14:24:28 +00:00
Compare commits
2 commits
942ed3a4ed
...
875f221d5b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
875f221d5b |
||
|
|
d8722322eb |
4 changed files with 78 additions and 38 deletions
68
src/drive.c
68
src/drive.c
|
|
@ -1507,24 +1507,19 @@ BOOL AnalyzePBR(HANDLE hLogicalVolume)
|
|||
|
||||
/*
|
||||
* This call returns the offset of the first ESP partition found
|
||||
* on the relevant drive, or 0ULL if no ESP was found.
|
||||
* on the relevant drive, or -1 if no ESP was found.
|
||||
*/
|
||||
uint64_t GetEspOffset(DWORD DriveIndex)
|
||||
int64_t GetEspOffset(HANDLE hPhysical)
|
||||
{
|
||||
uint64_t ret = 0ULL;
|
||||
int64_t ret = -1;
|
||||
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 layout for drive 0x%02x: %s", DriveIndex, WindowsErrorString());
|
||||
uprintf("Could not get drive layout: %s", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -1537,7 +1532,6 @@ uint64_t GetEspOffset(DWORD DriveIndex)
|
|||
}
|
||||
|
||||
out:
|
||||
safe_closehandle(hPhysical);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1731,10 +1725,33 @@ 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];
|
||||
|
|
@ -1759,25 +1776,30 @@ 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. Try to detect ISO9660/FAT/exFAT/NTFS/ReFS/SquashFS through the 512 bytes superblock at offset 0
|
||||
// 1. Detect magic-based file systems 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 (memcmp("hsqs", buf, 4) == 0) {
|
||||
ret = "SquashFS";
|
||||
goto out;
|
||||
}
|
||||
if (strncmp("CD001", &buf[0x01], 5) == 0) {
|
||||
ret = "ISO9660";
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// The beginning of a superblock for FAT/exFAT/NTFS/ReFS is pretty much always the same:
|
||||
// There are 3 bytes potentially used for a jump instruction, and then are 8 bytes of
|
||||
|
|
@ -1825,8 +1847,8 @@ const char* GetFsName(HANDLE hPhysical, LARGE_INTEGER StartingOffset)
|
|||
goto out;
|
||||
}
|
||||
|
||||
// 3. Try to detect ext2/ext3/ext4 through the 512 bytes superblock at offset 1024
|
||||
// We're already at the right offset
|
||||
// 3. Try to detect ext2/ext3/ext4/EROFS/F2FS through the 512 bytes superblock at
|
||||
// offset 1024 (which StartingOffset already points to)
|
||||
if (!SetFilePointerEx(hPhysical, StartingOffset, NULL, FILE_BEGIN))
|
||||
goto out;
|
||||
if (!ReadFile(hPhysical, buf, sector_size, &size, NULL) || size != sector_size)
|
||||
|
|
@ -1845,6 +1867,14 @@ 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.
|
||||
|
|
|
|||
|
|
@ -408,7 +408,8 @@ BOOL CyclePort(int index);
|
|||
int CycleDevice(int index);
|
||||
BOOL RefreshLayout(DWORD DriveIndex);
|
||||
BOOL GetOpticalMedia(IMG_SAVE* img_save);
|
||||
uint64_t GetEspOffset(DWORD DriveIndex);
|
||||
int64_t GetEspOffset(HANDLE hPhysical);
|
||||
BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset);
|
||||
const char* GetFsName(HANDLE hPhysical, LARGE_INTEGER StartingOffset);
|
||||
BOOL IsMsDevDrive(DWORD DriveIndex);
|
||||
BOOL IsFilteredDrive(DWORD DriveIndex);
|
||||
|
|
|
|||
35
src/format.c
35
src/format.c
|
|
@ -1444,7 +1444,7 @@ out:
|
|||
*/
|
||||
DWORD WINAPI FormatThread(void* param)
|
||||
{
|
||||
int r;
|
||||
int i, 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,7 +1517,9 @@ DWORD WINAPI FormatThread(void* param)
|
|||
}
|
||||
|
||||
// Unassign all drives letters
|
||||
drive_name[0] = RemoveDriveLetters(DriveIndex, TRUE, FALSE);
|
||||
// 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);
|
||||
if (drive_name[0] == 0) {
|
||||
uprintf("Unable to find a drive letter to use");
|
||||
ErrorStatus = RUFUS_ERROR(APPERR(ERROR_CANT_ASSIGN_LETTER));
|
||||
|
|
@ -2042,18 +2044,25 @@ out:
|
|||
PrintInfo(0, MSG_320, lmprintf(MSG_307));
|
||||
Sleep(200);
|
||||
VdsRescan(VDS_RESCAN_REFRESH, 0, TRUE);
|
||||
// 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]));
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
safe_closehandle(hPhysicalDrive);
|
||||
}
|
||||
}
|
||||
if (IS_ERROR(ErrorStatus)) {
|
||||
|
|
|
|||
10
src/rufus.rc
10
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.2407"
|
||||
CAPTION "Rufus 4.15.2409"
|
||||
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,2407,0
|
||||
PRODUCTVERSION 4,15,2407,0
|
||||
FILEVERSION 4,15,2409,0
|
||||
PRODUCTVERSION 4,15,2409,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.2407"
|
||||
VALUE "FileVersion", "4.15.2409"
|
||||
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.2407"
|
||||
VALUE "ProductVersion", "4.15.2409"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue