mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] improve drive geometry detection
* Try IOCTL_DISK_GET_DRIVE_GEOMETRY_EX if IOCTL_DISK_GET_DRIVE_GEOMETRY fails in Large Fat32 code * Report actual IOCTL errors * Use a larger buffer for geometry * Also add (guessed) FCC_DEVICE_NOT_READY handling to FormatEx
This commit is contained in:
		
							parent
							
								
									28c1bd6688
								
							
						
					
					
						commit
						5519212dd3
					
				
					 4 changed files with 38 additions and 30 deletions
				
			
		
							
								
								
									
										13
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -473,9 +473,8 @@ uint64_t GetDriveSize(DWORD DriveIndex) | |||
| 	BOOL r; | ||||
| 	HANDLE hPhysical; | ||||
| 	DWORD size; | ||||
| 	BYTE geometry[128]; | ||||
| 	void* disk_geometry = (void*)geometry; | ||||
| 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; | ||||
| 	BYTE geometry[256]; | ||||
| 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)(void*)geometry; | ||||
| 
 | ||||
| 	hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE); | ||||
| 	if (hPhysical == INVALID_HANDLE_VALUE) | ||||
|  | @ -588,11 +587,9 @@ int GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSyst | |||
| 	BOOL r, hasRufusExtra = FALSE; | ||||
| 	HANDLE hPhysical; | ||||
| 	DWORD size; | ||||
| 	BYTE geometry[128], layout[4096], part_type; | ||||
| 	void* disk_geometry = (void*)geometry; | ||||
| 	void* drive_layout = (void*)layout; | ||||
| 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; | ||||
| 	PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout; | ||||
| 	BYTE geometry[256], layout[4096], part_type; | ||||
| 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)(void*)geometry; | ||||
| 	PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; | ||||
| 	char* volume_name; | ||||
| 	char tmp[256]; | ||||
| 	DWORD i, nb_partitions = 0; | ||||
|  |  | |||
							
								
								
									
										41
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -116,7 +116,7 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, | |||
| 		PrintStatus(0, TRUE, MSG_218, nb_steps[fs_index], nb_steps[fs_index]); | ||||
| 		UpdateProgress(OP_CREATE_FS, 100.0f); | ||||
| 		if(*(BOOLEAN*)pData == FALSE) { | ||||
| 			uprintf("Error while formatting.\n"); | ||||
| 			uprintf("Error while formatting"); | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; | ||||
| 		} | ||||
| 		break; | ||||
|  | @ -128,27 +128,29 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, | |||
| 		// uprintf("Volume size: %s MB\n", (char*)(LONG_PTR)(*(ULONG32*)pData));
 | ||||
| 		break; | ||||
| 	case FCC_INCOMPATIBLE_FILE_SYSTEM: | ||||
| 		uprintf("Incompatible File System\n"); | ||||
| 		uprintf("Incompatible File System"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INCOMPATIBLE_FS); | ||||
| 		break; | ||||
| 	case FCC_ACCESS_DENIED: | ||||
| 		uprintf("Access denied\n"); | ||||
| 		uprintf("Access denied"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | ||||
| 		break; | ||||
| 	case FCC_MEDIA_WRITE_PROTECTED: | ||||
| 		uprintf("Media is write protected\n"); | ||||
| 		uprintf("Media is write protected"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_PROTECT; | ||||
| 		break; | ||||
| 	case FCC_VOLUME_IN_USE: | ||||
| 		uprintf("Volume is in use\n"); | ||||
| 		uprintf("Volume is in use"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_DEVICE_IN_USE; | ||||
| 		break; | ||||
| 	case FCC_DEVICE_NOT_READY: | ||||
| 		uprintf("The device is not ready"); | ||||
| 	case FCC_CANT_QUICK_FORMAT: | ||||
| 		uprintf("Cannot quick format this volume\n"); | ||||
| 		uprintf("Cannot quick format this volume"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_QUICK_FORMAT); | ||||
| 		break; | ||||
| 	case FCC_BAD_LABEL: | ||||
| 		uprintf("Bad label\n"); | ||||
| 		uprintf("Bad label"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_LABEL_TOO_LONG; | ||||
| 		break; | ||||
| 	case FCC_OUTPUT: | ||||
|  | @ -156,19 +158,19 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, | |||
| 		break; | ||||
| 	case FCC_CLUSTER_SIZE_TOO_BIG: | ||||
| 	case FCC_CLUSTER_SIZE_TOO_SMALL: | ||||
| 		uprintf("Unsupported cluster size\n"); | ||||
| 		uprintf("Unsupported cluster size"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INVALID_CLUSTER_SIZE); | ||||
| 		break; | ||||
| 	case FCC_VOLUME_TOO_BIG: | ||||
| 	case FCC_VOLUME_TOO_SMALL: | ||||
| 		uprintf("Volume is too %s\n", FCC_VOLUME_TOO_BIG?"big":"small"); | ||||
| 		uprintf("Volume is too %s", FCC_VOLUME_TOO_BIG?"big":"small"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INVALID_VOLUME_SIZE); | ||||
| 	case FCC_NO_MEDIA_IN_DRIVE: | ||||
| 		uprintf("No media in drive\n"); | ||||
| 		uprintf("No media in drive"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_MEDIA_IN_DRIVE; | ||||
| 		break; | ||||
| 	default: | ||||
| 		uprintf("FormatExCallback: received unhandled command %X\n", Command); | ||||
| 		uprintf("FormatExCallback: Received unhandled command 0x02%X - aborting", Command); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; | ||||
| 		break; | ||||
| 	} | ||||
|  | @ -371,6 +373,8 @@ static BOOL FormatFAT32(DWORD DriveIndex) | |||
| 	HANDLE hLogicalVolume; | ||||
| 	DWORD cbRet; | ||||
| 	DISK_GEOMETRY dgDrive; | ||||
| 	BYTE geometry_ex[256]; // DISK_GEOMETRY_EX is variable size
 | ||||
| 	PDISK_GEOMETRY_EX xdgDrive = (PDISK_GEOMETRY_EX)(void*)geometry_ex; | ||||
| 	PARTITION_INFORMATION piDrive; | ||||
| 	PARTITION_INFORMATION_EX xpiDrive; | ||||
| 	// Recommended values
 | ||||
|  | @ -417,21 +421,28 @@ static BOOL FormatFAT32(DWORD DriveIndex) | |||
| 	// Work out drive params
 | ||||
| 	if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dgDrive, | ||||
| 		sizeof(dgDrive), &cbRet, NULL)) { | ||||
| 		die("Failed to get device geometry\n", ERROR_NOT_SUPPORTED); | ||||
| 		if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, xdgDrive, | ||||
| 			sizeof(geometry_ex), &cbRet, NULL)) { | ||||
| 			uprintf("IOCTL_DISK_GET_DRIVE_GEOMETRY error: %s\n", WindowsErrorString()); | ||||
| 			die("Failed to get device geometry (both regular and _ex)\n", ERROR_NOT_SUPPORTED); | ||||
| 		} | ||||
| 		memcpy(&dgDrive, &xdgDrive->Geometry, sizeof(dgDrive)); | ||||
| 	} | ||||
| 	if (IS_ERROR(FormatStatus)) goto out; | ||||
| 	if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &piDrive, | ||||
| 		sizeof(piDrive), &cbRet, NULL)) { | ||||
| 		if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &xpiDrive, | ||||
| 			sizeof(xpiDrive), &cbRet, NULL)) { | ||||
| 			die("Failed to get partition info (both regular and _ex)", ERROR_NOT_SUPPORTED); | ||||
| 			uprintf("IOCTL_DISK_GET_PARTITION_INFO error: %s\n", WindowsErrorString()); | ||||
| 			die("Failed to get partition info (both regular and _ex)\n", ERROR_NOT_SUPPORTED); | ||||
| 		} | ||||
| 
 | ||||
| 		memset (&piDrive, 0, sizeof(piDrive)); | ||||
| 		memset(&piDrive, 0, sizeof(piDrive)); | ||||
| 		piDrive.StartingOffset.QuadPart = xpiDrive.StartingOffset.QuadPart; | ||||
| 		piDrive.PartitionLength.QuadPart = xpiDrive.PartitionLength.QuadPart; | ||||
| 		piDrive.HiddenSectors = (DWORD) (xpiDrive.StartingOffset.QuadPart / dgDrive.BytesPerSector); | ||||
| 	} | ||||
| 	if (IS_ERROR(FormatStatus)) goto out; | ||||
| 
 | ||||
| 	BytesPerSect = dgDrive.BytesPerSector; | ||||
| 
 | ||||
|  | @ -450,7 +461,7 @@ static BOOL FormatFAT32(DWORD DriveIndex) | |||
| 		// There would need to be an extra field in the FSInfo sector, and the old sector count could
 | ||||
| 		// be set to 0xffffffff. This is non standard though, the Windows FAT driver FASTFAT.SYS won't
 | ||||
| 		// understand this. Perhaps a future version of FAT32 and FASTFAT will handle this.
 | ||||
| 		die ("This drive is too big for FAT32 - max 2TB supported\n", APPERR(ERROR_INVALID_VOLUME_SIZE)); | ||||
| 		die("This drive is too big for FAT32 - max 2TB supported\n", APPERR(ERROR_INVALID_VOLUME_SIZE)); | ||||
| 	} | ||||
| 
 | ||||
| 	pFAT32BootSect = (FAT_BOOTSECTOR32*) calloc(BytesPerSect, 1); | ||||
|  |  | |||
|  | @ -49,7 +49,7 @@ typedef enum { | |||
| 	FCC_UNKNOWN15, | ||||
| 	FCC_UNKNOWN16, | ||||
| 	FCC_UNKNOWN17, | ||||
| 	FCC_UNKNOWN18, | ||||
| 	FCC_DEVICE_NOT_READY, | ||||
| 	FCC_CHECKDISK_PROGRESS, | ||||
| 	FCC_UNKNOWN1A, | ||||
| 	FCC_UNKNOWN1B, | ||||
|  |  | |||
							
								
								
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | |||
| 
 | ||||
| IDD_DIALOG DIALOGEX 12, 12, 206, 329 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| CAPTION "Rufus 1.4.6.442" | ||||
| CAPTION "Rufus 1.4.6.443" | ||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 | ||||
|  | @ -165,7 +165,7 @@ END | |||
| RTL_IDD_DIALOG DIALOGEX 12, 12, 206, 329 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL | ||||
| CAPTION "Rufus 1.4.6.442" | ||||
| CAPTION "Rufus 1.4.6.443" | ||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 | ||||
|  | @ -427,8 +427,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 1,4,6,442 | ||||
|  PRODUCTVERSION 1,4,6,442 | ||||
|  FILEVERSION 1,4,6,443 | ||||
|  PRODUCTVERSION 1,4,6,443 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -445,13 +445,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "1.4.6.442" | ||||
|             VALUE "FileVersion", "1.4.6.443" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||
|             VALUE "OriginalFilename", "rufus.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "1.4.6.442" | ||||
|             VALUE "ProductVersion", "1.4.6.443" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue