From 5519212dd31c09faa3ceb92eea417acf5c790d3a Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Sat, 29 Mar 2014 00:17:41 +0000 Subject: [PATCH] [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 --- src/drive.c | 13 +++++-------- src/format.c | 41 ++++++++++++++++++++++++++--------------- src/format.h | 2 +- src/rufus.rc | 12 ++++++------ 4 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/drive.c b/src/drive.c index 703fb06f..7116a126 100644 --- a/src/drive.c +++ b/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; diff --git a/src/format.c b/src/format.c index 1b74bd8e..4af1f248 100644 --- a/src/format.c +++ b/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); diff --git a/src/format.h b/src/format.h index 78b14904..bfedab96 100644 --- a/src/format.h +++ b/src/format.h @@ -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, diff --git a/src/rufus.rc b/src/rufus.rc index 15e5d67d..10e54cde 100644 --- a/src/rufus.rc +++ b/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"