mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[iso] fix ISO→ESP creation for Windows 11
* 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
This commit is contained in:
		
							parent
							
								
									14847a1a89
								
							
						
					
					
						commit
						00a802ca1d
					
				
					 5 changed files with 80 additions and 41 deletions
				
			
		
							
								
								
									
										18
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -1,7 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Rufus: The Reliable USB Formatting Utility |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  * Drive access function calls |  * Drive access function calls | ||||||
|  * Copyright © 2011-2021 Pete Batard <pete@akeo.ie> |  * Copyright © 2011-2022 Pete Batard <pete@akeo.ie> | ||||||
|  * |  * | ||||||
|  * This program is free software: you can redistribute it and/or modify |  * 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 |  * 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; | 	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 |  * 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 |  * get the frickin' device number for a drive? You have to use TWO different | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Rufus: The Reliable USB Formatting Utility |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  * Drive access function calls |  * Drive access function calls | ||||||
|  * Copyright © 2011-2021 Pete Batard <pete@akeo.ie> |  * Copyright © 2011-2022 Pete Batard <pete@akeo.ie> | ||||||
|  * |  * | ||||||
|  * This program is free software: you can redistribute it and/or modify |  * 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 |  * 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); | char* GetExtPartitionName(DWORD DriveIndex, uint64_t PartitionOffset); | ||||||
| BOOL WaitForLogical(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 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); | int GetDriveNumber(HANDLE hDrive, char* path); | ||||||
| BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters); | BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters); | ||||||
| UINT GetDriveTypeFromIndex(DWORD DriveIndex); | UINT GetDriveTypeFromIndex(DWORD DriveIndex); | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -1,7 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Rufus: The Reliable USB Formatting Utility |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  * Formatting function calls |  * Formatting function calls | ||||||
|  * Copyright © 2011-2021 Pete Batard <pete@akeo.ie> |  * Copyright © 2011-2022 Pete Batard <pete@akeo.ie> | ||||||
|  * |  * | ||||||
|  * This program is free software: you can redistribute it and/or modify |  * 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 |  * it under the terms of the GNU General Public License as published by | ||||||
|  | @ -2125,12 +2125,21 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	// Wait for the logical drive we just created to appear
 | 	// Wait for the logical drive we just created to appear
 | ||||||
| 	uprintf("Waiting for logical drive to reappear..."); | 	uprintf("Waiting for logical drive to reappear..."); | ||||||
| 	Sleep(200); | 	Sleep(200); | ||||||
|  | 	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])) { | 		if (!WaitForLogical(DriveIndex, partition_offset[PI_MAIN])) { | ||||||
| 			uprintf("Logical drive was not found - aborting"); | 			uprintf("Logical drive was not found - aborting"); | ||||||
| 			if (!IS_ERROR(FormatStatus)) | 			if (!IS_ERROR(FormatStatus)) | ||||||
| 				FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_TIMEOUT; | 				FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_TIMEOUT; | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 	CHECK_FOR_USER_CANCEL; | 	CHECK_FOR_USER_CANCEL; | ||||||
| 
 | 
 | ||||||
| 	// Format Casper partition if required. Do it before we format anything with
 | 	// Format Casper partition if required. Do it before we format anything with
 | ||||||
|  | @ -2190,6 +2199,8 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		UpdateProgress(OP_FIX_MBR, -1.0f); | 		UpdateProgress(OP_FIX_MBR, -1.0f); | ||||||
| 	} | 	} | ||||||
| 	Sleep(200); | 	Sleep(200); | ||||||
|  | 
 | ||||||
|  | 	if (!write_as_esp) { | ||||||
| 		WaitForLogical(DriveIndex, 0); | 		WaitForLogical(DriveIndex, 0); | ||||||
| 		// Try to continue
 | 		// Try to continue
 | ||||||
| 		CHECK_FOR_USER_CANCEL; | 		CHECK_FOR_USER_CANCEL; | ||||||
|  | @ -2197,17 +2208,18 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE); | 		volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE); | ||||||
| 		if (volume_name == NULL) { | 		if (volume_name == NULL) { | ||||||
| 			uprintf("Could not get volume name"); | 			uprintf("Could not get volume name"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_VOLUME_ID; | 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NO_VOLUME_ID; | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 		uprintf("Found volume %s", volume_name); | 		uprintf("Found volume %s", volume_name); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| 		// Windows is really finicky with regards to reassigning drive letters even after
 | 		// Windows is really finicky with regards to reassigning drive letters even after
 | ||||||
| 		// we forcibly removed them, so add yet another explicit call to RemoveDriveLetters()
 | 		// we forcibly removed them, so add yet another explicit call to RemoveDriveLetters()
 | ||||||
| 		RemoveDriveLetters(DriveIndex, FALSE, TRUE); | 		RemoveDriveLetters(DriveIndex, FALSE, TRUE); | ||||||
| 		if (!MountVolume(drive_name, volume_name)) { | 		if (!MountVolume(drive_name, volume_name)) { | ||||||
| 			uprintf("Could not remount %s as %C: %s\n", volume_name, drive_name[0], WindowsErrorString()); | 			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); | 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_MOUNT_VOLUME); | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 		CHECK_FOR_USER_CANCEL; | 		CHECK_FOR_USER_CANCEL; | ||||||
|  | @ -2218,6 +2230,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 			if (!SetFileAttributesA(volume_name, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)) | 			if (!SetFileAttributesA(volume_name, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)) | ||||||
| 				uprintf("Could not disable file indexing: %s", WindowsErrorString()); | 				uprintf("Could not disable file indexing: %s", WindowsErrorString()); | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	// Refresh the drive label - This is needed as Windows may have altered it from
 | 	// Refresh the drive label - This is needed as Windows may have altered it from
 | ||||||
| 	// the name we proposed, and we require an exact label, to patch config files.
 | 	// the name we proposed, and we require an exact label, to patch config files.
 | ||||||
|  | @ -2370,11 +2383,14 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| out: | 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) { | 	if ((boot_type == BT_IMAGE) && write_as_image) { | ||||||
| 		PrintInfo(0, MSG_320, lmprintf(MSG_307)); | 		PrintInfo(0, MSG_320, lmprintf(MSG_307)); | ||||||
| 		VdsRescan(VDS_RESCAN_REFRESH, 0, TRUE); | 		VdsRescan(VDS_RESCAN_REFRESH, 0, TRUE); | ||||||
| 	} | 	} | ||||||
| 	safe_free(volume_name); |  | ||||||
| 	safe_free(buffer); | 	safe_free(buffer); | ||||||
| 	safe_unlockclose(hLogicalVolume); | 	safe_unlockclose(hLogicalVolume); | ||||||
| 	safe_unlockclose(hPhysicalDrive);	// This can take a while
 | 	safe_unlockclose(hPhysicalDrive);	// This can take a while
 | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
|  * Rufus: The Reliable USB Formatting Utility |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  * Large FAT32 formatting |  * Large FAT32 formatting | ||||||
|  * Copyright © 2007-2009 Tom Thornhill/Ridgecrop |  * Copyright © 2007-2009 Tom Thornhill/Ridgecrop | ||||||
|  * Copyright © 2011-2021 Pete Batard <pete@akeo.ie> |  * Copyright © 2011-2022 Pete Batard <pete@akeo.ie> | ||||||
|  * |  * | ||||||
|  * This program is free software: you can redistribute it and/or modify |  * 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 |  * 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; \ | 	FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|err; \ | ||||||
| 	goto out; } while(0) | 	goto out; } while(0) | ||||||
| 
 | 
 | ||||||
|  | extern BOOL write_as_esp; | ||||||
|  | 
 | ||||||
| /* Large FAT32 */ | /* Large FAT32 */ | ||||||
| #pragma pack(push, 1) | #pragma pack(push, 1) | ||||||
| typedef struct tagFAT_BOOTSECTOR32 | typedef struct tagFAT_BOOTSECTOR32 | ||||||
|  | @ -196,7 +198,9 @@ BOOL FormatLargeFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterS | ||||||
| 	VolumeId = GetVolumeID(); | 	VolumeId = GetVolumeID(); | ||||||
| 
 | 
 | ||||||
| 	// Open the drive and lock it
 | 	// 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)) | 	if (IS_ERROR(FormatStatus)) | ||||||
| 		goto out; | 		goto out; | ||||||
| 	if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) | 	if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) | ||||||
|  | @ -450,7 +454,9 @@ BOOL FormatLargeFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterS | ||||||
| 	uprintf("Setting label..."); | 	uprintf("Setting label..."); | ||||||
| 	// Handle must be closed for SetVolumeLabel to work
 | 	// Handle must be closed for SetVolumeLabel to work
 | ||||||
| 	safe_closehandle(hLogicalVolume); | 	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))) { | 	if ((VolumeName == NULL) || (!SetVolumeLabelA(VolumeName, Label))) { | ||||||
| 		uprintf("Could not set label: %s", WindowsErrorString()); | 		uprintf("Could not set label: %s", WindowsErrorString()); | ||||||
| 		// Non fatal error
 | 		// Non fatal error
 | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | ||||||
| IDD_DIALOG DIALOGEX 12, 12, 232, 326 | IDD_DIALOG DIALOGEX 12, 12, 232, 326 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||||
| EXSTYLE WS_EX_ACCEPTFILES | EXSTYLE WS_EX_ACCEPTFILES | ||||||
| CAPTION "Rufus 3.18.1862" | CAPTION "Rufus 3.18.1863" | ||||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||||
| BEGIN | BEGIN | ||||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP |     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||||
|  | @ -395,8 +395,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 3,18,1862,0 |  FILEVERSION 3,18,1863,0 | ||||||
|  PRODUCTVERSION 3,18,1862,0 |  PRODUCTVERSION 3,18,1863,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -414,13 +414,13 @@ BEGIN | ||||||
|             VALUE "Comments", "https://rufus.ie" |             VALUE "Comments", "https://rufus.ie" | ||||||
|             VALUE "CompanyName", "Akeo Consulting" |             VALUE "CompanyName", "Akeo Consulting" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "3.18.1862" |             VALUE "FileVersion", "3.18.1863" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" |             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" | ||||||
|             VALUE "OriginalFilename", "rufus-3.18.exe" |             VALUE "OriginalFilename", "rufus-3.18.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "3.18.1862" |             VALUE "ProductVersion", "3.18.1863" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue