mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[misc] refactor partition creation
This commit is contained in:
		
							parent
							
								
									164d4b0ab0
								
							
						
					
					
						commit
						0f23c47184
					
				
					 6 changed files with 229 additions and 247 deletions
				
			
		
							
								
								
									
										318
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										318
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -74,7 +74,7 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryVolumeInformationFile, (HANDLE, PIO_STATUS_ | ||||||
| RUFUS_DRIVE_INFO SelectedDrive; | RUFUS_DRIVE_INFO SelectedDrive; | ||||||
| extern BOOL write_as_esp; | extern BOOL write_as_esp; | ||||||
| extern windows_version_t WindowsVersion; | extern windows_version_t WindowsVersion; | ||||||
| uint64_t partition_offset[PI_MAX]; | int partition_index[PI_MAX]; | ||||||
| uint64_t persistence_size = 0; | uint64_t persistence_size = 0; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -392,7 +392,7 @@ char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTr | ||||||
| 	if (PartitionOffset == 0) { | 	if (PartitionOffset == 0) { | ||||||
| 		i = 0; | 		i = 0; | ||||||
| 	} else if (matching_drive) { | 	} else if (matching_drive) { | ||||||
| 		for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.PartitionOffset[i]); i++); | 		for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.Partition[i].Offset); i++); | ||||||
| 		if (i >= MAX_PARTITIONS) { | 		if (i >= MAX_PARTITIONS) { | ||||||
| 			suprintf("Error: Could not find a partition at offset %lld on this disk", PartitionOffset); | 			suprintf("Error: Could not find a partition at offset %lld on this disk", PartitionOffset); | ||||||
| 			goto out; | 			goto out; | ||||||
|  | @ -428,11 +428,11 @@ char* GetExtPartitionName(DWORD DriveIndex, uint64_t PartitionOffset) | ||||||
| 	if (DriveIndex != SelectedDrive.DeviceNumber) | 	if (DriveIndex != SelectedDrive.DeviceNumber) | ||||||
| 		goto out; | 		goto out; | ||||||
| 	CheckDriveIndex(DriveIndex); | 	CheckDriveIndex(DriveIndex); | ||||||
| 	for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.PartitionOffset[i]); i++); | 	for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.Partition[i].Offset); i++); | ||||||
| 	if (i >= MAX_PARTITIONS) | 	if (i >= MAX_PARTITIONS) | ||||||
| 		goto out; | 		goto out; | ||||||
| 	static_sprintf(volume_name, "\\\\.\\PhysicalDrive%lu %I64u %I64u", DriveIndex, | 	static_sprintf(volume_name, "\\\\.\\PhysicalDrive%lu %I64u %I64u", DriveIndex, | ||||||
| 		SelectedDrive.PartitionOffset[i], SelectedDrive.PartitionSize[i]); | 		SelectedDrive.Partition[i].Offset, SelectedDrive.Partition[i].Size); | ||||||
| 	ret = safe_strdup(volume_name); | 	ret = safe_strdup(volume_name); | ||||||
| out: | out: | ||||||
| 	return ret; | 	return ret; | ||||||
|  | @ -1868,8 +1868,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 
 | 
 | ||||||
| 	SelectedDrive.nPartitions = 0; | 	SelectedDrive.nPartitions = 0; | ||||||
| 	memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset)); | 	memset(SelectedDrive.Partition, 0, sizeof(SelectedDrive.Partition)); | ||||||
| 	memset(SelectedDrive.PartitionSize, 0, sizeof(SelectedDrive.PartitionSize)); |  | ||||||
| 	// Populate the filesystem data
 | 	// Populate the filesystem data
 | ||||||
| 	FileSystemName[0] = 0; | 	FileSystemName[0] = 0; | ||||||
| 	volume_name = GetLogicalName(DriveIndex, 0, TRUE, FALSE); | 	volume_name = GetLogicalName(DriveIndex, 0, TRUE, FALSE); | ||||||
|  | @ -1961,8 +1960,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				if (i < MAX_PARTITIONS) { | 				if (i < MAX_PARTITIONS) { | ||||||
| 					SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | 					SelectedDrive.Partition[i].Offset = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | ||||||
| 					SelectedDrive.PartitionSize[i] = DriveLayout->PartitionEntry[i].PartitionLength.QuadPart; | 					SelectedDrive.Partition[i].Size = DriveLayout->PartitionEntry[i].PartitionLength.QuadPart; | ||||||
| 				} | 				} | ||||||
| 				suprintf("  Type: %s (0x%02x)\r\n  Detected File System: %s\r\n" | 				suprintf("  Type: %s (0x%02x)\r\n  Detected File System: %s\r\n" | ||||||
| 					"  Size: %s (%lld bytes)\r\n  Start Sector: %lld, Boot: %s", | 					"  Size: %s (%lld bytes)\r\n  Start Sector: %lld, Boot: %s", | ||||||
|  | @ -1992,8 +1991,9 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 			DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart); | 			DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart); | ||||||
| 		for (i = 0; i < DriveLayout->PartitionCount; i++) { | 		for (i = 0; i < DriveLayout->PartitionCount; i++) { | ||||||
| 			if (i < MAX_PARTITIONS) { | 			if (i < MAX_PARTITIONS) { | ||||||
| 				SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | 				SelectedDrive.Partition[i].Offset = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | ||||||
| 				SelectedDrive.PartitionSize[i] = DriveLayout->PartitionEntry[i].PartitionLength.QuadPart; | 				SelectedDrive.Partition[i].Size = DriveLayout->PartitionEntry[i].PartitionLength.QuadPart; | ||||||
|  | 				wcscpy(SelectedDrive.Partition[i].Name, DriveLayout->PartitionEntry[i].Gpt.Name); | ||||||
| 			} | 			} | ||||||
| 			SelectedDrive.nPartitions++; | 			SelectedDrive.nPartitions++; | ||||||
| 			isUefiNtfs = (wcscmp(DriveLayout->PartitionEntry[i].Gpt.Name, L"UEFI:NTFS") == 0); | 			isUefiNtfs = (wcscmp(DriveLayout->PartitionEntry[i].Gpt.Name, L"UEFI:NTFS") == 0); | ||||||
|  | @ -2232,15 +2232,17 @@ BOOL RemountVolume(char* drive_name, BOOL bSilent) | ||||||
|  * (especially IOCTL_DISK_UPDATE_PROPERTIES is *USELESS*), and therefore the OS will try to |  * (especially IOCTL_DISK_UPDATE_PROPERTIES is *USELESS*), and therefore the OS will try to | ||||||
|  * read the file system data at an old location, even if the partition has just been deleted. |  * read the file system data at an old location, even if the partition has just been deleted. | ||||||
|  */ |  */ | ||||||
| static BOOL ClearPartition(HANDLE hDrive, LARGE_INTEGER offset, DWORD size) | static BOOL ClearPartition(HANDLE hDrive, uint64_t offset, DWORD size) | ||||||
| { | { | ||||||
| 	BOOL r = FALSE; | 	BOOL r = FALSE; | ||||||
| 	uint8_t* buffer = calloc(size, 1); | 	uint8_t* buffer = calloc(size, 1); | ||||||
|  | 	LARGE_INTEGER li_offset; | ||||||
| 
 | 
 | ||||||
| 	if (buffer == NULL) | 	if (buffer == NULL) | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 
 | 
 | ||||||
| 	if (!SetFilePointerEx(hDrive, offset, NULL, FILE_BEGIN)) { | 	li_offset.QuadPart = offset; | ||||||
|  | 	if (!SetFilePointerEx(hDrive, li_offset, NULL, FILE_BEGIN)) { | ||||||
| 		free(buffer); | 		free(buffer); | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
|  | @ -2260,17 +2262,14 @@ static BOOL ClearPartition(HANDLE hDrive, LARGE_INTEGER offset, DWORD size) | ||||||
| BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions) | BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions) | ||||||
| { | { | ||||||
| 	const char* PartitionTypeName[] = { "MBR", "GPT", "SFD" }; | 	const char* PartitionTypeName[] = { "MBR", "GPT", "SFD" }; | ||||||
| 	const wchar_t *extra_part_name = L"", *main_part_name = write_as_esp ? L"EFI System Partition" : L"Main Data Partition"; |  | ||||||
| 	const LONGLONG main_part_size = write_as_esp ? MAX_ISO_TO_ESP_SIZE * MB : SelectedDrive.DiskSize; |  | ||||||
| 	const LONGLONG bytes_per_track = ((LONGLONG)SelectedDrive.SectorsPerTrack) * SelectedDrive.SectorSize; | 	const LONGLONG bytes_per_track = ((LONGLONG)SelectedDrive.SectorsPerTrack) * SelectedDrive.SectorSize; | ||||||
| 	const DWORD size_to_clear = MAX_SECTORS_TO_CLEAR * SelectedDrive.SectorSize; | 	const DWORD size_to_clear = MAX_SECTORS_TO_CLEAR * SelectedDrive.SectorSize; | ||||||
| 	uint8_t* buffer; | 	uint8_t* buffer; | ||||||
|  | 	uint64_t last_offset = SelectedDrive.DiskSize; | ||||||
| 	size_t uefi_ntfs_size = 0; | 	size_t uefi_ntfs_size = 0; | ||||||
|  | 	DWORD pi = 0, mi, i, size, bufsize; | ||||||
| 	CREATE_DISK CreateDisk = { PARTITION_STYLE_RAW, { { 0 } } }; | 	CREATE_DISK CreateDisk = { PARTITION_STYLE_RAW, { { 0 } } }; | ||||||
| 	DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = { 0 }; | 	DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = { 0 }; | ||||||
| 	BOOL r; |  | ||||||
| 	DWORD i, size, bufsize, pn = 0; |  | ||||||
| 	LONGLONG main_part_size_in_sectors, extra_part_size_in_tracks = 0; |  | ||||||
| 	// Go for a 260 MB sized ESP by default to keep everyone happy, including 4K sector users:
 | 	// Go for a 260 MB sized ESP by default to keep everyone happy, including 4K sector users:
 | ||||||
| 	// https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions
 | 	// https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions
 | ||||||
| 	// and folks using MacOS: https://github.com/pbatard/rufus/issues/979
 | 	// and folks using MacOS: https://github.com/pbatard/rufus/issues/979
 | ||||||
|  | @ -2288,17 +2287,19 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 
 | 
 | ||||||
| 	if (extra_partitions & XP_UEFI_NTFS) { | 	if (extra_partitions & XP_UEFI_NTFS) { | ||||||
| 		uefi_ntfs_size = GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA, "uefi-ntfs.img"); | 		uefi_ntfs_size = GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA, "uefi-ntfs.img"); | ||||||
| 		if (uefi_ntfs_size == 0) | 		if (uefi_ntfs_size == 0) { | ||||||
|  | 			uprintf("Could not access embedded 'uefi-ntfs.img'"); | ||||||
| 			return FALSE; | 			return FALSE; | ||||||
| 		} | 		} | ||||||
| 	memset(partition_offset, 0, sizeof(partition_offset)); | 	} | ||||||
| 	memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset)); |  | ||||||
| 	memset(SelectedDrive.PartitionSize, 0, sizeof(SelectedDrive.PartitionSize)); |  | ||||||
| 
 | 
 | ||||||
| 	// Compute the start offset of our first partition
 | 	memset(partition_index, 0, sizeof(partition_index)); | ||||||
|  | 	memset(SelectedDrive.Partition, 0, sizeof(SelectedDrive.Partition)); | ||||||
|  | 
 | ||||||
|  | 	// Compute the starting offset of the first partition
 | ||||||
| 	if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_OLD_BIOS_FIXES))) { | 	if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_OLD_BIOS_FIXES))) { | ||||||
| 		// Go with the MS 1 MB wastage at the beginning...
 | 		// Go with the MS 1 MB wastage at the beginning...
 | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = MB; | 		SelectedDrive.Partition[pi].Offset = 1 * MB; | ||||||
| 	} else { | 	} else { | ||||||
| 		// Some folks appear to think that 'Fixes for old BIOSes' is some kind of magic
 | 		// Some folks appear to think that 'Fixes for old BIOSes' is some kind of magic
 | ||||||
| 		// wand and are adamant to try to apply them when creating *MODERN* VHD drives.
 | 		// wand and are adamant to try to apply them when creating *MODERN* VHD drives.
 | ||||||
|  | @ -2308,11 +2309,10 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 		// CHS sizes that IBM imparted upon us. Long story short, we now align to a
 | 		// CHS sizes that IBM imparted upon us. Long story short, we now align to a
 | ||||||
| 		// cylinder size that is itself aligned to the cluster size.
 | 		// cylinder size that is itself aligned to the cluster size.
 | ||||||
| 		// If this actually breaks old systems, please send your complaints to IBM.
 | 		// If this actually breaks old systems, please send your complaints to IBM.
 | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = | 		SelectedDrive.Partition[pi].Offset = HI_ALIGN_X_TO_Y(bytes_per_track, ClusterSize); | ||||||
| 			((bytes_per_track + (ClusterSize - 1)) / ClusterSize) * ClusterSize; |  | ||||||
| 		// GRUB2 no longer fits in the usual 31½ KB that the above computation provides
 | 		// GRUB2 no longer fits in the usual 31½ KB that the above computation provides
 | ||||||
| 		// so just unconditionally double that size and get on with it.
 | 		// so just unconditionally double that size and get on with it.
 | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart *= 2; | 		SelectedDrive.Partition[pi].Offset *= 2; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Having the ESP up front may help (and is the Microsoft recommended way) but this
 | 	// Having the ESP up front may help (and is the Microsoft recommended way) but this
 | ||||||
|  | @ -2321,22 +2321,16 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 	if (((SelectedDrive.MediaType == FixedMedia) || (WindowsVersion.BuildNumber > 15000)) && | 	if (((SelectedDrive.MediaType == FixedMedia) || (WindowsVersion.BuildNumber > 15000)) && | ||||||
| 		(extra_partitions & XP_ESP)) { | 		(extra_partitions & XP_ESP)) { | ||||||
| 		assert(partition_style == PARTITION_STYLE_GPT); | 		assert(partition_style == PARTITION_STYLE_GPT); | ||||||
| 		extra_part_name = L"EFI System Partition"; | 		partition_index[PI_ESP] = pi; | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = esp_size; | 		wcscpy(SelectedDrive.Partition[pi].Name, L"EFI System Partition"); | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_GENERIC_ESP; | 		SelectedDrive.Partition[pi].Size = esp_size; | ||||||
| 		uprintf("● Creating %S (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart, | 		SelectedDrive.Partition[pi + 1].Offset = SelectedDrive.Partition[pi].Offset + SelectedDrive.Partition[pi].Size; | ||||||
| 			SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE)); | 		// Align next partition to track and cluster
 | ||||||
| 		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); | 		SelectedDrive.Partition[pi + 1].Offset = HI_ALIGN_X_TO_Y(SelectedDrive.Partition[pi + 1].Offset, bytes_per_track); | ||||||
| 		wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, extra_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name)); | 		if (ClusterSize % SelectedDrive.SectorSize == 0) | ||||||
| 		// Zero the first sectors from this partition to avoid file system caching issues
 | 			SelectedDrive.Partition[pi + 1].Offset = LO_ALIGN_X_TO_Y(SelectedDrive.Partition[pi + 1].Offset, ClusterSize); | ||||||
| 		if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear)) | 		assert(SelectedDrive.Partition[pi + 1].Offset >= SelectedDrive.Partition[pi].Offset + SelectedDrive.Partition[pi].Size); | ||||||
| 			uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString()); | 		pi++; | ||||||
| 		SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; |  | ||||||
| 		SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart; |  | ||||||
| 		partition_offset[PI_ESP] = SelectedDrive.PartitionOffset[pn]; |  | ||||||
| 		pn++; |  | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn - 1].StartingOffset.QuadPart + |  | ||||||
| 			DriveLayoutEx.PartitionEntry[pn - 1].PartitionLength.QuadPart; |  | ||||||
| 		// Clear the extra partition we processed
 | 		// Clear the extra partition we processed
 | ||||||
| 		extra_partitions &= ~(XP_ESP); | 		extra_partitions &= ~(XP_ESP); | ||||||
| 	} | 	} | ||||||
|  | @ -2344,175 +2338,157 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 	// If required, set the MSR partition (GPT only - must be created before the data part)
 | 	// If required, set the MSR partition (GPT only - must be created before the data part)
 | ||||||
| 	if (extra_partitions & XP_MSR) { | 	if (extra_partitions & XP_MSR) { | ||||||
| 		assert(partition_style == PARTITION_STYLE_GPT); | 		assert(partition_style == PARTITION_STYLE_GPT); | ||||||
| 		extra_part_name = L"Microsoft Reserved Partition"; | 		wcscpy(SelectedDrive.Partition[pi].Name, L"Microsoft Reserved Partition"); | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = 128*MB; | 		SelectedDrive.Partition[pi].Size = 128 * MB; | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MICROSOFT_RESERVED; | 		SelectedDrive.Partition[pi + 1].Offset = SelectedDrive.Partition[pi].Offset + SelectedDrive.Partition[pi].Size; | ||||||
| 		uprintf("● Creating %S (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart, | 		SelectedDrive.Partition[pi + 1].Offset = HI_ALIGN_X_TO_Y(SelectedDrive.Partition[pi + 1].Offset, bytes_per_track); | ||||||
| 			SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE)); | 		if (ClusterSize % SelectedDrive.SectorSize == 0) | ||||||
| 		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); | 			SelectedDrive.Partition[pi + 1].Offset = LO_ALIGN_X_TO_Y(SelectedDrive.Partition[pi + 1].Offset, ClusterSize); | ||||||
| 		wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, extra_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name)); | 		assert(SelectedDrive.Partition[pi + 1].Offset >= SelectedDrive.Partition[pi].Offset + SelectedDrive.Partition[pi].Size); | ||||||
| 		// Zero the first sectors from this partition to avoid file system caching issues
 | 		pi++; | ||||||
| 		if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear)) |  | ||||||
| 			uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString()); |  | ||||||
| 		SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; |  | ||||||
| 		SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart; |  | ||||||
| 		pn++; |  | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart + |  | ||||||
| 				DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; |  | ||||||
| 		// Clear the extra partition we processed
 |  | ||||||
| 		extra_partitions &= ~(XP_MSR); | 		extra_partitions &= ~(XP_MSR); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Set our main data partition
 | 	// Reserve an entry for the main partition
 | ||||||
| 	if (write_as_esp) { | 	partition_index[PI_MAIN] = pi++; | ||||||
| 		// Align ESP to 64 MB while leaving at least 32 MB free space
 | 	// Shorthand for the main index.
 | ||||||
| 		esp_size = max(esp_size, ((((LONGLONG)img_report.projected_size / MB) + 96) / 64) * 64 * MB); | 	mi = partition_index[PI_MAIN]; | ||||||
| 		main_part_size_in_sectors = (esp_size - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) / | 	wcscpy(SelectedDrive.Partition[mi].Name, write_as_esp ? L"EFI System Partition" : L"Main Data Partition"); | ||||||
| 			SelectedDrive.SectorSize; | 
 | ||||||
| 	} else { | 
 | ||||||
| 		main_part_size_in_sectors = (main_part_size - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) / |  | ||||||
| 			// Need 33 sectors at the end for secondary GPT
 |  | ||||||
| 			SelectedDrive.SectorSize - ((partition_style == PARTITION_STYLE_GPT) ? 33 : 0); |  | ||||||
| 	} |  | ||||||
| 	if (extra_partitions) { | 	if (extra_partitions) { | ||||||
| 		// Adjust the size according to extra partitions (which we always align to a track)
 | 		// Adjust the size according to extra partitions (which we always align to a track)
 | ||||||
| 		if (extra_partitions & XP_ESP) { | 		// TODO: Should we align these to cluster as well?
 | ||||||
| 			extra_part_name = L"EFI System"; | 		if (extra_partitions & XP_PERSISTENCE) { | ||||||
| 			extra_part_size_in_tracks = (esp_size + bytes_per_track - 1) / bytes_per_track; |  | ||||||
| 		} else if (extra_partitions & XP_UEFI_NTFS) { |  | ||||||
| 			extra_part_name = L"UEFI:NTFS"; |  | ||||||
| 			extra_part_size_in_tracks = (max(MIN_EXTRA_PART_SIZE, uefi_ntfs_size) + bytes_per_track - 1) / bytes_per_track; |  | ||||||
| 		} else if ((extra_partitions & XP_CASPER)) { |  | ||||||
| 			assert(persistence_size != 0); | 			assert(persistence_size != 0); | ||||||
| 			extra_part_name = L"Linux Persistence"; | 			partition_index[PI_CASPER] = pi; | ||||||
| 			extra_part_size_in_tracks = persistence_size / bytes_per_track; | 			wcscpy(SelectedDrive.Partition[pi].Name, L"Linux Persistence"); | ||||||
|  | 			SelectedDrive.Partition[pi++].Size = HI_ALIGN_X_TO_Y(persistence_size, bytes_per_track); | ||||||
|  | 		} | ||||||
|  | 		if (extra_partitions & XP_ESP) { | ||||||
|  | 			partition_index[PI_ESP] = pi; | ||||||
|  | 			wcscpy(SelectedDrive.Partition[pi].Name, L"EFI System Partition"); | ||||||
|  | 			SelectedDrive.Partition[pi++].Size = HI_ALIGN_X_TO_Y(esp_size, bytes_per_track); | ||||||
|  | 		} else if (extra_partitions & XP_UEFI_NTFS) { | ||||||
|  | 			partition_index[PI_UEFI_NTFS] = pi; | ||||||
|  | 			wcscpy(SelectedDrive.Partition[pi].Name, L"UEFI:NTFS"); | ||||||
|  | 			SelectedDrive.Partition[pi++].Size = HI_ALIGN_X_TO_Y(uefi_ntfs_size, bytes_per_track); | ||||||
| 		} else if (extra_partitions & XP_COMPAT) { | 		} else if (extra_partitions & XP_COMPAT) { | ||||||
| 			extra_part_name = L"BIOS Compatibility"; | 			wcscpy(SelectedDrive.Partition[pi].Name, L"BIOS Compatibility"); | ||||||
| 			extra_part_size_in_tracks = 1;	// One track for the extra partition
 | 			SelectedDrive.Partition[pi++].Size = bytes_per_track;	// One track for the extra partition
 | ||||||
| 		} else { |  | ||||||
| 			assert(FALSE); |  | ||||||
| 		} | 		} | ||||||
| 		// NB: Because we already subtracted the backup GPT size from the main partition size and
 | 		assert(pi <= MAX_PARTITIONS); | ||||||
| 		// this extra partition is indexed on main size, it does not overflow into the backup GPT.
 |  | ||||||
| 		main_part_size_in_sectors = ((main_part_size_in_sectors / SelectedDrive.SectorsPerTrack) - |  | ||||||
| 			extra_part_size_in_tracks) * SelectedDrive.SectorsPerTrack; |  | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	// Compute the offsets of the extra partitions (which we always align to a track)
 | ||||||
|  | 	last_offset = SelectedDrive.DiskSize; | ||||||
|  | 	if (partition_style == PARTITION_STYLE_GPT) | ||||||
|  | 		last_offset -= 33 * SelectedDrive.SectorSize; | ||||||
|  | 	for (i = pi - 1; i > mi; i--) { | ||||||
|  | 		assert(SelectedDrive.Partition[i].Size < last_offset); | ||||||
|  | 		SelectedDrive.Partition[i].Offset = LO_ALIGN_X_TO_Y(last_offset - SelectedDrive.Partition[i].Size, bytes_per_track); | ||||||
|  | 		last_offset = SelectedDrive.Partition[i].Offset; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// With the above, Compute the main partition size (which we align to a track)
 | ||||||
|  | 	assert(last_offset > SelectedDrive.Partition[mi].Offset); | ||||||
|  | 	SelectedDrive.Partition[mi].Size = LO_ALIGN_X_TO_Y(last_offset - SelectedDrive.Partition[mi].Offset, bytes_per_track); | ||||||
| 	// Try to make sure that the main partition size is a multiple of the cluster size
 | 	// Try to make sure that the main partition size is a multiple of the cluster size
 | ||||||
| 	// This can be especially important when trying to capture an NTFS partition as FFU, as, when
 | 	// This can be especially important when trying to capture an NTFS partition as FFU, as, when
 | ||||||
| 	// the NTFS partition is aligned to cluster size, the FFU capture parses the NTFS allocated
 | 	// the NTFS partition is aligned to cluster size, the FFU capture parses the NTFS allocated
 | ||||||
| 	// map to only record clusters that are in use, whereas, if not aligned, the FFU capture uses
 | 	// map to only record clusters that are in use, whereas, if not aligned, the FFU capture uses
 | ||||||
| 	// a full sector by sector scan of the NTFS partition and records any non-zero garbage, which
 | 	// a full sector by sector scan of the NTFS partition and records any non-zero garbage, which
 | ||||||
| 	// may include garbage leftover data from a previous reformat...
 | 	// may include garbage leftover data from a previous reformat...
 | ||||||
| 	if (ClusterSize % SelectedDrive.SectorSize == 0) { | 	if (ClusterSize % SelectedDrive.SectorSize == 0) | ||||||
| 		main_part_size_in_sectors = (((main_part_size_in_sectors * SelectedDrive.SectorSize) / | 		SelectedDrive.Partition[mi].Size = LO_ALIGN_X_TO_Y(SelectedDrive.Partition[mi].Size, ClusterSize); | ||||||
| 			ClusterSize) * ClusterSize) / SelectedDrive.SectorSize; | 	if (SelectedDrive.Partition[mi].Size <= 0) { | ||||||
| 	} | 		uprintf("Error: Invalid %S size", SelectedDrive.Partition[mi].Name); | ||||||
| 	if (main_part_size_in_sectors <= 0) { |  | ||||||
| 		uprintf("Error: Invalid %S size", main_part_name); |  | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
| 	uprintf("● Creating %S (offset: %lld, size: %s)", main_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart, |  | ||||||
| 		SizeToHumanReadable(main_part_size_in_sectors * SelectedDrive.SectorSize, TRUE, FALSE)); |  | ||||||
| 	// Zero the beginning of this partition to avoid conflicting leftovers
 |  | ||||||
| 	if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear)) |  | ||||||
| 		uprintf("Could not zero %S: %s", main_part_name, WindowsErrorString()); |  | ||||||
| 
 | 
 | ||||||
| 	DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = main_part_size_in_sectors * SelectedDrive.SectorSize; | 	// Build the DriveLayoutEx table
 | ||||||
|  | 	for (i = 0; i < pi; i++) { | ||||||
|  | 		uprintf("● Creating %S%s (offset: %lld, size: %s)", SelectedDrive.Partition[i].Name, | ||||||
|  | 			(wcsstr(SelectedDrive.Partition[i].Name, L"Partition") == NULL) ? " Partition" : "", | ||||||
|  | 			SelectedDrive.Partition[i].Offset, | ||||||
|  | 			SizeToHumanReadable(SelectedDrive.Partition[i].Size, TRUE, FALSE)); | ||||||
|  | 		// Zero the first sectors of the partition to avoid file system caching issues
 | ||||||
|  | 		if (!ClearPartition(hDrive, SelectedDrive.Partition[i].Offset, | ||||||
|  | 			(DWORD)MIN(size_to_clear, SelectedDrive.Partition[i].Size))) | ||||||
|  | 			uprintf("Could not zero %S: %s", SelectedDrive.Partition[i].Name, WindowsErrorString()); | ||||||
|  | 		DriveLayoutEx.PartitionEntry[i].PartitionStyle = partition_style; | ||||||
|  | 		DriveLayoutEx.PartitionEntry[i].StartingOffset.QuadPart = SelectedDrive.Partition[i].Offset; | ||||||
|  | 		DriveLayoutEx.PartitionEntry[i].PartitionLength.QuadPart = SelectedDrive.Partition[i].Size; | ||||||
|  | 		DriveLayoutEx.PartitionEntry[i].PartitionNumber = i + 1; | ||||||
|  | 		DriveLayoutEx.PartitionEntry[i].RewritePartition = TRUE; | ||||||
| 		if (partition_style == PARTITION_STYLE_MBR) { | 		if (partition_style == PARTITION_STYLE_MBR) { | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].Mbr.BootIndicator = (boot_type != BT_NON_BOOTABLE); | 			if (i == mi) { | ||||||
|  | 				DriveLayoutEx.PartitionEntry[i].Mbr.BootIndicator = (boot_type != BT_NON_BOOTABLE); | ||||||
| 				switch (file_system) { | 				switch (file_system) { | ||||||
| 				case FS_FAT16: | 				case FS_FAT16: | ||||||
| 			DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x0e;	// FAT16 LBA
 | 					DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x0e;	// FAT16 LBA
 | ||||||
| 					break; | 					break; | ||||||
| 				case FS_NTFS: | 				case FS_NTFS: | ||||||
| 				case FS_EXFAT: | 				case FS_EXFAT: | ||||||
| 				case FS_UDF: | 				case FS_UDF: | ||||||
| 				case FS_REFS: | 				case FS_REFS: | ||||||
| 			DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x07; | 					DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x07; | ||||||
| 					break; | 					break; | ||||||
| 				case FS_EXT2: | 				case FS_EXT2: | ||||||
| 				case FS_EXT3: | 				case FS_EXT3: | ||||||
| 				case FS_EXT4: | 				case FS_EXT4: | ||||||
| 			DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x83; | 					DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x83; | ||||||
| 					break; | 					break; | ||||||
| 				case FS_FAT32: | 				case FS_FAT32: | ||||||
| 			DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x0c;	// FAT32 LBA
 | 					DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x0c;	// FAT32 LBA
 | ||||||
| 					break; | 					break; | ||||||
| 				default: | 				default: | ||||||
| 					uprintf("Unsupported file system"); | 					uprintf("Unsupported file system"); | ||||||
| 					return FALSE; | 					return FALSE; | ||||||
| 				} | 				} | ||||||
| 	} else { |  | ||||||
| 		if (write_as_esp) |  | ||||||
| 			DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_GENERIC_ESP; |  | ||||||
| 		else if (IS_EXT(file_system)) |  | ||||||
| 			DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_LINUX_DATA; |  | ||||||
| 		else |  | ||||||
| 			DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MICROSOFT_DATA; |  | ||||||
| 		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); |  | ||||||
| 		wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, main_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name)); |  | ||||||
| 			} | 			} | ||||||
| 	SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; | 			// May override the the type of main partition if write_as_esp is active
 | ||||||
| 	SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart; | 			if ((wcscmp(SelectedDrive.Partition[i].Name, L"EFI System Partition") == 0) || | ||||||
| 	partition_offset[PI_MAIN] = SelectedDrive.PartitionOffset[pn]; | 				(wcscmp(SelectedDrive.Partition[i].Name, L"UEFI:NTFS") == 0)) | ||||||
| 	pn++; | 				DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0xef; | ||||||
| 
 | 			else if (wcscmp(SelectedDrive.Partition[i].Name, L"Linux Persistence") == 0) | ||||||
| 	// Set the optional extra partition
 | 				DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x83; | ||||||
| 	if (extra_partitions) { | 			else if (wcscmp(SelectedDrive.Partition[i].Name, L"BIOS Compatibility") == 0) | ||||||
| 		// Should end on a track boundary
 | 				DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = RUFUS_EXTRA_PARTITION_TYPE; | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart + | 		} else { | ||||||
| 			DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; | 			assert(partition_style == PARTITION_STYLE_GPT); | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = (extra_partitions & XP_UEFI_NTFS) ? uefi_ntfs_size : | 			if (wcscmp(SelectedDrive.Partition[i].Name, L"UEFI:NTFS") == 0) { | ||||||
| 			extra_part_size_in_tracks * bytes_per_track; | 				DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_GENERIC_ESP; | ||||||
| 		uprintf("● Creating %S Partition (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart, |  | ||||||
| 			SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE)); |  | ||||||
| 		SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; |  | ||||||
| 		SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart; |  | ||||||
| 		if (extra_partitions & XP_CASPER) |  | ||||||
| 			partition_offset[PI_CASPER] = SelectedDrive.PartitionOffset[pn]; |  | ||||||
| 		else if (extra_partitions & XP_ESP) |  | ||||||
| 			partition_offset[PI_ESP] = SelectedDrive.PartitionOffset[pn]; |  | ||||||
| 
 |  | ||||||
| 		if (partition_style == PARTITION_STYLE_GPT) { |  | ||||||
| 			if (extra_partitions & XP_ESP) |  | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_GENERIC_ESP; |  | ||||||
| 			else if (extra_partitions & XP_CASPER) |  | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_LINUX_DATA; |  | ||||||
| 			else |  | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MICROSOFT_DATA; |  | ||||||
| 			if (extra_partitions & XP_UEFI_NTFS) { |  | ||||||
| 				// Prevent a drive letter from being assigned to the UEFI:NTFS partition
 | 				// Prevent a drive letter from being assigned to the UEFI:NTFS partition
 | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Gpt.Attributes = GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER; | 				DriveLayoutEx.PartitionEntry[i].Gpt.Attributes = GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER; | ||||||
| #if !defined(_DEBUG) | #if !defined(_DEBUG) | ||||||
| 				// Also make the partition read-only for release versions
 | 				// Also make the partition read-only for release versions
 | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Gpt.Attributes += GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY; | 				DriveLayoutEx.PartitionEntry[i].Gpt.Attributes += GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY; | ||||||
| #endif | #endif | ||||||
| 			} | 			} else if (wcscmp(SelectedDrive.Partition[i].Name, L"EFI System Partition") == 0) | ||||||
| 			IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); | 				DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_GENERIC_ESP; | ||||||
| 			wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, (extra_partitions & XP_ESP) ? L"EFI System Partition" : extra_part_name, | 			else if (wcscmp(SelectedDrive.Partition[i].Name, L"Linux Persistence") == 0) | ||||||
| 				ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name)); | 				DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_LINUX_DATA; | ||||||
| 		} else { | 			else if (wcscmp(SelectedDrive.Partition[i].Name, L"Microsoft Reserved Partition") == 0) | ||||||
| 			if (extra_partitions & (XP_UEFI_NTFS | XP_ESP)) { | 				DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_MICROSOFT_RESERVED; | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0xef; | 			else | ||||||
| 			} else if (extra_partitions & XP_CASPER) { | 				DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_MICROSOFT_DATA; | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x83; | 			IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[i].Gpt.PartitionId)); | ||||||
| 			} else if (extra_partitions & XP_COMPAT) { | 			wcscpy(DriveLayoutEx.PartitionEntry[i].Gpt.Name, SelectedDrive.Partition[i].Name); | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = RUFUS_EXTRA_PARTITION_TYPE; |  | ||||||
| 				// Set the one track compatibility partition to be all hidden sectors
 |  | ||||||
| 				DriveLayoutEx.PartitionEntry[pn].Mbr.HiddenSectors = SelectedDrive.SectorsPerTrack; |  | ||||||
| 			} else { |  | ||||||
| 				assert(FALSE); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// We need to write the UEFI:NTFS partition before we refresh the disk
 | 	// We need to write the UEFI:NTFS partition before we refresh the disk
 | ||||||
| 	if (extra_partitions & XP_UEFI_NTFS) { | 	if (extra_partitions & XP_UEFI_NTFS) { | ||||||
| 			uprintf("Writing %S data...", extra_part_name); | 		LARGE_INTEGER li; | ||||||
| 			if (!SetFilePointerEx(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, NULL, FILE_BEGIN)) { | 		uprintf("Writing UEFI:NTFS data...", SelectedDrive.Partition[partition_index[PI_UEFI_NTFS]].Name); | ||||||
|  | 		li.QuadPart = SelectedDrive.Partition[partition_index[PI_UEFI_NTFS]].Offset; | ||||||
|  | 		if (!SetFilePointerEx(hDrive, li, NULL, FILE_BEGIN)) { | ||||||
| 			uprintf("  Could not set position"); | 			uprintf("  Could not set position"); | ||||||
| 			return FALSE; | 			return FALSE; | ||||||
| 		} | 		} | ||||||
| 			buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA, "uefi-ntfs.img", &bufsize, FALSE); | 		buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA, | ||||||
|  | 			"uefi-ntfs.img", &bufsize, FALSE); | ||||||
| 		if (buffer == NULL) { | 		if (buffer == NULL) { | ||||||
| 			uprintf("  Could not access source image"); | 			uprintf("  Could not access source image"); | ||||||
| 			return FALSE; | 			return FALSE; | ||||||
|  | @ -2522,15 +2498,6 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 			return FALSE; | 			return FALSE; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 		pn++; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Initialize the remaining partition data
 |  | ||||||
| 	for (i = 0; i < pn; i++) { |  | ||||||
| 		DriveLayoutEx.PartitionEntry[i].PartitionNumber = i + 1; |  | ||||||
| 		DriveLayoutEx.PartitionEntry[i].PartitionStyle = partition_style; |  | ||||||
| 		DriveLayoutEx.PartitionEntry[i].RewritePartition = TRUE; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	switch (partition_style) { | 	switch (partition_style) { | ||||||
| 	case PARTITION_STYLE_MBR: | 	case PARTITION_STYLE_MBR: | ||||||
|  | @ -2558,7 +2525,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 		CreateDisk.Gpt.MaxPartitionCount = MAX_PARTITIONS; | 		CreateDisk.Gpt.MaxPartitionCount = MAX_PARTITIONS; | ||||||
| 
 | 
 | ||||||
| 		DriveLayoutEx.PartitionStyle = PARTITION_STYLE_GPT; | 		DriveLayoutEx.PartitionStyle = PARTITION_STYLE_GPT; | ||||||
| 		DriveLayoutEx.PartitionCount = pn; | 		DriveLayoutEx.PartitionCount = pi; | ||||||
| 		// At the very least, a GPT disk has 34 reserved sectors at the beginning and 33 at the end.
 | 		// At the very least, a GPT disk has 34 reserved sectors at the beginning and 33 at the end.
 | ||||||
| 		DriveLayoutEx.Type.Gpt.StartingUsableOffset.QuadPart = 34 * SelectedDrive.SectorSize; | 		DriveLayoutEx.Type.Gpt.StartingUsableOffset.QuadPart = 34 * SelectedDrive.SectorSize; | ||||||
| 		DriveLayoutEx.Type.Gpt.UsableLength.QuadPart = SelectedDrive.DiskSize - (34+33) * SelectedDrive.SectorSize; | 		DriveLayoutEx.Type.Gpt.UsableLength.QuadPart = SelectedDrive.DiskSize - (34+33) * SelectedDrive.SectorSize; | ||||||
|  | @ -2569,8 +2536,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 
 | 
 | ||||||
| 	// If you don't call IOCTL_DISK_CREATE_DISK, the IOCTL_DISK_SET_DRIVE_LAYOUT_EX call will fail
 | 	// If you don't call IOCTL_DISK_CREATE_DISK, the IOCTL_DISK_SET_DRIVE_LAYOUT_EX call will fail
 | ||||||
| 	size = sizeof(CreateDisk); | 	size = sizeof(CreateDisk); | ||||||
| 	r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK, (BYTE*)&CreateDisk, size, NULL, 0, &size, NULL); | 	if (!DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK, (BYTE*)&CreateDisk, size, NULL, 0, &size, NULL)) { | ||||||
| 	if (!r) { |  | ||||||
| 		uprintf("Could not reset disk: %s", WindowsErrorString()); | 		uprintf("Could not reset disk: %s", WindowsErrorString()); | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
|  | @ -2578,9 +2544,9 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 	// "The goggles, they do nothing!"
 | 	// "The goggles, they do nothing!"
 | ||||||
| 	RefreshDriveLayout(hDrive); | 	RefreshDriveLayout(hDrive); | ||||||
| 
 | 
 | ||||||
| 	size = sizeof(DriveLayoutEx) - ((partition_style == PARTITION_STYLE_GPT)?((4-pn)*sizeof(PARTITION_INFORMATION_EX)):0); | 	size = sizeof(DriveLayoutEx) - ((partition_style == PARTITION_STYLE_GPT) ? | ||||||
| 	r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, (BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL); | 		((4 - pi) * sizeof(PARTITION_INFORMATION_EX)) : 0); | ||||||
| 	if (!r) { | 	if (!DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, (BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL)) { | ||||||
| 		uprintf("Could not set drive layout: %s", WindowsErrorString()); | 		uprintf("Could not set drive layout: %s", WindowsErrorString()); | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								src/drive.h
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/drive.h
									
										
									
									
									
								
							|  | @ -36,12 +36,13 @@ | ||||||
| #define XP_ESP                              0x02 | #define XP_ESP                              0x02 | ||||||
| #define XP_UEFI_NTFS                        0x04 | #define XP_UEFI_NTFS                        0x04 | ||||||
| #define XP_COMPAT                           0x08 | #define XP_COMPAT                           0x08 | ||||||
| #define XP_CASPER                           0x10 | #define XP_PERSISTENCE                      0x10 | ||||||
| 
 | 
 | ||||||
| #define PI_MAIN                             0 | #define PI_MAIN                             0 | ||||||
| #define PI_ESP                              1 | #define PI_ESP                              1 | ||||||
| #define PI_CASPER                           2 | #define PI_CASPER                           2 | ||||||
| #define PI_MAX                              3 | #define PI_UEFI_NTFS                        3 | ||||||
|  | #define PI_MAX                              4 | ||||||
| 
 | 
 | ||||||
| // The following should match VDS_FSOF_FLAGS as much as possible
 | // The following should match VDS_FSOF_FLAGS as much as possible
 | ||||||
| #define FP_FORCE                            0x00000001 | #define FP_FORCE                            0x00000001 | ||||||
|  | @ -362,8 +363,11 @@ typedef struct { | ||||||
| 	MEDIA_TYPE MediaType; | 	MEDIA_TYPE MediaType; | ||||||
| 	int PartitionStyle; | 	int PartitionStyle; | ||||||
| 	int nPartitions;	// number of partitions we actually care about
 | 	int nPartitions;	// number of partitions we actually care about
 | ||||||
| 	uint64_t PartitionOffset[MAX_PARTITIONS]; | 	struct { | ||||||
| 	uint64_t PartitionSize[MAX_PARTITIONS]; | 		wchar_t Name[36]; | ||||||
|  | 		uint64_t Offset; | ||||||
|  | 		uint64_t Size; | ||||||
|  | 	} Partition[MAX_PARTITIONS]; | ||||||
| 	int FSType; | 	int FSType; | ||||||
| 	char proposed_label[16]; | 	char proposed_label[16]; | ||||||
| 	BOOL has_protective_mbr; | 	BOOL has_protective_mbr; | ||||||
|  | @ -374,7 +378,7 @@ typedef struct { | ||||||
| 	} ClusterSize[FS_MAX]; | 	} ClusterSize[FS_MAX]; | ||||||
| } RUFUS_DRIVE_INFO; | } RUFUS_DRIVE_INFO; | ||||||
| extern RUFUS_DRIVE_INFO SelectedDrive; | extern RUFUS_DRIVE_INFO SelectedDrive; | ||||||
| extern uint64_t partition_offset[PI_MAX]; | extern int partition_index[PI_MAX]; | ||||||
| 
 | 
 | ||||||
| BOOL SetAutoMount(BOOL enable); | BOOL SetAutoMount(BOOL enable); | ||||||
| BOOL GetAutoMount(BOOL* enabled); | BOOL GetAutoMount(BOOL* enabled); | ||||||
|  |  | ||||||
							
								
								
									
										51
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										51
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -972,7 +972,7 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Ensure that we have sufficient space for the SBR
 | 	// Ensure that we have sufficient space for the SBR
 | ||||||
| 	max_size = (DWORD)SelectedDrive.PartitionOffset[0]; | 	max_size = (DWORD)SelectedDrive.Partition[0].Offset; | ||||||
| 	if (br_size + size > max_size) { | 	if (br_size + size > max_size) { | ||||||
| 		uprintf("  SBR size is too large - You may need to uncheck 'Add fixes for old BIOSes'."); | 		uprintf("  SBR size is too large - You may need to uncheck 'Add fixes for old BIOSes'."); | ||||||
| 		if (sub_type == BT_MAX) | 		if (sub_type == BT_MAX) | ||||||
|  | @ -1456,23 +1456,32 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	large_drive = (SelectedDrive.DiskSize > (1*TB)); | 	large_drive = (SelectedDrive.DiskSize > (1*TB)); | ||||||
| 	if (large_drive) | 	if (large_drive) | ||||||
| 		uprintf("Notice: Large drive detected (may produce short writes)"); | 		uprintf("Notice: Large drive detected (may produce short writes)"); | ||||||
|  | 
 | ||||||
| 	// Find out if we need to add any extra partitions
 | 	// Find out if we need to add any extra partitions
 | ||||||
| 	if ((windows_to_go) && (target_type == TT_UEFI) && (partition_type == PARTITION_STYLE_GPT)) | 	extra_partitions = 0; | ||||||
|  | 	if ((boot_type == BT_IMAGE) && !write_as_image && HAS_PERSISTENCE(img_report) && persistence_size) | ||||||
|  | 		extra_partitions |= XP_PERSISTENCE; | ||||||
| 	// According to Microsoft, every GPT disk (we RUN Windows from) must have an MSR due to not having hidden sectors
 | 	// According to Microsoft, every GPT disk (we RUN Windows from) must have an MSR due to not having hidden sectors
 | ||||||
| 	// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-and-gpt-faq#disks-that-require-an-msr
 | 	// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-and-gpt-faq#disks-that-require-an-msr
 | ||||||
| 		extra_partitions = XP_ESP | XP_MSR; | 	if ((windows_to_go) && (target_type == TT_UEFI) && (partition_type == PARTITION_STYLE_GPT)) | ||||||
| 	else if ( ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) && | 		extra_partitions |= XP_ESP | XP_MSR; | ||||||
| 			  ((boot_type == BT_UEFI_NTFS) || ((boot_type == BT_IMAGE) && IS_EFI_BOOTABLE(img_report) && | 	// If we have a bootable image with UEFI bootloaders and the target file system is NTFS or exFAT
 | ||||||
| 			   ((target_type == TT_UEFI) || (windows_to_go) || (allow_dual_uefi_bios) || | 	// or the UEFI:NTFS option is selected, we add the UEFI:NTFS partition...
 | ||||||
| 			   (img_report.has_4GB_file) || (img_report.needs_ntfs)))) ) | 	else if (((boot_type == BT_IMAGE) && IS_EFI_BOOTABLE(img_report)) && ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) || | ||||||
| 		extra_partitions = XP_UEFI_NTFS; | 			 (boot_type == BT_UEFI_NTFS)) { | ||||||
| 	else if ((boot_type == BT_IMAGE) && !write_as_image && HAS_PERSISTENCE(img_report) && persistence_size) | 		extra_partitions |= XP_UEFI_NTFS; | ||||||
| 		extra_partitions = XP_CASPER; | 		// ...but only if we're not dealing with a Windows image in installer mode with target
 | ||||||
| 	else if (IsChecked(IDC_OLD_BIOS_FIXES)) | 		//  system set to BIOS and without dual BIOS+UEFI boot enabled.
 | ||||||
| 		extra_partitions = XP_COMPAT; | 		if ((boot_type == BT_IMAGE) && HAS_BOOTMGR_BIOS(img_report) && (!windows_to_go) && | ||||||
|  | 			(target_type == TT_BIOS) && (!allow_dual_uefi_bios)) | ||||||
|  | 			extra_partitions &= ~XP_UEFI_NTFS; | ||||||
|  | 	} | ||||||
|  | 	if (IsChecked(IDC_OLD_BIOS_FIXES)) | ||||||
|  | 		extra_partitions |= XP_COMPAT; | ||||||
|  | 
 | ||||||
| 	// On pre 1703 platforms (and even on later ones), anything with ext2/ext3 doesn't sit
 | 	// On pre 1703 platforms (and even on later ones), anything with ext2/ext3 doesn't sit
 | ||||||
| 	// too well with Windows. Same with ESPs. Relaxing our locking rules seems to help...
 | 	// too well with Windows. Same with ESPs. Relaxing our locking rules seems to help...
 | ||||||
| 	if ((extra_partitions & (XP_ESP | XP_CASPER)) || IS_EXT(fs_type)) | 	if ((extra_partitions & (XP_ESP | XP_PERSISTENCE)) || IS_EXT(fs_type)) | ||||||
| 		actual_lock_drive = FALSE; | 		actual_lock_drive = FALSE; | ||||||
| 	// Windows 11 is a lot more proactive in locking ESPs and MSRs than previous versions
 | 	// Windows 11 is a lot more proactive in locking ESPs and MSRs than previous versions
 | ||||||
| 	// were, meaning that we also can't lock the drive without incurring errors...
 | 	// were, meaning that we also can't lock the drive without incurring errors...
 | ||||||
|  | @ -1710,13 +1719,13 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	Sleep(200); | 	Sleep(200); | ||||||
| 	if (write_as_esp || write_as_ext) { | 	if (write_as_esp || write_as_ext) { | ||||||
| 		// Can't format ESPs or ext2/ext3 partitions unless we mount them ourselves
 | 		// Can't format ESPs or ext2/ext3 partitions unless we mount them ourselves
 | ||||||
| 		volume_name = AltMountVolume(DriveIndex, partition_offset[PI_MAIN], FALSE); | 		volume_name = AltMountVolume(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, FALSE); | ||||||
| 		if (volume_name == NULL) { | 		if (volume_name == NULL) { | ||||||
| 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER); | 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER); | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		if (!WaitForLogical(DriveIndex, partition_offset[PI_MAIN])) { | 		if (!WaitForLogical(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset)) { | ||||||
| 			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; | ||||||
|  | @ -1727,12 +1736,12 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 
 | 
 | ||||||
| 	// Format Casper partition if required. Do it before we format anything with
 | 	// Format Casper partition if required. Do it before we format anything with
 | ||||||
| 	// a file system that Windows will recognize, to avoid concurrent access.
 | 	// a file system that Windows will recognize, to avoid concurrent access.
 | ||||||
| 	if (extra_partitions & XP_CASPER) { | 	if (extra_partitions & XP_PERSISTENCE) { | ||||||
| 		uint32_t ext_version = ReadSetting32(SETTING_USE_EXT_VERSION); | 		uint32_t ext_version = ReadSetting32(SETTING_USE_EXT_VERSION); | ||||||
| 		if ((ext_version < 2) || (ext_version > 4)) | 		if ((ext_version < 2) || (ext_version > 4)) | ||||||
| 			ext_version = 3; | 			ext_version = 3; | ||||||
| 		uprintf("Using %s-like method to enable persistence", img_report.uses_casper ? "Ubuntu" : "Debian"); | 		uprintf("Using %s-like method to enable persistence", img_report.uses_casper ? "Ubuntu" : "Debian"); | ||||||
| 		if (!FormatPartition(DriveIndex, partition_offset[PI_CASPER], 0, FS_EXT2 + (ext_version - 2), | 		if (!FormatPartition(DriveIndex, SelectedDrive.Partition[partition_index[PI_CASPER]].Offset, 0, FS_EXT2 + (ext_version - 2), | ||||||
| 			img_report.uses_casper ? "casper-rw" : "persistence", | 			img_report.uses_casper ? "casper-rw" : "persistence", | ||||||
| 			(img_report.uses_casper ? 0 : FP_CREATE_PERSISTENCE_CONF) | | 			(img_report.uses_casper ? 0 : FP_CREATE_PERSISTENCE_CONF) | | ||||||
| 			(IsChecked(IDC_QUICK_FORMAT) ? FP_QUICK : 0))) { | 			(IsChecked(IDC_QUICK_FORMAT) ? FP_QUICK : 0))) { | ||||||
|  | @ -1757,7 +1766,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	if (write_as_esp) | 	if (write_as_esp) | ||||||
| 		Flags |= FP_LARGE_FAT32; | 		Flags |= FP_LARGE_FAT32; | ||||||
| 
 | 
 | ||||||
| 	ret = FormatPartition(DriveIndex, partition_offset[PI_MAIN], ClusterSize, fs_type, label, Flags); | 	ret = FormatPartition(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, ClusterSize, fs_type, label, Flags); | ||||||
| 	if (!ret) { | 	if (!ret) { | ||||||
| 		// Error will be set by FormatPartition() in FormatStatus
 | 		// Error will be set by FormatPartition() in FormatStatus
 | ||||||
| 		uprintf("Format error: %s", StrError(FormatStatus, TRUE)); | 		uprintf("Format error: %s", StrError(FormatStatus, TRUE)); | ||||||
|  | @ -1790,7 +1799,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		// Try to continue
 | 		// Try to continue
 | ||||||
| 		CHECK_FOR_USER_CANCEL; | 		CHECK_FOR_USER_CANCEL; | ||||||
| 
 | 
 | ||||||
| 		volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE); | 		volume_name = GetLogicalName(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, 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; | ||||||
|  | @ -1848,7 +1857,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		} else { | 		} else { | ||||||
| 			// We still have a lock, which we need to modify the volume boot record
 | 			// We still have a lock, which we need to modify the volume boot record
 | ||||||
| 			// => no need to reacquire the lock...
 | 			// => no need to reacquire the lock...
 | ||||||
| 			hLogicalVolume = GetLogicalHandle(DriveIndex, partition_offset[PI_MAIN], FALSE, TRUE, FALSE); | 			hLogicalVolume = GetLogicalHandle(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, FALSE, TRUE, FALSE); | ||||||
| 			if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) { | 			if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) { | ||||||
| 				uprintf("Could not re-mount volume for partition boot record access"); | 				uprintf("Could not re-mount volume for partition boot record access"); | ||||||
| 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||||
|  | @ -1999,7 +2008,7 @@ out: | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (IS_ERROR(FormatStatus)) { | 	if (IS_ERROR(FormatStatus)) { | ||||||
| 		volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE); | 		volume_name = GetLogicalName(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, TRUE, TRUE); | ||||||
| 		if (volume_name != NULL) { | 		if (volume_name != NULL) { | ||||||
| 			if (MountVolume(drive_name, volume_name)) | 			if (MountVolume(drive_name, volume_name)) | ||||||
| 				uprintf("Re-mounted volume as %c: after error", toupper(drive_name[0])); | 				uprintf("Re-mounted volume as %c: after error", toupper(drive_name[0])); | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
| * Rufus: The Reliable USB Formatting Utility | * Rufus: The Reliable USB Formatting Utility | ||||||
| * Constants and defines missing from various toolchains | * Constants and defines missing from various toolchains | ||||||
| * Copyright © 2016-2022 Pete Batard <pete@akeo.ie> | * Copyright © 2016-2024 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 | ||||||
|  | @ -31,6 +31,9 @@ | ||||||
| #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #define LO_ALIGN_X_TO_Y(x, y) (((x) / (y)) * (y)) | ||||||
|  | #define HI_ALIGN_X_TO_Y(x, y) ((((x) + (y) - 1) / (y)) * (y)) | ||||||
|  | 
 | ||||||
| #if defined(__GNUC__) | #if defined(__GNUC__) | ||||||
| #define ALIGNED(m) __attribute__ ((__aligned__(m))) | #define ALIGNED(m) __attribute__ ((__aligned__(m))) | ||||||
| #elif defined(_MSC_VER) | #elif defined(_MSC_VER) | ||||||
|  |  | ||||||
							
								
								
									
										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 4.5.2109" | CAPTION "Rufus 4.5.2110" | ||||||
| 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 | ||||||
|  | @ -392,8 +392,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 4,5,2109,0 |  FILEVERSION 4,5,2110,0 | ||||||
|  PRODUCTVERSION 4,5,2109,0 |  PRODUCTVERSION 4,5,2110,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -411,13 +411,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", "4.5.2109" |             VALUE "FileVersion", "4.5.2110" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2024 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-4.5.exe" |             VALUE "OriginalFilename", "rufus-4.5.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "4.5.2109" |             VALUE "ProductVersion", "4.5.2110" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Rufus: The Reliable USB Formatting Utility |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  * Windows User Experience |  * Windows User Experience | ||||||
|  * Copyright © 2022-2023 Pete Batard <pete@akeo.ie> |  * Copyright © 2022-2024 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 | ||||||
|  | @ -690,14 +690,14 @@ BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp) | ||||||
| 		// VDS cannot list ESP volumes (talk about allegedly improving on the old disk and volume APIs, only to
 | 		// VDS cannot list ESP volumes (talk about allegedly improving on the old disk and volume APIs, only to
 | ||||||
| 		// completely neuter it) and IVdsDiskPartitionMF::FormatPartitionEx(), which is what you are supposed to
 | 		// completely neuter it) and IVdsDiskPartitionMF::FormatPartitionEx(), which is what you are supposed to
 | ||||||
| 		// use for ESPs, explicitly states: "This method cannot be used to format removable media."
 | 		// use for ESPs, explicitly states: "This method cannot be used to format removable media."
 | ||||||
| 		if (!FormatPartition(DriveIndex, partition_offset[PI_ESP], cluster_size, FS_FAT32, "", | 		if (!FormatPartition(DriveIndex, SelectedDrive.Partition[partition_index[PI_ESP]].Offset, cluster_size, FS_FAT32, "", | ||||||
| 			FP_QUICK | FP_FORCE | FP_LARGE_FAT32 | FP_NO_BOOT)) { | 			FP_QUICK | FP_FORCE | FP_LARGE_FAT32 | FP_NO_BOOT)) { | ||||||
| 			uprintf("Could not format EFI System Partition"); | 			uprintf("Could not format EFI System Partition"); | ||||||
| 			return FALSE; | 			return FALSE; | ||||||
| 		} | 		} | ||||||
| 		Sleep(200); | 		Sleep(200); | ||||||
| 		// Need to have the ESP mounted to invoke bcdboot
 | 		// Need to have the ESP mounted to invoke bcdboot
 | ||||||
| 		ms_efi = AltMountVolume(DriveIndex, partition_offset[PI_ESP], FALSE); | 		ms_efi = AltMountVolume(DriveIndex, SelectedDrive.Partition[partition_index[PI_ESP]].Offset, FALSE); | ||||||
| 		if (ms_efi == NULL) { | 		if (ms_efi == NULL) { | ||||||
| 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER); | 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER); | ||||||
| 			return FALSE; | 			return FALSE; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue