[core] make sure the main partition size is aligned to the cluster size

* Having NTFS partitions properly aligned to the cluster size can drastically
  improve the speed of capturing a disk to an FFU image, as, when the size
  is aligned, the FFU capture uses the actual NTFS allocation map to only read
  and capture the clusters that are actually in use, whereas, if no aligned,
  FFU capture falls back to a sector by sector copy that is both much slower
  and also includes unwanted leftover garbage.
* Also only enable FFU when we detect FFUProvider.dll as a system library.
This commit is contained in:
Pete Batard 2023-07-04 13:26:04 +01:00
parent 0b1c68635a
commit 10dbfdd7e1
No known key found for this signature in database
GPG Key ID: 38E0CF5E69EDD671
3 changed files with 24 additions and 14 deletions

View File

@ -2269,8 +2269,8 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
const DWORD size_to_clear = MAX_SECTORS_TO_CLEAR * SelectedDrive.SectorSize;
uint8_t* buffer;
size_t uefi_ntfs_size = 0;
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}};
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
CREATE_DISK CreateDisk = { PARTITION_STYLE_RAW, { { 0 } } };
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = { 0 };
BOOL r;
DWORD i, size, bufsize, pn = 0;
LONGLONG main_part_size_in_sectors, extra_part_size_in_tracks = 0;
@ -2278,9 +2278,13 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
// https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions
// and folks using MacOS: https://github.com/pbatard/rufus/issues/979
LONGLONG esp_size = 260 * MB;
LONGLONG ClusterSize = (LONGLONG)ComboBox_GetCurItemData(hClusterSize);
PrintInfoDebug(0, MSG_238, PartitionTypeName[partition_style]);
if (ClusterSize == 0)
ClusterSize = 0x200;
if (partition_style == PARTITION_STYLE_SFD)
// Nothing to do
return TRUE;
@ -2307,9 +2311,6 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
// 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_GetCurItemData(hClusterSize);
if (ClusterSize == 0)
ClusterSize = 0x200;
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart =
((bytes_per_track + (ClusterSize - 1)) / ClusterSize) * ClusterSize;
// GRUB2 no longer fits in the usual 31½ KB that the above computation provides
@ -2399,6 +2400,16 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
main_part_size_in_sectors = ((main_part_size_in_sectors / SelectedDrive.SectorsPerTrack) -
extra_part_size_in_tracks) * SelectedDrive.SectorsPerTrack;
}
// Try to make sure that the main partition size is a multiple of the cluster size
// This can be especially important when trying to capture an NTFS partition as FFU, as, when
// the NTFS partition is aligned to cluster size, the FFU capture parses the NTFS allocated
// map to only record clusters that are in use, whereas, if not aligned, the FFU capture uses
// a full sector by sector scan of the NTFS partition and records any non-zero garbage, which
// may include garbage leftover data from a previous reformat...
if (ClusterSize % SelectedDrive.SectorSize == 0) {
main_part_size_in_sectors = (((main_part_size_in_sectors * SelectedDrive.SectorSize) /
ClusterSize) * ClusterSize) / SelectedDrive.SectorSize;
}
if (main_part_size_in_sectors <= 0) {
uprintf("Error: Invalid %S size", main_part_name);
return FALSE;

View File

@ -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 4.2.2062"
CAPTION "Rufus 4.2.2063"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -392,8 +392,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,2,2062,0
PRODUCTVERSION 4,2,2062,0
FILEVERSION 4,2,2063,0
PRODUCTVERSION 4,2,2063,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -411,13 +411,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "4.2.2062"
VALUE "FileVersion", "4.2.2063"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-4.2.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "4.2.2062"
VALUE "ProductVersion", "4.2.2063"
END
END
BLOCK "VarFileInfo"

View File

@ -1023,10 +1023,9 @@ void SaveVHD(void)
static_sprintf(filename, "%s.vhdx", rufus_drive[DriveIndex].label);
img_save.DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, DriveIndex);
img_save.DevicePath = GetPhysicalName(img_save.DeviceNum);
// FFU support started with Windows 10 1709 (build 16299) and requires GPT
// TODO: Better check for FFU compatibility
if (WindowsVersion.Major < 10 || WindowsVersion.BuildNumber < 16299 ||
SelectedDrive.PartitionStyle != PARTITION_STYLE_GPT)
// FFU support started with Windows 10 1709 (through FfuProvider.dll) and requires GPT
static_sprintf(path, "%s\\dism\\FfuProvider.dll", sysnative_dir);
if ((_accessU(path, 0) != 0) || SelectedDrive.PartitionStyle != PARTITION_STYLE_GPT)
img_ext.count = 2;
img_save.ImagePath = FileDialog(TRUE, NULL, &img_ext, 0);
img_save.Type = VIRTUAL_STORAGE_TYPE_DEVICE_VHD;