From 500172a7a3604abd194cec984ce642c53cc280a9 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Fri, 3 Jul 2020 15:24:37 +0100 Subject: [PATCH] [core] fix format error when trying to use old BIOS fixes with VHDs * And other improvements * Closes #1409 --- src/drive.c | 25 ++++++++++++++++++------- src/format.c | 6 +++++- src/format.h | 7 ++++++- src/missing.h | 3 +++ src/rufus.c | 2 +- src/rufus.rc | 10 +++++----- 6 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/drive.c b/src/drive.c index 9222eae8..f964486d 100644 --- a/src/drive.c +++ b/src/drive.c @@ -22,6 +22,7 @@ #endif #include +#include #include #include #include @@ -507,7 +508,7 @@ BOOL RefreshLayout(DWORD DriveIndex) */ BOOL DeletePartitions(DWORD DriveIndex) { - BOOL r = FALSE; + BOOL r = FALSE, bNeverFound = TRUE; HRESULT hr; ULONG ulFetched; wchar_t wPhysicalName[24]; @@ -642,6 +643,7 @@ BOOL DeletePartitions(DWORD DriveIndex) IVdsDisk_Release(pDisk); continue; } + bNeverFound = FALSE; // Instantiate the AdvanceDisk interface for our disk. hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk); @@ -707,6 +709,8 @@ BOOL DeletePartitions(DWORD DriveIndex) } out: + if (bNeverFound) + FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_PATH_NOT_FOUND; return r; } @@ -1354,10 +1358,6 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys return FALSE; } -#if defined(__GNUC__) -// GCC 4.9 bugs us about the fact that MS defined an expandable array as array[1] -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif switch (DriveLayout->PartitionStyle) { case PARTITION_STYLE_MBR: SelectedDrive.PartitionStyle = PARTITION_STYLE_MBR; @@ -1716,8 +1716,19 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m // Go with the MS 1 MB wastage at the beginning... DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = MB; } else { - // Align on Cylinder - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = bytes_per_track; + // Some folks appear to think that 'Fixes for old BIOSes' is some kind of magic + // wand and are adamant to try to apply them when creating *MODERN* VHD drives. + // This, however, wrecks havok on MS' internal format calls because, as opposed + // to what is the case for regular drives, VHDs require each cluster block to + // be aligned to the cluster size, and that may not be the case with the stupid + // CHS sizes that IBM imparted upon us. Long story short, we now align to a + // cylinder size that is itself aligned to the cluster size. + // If this actually breaks old systems, please send your complaints to IBM. + LONGLONG ClusterSize = (LONGLONG)ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize)); + if (ClusterSize == 0) + ClusterSize = 0x200; + DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = + ((bytes_per_track + (ClusterSize - 1)) / ClusterSize) * ClusterSize; } // If required, set the MSR partition (GPT only - must be created before the data part) diff --git a/src/format.c b/src/format.c index ef2303bf..7c310546 100644 --- a/src/format.c +++ b/src/format.c @@ -181,8 +181,12 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, uprintf("No media in drive"); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_MEDIA_IN_DRIVE; break; + case FCC_ALIGNMENT_VIOLATION: + uprintf("Partition start offset is not aligned to the cluster size"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OFFSET_ALIGNMENT_VIOLATION; + break; default: - uprintf("FormatExCallback: Received unhandled command 0x02%X - aborting", Command); + uprintf("FormatExCallback: Received unhandled command 0x%02X - aborting", Command); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; break; } diff --git a/src/format.h b/src/format.h index 48aeb081..398b60a6 100644 --- a/src/format.h +++ b/src/format.h @@ -22,7 +22,7 @@ #pragma once /* Callback command types (some errorcode were filled from HPUSBFW V2.2.3 and their - designation from msdn.microsoft.com/en-us/library/windows/desktop/aa819439.aspx */ + designation from docs.microsoft.com/windows/win32/api/vds/nf-vds-ivdsvolumemf2-formatex */ typedef enum { FCC_PROGRESS, FCC_DONE_WITH_STRUCTURE, @@ -57,6 +57,11 @@ typedef enum { FCC_UNKNOWN1E, FCC_UNKNOWN1F, FCC_READ_ONLY_MODE, + FCC_UNKNOWN21, + FCC_UNKNOWN22, + FCC_UNKNOWN23, + FCC_UNKNOWN24, + FCC_ALIGNMENT_VIOLATION, } FILE_SYSTEM_CALLBACK_COMMAND; typedef struct { diff --git a/src/missing.h b/src/missing.h index 636ef10c..0a21ab2a 100644 --- a/src/missing.h +++ b/src/missing.h @@ -118,6 +118,9 @@ static __inline void *_reallocf(void *ptr, size_t size) { #ifndef HTTP_PROTOCOL_FLAG_HTTP2 #define HTTP_PROTOCOL_FLAG_HTTP2 2 #endif +#ifndef ERROR_OFFSET_ALIGNMENT_VIOLATION +#define ERROR_OFFSET_ALIGNMENT_VIOLATION 327 +#endif /* The following is used for native ISO mounting in Windows 8 or later */ #define VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT \ diff --git a/src/rufus.c b/src/rufus.c index 8947570e..d028d440 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -2230,7 +2230,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA // Try to reselect current FS from the drive for non-bootable tmp[0] = 0; if ((selected_fs == FS_UNKNOWN) && (SelectedDrive.DeviceNumber != 0)) - GetDrivePartitionData(SelectedDrive.DeviceNumber, tmp, sizeof(tmp), TRUE); + GetDrivePartitionData(SelectedDrive.DeviceNumber, tmp, sizeof(tmp), !usb_debug); SetFileSystemAndClusterSize(tmp); ToggleImageOptions(); SetProposedLabel(ComboBox_GetCurSel(hDeviceList)); diff --git a/src/rufus.rc b/src/rufus.rc index 87d1576c..2bffc811 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.12.1686" +CAPTION "Rufus 3.12.1687" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -397,8 +397,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,1686,0 - PRODUCTVERSION 3,12,1686,0 + FILEVERSION 3,12,1687,0 + PRODUCTVERSION 3,12,1687,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -416,13 +416,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.12.1686" + VALUE "FileVersion", "3.12.1687" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.12.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.12.1686" + VALUE "ProductVersion", "3.12.1687" END END BLOCK "VarFileInfo"