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; | 	BOOL r; | ||||||
| 	HANDLE hPhysical; | 	HANDLE hPhysical; | ||||||
| 	DWORD size; | 	DWORD size; | ||||||
| 	BYTE geometry[128]; | 	BYTE geometry[256]; | ||||||
| 	void* disk_geometry = (void*)geometry; | 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)(void*)geometry; | ||||||
| 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; |  | ||||||
| 
 | 
 | ||||||
| 	hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE); | 	hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE); | ||||||
| 	if (hPhysical == INVALID_HANDLE_VALUE) | 	if (hPhysical == INVALID_HANDLE_VALUE) | ||||||
|  | @ -588,11 +587,9 @@ int GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSyst | ||||||
| 	BOOL r, hasRufusExtra = FALSE; | 	BOOL r, hasRufusExtra = FALSE; | ||||||
| 	HANDLE hPhysical; | 	HANDLE hPhysical; | ||||||
| 	DWORD size; | 	DWORD size; | ||||||
| 	BYTE geometry[128], layout[4096], part_type; | 	BYTE geometry[256], layout[4096], part_type; | ||||||
| 	void* disk_geometry = (void*)geometry; | 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)(void*)geometry; | ||||||
| 	void* drive_layout = (void*)layout; | 	PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; | ||||||
| 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; |  | ||||||
| 	PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout; |  | ||||||
| 	char* volume_name; | 	char* volume_name; | ||||||
| 	char tmp[256]; | 	char tmp[256]; | ||||||
| 	DWORD i, nb_partitions = 0; | 	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]); | 		PrintStatus(0, TRUE, MSG_218, nb_steps[fs_index], nb_steps[fs_index]); | ||||||
| 		UpdateProgress(OP_CREATE_FS, 100.0f); | 		UpdateProgress(OP_CREATE_FS, 100.0f); | ||||||
| 		if(*(BOOLEAN*)pData == FALSE) { | 		if(*(BOOLEAN*)pData == FALSE) { | ||||||
| 			uprintf("Error while formatting.\n"); | 			uprintf("Error while formatting"); | ||||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; | 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; | ||||||
| 		} | 		} | ||||||
| 		break; | 		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));
 | 		// uprintf("Volume size: %s MB\n", (char*)(LONG_PTR)(*(ULONG32*)pData));
 | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_INCOMPATIBLE_FILE_SYSTEM: | 	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); | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INCOMPATIBLE_FS); | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_ACCESS_DENIED: | 	case FCC_ACCESS_DENIED: | ||||||
| 		uprintf("Access denied\n"); | 		uprintf("Access denied"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_MEDIA_WRITE_PROTECTED: | 	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; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_PROTECT; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_VOLUME_IN_USE: | 	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; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_DEVICE_IN_USE; | ||||||
| 		break; | 		break; | ||||||
|  | 	case FCC_DEVICE_NOT_READY: | ||||||
|  | 		uprintf("The device is not ready"); | ||||||
| 	case FCC_CANT_QUICK_FORMAT: | 	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); | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_QUICK_FORMAT); | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_BAD_LABEL: | 	case FCC_BAD_LABEL: | ||||||
| 		uprintf("Bad label\n"); | 		uprintf("Bad label"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_LABEL_TOO_LONG; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_LABEL_TOO_LONG; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_OUTPUT: | 	case FCC_OUTPUT: | ||||||
|  | @ -156,19 +158,19 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_CLUSTER_SIZE_TOO_BIG: | 	case FCC_CLUSTER_SIZE_TOO_BIG: | ||||||
| 	case FCC_CLUSTER_SIZE_TOO_SMALL: | 	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); | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INVALID_CLUSTER_SIZE); | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_VOLUME_TOO_BIG: | 	case FCC_VOLUME_TOO_BIG: | ||||||
| 	case FCC_VOLUME_TOO_SMALL: | 	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); | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INVALID_VOLUME_SIZE); | ||||||
| 	case FCC_NO_MEDIA_IN_DRIVE: | 	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; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_MEDIA_IN_DRIVE; | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	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; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  | @ -371,6 +373,8 @@ static BOOL FormatFAT32(DWORD DriveIndex) | ||||||
| 	HANDLE hLogicalVolume; | 	HANDLE hLogicalVolume; | ||||||
| 	DWORD cbRet; | 	DWORD cbRet; | ||||||
| 	DISK_GEOMETRY dgDrive; | 	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 piDrive; | ||||||
| 	PARTITION_INFORMATION_EX xpiDrive; | 	PARTITION_INFORMATION_EX xpiDrive; | ||||||
| 	// Recommended values
 | 	// Recommended values
 | ||||||
|  | @ -417,21 +421,28 @@ static BOOL FormatFAT32(DWORD DriveIndex) | ||||||
| 	// Work out drive params
 | 	// Work out drive params
 | ||||||
| 	if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dgDrive, | 	if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dgDrive, | ||||||
| 		sizeof(dgDrive), &cbRet, NULL)) { | 		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 (IS_ERROR(FormatStatus)) goto out; | ||||||
| 	if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &piDrive, | 	if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &piDrive, | ||||||
| 		sizeof(piDrive), &cbRet, NULL)) { | 		sizeof(piDrive), &cbRet, NULL)) { | ||||||
| 		if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &xpiDrive, | 		if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &xpiDrive, | ||||||
| 			sizeof(xpiDrive), &cbRet, NULL)) { | 			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.StartingOffset.QuadPart = xpiDrive.StartingOffset.QuadPart; | ||||||
| 		piDrive.PartitionLength.QuadPart = xpiDrive.PartitionLength.QuadPart; | 		piDrive.PartitionLength.QuadPart = xpiDrive.PartitionLength.QuadPart; | ||||||
| 		piDrive.HiddenSectors = (DWORD) (xpiDrive.StartingOffset.QuadPart / dgDrive.BytesPerSector); | 		piDrive.HiddenSectors = (DWORD) (xpiDrive.StartingOffset.QuadPart / dgDrive.BytesPerSector); | ||||||
| 	} | 	} | ||||||
|  | 	if (IS_ERROR(FormatStatus)) goto out; | ||||||
| 
 | 
 | ||||||
| 	BytesPerSect = dgDrive.BytesPerSector; | 	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
 | 		// 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
 | 		// 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.
 | 		// 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); | 	pFAT32BootSect = (FAT_BOOTSECTOR32*) calloc(BytesPerSect, 1); | ||||||
|  |  | ||||||
|  | @ -49,7 +49,7 @@ typedef enum { | ||||||
| 	FCC_UNKNOWN15, | 	FCC_UNKNOWN15, | ||||||
| 	FCC_UNKNOWN16, | 	FCC_UNKNOWN16, | ||||||
| 	FCC_UNKNOWN17, | 	FCC_UNKNOWN17, | ||||||
| 	FCC_UNKNOWN18, | 	FCC_DEVICE_NOT_READY, | ||||||
| 	FCC_CHECKDISK_PROGRESS, | 	FCC_CHECKDISK_PROGRESS, | ||||||
| 	FCC_UNKNOWN1A, | 	FCC_UNKNOWN1A, | ||||||
| 	FCC_UNKNOWN1B, | 	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 | IDD_DIALOG DIALOGEX 12, 12, 206, 329 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | 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 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||||
| BEGIN | BEGIN | ||||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 |     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 | ||||||
|  | @ -165,7 +165,7 @@ END | ||||||
| RTL_IDD_DIALOG DIALOGEX 12, 12, 206, 329 | RTL_IDD_DIALOG DIALOGEX 12, 12, 206, 329 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | 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 | 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 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||||
| BEGIN | BEGIN | ||||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 |     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 | ||||||
|  | @ -427,8 +427,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 1,4,6,442 |  FILEVERSION 1,4,6,443 | ||||||
|  PRODUCTVERSION 1,4,6,442 |  PRODUCTVERSION 1,4,6,443 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -445,13 +445,13 @@ BEGIN | ||||||
|         BEGIN |         BEGIN | ||||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" |             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "1.4.6.442" |             VALUE "FileVersion", "1.4.6.443" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus.exe" |             VALUE "OriginalFilename", "rufus.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "1.4.6.442" |             VALUE "ProductVersion", "1.4.6.443" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue