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…
Reference in a new issue