mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[ext2fs] fix creation of persistent partitions for pre-1703 platforms
* Windows platforms prior to Windows 10 1703 cannot access any logical partition besides the
  first one (we don't even get a volume for those).
* This fix enables the use of physical + offset for ext# formatting to work around this,
  which is file since we don't actually need to mount the partition.
* Also fix ext2fs_open2() not handling normalized versions of Windows drive paths ("\\?\...")
* Also fix an issue where we would make the drive letter unavailable after formatting a
  standalone partition to ext#.
* Also ensure that we return an error if the drive we attempt to locate a partition on
  through an offset does not match the currently selected one.
* Also remove some unused calls in drive.c.
* Closes #1374
			
			
This commit is contained in:
		
							parent
							
								
									0a24940c85
								
							
						
					
					
						commit
						bf8d888b21
					
				
					 7 changed files with 89 additions and 83 deletions
				
			
		
							
								
								
									
										81
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										81
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -242,23 +242,6 @@ out: | ||||||
| 	return (success)?safe_strdup(physical_name):NULL; | 	return (success)?safe_strdup(physical_name):NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * 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) |  | ||||||
|  * If PartitionOffset is 0, the offset is ignored and the first partition found is returned. |  | ||||||
|  */ |  | ||||||
| char* GetPartitionName(DWORD DriveIndex, uint64_t PartitionOffset) |  | ||||||
| { |  | ||||||
| 	char partition_name[32]; |  | ||||||
| 	DWORD i = MAX_PARTITIONS + 1; |  | ||||||
| 
 |  | ||||||
| 	CheckDriveIndex(DriveIndex); |  | ||||||
| 	for (i = 1; (i <= MAX_PARTITIONS) && (PartitionOffset != 0) && (SelectedDrive.PartitionOffset[i - 1] != PartitionOffset); i++); |  | ||||||
| 	static_sprintf(partition_name, "\\Device\\Harddisk%lu\\Partition%lu", DriveIndex, i); |  | ||||||
| out: |  | ||||||
| 	return (i <= MAX_PARTITIONS) ? safe_strdup(partition_name) : NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * Return a handle to the physical drive identified by DriveIndex |  * Return a handle to the physical drive identified by DriveIndex | ||||||
|  */ |  */ | ||||||
|  | @ -387,11 +370,14 @@ char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrail | ||||||
| 	// Now process all the volumes we found, and try to match one with our partition offset
 | 	// Now process all the volumes we found, and try to match one with our partition offset
 | ||||||
| 	for (i = 0; (i < found_name.Index) && (PartitionOffset != 0) && (PartitionOffset != found_offset[i]); i++); | 	for (i = 0; (i < found_name.Index) && (PartitionOffset != 0) && (PartitionOffset != found_offset[i]); i++); | ||||||
| 
 | 
 | ||||||
| 	if (i < found_name.Index) | 	if (i < found_name.Index) { | ||||||
| 		ret = safe_strdup(found_name.String[i]); | 		ret = safe_strdup(found_name.String[i]); | ||||||
| 	else | 	} else { | ||||||
| 		// NB: We need to re-add DRIVE_INDEX_MIN for this call since CheckDriveIndex() substracted it
 | 		// NB: We need to re-add DRIVE_INDEX_MIN for this call since CheckDriveIndex() substracted it
 | ||||||
| 		ret = AltGetLogicalName(DriveIndex + DRIVE_INDEX_MIN, PartitionOffset, bKeepTrailingBackslash, bSilent); | 		ret = AltGetLogicalName(DriveIndex + DRIVE_INDEX_MIN, PartitionOffset, bKeepTrailingBackslash, bSilent); | ||||||
|  | 		if ((ret != NULL) && (strchr(ret, ' ') != NULL)) | ||||||
|  | 			uprintf("Warning: Using physical device to access partition data"); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
| 	if (hVolume != INVALID_HANDLE_VALUE) | 	if (hVolume != INVALID_HANDLE_VALUE) | ||||||
|  | @ -409,26 +395,38 @@ out: | ||||||
| */ | */ | ||||||
| char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent) | char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent) | ||||||
| { | { | ||||||
|  | 	BOOL matching_drive = (DriveIndex == SelectedDrive.DeviceNumber); | ||||||
| 	DWORD i; | 	DWORD i; | ||||||
| 	char *ret = NULL, volume_name[MAX_PATH], path[MAX_PATH]; | 	char *ret = NULL, volume_name[MAX_PATH], path[64]; | ||||||
| 
 | 
 | ||||||
| 	CheckDriveIndex(DriveIndex); | 	CheckDriveIndex(DriveIndex); | ||||||
| 
 | 
 | ||||||
| 	// Match the offset to a partition index
 | 	// Match the offset to a partition index
 | ||||||
| 	for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != 0) && (PartitionOffset != SelectedDrive.PartitionOffset[i]); i++); | 	if (PartitionOffset == 0) { | ||||||
|  | 		i = 0; | ||||||
|  | 	} else if (matching_drive) { | ||||||
|  | 		for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.PartitionOffset[i]); 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; | ||||||
| 		} | 		} | ||||||
|  | 	} else { | ||||||
|  | 		suprintf("Error: Searching for a partition on a non matching disk"); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
| 	static_sprintf(path, "Harddisk%luPartition%lu", DriveIndex, i + 1); | 	static_sprintf(path, "Harddisk%luPartition%lu", DriveIndex, i + 1); | ||||||
| 	static_strcpy(volume_name, groot_name); | 	static_strcpy(volume_name, groot_name); | ||||||
| 	if (!QueryDosDeviceA(path, &volume_name[groot_len], (DWORD)(MAX_PATH - groot_len)) || (strlen(volume_name) < 20)) { | 	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()); | 		suprintf("Could not find a DOS volume name for '%s': %s", path, WindowsErrorString()); | ||||||
| 	} else { | 		// If we are on the right drive, we enable a custom access mode through physical + offset
 | ||||||
| 		if (bKeepTrailingBackslash) | 		if (!matching_drive) | ||||||
|  | 			goto out; | ||||||
|  | 		static_sprintf(volume_name, "\\\\.\\PhysicalDrive%lu%s %I64u %I64u", DriveIndex, bKeepTrailingBackslash ? "\\" : "", | ||||||
|  | 			SelectedDrive.PartitionOffset[i], SelectedDrive.PartitionSize[i]); | ||||||
|  | 	} else if (bKeepTrailingBackslash) { | ||||||
| 		static_strcat(volume_name, "\\"); | 		static_strcat(volume_name, "\\"); | ||||||
| 		ret = safe_strdup(volume_name); |  | ||||||
| 	} | 	} | ||||||
|  | 	ret = safe_strdup(volume_name); | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
| 	return ret; | 	return ret; | ||||||
|  | @ -772,24 +770,6 @@ HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDr | ||||||
| 	return hLogical; | 	return hLogical; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * Similar to the above, but use the partition name instead |  | ||||||
|  */ |  | ||||||
| HANDLE GetPartitionHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare) |  | ||||||
| { |  | ||||||
| 	HANDLE handle = INVALID_HANDLE_VALUE; |  | ||||||
| 	char* volume_name = GetPartitionName(DriveIndex, PartitionOffset); |  | ||||||
| 
 |  | ||||||
| 	if (volume_name == NULL) { |  | ||||||
| 		uprintf("Could not get partition volume name"); |  | ||||||
| 		return NULL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	handle = GetHandle(volume_name, bLockDrive, bWriteAccess, bWriteShare); |  | ||||||
| 	free(volume_name); |  | ||||||
| 	return handle; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * Who would have thought that Microsoft would make it so unbelievably hard to |  * Who would have thought that Microsoft would make it so unbelievably hard to | ||||||
|  * get the frickin' device number for a drive? You have to use TWO different |  * get the frickin' device number for a drive? You have to use TWO different | ||||||
|  | @ -984,7 +964,7 @@ BOOL GetDriveLabel(DWORD DriveIndex, char* letters, char** label) | ||||||
| 		if (GetVolumeInformationByHandleW(h, VolumeName, 64, &VolumeSerialNumber, | 		if (GetVolumeInformationByHandleW(h, VolumeName, 64, &VolumeSerialNumber, | ||||||
| 			&MaximumComponentLength, &FileSystemFlags, FileSystemName, 64)) { | 			&MaximumComponentLength, &FileSystemFlags, FileSystemName, 64)) { | ||||||
| 			wchar_to_utf8_no_alloc(VolumeName, VolumeLabel, sizeof(VolumeLabel)); | 			wchar_to_utf8_no_alloc(VolumeName, VolumeLabel, sizeof(VolumeLabel)); | ||||||
| 			*label = VolumeLabel; | 			*label = (VolumeLabel[0] != 0) ? VolumeLabel : STR_NO_LABEL; | ||||||
| 		} | 		} | ||||||
| 		// Drive without volume assigned - always enabled
 | 		// Drive without volume assigned - always enabled
 | ||||||
| 		return TRUE; | 		return TRUE; | ||||||
|  | @ -1167,6 +1147,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 
 | 
 | ||||||
| 	SelectedDrive.nPartitions = 0; | 	SelectedDrive.nPartitions = 0; | ||||||
| 	memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset)); | 	memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset)); | ||||||
|  | 	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); | ||||||
|  | @ -1255,8 +1236,10 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				if (i < MAX_PARTITIONS) | 				if (i < MAX_PARTITIONS) { | ||||||
| 					SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | 					SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | ||||||
|  | 					SelectedDrive.PartitionSize[i] = DriveLayout->PartitionEntry[i].PartitionLength.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, | ||||||
|  | @ -1282,8 +1265,10 @@ 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) | 			if (i < MAX_PARTITIONS) { | ||||||
| 				SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | 				SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart; | ||||||
|  | 				SelectedDrive.PartitionSize[i] = DriveLayout->PartitionEntry[i].PartitionLength.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)" : "", | ||||||
|  | @ -1551,6 +1536,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 	} | 	} | ||||||
| 	memset(partition_offset, 0, sizeof(partition_offset)); | 	memset(partition_offset, 0, sizeof(partition_offset)); | ||||||
| 	memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset)); | 	memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset)); | ||||||
|  | 	memset(SelectedDrive.PartitionSize, 0, sizeof(SelectedDrive.PartitionSize)); | ||||||
| 
 | 
 | ||||||
| 	// 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))) { | ||||||
|  | @ -1575,6 +1561,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 		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; | 		SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; | ||||||
|  | 		SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.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; | ||||||
|  | @ -1657,6 +1644,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 		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; | 	SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; | ||||||
|  | 	SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart; | ||||||
| 	partition_offset[PI_MAIN] = SelectedDrive.PartitionOffset[pn]; | 	partition_offset[PI_MAIN] = SelectedDrive.PartitionOffset[pn]; | ||||||
| 	pn++; | 	pn++; | ||||||
| 
 | 
 | ||||||
|  | @ -1670,6 +1658,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | ||||||
| 		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; | 		SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart; | ||||||
|  | 		SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart; | ||||||
| 		if (extra_partitions & XP_CASPER) | 		if (extra_partitions & XP_CASPER) | ||||||
| 			partition_offset[PI_CASPER] = SelectedDrive.PartitionOffset[pn]; | 			partition_offset[PI_CASPER] = SelectedDrive.PartitionOffset[pn]; | ||||||
| 		else if (extra_partitions & XP_ESP) | 		else if (extra_partitions & XP_ESP) | ||||||
|  |  | ||||||
|  | @ -351,6 +351,7 @@ typedef struct { | ||||||
| 	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]; | 	uint64_t PartitionOffset[MAX_PARTITIONS]; | ||||||
|  | 	uint64_t PartitionSize[MAX_PARTITIONS]; | ||||||
| 	int FSType; | 	int FSType; | ||||||
| 	char proposed_label[16]; | 	char proposed_label[16]; | ||||||
| 	BOOL has_protective_mbr; | 	BOOL has_protective_mbr; | ||||||
|  | @ -366,14 +367,12 @@ 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, 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, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent); | char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent); | ||||||
| char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent); | char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent); | ||||||
| BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset); | BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset); | ||||||
| HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); | HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); | ||||||
| HANDLE 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); | ||||||
|  |  | ||||||
|  | @ -63,6 +63,9 @@ typedef struct _NT_PRIVATE_DATA { | ||||||
|     ULONG   buffer_size; |     ULONG   buffer_size; | ||||||
|     BOOLEAN read_only; |     BOOLEAN read_only; | ||||||
|     BOOLEAN written; |     BOOLEAN written; | ||||||
|  |     // Used by Rufus
 | ||||||
|  |     __u64   offset; | ||||||
|  |     __u64   size; | ||||||
| } NT_PRIVATE_DATA, *PNT_PRIVATE_DATA; | } NT_PRIVATE_DATA, *PNT_PRIVATE_DATA; | ||||||
| 
 | 
 | ||||||
| //
 | //
 | ||||||
|  | @ -199,7 +202,7 @@ static NTSTATUS _OpenNtName(IN PCSTR Name, IN BOOLEAN Readonly, OUT PHANDLE Hand | ||||||
| 	UnicodeString.MaximumLength = sizeof(Buffer); // in bytes!!!
 | 	UnicodeString.MaximumLength = sizeof(Buffer); // in bytes!!!
 | ||||||
| 
 | 
 | ||||||
| 	// Initialize object
 | 	// Initialize object
 | ||||||
| 	InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL ); | 	InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); | ||||||
| 
 | 
 | ||||||
| 	// Try to open it in initial mode
 | 	// Try to open it in initial mode
 | ||||||
| 	if (ARGUMENT_PRESENT(OpenedReadonly)) | 	if (ARGUMENT_PRESENT(OpenedReadonly)) | ||||||
|  | @ -286,13 +289,17 @@ static __inline NTSTATUS _CloseDisk(IN HANDLE Handle) | ||||||
| 	return (pfNtClose == NULL) ? STATUS_DLL_NOT_FOUND : pfNtClose(Handle); | 	return (pfNtClose == NULL) ? STATUS_DLL_NOT_FOUND : pfNtClose(Handle); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static PCSTR _NormalizeDeviceName(IN PCSTR Device, IN PSTR NormalizedDeviceNameBuffer) | static PCSTR _NormalizeDeviceName(IN PCSTR Device, IN PSTR NormalizedDeviceNameBuffer, OUT __u64 *Offset, OUT __u64 *Size) | ||||||
| { | { | ||||||
|  | 	*Offset = *Size = 0ULL; | ||||||
| 	// Convert non NT paths to NT
 | 	// Convert non NT paths to NT
 | ||||||
| 	if (Device[0] == '\\') { | 	if (Device[0] == '\\') { | ||||||
| 		if ((strlen(Device) < 4) || (Device[3] != '\\')) | 		if ((strlen(Device) < 4) || (Device[3] != '\\')) | ||||||
| 			return Device; | 			return Device; | ||||||
| 		strcpy(NormalizedDeviceNameBuffer, Device); | 		// Handle custom paths of the form "<Physical> <Offset> <Size>" used by Rufus to
 | ||||||
|  | 		// enable multi-partition access on removable devices, for pre 1703 platforms.
 | ||||||
|  | 		if (sscanf(Device, "%s %I64u %I64u", NormalizedDeviceNameBuffer, Offset, Size) < 1) | ||||||
|  | 			return NULL; | ||||||
| 		if ((NormalizedDeviceNameBuffer[1] == '\\') || (NormalizedDeviceNameBuffer[1] == '.')) | 		if ((NormalizedDeviceNameBuffer[1] == '\\') || (NormalizedDeviceNameBuffer[1] == '.')) | ||||||
| 			NormalizedDeviceNameBuffer[1] = '?'; | 			NormalizedDeviceNameBuffer[1] = '?'; | ||||||
| 		if (NormalizedDeviceNameBuffer[2] == '.') | 		if (NormalizedDeviceNameBuffer[2] == '.') | ||||||
|  | @ -341,7 +348,8 @@ static VOID _GetDeviceSize(IN HANDLE h, OUT unsigned __int64 *FsSize) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static BOOLEAN _Ext2OpenDevice(IN PCSTR Name, IN BOOLEAN ReadOnly, OUT PHANDLE Handle, OUT PBOOLEAN OpenedReadonly OPTIONAL, OUT errcode_t *Errno OPTIONAL) | static BOOLEAN _Ext2OpenDevice(IN PCSTR Name, IN BOOLEAN ReadOnly, OUT PHANDLE Handle, | ||||||
|  | 	OUT __u64 *Offset, OUT __u64 *Size, OUT PBOOLEAN OpenedReadonly OPTIONAL, OUT errcode_t *Errno OPTIONAL) | ||||||
| { | { | ||||||
| 	CHAR NormalizedDeviceName[512]; | 	CHAR NormalizedDeviceName[512]; | ||||||
| 	NTSTATUS Status; | 	NTSTATUS Status; | ||||||
|  | @ -358,7 +366,7 @@ static BOOLEAN _Ext2OpenDevice(IN PCSTR Name, IN BOOLEAN ReadOnly, OUT PHANDLE H | ||||||
| 		(':' == *(Name + 1)) && ('\0' == *(Name + 2))) { | 		(':' == *(Name + 1)) && ('\0' == *(Name + 2))) { | ||||||
| 		Status = _OpenDriveLetter(*Name, ReadOnly, Handle, OpenedReadonly); | 		Status = _OpenDriveLetter(*Name, ReadOnly, Handle, OpenedReadonly); | ||||||
| 	} else { | 	} else { | ||||||
| 		Name = _NormalizeDeviceName(Name, NormalizedDeviceName); | 		Name = _NormalizeDeviceName(Name, NormalizedDeviceName, Offset, Size); | ||||||
| 		if (Name == NULL) { | 		if (Name == NULL) { | ||||||
| 			LastWinError = ERROR_INVALID_PARAMETER; | 			LastWinError = ERROR_INVALID_PARAMETER; | ||||||
| 			if (ARGUMENT_PRESENT(Errno)) | 			if (ARGUMENT_PRESENT(Errno)) | ||||||
|  | @ -438,12 +446,13 @@ static BOOLEAN _SetPartType(IN HANDLE Handle, IN UCHAR Type) | ||||||
| errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags) | errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags) | ||||||
| { | { | ||||||
| 	errcode_t errcode = 0; | 	errcode_t errcode = 0; | ||||||
|  | 	__u64 Offset, Size; | ||||||
| 	HANDLE h; | 	HANDLE h; | ||||||
| 	BOOLEAN Readonly; | 	BOOLEAN Readonly; | ||||||
| 
 | 
 | ||||||
| 	*mount_flags = 0; | 	*mount_flags = 0; | ||||||
| 
 | 
 | ||||||
| 	if (!_Ext2OpenDevice(file, TRUE, &h, &Readonly, &errcode)) | 	if (!_Ext2OpenDevice(file, TRUE, &h, &Offset, &Size, &Readonly, &errcode)) | ||||||
| 		return errcode; | 		return errcode; | ||||||
| 
 | 
 | ||||||
| 	*mount_flags &= _IsMounted(h) ? EXT2_MF_MOUNTED : 0; | 	*mount_flags &= _IsMounted(h) ? EXT2_MF_MOUNTED : 0; | ||||||
|  | @ -463,18 +472,19 @@ errcode_t ext2fs_check_mount_point(const char *file, int *mount_flags, char *mtp | ||||||
| // different removable devices (e.g. UFD) may be remounted under the same path.
 | // different removable devices (e.g. UFD) may be remounted under the same path.
 | ||||||
| errcode_t ext2fs_get_device_size2(const char *file, int blocksize, blk64_t *retblocks) | errcode_t ext2fs_get_device_size2(const char *file, int blocksize, blk64_t *retblocks) | ||||||
| { | { | ||||||
| 	errcode_t errcode; | 	errcode_t errcode = 0; | ||||||
| 	__int64 fs_size = 0; | 	__u64 Offset, Size = 0; | ||||||
| 	HANDLE h; | 	HANDLE h; | ||||||
| 	BOOLEAN Readonly; | 	BOOLEAN Readonly; | ||||||
| 
 | 
 | ||||||
| 	if (!_Ext2OpenDevice(file, TRUE, &h, &Readonly, &errcode)) | 	if (!_Ext2OpenDevice(file, TRUE, &h, &Offset, &Size, &Readonly, &errcode)) | ||||||
| 		return errcode; | 		return errcode; | ||||||
| 
 | 
 | ||||||
| 	_GetDeviceSize(h, &fs_size); | 	if (Size == 0LL) | ||||||
|  | 		_GetDeviceSize(h, &Size); | ||||||
| 	_CloseDisk(h); | 	_CloseDisk(h); | ||||||
| 
 | 
 | ||||||
| 	*retblocks = (blk64_t)(fs_size / blocksize); | 	*retblocks = (blk64_t)(Size / blocksize); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -529,7 +539,8 @@ static errcode_t nt_open(const char *name, int flags, io_channel *channel) | ||||||
| 	io->private_data = nt_data; | 	io->private_data = nt_data; | ||||||
| 
 | 
 | ||||||
| 	// Open the device
 | 	// Open the device
 | ||||||
| 	if (!_Ext2OpenDevice(name, (BOOLEAN)!BooleanFlagOn(flags, EXT2_FLAG_RW), &nt_data->handle, &nt_data->read_only, &errcode)) { | 	if (!_Ext2OpenDevice(name, (BOOLEAN)!BooleanFlagOn(flags, EXT2_FLAG_RW), &nt_data->handle, | ||||||
|  | 		&nt_data->offset, &nt_data->size, &nt_data->read_only, &errcode)) { | ||||||
| 		if (!errcode) | 		if (!errcode) | ||||||
| 			errcode = EIO; | 			errcode = EIO; | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -631,7 +642,7 @@ static errcode_t nt_read_blk(io_channel channel, unsigned long block, int count, | ||||||
| 
 | 
 | ||||||
| 	size = (count < 0) ? (ULONG)(-count) : (ULONG)(count * channel->block_size); | 	size = (count < 0) ? (ULONG)(-count) : (ULONG)(count * channel->block_size); | ||||||
| 
 | 
 | ||||||
| 	offset.QuadPart = block * channel->block_size; | 	offset.QuadPart = block * channel->block_size + nt_data->offset; | ||||||
| 
 | 
 | ||||||
| 	// If not fit to the block
 | 	// If not fit to the block
 | ||||||
| 	if (size <= nt_data->buffer_size) { | 	if (size <= nt_data->buffer_size) { | ||||||
|  | @ -686,7 +697,7 @@ static errcode_t nt_write_blk(io_channel channel, unsigned long block, int count | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	assert((write_size % 512) == 0); | 	assert((write_size % 512) == 0); | ||||||
| 	offset.QuadPart = block * channel->block_size; | 	offset.QuadPart = block * channel->block_size + nt_data->offset; | ||||||
| 
 | 
 | ||||||
| 	if (!_RawWrite(nt_data->handle, offset, write_size, buf, &errcode)) { | 	if (!_RawWrite(nt_data->handle, offset, write_size, buf, &errcode)) { | ||||||
| 		if (channel->write_error) | 		if (channel->write_error) | ||||||
|  |  | ||||||
|  | @ -158,7 +158,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, | ||||||
| 		goto cleanup; | 		goto cleanup; | ||||||
| 	strcpy(fs->device_name, name); | 	strcpy(fs->device_name, name); | ||||||
| 	cp = strchr(fs->device_name, '?'); | 	cp = strchr(fs->device_name, '?'); | ||||||
| 	if (!io_options && cp) { | 	// Don't process "?\" as an option since some Windows device paths use "\\?\..."
 | ||||||
|  | 	if (!io_options && cp && cp[1] != '\\') { | ||||||
| 		*cp++ = 0; | 		*cp++ = 0; | ||||||
| 		io_options = cp; | 		io_options = cp; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										28
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -825,18 +825,18 @@ const char* GetExtFsLabel(DWORD DriveIndex, uint64_t PartitionOffset) | ||||||
| 	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 = AltMountVolume(DriveIndex, PartitionOffset, TRUE); | 	char* volume_name = AltGetLogicalName(DriveIndex, PartitionOffset, FALSE, TRUE); | ||||||
| 
 | 
 | ||||||
| 	if (volume_name == NULL) | 	if (volume_name == NULL) | ||||||
| 		return 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); | ||||||
|  | 	free(volume_name); | ||||||
| 	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); | ||||||
| 		label[EXT2_LABEL_LEN] = 0; | 		label[EXT2_LABEL_LEN] = 0; | ||||||
| 	} | 	} | ||||||
| 	if (ext2fs != NULL) | 	if (ext2fs != NULL) | ||||||
| 		ext2fs_close(ext2fs); | 		ext2fs_close(ext2fs); | ||||||
| 	AltUnmountVolume(volume_name, TRUE); |  | ||||||
| 	return (r == 0) ? label : NULL; | 	return (r == 0) ? label : NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -879,18 +879,20 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP | ||||||
| 	} | 	} | ||||||
| 	CloseHandle(h); | 	CloseHandle(h); | ||||||
| #else | #else | ||||||
| 	volume_name = AltMountVolume(DriveIndex, PartitionOffset, FALSE); | 	volume_name = AltGetLogicalName(DriveIndex, PartitionOffset, FALSE, TRUE); | ||||||
| #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; | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
|  | 	if (strchr(volume_name, ' ') != NULL) | ||||||
|  | 		uprintf("Notice: Using physical device to access partition data"); | ||||||
| 
 | 
 | ||||||
| 	if ((strcmp(FSName, FileSystemLabel[FS_EXT2]) != 0) && (strcmp(FSName, FileSystemLabel[FS_EXT3]) != 0)) { | 	if ((strcmp(FSName, FileSystemLabel[FS_EXT2]) != 0) && (strcmp(FSName, FileSystemLabel[FS_EXT3]) != 0)) { | ||||||
| 		if (strcmp(FSName, FileSystemLabel[FS_EXT4]) == 0) | 		if (strcmp(FSName, FileSystemLabel[FS_EXT4]) == 0) | ||||||
| 			uprintf("ext4 file system is not supported, will use ext3 instead"); | 			uprintf("ext4 file system is not supported, defaulting to ext3"); | ||||||
| 		else | 		else | ||||||
| 			uprintf("invalid ext file system version requested, will use ext3"); | 			uprintf("Invalid ext file system version requested, defaulting to ext3"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if ((strcmp(FSName, FileSystemLabel[FS_EXT2]) != 0) && (strcmp(FSName, FileSystemLabel[FS_EXT3]) != 0)) | 	if ((strcmp(FSName, FileSystemLabel[FS_EXT2]) != 0) && (strcmp(FSName, FileSystemLabel[FS_EXT3]) != 0)) | ||||||
|  | @ -1097,9 +1099,9 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP | ||||||
| 	ret = TRUE; | 	ret = TRUE; | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
|  | 	free(volume_name); | ||||||
| 	ext2fs_free(ext2fs); | 	ext2fs_free(ext2fs); | ||||||
| 	free(buf); | 	free(buf); | ||||||
| 	AltUnmountVolume(volume_name, FALSE); |  | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -2411,7 +2413,7 @@ out: | ||||||
| DWORD WINAPI FormatThread(void* param) | DWORD WINAPI FormatThread(void* param) | ||||||
| { | { | ||||||
| 	int i, r; | 	int i, r; | ||||||
| 	BOOL ret, use_large_fat32, windows_to_go; | 	BOOL ret, use_large_fat32, windows_to_go, actual_lock_drive = lock_drive; | ||||||
| 	DWORD DriveIndex = (DWORD)(uintptr_t)param, ClusterSize, Flags; | 	DWORD DriveIndex = (DWORD)(uintptr_t)param, ClusterSize, Flags; | ||||||
| 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | ||||||
| 	HANDLE hLogicalVolume = INVALID_HANDLE_VALUE; | 	HANDLE hLogicalVolume = INVALID_HANDLE_VALUE; | ||||||
|  | @ -2445,9 +2447,13 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		extra_partitions = XP_CASPER; | 		extra_partitions = XP_CASPER; | ||||||
| 	else if (IsChecked(IDC_OLD_BIOS_FIXES)) | 	else if (IsChecked(IDC_OLD_BIOS_FIXES)) | ||||||
| 		extra_partitions = XP_COMPAT; | 		extra_partitions = XP_COMPAT; | ||||||
|  | 	// On pre 1703 platforms (and even on later ones), anything with ext2/ext3 doesn't sit
 | ||||||
|  | 	// too well with Windows. Relaxing our locking rules seems to help...
 | ||||||
|  | 	if ((extra_partitions == XP_CASPER) || (fs_type >= FS_EXT2)) | ||||||
|  | 		actual_lock_drive = FALSE; | ||||||
| 
 | 
 | ||||||
| 	PrintInfoDebug(0, MSG_225); | 	PrintInfoDebug(0, MSG_225); | ||||||
| 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, lock_drive, FALSE, !lock_drive); | 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, actual_lock_drive, FALSE, !actual_lock_drive); | ||||||
| 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -2499,7 +2505,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Now get RW access to the physical drive...
 | 	// Now get RW access to the physical drive...
 | ||||||
| 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, lock_drive, TRUE, !lock_drive); | 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, actual_lock_drive, TRUE, !actual_lock_drive); | ||||||
| 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED; | 		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED; | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -2507,7 +2513,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	RefreshDriveLayout(hPhysicalDrive); | 	RefreshDriveLayout(hPhysicalDrive); | ||||||
| 
 | 
 | ||||||
| 	// ...and get a lock to the logical drive so that we can actually write something
 | 	// ...and get a lock to the logical drive so that we can actually write something
 | ||||||
| 	hLogicalVolume = GetLogicalHandle(DriveIndex, 0, TRUE, FALSE, !lock_drive); | 	hLogicalVolume = GetLogicalHandle(DriveIndex, 0, TRUE, FALSE, !actual_lock_drive); | ||||||
| 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||||
| 		uprintf("Could not lock volume"); | 		uprintf("Could not lock volume"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||||
|  | @ -2724,7 +2730,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 
 | 
 | ||||||
| 	if (use_vds) { | 	if (use_vds) { | ||||||
| 		// Get RW access back to the physical drive...
 | 		// Get RW access back to the physical drive...
 | ||||||
| 		hPhysicalDrive = GetPhysicalHandle(DriveIndex, lock_drive, TRUE, !lock_drive); | 		hPhysicalDrive = GetPhysicalHandle(DriveIndex, actual_lock_drive, TRUE, !actual_lock_drive); | ||||||
| 		if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | 		if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||||
| 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED; | 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED; | ||||||
| 			goto out; | 			goto out; | ||||||
|  |  | ||||||
|  | @ -1227,7 +1227,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param) | ||||||
| 			} | 			} | ||||||
| 			if (SelectedDrive.MediaType != FixedMedia) { | 			if (SelectedDrive.MediaType != FixedMedia) { | ||||||
| 				if ((target_type == TT_UEFI) && (partition_type == PARTITION_STYLE_GPT) && (nWindowsBuildNumber < 15000)) { | 				if ((target_type == TT_UEFI) && (partition_type == PARTITION_STYLE_GPT) && (nWindowsBuildNumber < 15000)) { | ||||||
| 					// Up to Windows 10 Creators Update, we were screwed, since we need access to 2 partitions at the same time.
 | 					// Up to Windows 10 Creators Update (1703), we were screwed, since we need access to 2 partitions at the same time.
 | ||||||
| 					// Thankfully, the newer Windows allow mounting multiple partitions on the same REMOVABLE drive.
 | 					// Thankfully, the newer Windows allow mounting multiple partitions on the same REMOVABLE drive.
 | ||||||
| 					MessageBoxExU(hMainDialog, lmprintf(MSG_198), lmprintf(MSG_190), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | 					MessageBoxExU(hMainDialog, lmprintf(MSG_198), lmprintf(MSG_190), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); | ||||||
| 					goto out; | 					goto out; | ||||||
|  |  | ||||||
							
								
								
									
										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.8.1578" | CAPTION "Rufus 3.8.1579" | ||||||
| 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,8,1578,0 |  FILEVERSION 3,8,1579,0 | ||||||
|  PRODUCTVERSION 3,8,1578,0 |  PRODUCTVERSION 3,8,1579,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -413,13 +413,13 @@ BEGIN | ||||||
|             VALUE "Comments", "https://rufus.ie" |             VALUE "Comments", "https://rufus.ie" | ||||||
|             VALUE "CompanyName", "Akeo Consulting" |             VALUE "CompanyName", "Akeo Consulting" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "3.8.1578" |             VALUE "FileVersion", "3.8.1579" | ||||||
|             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/licenses/gpl-3.0.html" |             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" | ||||||
|             VALUE "OriginalFilename", "rufus-3.8.exe" |             VALUE "OriginalFilename", "rufus-3.8.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "3.8.1578" |             VALUE "ProductVersion", "3.8.1579" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue