From 00a802ca1d89238463846dc0967880ec9f595348 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 20 Jan 2022 15:24:35 +0100 Subject: [PATCH] =?UTF-8?q?[iso]=20fix=20ISO=E2=86=92ESP=20creation=20for?= =?UTF-8?q?=20Windows=2011?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * In their great "wisdom", Microsoft made it even harder to access ESPs on Windows 11, meaning that we have to use even more convoluted ways of providing the ISO→ESP feature. * Closes #1855 --- src/drive.c | 18 ++++++++++- src/drive.h | 3 +- src/format.c | 78 ++++++++++++++++++++++++++++------------------ src/format_fat32.c | 12 +++++-- src/rufus.rc | 10 +++--- 5 files changed, 80 insertions(+), 41 deletions(-) diff --git a/src/drive.c b/src/drive.c index 6d5961d5..ce9703f4 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-2021 Pete Batard + * Copyright © 2011-2022 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 @@ -1034,6 +1034,22 @@ HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDr return hLogical; } +/* Alternate version of the above, for ESPs */ +HANDLE AltGetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare) +{ + HANDLE hLogical = INVALID_HANDLE_VALUE; + char* LogicalPath = AltGetLogicalName(DriveIndex, PartitionOffset, FALSE, FALSE); + + if (LogicalPath == NULL) { + uprintf("No logical drive found"); + return NULL; + } + + hLogical = GetHandle(LogicalPath, bLockDrive, bWriteAccess, bWriteShare); + free(LogicalPath); + return hLogical; +} + /* * Who would have thought that Microsoft would make it so unbelievably hard to * get the frickin' device number for a drive? You have to use TWO different diff --git a/src/drive.h b/src/drive.h index 8ad642eb..bb17929c 100644 --- a/src/drive.h +++ b/src/drive.h @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Drive access function calls - * Copyright © 2011-2021 Pete Batard + * Copyright © 2011-2022 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 @@ -384,6 +384,7 @@ char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTr char* GetExtPartitionName(DWORD DriveIndex, uint64_t PartitionOffset); BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset); HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); +HANDLE AltGetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); int GetDriveNumber(HANDLE hDrive, char* path); BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters); UINT GetDriveTypeFromIndex(DWORD DriveIndex); diff --git a/src/format.c b/src/format.c index eb492d17..32b52c11 100644 --- a/src/format.c +++ b/src/format.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Formatting function calls - * Copyright © 2011-2021 Pete Batard + * Copyright © 2011-2022 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 @@ -2125,11 +2125,20 @@ DWORD WINAPI FormatThread(void* param) // Wait for the logical drive we just created to appear uprintf("Waiting for logical drive to reappear..."); Sleep(200); - if (!WaitForLogical(DriveIndex, partition_offset[PI_MAIN])) { - uprintf("Logical drive was not found - aborting"); - if (!IS_ERROR(FormatStatus)) - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_TIMEOUT; - goto out; + if (write_as_esp) { + // Can't format the ESP unless we mount it ourself + volume_name = AltMountVolume(DriveIndex, partition_offset[PI_MAIN], FALSE); + if (volume_name == NULL) { + FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER); + goto out; + } + } else { + if (!WaitForLogical(DriveIndex, partition_offset[PI_MAIN])) { + uprintf("Logical drive was not found - aborting"); + if (!IS_ERROR(FormatStatus)) + FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_TIMEOUT; + goto out; + } } CHECK_FOR_USER_CANCEL; @@ -2190,33 +2199,37 @@ DWORD WINAPI FormatThread(void* param) UpdateProgress(OP_FIX_MBR, -1.0f); } Sleep(200); - WaitForLogical(DriveIndex, 0); - // Try to continue - CHECK_FOR_USER_CANCEL; - volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE); - if (volume_name == NULL) { - uprintf("Could not get volume name"); - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_VOLUME_ID; - goto out; - } - uprintf("Found volume %s", volume_name); + if (!write_as_esp) { + WaitForLogical(DriveIndex, 0); + // Try to continue + CHECK_FOR_USER_CANCEL; - // Windows is really finicky with regards to reassigning drive letters even after - // we forcibly removed them, so add yet another explicit call to RemoveDriveLetters() - RemoveDriveLetters(DriveIndex, FALSE, TRUE); - if (!MountVolume(drive_name, volume_name)) { - uprintf("Could not remount %s as %C: %s\n", volume_name, drive_name[0], WindowsErrorString()); - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_MOUNT_VOLUME); - goto out; - } - CHECK_FOR_USER_CANCEL; + volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE); + if (volume_name == NULL) { + uprintf("Could not get volume name"); + FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NO_VOLUME_ID; + goto out; + } + uprintf("Found volume %s", volume_name); - // Disable file indexing, unless it was force-enabled by the user - if ((!enable_file_indexing) && ((fs_type == FS_NTFS) || (fs_type == FS_UDF) || (fs_type == FS_REFS))) { - uprintf("Disabling file indexing..."); - if (!SetFileAttributesA(volume_name, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)) - uprintf("Could not disable file indexing: %s", WindowsErrorString()); + + // Windows is really finicky with regards to reassigning drive letters even after + // we forcibly removed them, so add yet another explicit call to RemoveDriveLetters() + RemoveDriveLetters(DriveIndex, FALSE, TRUE); + if (!MountVolume(drive_name, volume_name)) { + uprintf("Could not remount %s as %C: %s\n", volume_name, drive_name[0], WindowsErrorString()); + FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_MOUNT_VOLUME); + goto out; + } + CHECK_FOR_USER_CANCEL; + + // Disable file indexing, unless it was force-enabled by the user + if ((!enable_file_indexing) && ((fs_type == FS_NTFS) || (fs_type == FS_UDF) || (fs_type == FS_REFS))) { + uprintf("Disabling file indexing..."); + if (!SetFileAttributesA(volume_name, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)) + uprintf("Could not disable file indexing: %s", WindowsErrorString()); + } } // Refresh the drive label - This is needed as Windows may have altered it from @@ -2370,11 +2383,14 @@ DWORD WINAPI FormatThread(void* param) } out: + if (write_as_esp && volume_name != NULL) + AltUnmountVolume(volume_name, TRUE); + else + safe_free(volume_name); if ((boot_type == BT_IMAGE) && write_as_image) { PrintInfo(0, MSG_320, lmprintf(MSG_307)); VdsRescan(VDS_RESCAN_REFRESH, 0, TRUE); } - safe_free(volume_name); safe_free(buffer); safe_unlockclose(hLogicalVolume); safe_unlockclose(hPhysicalDrive); // This can take a while diff --git a/src/format_fat32.c b/src/format_fat32.c index 087c8b2d..817f745d 100644 --- a/src/format_fat32.c +++ b/src/format_fat32.c @@ -2,7 +2,7 @@ * Rufus: The Reliable USB Formatting Utility * Large FAT32 formatting * Copyright © 2007-2009 Tom Thornhill/Ridgecrop - * Copyright © 2011-2021 Pete Batard + * Copyright © 2011-2022 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 @@ -42,6 +42,8 @@ FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|err; \ goto out; } while(0) +extern BOOL write_as_esp; + /* Large FAT32 */ #pragma pack(push, 1) typedef struct tagFAT_BOOTSECTOR32 @@ -196,7 +198,9 @@ BOOL FormatLargeFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterS VolumeId = GetVolumeID(); // Open the drive and lock it - hLogicalVolume = GetLogicalHandle(DriveIndex, PartitionOffset, TRUE, TRUE, FALSE); + hLogicalVolume = write_as_esp ? + AltGetLogicalHandle(DriveIndex, PartitionOffset, TRUE, TRUE, FALSE) : + GetLogicalHandle(DriveIndex, PartitionOffset, TRUE, TRUE, FALSE); if (IS_ERROR(FormatStatus)) goto out; if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) @@ -450,7 +454,9 @@ BOOL FormatLargeFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterS uprintf("Setting label..."); // Handle must be closed for SetVolumeLabel to work safe_closehandle(hLogicalVolume); - VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE); + VolumeName = write_as_esp ? + AltGetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE) : + GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE); if ((VolumeName == NULL) || (!SetVolumeLabelA(VolumeName, Label))) { uprintf("Could not set label: %s", WindowsErrorString()); // Non fatal error diff --git a/src/rufus.rc b/src/rufus.rc index d209b654..91b3ec18 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 3.18.1862" +CAPTION "Rufus 3.18.1863" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -395,8 +395,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,18,1862,0 - PRODUCTVERSION 3,18,1862,0 + FILEVERSION 3,18,1863,0 + PRODUCTVERSION 3,18,1863,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -414,13 +414,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.18.1862" + VALUE "FileVersion", "3.18.1863" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.18.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.18.1862" + VALUE "ProductVersion", "3.18.1863" END END BLOCK "VarFileInfo"