mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] use offset rather than index to identify a partition
* Also fix potential bcdboot invocation failure by introducing a new AltGetLogicalName() call. * Also use the AltMount calls for ext# formatting
This commit is contained in:
		
							parent
							
								
									1fa0aaf325
								
							
						
					
					
						commit
						94e2015edf
					
				
					 4 changed files with 133 additions and 112 deletions
				
			
		
							
								
								
									
										156
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										156
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -86,7 +86,7 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryVolumeInformationFile, (HANDLE, PIO_STATUS_ | ||||||
|  */ |  */ | ||||||
| RUFUS_DRIVE_INFO SelectedDrive; | RUFUS_DRIVE_INFO SelectedDrive; | ||||||
| BOOL installed_uefi_ntfs; | BOOL installed_uefi_ntfs; | ||||||
| DWORD partition_index[3]; | uint64_t partition_offset[3]; | ||||||
| uint64_t persistence_size = 0; | uint64_t persistence_size = 0; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -245,22 +245,18 @@ out: | ||||||
| /*
 | /*
 | ||||||
|  * Return the path to access a partition on a specific disk, or NULL on error. |  * Return the path to access a partition on a specific disk, or NULL on error. | ||||||
|  * The string is allocated and must be freed (to ensure concurrent access) |  * The string is allocated and must be freed (to ensure concurrent access) | ||||||
|  |  * If PartitionOffset is 0, the offset is ignored and the first partition found is returned. | ||||||
|  */ |  */ | ||||||
| char* GetPartitionName(DWORD DriveIndex, DWORD PartitionIndex) | char* GetPartitionName(DWORD DriveIndex, uint64_t PartitionOffset) | ||||||
| { | { | ||||||
| 	BOOL success = FALSE; |  | ||||||
| 	char partition_name[32]; | 	char partition_name[32]; | ||||||
|  | 	DWORD i = MAX_PARTITIONS + 1; | ||||||
| 
 | 
 | ||||||
| 	CheckDriveIndex(DriveIndex); | 	CheckDriveIndex(DriveIndex); | ||||||
| 	if (PartitionIndex >= MAX_PARTITIONS) | 	for (i = 1; (i <= MAX_PARTITIONS) && (PartitionOffset != 0) && (SelectedDrive.PartitionOffset[i - 1] != PartitionOffset); i++); | ||||||
| 		goto out; | 	static_sprintf(partition_name, "\\Device\\Harddisk%lu\\Partition%lu", DriveIndex, i); | ||||||
| 	if (PartitionIndex == 0) |  | ||||||
| 		PartitionIndex = 1; |  | ||||||
| 	 |  | ||||||
| 	static_sprintf(partition_name, "\\Device\\Harddisk%lu\\Partition%lu", DriveIndex, PartitionIndex); |  | ||||||
| 	success = TRUE; |  | ||||||
| out: | out: | ||||||
| 	return (success) ? safe_strdup(partition_name) : NULL; | 	return (i <= MAX_PARTITIONS) ? safe_strdup(partition_name) : NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -278,11 +274,10 @@ HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, B | ||||||
| /*
 | /*
 | ||||||
|  * Return the GUID volume name for the disk and partition specified, or NULL if not found. |  * Return the GUID volume name for the disk and partition specified, or NULL if not found. | ||||||
|  * See http://msdn.microsoft.com/en-us/library/cc542456.aspx
 |  * See http://msdn.microsoft.com/en-us/library/cc542456.aspx
 | ||||||
|  * PartitionIndex starts at 1 (for the first partition). If PartitionIndex is zero, then |  * If PartitionOffset is 0, the offset is ignored and the first partition found is returned. | ||||||
|  * the first partition found by this function (which *MAY NOT* be the actual first partition) |  * The returned string is allocated and must be freed. | ||||||
|  * is returned. The returned string is allocated and must be freed. |  | ||||||
|  */ |  */ | ||||||
| char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingBackslash, BOOL bSilent) | char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent) | ||||||
| { | { | ||||||
| 	static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" }; | 	static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" }; | ||||||
| 	static const char* volume_start = "\\\\?\\"; | 	static const char* volume_start = "\\\\?\\"; | ||||||
|  | @ -294,13 +289,11 @@ char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingB | ||||||
| 	UINT drive_type; | 	UINT drive_type; | ||||||
| 	StrArray found_name; | 	StrArray found_name; | ||||||
| 	uint64_t found_offset[MAX_PARTITIONS] = { 0 }; | 	uint64_t found_offset[MAX_PARTITIONS] = { 0 }; | ||||||
| 	uint32_t i, j, k; | 	uint32_t i, j; | ||||||
| 	size_t len; | 	size_t len; | ||||||
| 
 | 
 | ||||||
| 	StrArrayCreate(&found_name, MAX_PARTITIONS); | 	StrArrayCreate(&found_name, MAX_PARTITIONS); | ||||||
| 	CheckDriveIndex(DriveIndex); | 	CheckDriveIndex(DriveIndex); | ||||||
| 	if (PartitionIndex > MAX_PARTITIONS) |  | ||||||
| 		goto out; |  | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; hDrive == INVALID_HANDLE_VALUE; i++) { | 	for (i = 0; hDrive == INVALID_HANDLE_VALUE; i++) { | ||||||
| 		if (i == 0) { | 		if (i == 0) { | ||||||
|  | @ -391,33 +384,14 @@ char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingB | ||||||
| 	if (found_name.Index == 0) | 	if (found_name.Index == 0) | ||||||
| 		goto out; | 		goto out; | ||||||
| 
 | 
 | ||||||
| 	// Now process all the volumes we found, and find the one that matches our partition index
 | 	// Now process all the volumes we found, and try to match one with our partition offset
 | ||||||
| 	if (PartitionIndex == 0) { | 	for (i = 0; (i < found_name.Index) && (PartitionOffset != 0) && (PartitionOffset != found_offset[i]); i++); | ||||||
| 		i = 0; | 
 | ||||||
| 	} else for (i = 0, k = 0; i < found_name.Index; i++) { | 	if (i < found_name.Index) | ||||||
| 		for (j = 0; j < found_name.Index; j++) { |  | ||||||
| 			if (found_offset[i] > found_offset[j]) |  | ||||||
| 				k++; |  | ||||||
| 		} |  | ||||||
| 		if (k == ((int)PartitionIndex) - 1) |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| 	if (i < found_name.Index) { |  | ||||||
| 		ret = safe_strdup(found_name.String[i]); | 		ret = safe_strdup(found_name.String[i]); | ||||||
| 	} else { | 	else | ||||||
| 		// Some volumes, such as ESPs, are not listed by Windows, be it with VDS or other APIs.
 | 		// NB: We need to re-add DRIVE_INDEX_MIN for this call since CheckDriveIndex() substracted it
 | ||||||
| 		// For these, we return the "\\?\GLOBALROOT\Device\HarddiskVolume#" identifier that
 | 		ret = AltGetLogicalName(DriveIndex + DRIVE_INDEX_MIN, PartitionOffset, bKeepTrailingBackslash, bSilent); | ||||||
| 		// matches our "Harddisk#Partition#", as reported by QueryDosDevice().
 |  | ||||||
| 		static_sprintf(path, "Harddisk%luPartition%lu", DriveIndex, PartitionIndex); |  | ||||||
| 		static_strcpy(volume_name, groot_name); |  | ||||||
| 		if (!QueryDosDeviceA(path, &volume_name[groot_len], (DWORD)(MAX_PATH - groot_len)) || (strlen(volume_name) < 20)) { |  | ||||||
| 			uprintf("Could not find the DOS volume name for '%s': %s", path, WindowsErrorString()); |  | ||||||
| 		} else { |  | ||||||
| 			if (bKeepTrailingBackslash) |  | ||||||
| 				static_strcat(volume_name, "\\"); |  | ||||||
| 			ret = safe_strdup(volume_name); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
| 	if (hVolume != INVALID_HANDLE_VALUE) | 	if (hVolume != INVALID_HANDLE_VALUE) | ||||||
|  | @ -426,6 +400,40 @@ out: | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Alternative version of the above, needed because some volumes, such as ESPs, are not listed | ||||||
|  |  * by Windows, be it with VDS or other APIs. | ||||||
|  |  * For these, we return the "\\?\GLOBALROOT\Device\HarddiskVolume#" identifier that matches | ||||||
|  |  * our "Harddisk#Partition#", as reported by QueryDosDevice(). | ||||||
|  |  * The returned string is allocated and must be freed. | ||||||
|  | */ | ||||||
|  | char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent) | ||||||
|  | { | ||||||
|  | 	DWORD i; | ||||||
|  | 	char *ret = NULL, volume_name[MAX_PATH], path[MAX_PATH]; | ||||||
|  | 
 | ||||||
|  | 	CheckDriveIndex(DriveIndex); | ||||||
|  | 
 | ||||||
|  | 	// Match the offset to a partition index
 | ||||||
|  | 	for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != 0) && (PartitionOffset != SelectedDrive.PartitionOffset[i]); i++); | ||||||
|  | 	if (i >= MAX_PARTITIONS) { | ||||||
|  | 		suprintf("Error: Could not find a partition at offset %lld on this disk", PartitionOffset); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 	static_sprintf(path, "Harddisk%luPartition%lu", DriveIndex, i + 1); | ||||||
|  | 	static_strcpy(volume_name, groot_name); | ||||||
|  | 	if (!QueryDosDeviceA(path, &volume_name[groot_len], (DWORD)(MAX_PATH - groot_len)) || (strlen(volume_name) < 20)) { | ||||||
|  | 		suprintf("Could not find the DOS volume name for '%s': %s", path, WindowsErrorString()); | ||||||
|  | 	} else { | ||||||
|  | 		if (bKeepTrailingBackslash) | ||||||
|  | 			static_strcat(volume_name, "\\"); | ||||||
|  | 		ret = safe_strdup(volume_name); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Call on VDS to refresh the drive layout |  * Call on VDS to refresh the drive layout | ||||||
|  */ |  */ | ||||||
|  | @ -720,7 +728,7 @@ out: | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Wait for a logical drive to reappear - Used when a drive has just been repartitioned */ | /* Wait for a logical drive to reappear - Used when a drive has just been repartitioned */ | ||||||
| BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex) | BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset) | ||||||
| { | { | ||||||
| 	uint64_t EndTime; | 	uint64_t EndTime; | ||||||
| 	char* LogicalPath = NULL; | 	char* LogicalPath = NULL; | ||||||
|  | @ -729,7 +737,7 @@ BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex) | ||||||
| 	// make sure we don't spend more than DRIVE_ACCESS_TIMEOUT in wait.
 | 	// make sure we don't spend more than DRIVE_ACCESS_TIMEOUT in wait.
 | ||||||
| 	EndTime = GetTickCount64() + DRIVE_ACCESS_TIMEOUT; | 	EndTime = GetTickCount64() + DRIVE_ACCESS_TIMEOUT; | ||||||
| 	do { | 	do { | ||||||
| 		LogicalPath = GetLogicalName(DriveIndex, PartitionIndex, FALSE, TRUE); | 		LogicalPath = GetLogicalName(DriveIndex, PartitionOffset, FALSE, TRUE); | ||||||
| 		// Need to filter out GlobalRoot devices as we don't want to wait on those
 | 		// Need to filter out GlobalRoot devices as we don't want to wait on those
 | ||||||
| 		if ((LogicalPath != NULL) && (strncmp(LogicalPath, groot_name, groot_len) != 0)) { | 		if ((LogicalPath != NULL) && (strncmp(LogicalPath, groot_name, groot_len) != 0)) { | ||||||
| 			free(LogicalPath); | 			free(LogicalPath); | ||||||
|  | @ -749,10 +757,10 @@ BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex) | ||||||
|  * Returns INVALID_HANDLE_VALUE on error or NULL if no logical path exists (typical |  * Returns INVALID_HANDLE_VALUE on error or NULL if no logical path exists (typical | ||||||
|  * of unpartitioned drives) |  * of unpartitioned drives) | ||||||
|  */ |  */ | ||||||
| HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare) | HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare) | ||||||
| { | { | ||||||
| 	HANDLE hLogical = INVALID_HANDLE_VALUE; | 	HANDLE hLogical = INVALID_HANDLE_VALUE; | ||||||
| 	char* LogicalPath = GetLogicalName(DriveIndex, PartitionIndex, FALSE, FALSE); | 	char* LogicalPath = GetLogicalName(DriveIndex, PartitionOffset, FALSE, FALSE); | ||||||
| 
 | 
 | ||||||
| 	if (LogicalPath == NULL) { | 	if (LogicalPath == NULL) { | ||||||
| 		uprintf("No logical drive found (unpartitioned?)"); | 		uprintf("No logical drive found (unpartitioned?)"); | ||||||
|  | @ -767,10 +775,10 @@ HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, | ||||||
| /*
 | /*
 | ||||||
|  * Similar to the above, but use the partition name instead |  * Similar to the above, but use the partition name instead | ||||||
|  */ |  */ | ||||||
| HANDLE GetPartitionHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare) | HANDLE GetPartitionHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare) | ||||||
| { | { | ||||||
| 	HANDLE handle = INVALID_HANDLE_VALUE; | 	HANDLE handle = INVALID_HANDLE_VALUE; | ||||||
| 	char* volume_name = GetPartitionName(DriveIndex, PartitionIndex); | 	char* volume_name = GetPartitionName(DriveIndex, PartitionOffset); | ||||||
| 
 | 
 | ||||||
| 	if (volume_name == NULL) { | 	if (volume_name == NULL) { | ||||||
| 		uprintf("Could not get partition volume name"); | 		uprintf("Could not get partition volume name"); | ||||||
|  | @ -1158,6 +1166,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)); | ||||||
| 	// 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); | ||||||
|  | @ -1246,6 +1255,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				if (i < MAX_PARTITIONS) | ||||||
|  | 					SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | ||||||
| 				// NB: MinGW's gcc 4.9.2 broke "%lld" printout on XP so we use the inttypes.h "PRI##" qualifiers
 | 				// NB: MinGW's gcc 4.9.2 broke "%lld" printout on XP so we use the inttypes.h "PRI##" qualifiers
 | ||||||
| 				suprintf("  Type: %s (0x%02x)\r\n  Size: %s (%" PRIi64 " bytes)\r\n  Start Sector: %" PRIi64 ", Boot: %s", | 				suprintf("  Type: %s (0x%02x)\r\n  Size: %s (%" PRIi64 " bytes)\r\n  Start Sector: %" PRIi64 ", Boot: %s", | ||||||
| 					((part_type==0x07||super_floppy_disk)&&(FileSystemName[0]!=0))?FileSystemName:GetPartitionType(part_type), super_floppy_disk?0:part_type, | 					((part_type==0x07||super_floppy_disk)&&(FileSystemName[0]!=0))?FileSystemName:GetPartitionType(part_type), super_floppy_disk?0:part_type, | ||||||
|  | @ -1271,6 +1282,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 		suprintf("Max parts: %d, Start Offset: %" PRIi64 ", Usable = %" PRIi64 " bytes", | 		suprintf("Max parts: %d, Start Offset: %" PRIi64 ", Usable = %" PRIi64 " bytes", | ||||||
| 			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) | ||||||
|  | 				SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | ||||||
| 			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); | ||||||
| 			suprintf("Partition %d%s:\r\n  Type: %s\r\n  Name: '%S'", i+1, isUefiNtfs ? " (UEFI:NTFS)" : "", | 			suprintf("Partition %d%s:\r\n  Type: %s\r\n  Name: '%S'", i+1, isUefiNtfs ? " (UEFI:NTFS)" : "", | ||||||
|  | @ -1401,33 +1414,33 @@ BOOL MountVolume(char* drive_name, char *volume_name) | ||||||
| /*
 | /*
 | ||||||
|  * Alternate version of MountVolume required for ESP's, since Windows (including VDS) does |  * Alternate version of MountVolume required for ESP's, since Windows (including VDS) does | ||||||
|  * *NOT* provide any means of mounting these volume but through DefineDosDevice(). Also |  * *NOT* provide any means of mounting these volume but through DefineDosDevice(). Also | ||||||
|  * note the bcdboot is very finicky about what it may or may not handle, even if the |  * note that bcdboot is very finicky about what it may or may not handle, even if the | ||||||
|  * mount was successful (e.g. '\Device\HarddiskVolume###' vs 'Device\HarddiskVolume###'). |  * mount was successful (e.g. '\Device\HarddiskVolume###' vs 'Device\HarddiskVolume###'). | ||||||
|  * Returned string is static (no concurrency) and should not be freed. |  * Returned string is static (no concurrency) and must not be freed. | ||||||
|  */ |  */ | ||||||
| char* AltMountVolume(DWORD DriveIndex, DWORD PartitionIndex) | char* AltMountVolume(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bSilent) | ||||||
| { | { | ||||||
| 	char* ret = NULL, *volume_name = NULL; | 	char* ret = NULL, *volume_name = NULL; | ||||||
| 	static char mounted_drive[] = "?:"; | 	static char mounted_drive[] = "?:"; | ||||||
| 
 | 
 | ||||||
| 	mounted_drive[0] = GetUnusedDriveLetter(); | 	mounted_drive[0] = GetUnusedDriveLetter(); | ||||||
| 	if (mounted_drive[0] == 0) { | 	if (mounted_drive[0] == 0) { | ||||||
| 		uprintf("Could not find an unused drive letter"); | 		suprintf("Could not find an unused drive letter"); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	volume_name = GetLogicalName(DriveIndex, PartitionIndex, FALSE, TRUE); | 	// Can't use a regular volume GUID for ESPs...
 | ||||||
|  | 	volume_name = AltGetLogicalName(DriveIndex, PartitionOffset, FALSE, TRUE); | ||||||
| 	if ((volume_name == NULL) || (strncmp(volume_name, groot_name, groot_len) != 0)) { | 	if ((volume_name == NULL) || (strncmp(volume_name, groot_name, groot_len) != 0)) { | ||||||
| 		uprintf("Unexpected volume name: '%s'", volume_name); | 		suprintf("Unexpected volume name: '%s'", volume_name); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// bcdboot sure won't like it if you forget the starting '\'
 | 	suprintf("Mounting '%s' as '%s'", &volume_name[14], mounted_drive); | ||||||
|  | 	// bcdboot doesn't like it if you forget the starting '\'
 | ||||||
| 	if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, mounted_drive, &volume_name[14])) { | 	if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, mounted_drive, &volume_name[14])) { | ||||||
| 		uprintf("Could not mount '%s' to '%s': %s", &volume_name[14], mounted_drive, WindowsErrorString()); | 		suprintf("Mount operation failed: %s", WindowsErrorString()); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	uprintf("Successfully mounted '%s' (Partition %d) as '%s'", &volume_name[14], PartitionIndex, mounted_drive); |  | ||||||
| 	ret = mounted_drive; | 	ret = mounted_drive; | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
|  | @ -1438,15 +1451,15 @@ out: | ||||||
| /*
 | /*
 | ||||||
|  * Unmount a volume that was mounted by AltmountVolume() |  * Unmount a volume that was mounted by AltmountVolume() | ||||||
|  */ |  */ | ||||||
| BOOL AltUnmountVolume(const char* drive_name) | BOOL AltUnmountVolume(const char* drive_name, BOOL bSilent) | ||||||
| { | { | ||||||
| 	if (drive_name == NULL) | 	if (drive_name == NULL) | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive_name, NULL)) { | 	if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive_name, NULL)) { | ||||||
| 		uprintf("Could not unmount '%s': %s", drive_name, WindowsErrorString()); | 		suprintf("Could not unmount '%s': %s", drive_name, WindowsErrorString()); | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
| 	uprintf("Successfully unmounted '%s'", drive_name); | 	suprintf("Successfully unmounted '%s'", drive_name); | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1536,7 +1549,8 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 		if (uefi_ntfs_size == 0) | 		if (uefi_ntfs_size == 0) | ||||||
| 			return FALSE; | 			return FALSE; | ||||||
| 	} | 	} | ||||||
| 	memset(partition_index, 0, sizeof(partition_index)); | 	memset(partition_offset, 0, sizeof(partition_offset)); | ||||||
|  | 	memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset)); | ||||||
| 
 | 
 | ||||||
| 	// Compute the start offset of our first partition
 | 	// Compute the start offset of our first partition
 | ||||||
| 	if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_OLD_BIOS_FIXES))) { | 	if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_OLD_BIOS_FIXES))) { | ||||||
|  | @ -1560,6 +1574,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 		// Zero the first sectors from this partition to avoid file system caching issues
 | 		// Zero the first sectors from this partition to avoid file system caching issues
 | ||||||
| 		if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear)) | 		if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear)) | ||||||
| 			uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString()); | 			uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString()); | ||||||
|  | 		SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; | ||||||
| 		pn++; | 		pn++; | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart + | 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart + | ||||||
| 				DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; | 				DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; | ||||||
|  | @ -1641,15 +1656,12 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); | 		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); | ||||||
| 		wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, main_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name)); | 		wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, main_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name)); | ||||||
| 	} | 	} | ||||||
|  | 	SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; | ||||||
|  | 	partition_offset[PI_MAIN] = SelectedDrive.PartitionOffset[pn]; | ||||||
| 	pn++; | 	pn++; | ||||||
| 	partition_index[PI_MAIN] = pn; |  | ||||||
| 
 | 
 | ||||||
| 	// Set the optional extra partition
 | 	// Set the optional extra partition
 | ||||||
| 	if (extra_partitions) { | 	if (extra_partitions) { | ||||||
| 		if (extra_partitions & XP_CASPER) |  | ||||||
| 			partition_index[PI_CASPER] = pn + 1; |  | ||||||
| 		else if (extra_partitions & XP_ESP) |  | ||||||
| 			partition_index[PI_ESP] = pn + 1; |  | ||||||
| 		// Should end on a track boundary
 | 		// Should end on a track boundary
 | ||||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart + | 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart + | ||||||
| 			DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; | 			DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; | ||||||
|  | @ -1657,6 +1669,12 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 			extra_part_size_in_tracks * bytes_per_track; | 			extra_part_size_in_tracks * bytes_per_track; | ||||||
| 		uprintf("● Creating %S Partition (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart, | 		uprintf("● Creating %S Partition (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart, | ||||||
| 			SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE)); | 			SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE)); | ||||||
|  | 		SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.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 (partition_style == PARTITION_STYLE_GPT) { | ||||||
| 			DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = (extra_partitions & XP_ESP) ? PARTITION_SYSTEM_GUID : PARTITION_BASIC_DATA_GUID; | 			DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = (extra_partitions & XP_ESP) ? PARTITION_SYSTEM_GUID : PARTITION_BASIC_DATA_GUID; | ||||||
| 			IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); | 			IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								src/drive.h
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								src/drive.h
									
										
									
									
									
								
							|  | @ -350,6 +350,7 @@ 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]; | ||||||
| 	int FSType; | 	int FSType; | ||||||
| 	char proposed_label[16]; | 	char proposed_label[16]; | ||||||
| 	BOOL has_protective_mbr; | 	BOOL has_protective_mbr; | ||||||
|  | @ -360,18 +361,19 @@ 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 DWORD partition_index[3]; | extern uint64_t partition_offset[3]; | ||||||
| 
 | 
 | ||||||
| BOOL SetAutoMount(BOOL enable); | BOOL SetAutoMount(BOOL enable); | ||||||
| BOOL GetAutoMount(BOOL* enabled); | BOOL GetAutoMount(BOOL* enabled); | ||||||
| char* GetPhysicalName(DWORD DriveIndex); | char* GetPhysicalName(DWORD DriveIndex); | ||||||
| char* GetPartitionName(DWORD DriveIndex, DWORD PartitionIndex); | char* GetPartitionName(DWORD DriveIndex, uint64_t PartitionOffset); | ||||||
| BOOL DeletePartitions(DWORD DriveIndex); | BOOL DeletePartitions(DWORD DriveIndex); | ||||||
| HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); | HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); | ||||||
| char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingBackslash, BOOL bSilent); | char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent); | ||||||
| BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex); | char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent); | ||||||
| HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); | BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset); | ||||||
| HANDLE GetPartitionHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); | HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); | ||||||
|  | HANDLE GetPartitionHandle(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); | ||||||
|  | @ -384,14 +386,14 @@ BOOL AnalyzePBR(HANDLE hLogicalVolume); | ||||||
| BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize, BOOL bSilent); | BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize, BOOL bSilent); | ||||||
| BOOL UnmountVolume(HANDLE hDrive); | BOOL UnmountVolume(HANDLE hDrive); | ||||||
| BOOL MountVolume(char* drive_name, char *drive_guid); | BOOL MountVolume(char* drive_name, char *drive_guid); | ||||||
| BOOL AltUnmountVolume(const char* drive_name); | BOOL AltUnmountVolume(const char* drive_name, BOOL bSilent); | ||||||
| char* AltMountVolume(DWORD DriveIndex, DWORD PartitionIndex); | char* AltMountVolume(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bSilent); | ||||||
| BOOL RemountVolume(char* drive_name); | BOOL RemountVolume(char* drive_name); | ||||||
| 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); | ||||||
| BOOL InitializeDisk(HANDLE hDrive); | BOOL InitializeDisk(HANDLE hDrive); | ||||||
| BOOL RefreshDriveLayout(HANDLE hDrive); | BOOL RefreshDriveLayout(HANDLE hDrive); | ||||||
| const char* GetPartitionType(BYTE Type); | const char* GetPartitionType(BYTE Type); | ||||||
| const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex); | const char* GetExtFsLabel(DWORD DriveIndex, uint64_t PartitionOffset); | ||||||
| BOOL GetDevices(DWORD devnum); | BOOL GetDevices(DWORD devnum); | ||||||
| BOOL CyclePort(int index); | BOOL CyclePort(int index); | ||||||
| int CycleDevice(int index); | int CycleDevice(int index); | ||||||
|  |  | ||||||
							
								
								
									
										59
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										59
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -373,7 +373,7 @@ static DWORD GetFATSizeSectors(DWORD DskSize, DWORD ReservedSecCnt, DWORD SecPer | ||||||
|  * Large FAT32 volume formatting from fat32format by Tom Thornhill |  * Large FAT32 volume formatting from fat32format by Tom Thornhill | ||||||
|  * http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
 |  * http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
 | ||||||
|  */ |  */ | ||||||
| static BOOL FormatFAT32(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) | static BOOL FormatFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) | ||||||
| { | { | ||||||
| 	BOOL r = FALSE; | 	BOOL r = FALSE; | ||||||
| 	DWORD i; | 	DWORD i; | ||||||
|  | @ -420,7 +420,7 @@ static BOOL FormatFAT32(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSiz | ||||||
| 	VolumeId = GetVolumeID(); | 	VolumeId = GetVolumeID(); | ||||||
| 
 | 
 | ||||||
| 	// Open the drive and lock it
 | 	// Open the drive and lock it
 | ||||||
| 	hLogicalVolume = GetLogicalHandle(DriveIndex, PartitionIndex, TRUE, TRUE, FALSE); | 	hLogicalVolume = 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)) | ||||||
|  | @ -651,7 +651,7 @@ static BOOL FormatFAT32(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSiz | ||||||
| 	PrintInfoDebug(0, MSG_221); | 	PrintInfoDebug(0, MSG_221); | ||||||
| 	// 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, PartitionIndex, TRUE, TRUE); | 	VolumeName = 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
 | ||||||
|  | @ -819,14 +819,16 @@ errcode_t ext2fs_print_progress(int64_t cur_value, int64_t max_value) | ||||||
| 	return IS_ERROR(FormatStatus) ? EXT2_ET_CANCEL_REQUESTED : 0; | 	return IS_ERROR(FormatStatus) ? EXT2_ET_CANCEL_REQUESTED : 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex) | const char* GetExtFsLabel(DWORD DriveIndex, uint64_t PartitionOffset) | ||||||
| { | { | ||||||
| 	static char label[EXT2_LABEL_LEN + 1]; | 	static char label[EXT2_LABEL_LEN + 1]; | ||||||
| 	errcode_t r; | 	errcode_t r; | ||||||
| 	ext2_filsys ext2fs = NULL; | 	ext2_filsys ext2fs = NULL; | ||||||
| 	io_manager manager = nt_io_manager(); | 	io_manager manager = nt_io_manager(); | ||||||
| 	char* volume_name = GetPartitionName(DriveIndex, PartitionIndex); | 	char* volume_name = AltMountVolume(DriveIndex, PartitionOffset, TRUE); | ||||||
| 
 | 
 | ||||||
|  | 	if (volume_name == NULL) | ||||||
|  | 		return NULL; | ||||||
| 	r = ext2fs_open(volume_name, EXT2_FLAG_SKIP_MMP, 0, 0, manager, &ext2fs); | 	r = ext2fs_open(volume_name, EXT2_FLAG_SKIP_MMP, 0, 0, manager, &ext2fs); | ||||||
| 	if (r == 0) { | 	if (r == 0) { | ||||||
| 		strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN); | 		strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN); | ||||||
|  | @ -834,11 +836,11 @@ const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex) | ||||||
| 	} | 	} | ||||||
| 	if (ext2fs != NULL) | 	if (ext2fs != NULL) | ||||||
| 		ext2fs_close(ext2fs); | 		ext2fs_close(ext2fs); | ||||||
| 	free(volume_name); | 	AltUnmountVolume(volume_name, TRUE); | ||||||
| 	return (r == 0) ? label : NULL; | 	return (r == 0) ? label : NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) | BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) | ||||||
| { | { | ||||||
| 	// Mostly taken from mke2fs.conf
 | 	// Mostly taken from mke2fs.conf
 | ||||||
| 	const float reserve_ratio = 0.05f; | 	const float reserve_ratio = 0.05f; | ||||||
|  | @ -877,7 +879,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR | ||||||
| 	} | 	} | ||||||
| 	CloseHandle(h); | 	CloseHandle(h); | ||||||
| #else | #else | ||||||
| 	volume_name = GetPartitionName(DriveIndex, PartitionIndex); | 	volume_name = AltMountVolume(DriveIndex, PartitionOffset, FALSE); | ||||||
| #endif | #endif | ||||||
| 	if ((volume_name == NULL) | (strlen(FSName) != 4) || (strncmp(FSName, "ext", 3) != 0)) { | 	if ((volume_name == NULL) | (strlen(FSName) != 4) || (strncmp(FSName, "ext", 3) != 0)) { | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER; | 		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER; | ||||||
|  | @ -1097,14 +1099,14 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR | ||||||
| out: | out: | ||||||
| 	ext2fs_free(ext2fs); | 	ext2fs_free(ext2fs); | ||||||
| 	free(buf); | 	free(buf); | ||||||
| 	free(volume_name); | 	AltUnmountVolume(volume_name, FALSE); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Call on VDS to format a partition |  * Call on VDS to format a partition | ||||||
|  */ |  */ | ||||||
| static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) | static BOOL FormatDriveVds(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) | ||||||
| { | { | ||||||
| 	BOOL r = FALSE, bFoundVolume = FALSE; | 	BOOL r = FALSE, bFoundVolume = FALSE; | ||||||
| 	HRESULT hr; | 	HRESULT hr; | ||||||
|  | @ -1122,7 +1124,7 @@ static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD Cluster | ||||||
| 		PrintInfoDebug(0, MSG_222, FSName); | 		PrintInfoDebug(0, MSG_222, FSName); | ||||||
| 	} | 	} | ||||||
| 	LastRefresh = 0; | 	LastRefresh = 0; | ||||||
| 	VolumeName = GetLogicalName(DriveIndex, PartitionIndex, TRUE, TRUE); | 	VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE); | ||||||
| 	wVolumeName = utf8_to_wchar(VolumeName); | 	wVolumeName = utf8_to_wchar(VolumeName); | ||||||
| 	if (wVolumeName == NULL) { | 	if (wVolumeName == NULL) { | ||||||
| 		uprintf("Could not read volume name"); | 		uprintf("Could not read volume name"); | ||||||
|  | @ -1350,7 +1352,7 @@ out: | ||||||
| /*
 | /*
 | ||||||
|  * Call on fmifs.dll's FormatEx() to format the drive |  * Call on fmifs.dll's FormatEx() to format the drive | ||||||
|  */ |  */ | ||||||
| static BOOL FormatDrive(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) | static BOOL FormatDrive(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) | ||||||
| { | { | ||||||
| 	BOOL r = FALSE; | 	BOOL r = FALSE; | ||||||
| 	PF_DECL(FormatEx); | 	PF_DECL(FormatEx); | ||||||
|  | @ -1364,10 +1366,10 @@ static BOOL FormatDrive(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSiz | ||||||
| 	} else { | 	} else { | ||||||
| 		PrintInfoDebug(0, MSG_222, FSName); | 		PrintInfoDebug(0, MSG_222, FSName); | ||||||
| 	} | 	} | ||||||
| 	VolumeName = GetLogicalName(DriveIndex, PartitionIndex, TRUE, TRUE); | 	VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE); | ||||||
| 	wVolumeName = utf8_to_wchar(VolumeName); | 	wVolumeName = utf8_to_wchar(VolumeName); | ||||||
| 	if (wVolumeName == NULL) { | 	if (wVolumeName == NULL) { | ||||||
| 		uprintf("Could not read volume name\n"); | 		uprintf("Could not read volume name"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
|  | @ -1429,9 +1431,9 @@ out: | ||||||
| 	return r; | 	return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static BOOL FormatPartition(DWORD DriveIndex, DWORD PartitionIndex, DWORD UnitAllocationSize, USHORT FSType, LPCSTR Label, DWORD Flags) | static BOOL FormatPartition(DWORD DriveIndex, uint64_t PartitionOffset, DWORD UnitAllocationSize, USHORT FSType, LPCSTR Label, DWORD Flags) | ||||||
| { | { | ||||||
| 	if ((DriveIndex < 0x80) || (DriveIndex > 0x100) || (PartitionIndex >= MAX_PARTITIONS) || (FSType >= FS_MAX) || | 	if ((DriveIndex < 0x80) || (DriveIndex > 0x100) || (FSType >= FS_MAX) || | ||||||
| 		// The following validates that UnitAllocationSize is a power of 2
 | 		// The following validates that UnitAllocationSize is a power of 2
 | ||||||
| 		((UnitAllocationSize != 0) && (UnitAllocationSize & (UnitAllocationSize - 1)))) { | 		((UnitAllocationSize != 0) && (UnitAllocationSize & (UnitAllocationSize - 1)))) { | ||||||
| 		ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER; | 		ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER; | ||||||
|  | @ -1439,13 +1441,13 @@ static BOOL FormatPartition(DWORD DriveIndex, DWORD PartitionIndex, DWORD UnitAl | ||||||
| 	} | 	} | ||||||
| 	actual_fs_type = FSType; | 	actual_fs_type = FSType; | ||||||
| 	if ((FSType == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32) || (Flags & FP_LARGE_FAT32))) | 	if ((FSType == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32) || (Flags & FP_LARGE_FAT32))) | ||||||
| 		return FormatFAT32(DriveIndex, PartitionIndex, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags); | 		return FormatFAT32(DriveIndex, PartitionOffset, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags); | ||||||
| 	else if (FSType >= FS_EXT2) | 	else if (FSType >= FS_EXT2) | ||||||
| 		return FormatExtFs(DriveIndex, PartitionIndex, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags); | 		return FormatExtFs(DriveIndex, PartitionOffset, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags); | ||||||
| 	else if (use_vds) | 	else if (use_vds) | ||||||
| 		return FormatDriveVds(DriveIndex, PartitionIndex, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags); | 		return FormatDriveVds(DriveIndex, PartitionOffset, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags); | ||||||
| 	else | 	else | ||||||
| 		return FormatDrive(DriveIndex, PartitionIndex, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags); | 		return FormatDrive(DriveIndex, PartitionOffset, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -2159,7 +2161,7 @@ static 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_index[PI_ESP], cluster_size, FS_FAT32, "", | 		if (!FormatPartition(DriveIndex, partition_offset[PI_ESP], 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; | ||||||
|  | @ -2169,7 +2171,7 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp) | ||||||
| 
 | 
 | ||||||
| 	if (use_esp) { | 	if (use_esp) { | ||||||
| 		// Need to have the ESP mounted to invoke bcdboot
 | 		// Need to have the ESP mounted to invoke bcdboot
 | ||||||
| 		ms_efi = AltMountVolume(DriveIndex, partition_index[PI_ESP]); | 		ms_efi = AltMountVolume(DriveIndex, partition_offset[PI_ESP], 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; | ||||||
|  | @ -2192,7 +2194,7 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp) | ||||||
| 
 | 
 | ||||||
| 	if (use_esp) { | 	if (use_esp) { | ||||||
| 		Sleep(200); | 		Sleep(200); | ||||||
| 		AltUnmountVolume(ms_efi); | 		AltUnmountVolume(ms_efi, FALSE); | ||||||
| 	} | 	} | ||||||
| 	PrintInfo(0, MSG_267, 99.9f); | 	PrintInfo(0, MSG_267, 99.9f); | ||||||
| 	UpdateProgress(OP_DOS, 99.9f); | 	UpdateProgress(OP_DOS, 99.9f); | ||||||
|  | @ -2679,7 +2681,7 @@ 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 (!WaitForLogical(DriveIndex, partition_index[PI_MAIN])) { | 	if (!WaitForLogical(DriveIndex, partition_offset[PI_MAIN])) { | ||||||
| 		uprintf("Logical drive was not found - aborting"); | 		uprintf("Logical drive was not found - aborting"); | ||||||
| 		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; | ||||||
|  | @ -2693,7 +2695,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		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_index[PI_CASPER], 0, FS_EXT2 + (ext_version - 2), | 		if (!FormatPartition(DriveIndex, partition_offset[PI_CASPER], 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))) { | ||||||
|  | @ -2716,7 +2718,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	if ((fs_type == FS_NTFS) && (enable_ntfs_compression)) | 	if ((fs_type == FS_NTFS) && (enable_ntfs_compression)) | ||||||
| 		Flags |= FP_COMPRESSION; | 		Flags |= FP_COMPRESSION; | ||||||
| 
 | 
 | ||||||
| 	ret = FormatPartition(DriveIndex, partition_index[PI_MAIN], ClusterSize, fs_type, label, Flags); | 	ret = FormatPartition(DriveIndex, partition_offset[PI_MAIN], 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)); | ||||||
|  | @ -2747,7 +2749,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_index[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; | ||||||
|  | @ -2800,8 +2802,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...
 | ||||||
| 			// TODO: Shouldn't PI always be 1 here?
 | 			hLogicalVolume = GetLogicalHandle(DriveIndex, partition_offset[PI_MAIN], FALSE, TRUE, FALSE); | ||||||
| 			hLogicalVolume = GetLogicalHandle(DriveIndex, partition_index[PI_MAIN], 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; | ||||||
|  |  | ||||||
							
								
								
									
										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.7.1561" | CAPTION "Rufus 3.7.1562" | ||||||
| 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 | ||||||
|  | @ -394,8 +394,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 3,7,1561,0 |  FILEVERSION 3,7,1562,0 | ||||||
|  PRODUCTVERSION 3,7,1561,0 |  PRODUCTVERSION 3,7,1562,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -413,13 +413,13 @@ BEGIN | ||||||
|             VALUE "Comments", "https://akeo.ie" |             VALUE "Comments", "https://akeo.ie" | ||||||
|             VALUE "CompanyName", "Akeo Consulting" |             VALUE "CompanyName", "Akeo Consulting" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "3.7.1561" |             VALUE "FileVersion", "3.7.1562" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus-3.7.exe" |             VALUE "OriginalFilename", "rufus-3.7.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "3.7.1561" |             VALUE "ProductVersion", "3.7.1562" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue