Skip to content

Commit

Permalink
[misc] refactor partition creation
Browse files Browse the repository at this point in the history
  • Loading branch information
pbatard committed Feb 8, 2024
1 parent 164d4b0 commit 0f23c47
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 246 deletions.
386 changes: 176 additions & 210 deletions src/drive.c

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions src/drive.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@
#define XP_ESP 0x02
#define XP_UEFI_NTFS 0x04
#define XP_COMPAT 0x08
#define XP_CASPER 0x10
#define XP_PERSISTENCE 0x10

#define PI_MAIN 0
#define PI_ESP 1
#define PI_CASPER 2
#define PI_MAX 3
#define PI_UEFI_NTFS 3
#define PI_MAX 4

// The following should match VDS_FSOF_FLAGS as much as possible
#define FP_FORCE 0x00000001
Expand Down Expand Up @@ -362,8 +363,11 @@ typedef struct {
MEDIA_TYPE MediaType;
int PartitionStyle;
int nPartitions; // number of partitions we actually care about
uint64_t PartitionOffset[MAX_PARTITIONS];
uint64_t PartitionSize[MAX_PARTITIONS];
struct {
wchar_t Name[36];
uint64_t Offset;
uint64_t Size;
} Partition[MAX_PARTITIONS];
int FSType;
char proposed_label[16];
BOOL has_protective_mbr;
Expand All @@ -374,7 +378,7 @@ typedef struct {
} ClusterSize[FS_MAX];
} RUFUS_DRIVE_INFO;
extern RUFUS_DRIVE_INFO SelectedDrive;
extern uint64_t partition_offset[PI_MAX];
extern int partition_index[PI_MAX];

BOOL SetAutoMount(BOOL enable);
BOOL GetAutoMount(BOOL* enabled);
Expand Down
53 changes: 31 additions & 22 deletions src/format.c
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
}

// Ensure that we have sufficient space for the SBR
max_size = (DWORD)SelectedDrive.PartitionOffset[0];
max_size = (DWORD)SelectedDrive.Partition[0].Offset;
if (br_size + size > max_size) {
uprintf(" SBR size is too large - You may need to uncheck 'Add fixes for old BIOSes'.");
if (sub_type == BT_MAX)
Expand Down Expand Up @@ -1456,23 +1456,32 @@ DWORD WINAPI FormatThread(void* param)
large_drive = (SelectedDrive.DiskSize > (1*TB));
if (large_drive)
uprintf("Notice: Large drive detected (may produce short writes)");

// Find out if we need to add any extra partitions
extra_partitions = 0;
if ((boot_type == BT_IMAGE) && !write_as_image && HAS_PERSISTENCE(img_report) && persistence_size)
extra_partitions |= XP_PERSISTENCE;
// According to Microsoft, every GPT disk (we RUN Windows from) must have an MSR due to not having hidden sectors
// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-and-gpt-faq#disks-that-require-an-msr
if ((windows_to_go) && (target_type == TT_UEFI) && (partition_type == PARTITION_STYLE_GPT))
// According to Microsoft, every GPT disk (we RUN Windows from) must have an MSR due to not having hidden sectors
// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-and-gpt-faq#disks-that-require-an-msr
extra_partitions = XP_ESP | XP_MSR;
else if ( ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) &&
((boot_type == BT_UEFI_NTFS) || ((boot_type == BT_IMAGE) && IS_EFI_BOOTABLE(img_report) &&
((target_type == TT_UEFI) || (windows_to_go) || (allow_dual_uefi_bios) ||
(img_report.has_4GB_file) || (img_report.needs_ntfs)))) )
extra_partitions = XP_UEFI_NTFS;
else if ((boot_type == BT_IMAGE) && !write_as_image && HAS_PERSISTENCE(img_report) && persistence_size)
extra_partitions = XP_CASPER;
else if (IsChecked(IDC_OLD_BIOS_FIXES))
extra_partitions = XP_COMPAT;
extra_partitions |= XP_ESP | XP_MSR;
// If we have a bootable image with UEFI bootloaders and the target file system is NTFS or exFAT
// or the UEFI:NTFS option is selected, we add the UEFI:NTFS partition...
else if (((boot_type == BT_IMAGE) && IS_EFI_BOOTABLE(img_report)) && ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) ||
(boot_type == BT_UEFI_NTFS)) {
extra_partitions |= XP_UEFI_NTFS;
// ...but only if we're not dealing with a Windows image in installer mode with target
// system set to BIOS and without dual BIOS+UEFI boot enabled.
if ((boot_type == BT_IMAGE) && HAS_BOOTMGR_BIOS(img_report) && (!windows_to_go) &&
(target_type == TT_BIOS) && (!allow_dual_uefi_bios))
extra_partitions &= ~XP_UEFI_NTFS;
}
if (IsChecked(IDC_OLD_BIOS_FIXES))
extra_partitions |= XP_COMPAT;

// On pre 1703 platforms (and even on later ones), anything with ext2/ext3 doesn't sit
// too well with Windows. Same with ESPs. Relaxing our locking rules seems to help...
if ((extra_partitions & (XP_ESP | XP_CASPER)) || IS_EXT(fs_type))
if ((extra_partitions & (XP_ESP | XP_PERSISTENCE)) || IS_EXT(fs_type))
actual_lock_drive = FALSE;
// Windows 11 is a lot more proactive in locking ESPs and MSRs than previous versions
// were, meaning that we also can't lock the drive without incurring errors...
Expand Down Expand Up @@ -1710,13 +1719,13 @@ DWORD WINAPI FormatThread(void* param)
Sleep(200);
if (write_as_esp || write_as_ext) {
// Can't format ESPs or ext2/ext3 partitions unless we mount them ourselves
volume_name = AltMountVolume(DriveIndex, partition_offset[PI_MAIN], FALSE);
volume_name = AltMountVolume(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, FALSE);
if (volume_name == NULL) {
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER);
goto out;
}
} else {
if (!WaitForLogical(DriveIndex, partition_offset[PI_MAIN])) {
if (!WaitForLogical(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset)) {
uprintf("Logical drive was not found - aborting");
if (!IS_ERROR(FormatStatus))
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_TIMEOUT;
Expand All @@ -1727,12 +1736,12 @@ DWORD WINAPI FormatThread(void* param)

// Format Casper partition if required. Do it before we format anything with
// a file system that Windows will recognize, to avoid concurrent access.
if (extra_partitions & XP_CASPER) {
if (extra_partitions & XP_PERSISTENCE) {
uint32_t ext_version = ReadSetting32(SETTING_USE_EXT_VERSION);
if ((ext_version < 2) || (ext_version > 4))
ext_version = 3;
uprintf("Using %s-like method to enable persistence", img_report.uses_casper ? "Ubuntu" : "Debian");
if (!FormatPartition(DriveIndex, partition_offset[PI_CASPER], 0, FS_EXT2 + (ext_version - 2),
if (!FormatPartition(DriveIndex, SelectedDrive.Partition[partition_index[PI_CASPER]].Offset, 0, FS_EXT2 + (ext_version - 2),
img_report.uses_casper ? "casper-rw" : "persistence",
(img_report.uses_casper ? 0 : FP_CREATE_PERSISTENCE_CONF) |
(IsChecked(IDC_QUICK_FORMAT) ? FP_QUICK : 0))) {
Expand All @@ -1757,7 +1766,7 @@ DWORD WINAPI FormatThread(void* param)
if (write_as_esp)
Flags |= FP_LARGE_FAT32;

ret = FormatPartition(DriveIndex, partition_offset[PI_MAIN], ClusterSize, fs_type, label, Flags);
ret = FormatPartition(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, ClusterSize, fs_type, label, Flags);
if (!ret) {
// Error will be set by FormatPartition() in FormatStatus
uprintf("Format error: %s", StrError(FormatStatus, TRUE));
Expand Down Expand Up @@ -1790,7 +1799,7 @@ DWORD WINAPI FormatThread(void* param)
// Try to continue
CHECK_FOR_USER_CANCEL;

volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE);
volume_name = GetLogicalName(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, TRUE, TRUE);
if (volume_name == NULL) {
uprintf("Could not get volume name");
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NO_VOLUME_ID;
Expand Down Expand Up @@ -1848,7 +1857,7 @@ DWORD WINAPI FormatThread(void* param)
} else {
// We still have a lock, which we need to modify the volume boot record
// => no need to reacquire the lock...
hLogicalVolume = GetLogicalHandle(DriveIndex, partition_offset[PI_MAIN], FALSE, TRUE, FALSE);
hLogicalVolume = GetLogicalHandle(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, FALSE, TRUE, FALSE);
if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) {
uprintf("Could not re-mount volume for partition boot record access");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
Expand Down Expand Up @@ -1999,7 +2008,7 @@ DWORD WINAPI FormatThread(void* param)
}
}
if (IS_ERROR(FormatStatus)) {
volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE);
volume_name = GetLogicalName(DriveIndex, SelectedDrive.Partition[partition_index[PI_MAIN]].Offset, TRUE, TRUE);
if (volume_name != NULL) {
if (MountVolume(drive_name, volume_name))
uprintf("Re-mounted volume as %c: after error", toupper(drive_name[0]));
Expand Down
5 changes: 4 additions & 1 deletion src/missing.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Constants and defines missing from various toolchains
* Copyright © 2016-2022 Pete Batard <[email protected]>
* Copyright © 2016-2024 Pete Batard <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -31,6 +31,9 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif

#define LO_ALIGN_X_TO_Y(x, y) (((x) / (y)) * (y))
#define HI_ALIGN_X_TO_Y(x, y) ((((x) + (y) - 1) / (y)) * (y))

#if defined(__GNUC__)
#define ALIGNED(m) __attribute__ ((__aligned__(m)))
#elif defined(_MSC_VER)
Expand Down
10 changes: 5 additions & 5 deletions src/rufus.rc
Original file line number Diff line number Diff line change
Expand Up @@ -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.5.2109"
CAPTION "Rufus 4.5.2110"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
Expand Down Expand Up @@ -392,8 +392,8 @@ END
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,5,2109,0
PRODUCTVERSION 4,5,2109,0
FILEVERSION 4,5,2110,0
PRODUCTVERSION 4,5,2110,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
Expand All @@ -411,13 +411,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "4.5.2109"
VALUE "FileVersion", "4.5.2110"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "� 2011-2024 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-4.5.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "4.5.2109"
VALUE "ProductVersion", "4.5.2110"
END
END
BLOCK "VarFileInfo"
Expand Down
6 changes: 3 additions & 3 deletions src/wue.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Windows User Experience
* Copyright © 2022-2023 Pete Batard <[email protected]>
* Copyright © 2022-2024 Pete Batard <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -690,14 +690,14 @@ BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
// VDS cannot list ESP volumes (talk about allegedly improving on the old disk and volume APIs, only to
// completely neuter it) and IVdsDiskPartitionMF::FormatPartitionEx(), which is what you are supposed to
// use for ESPs, explicitly states: "This method cannot be used to format removable media."
if (!FormatPartition(DriveIndex, partition_offset[PI_ESP], cluster_size, FS_FAT32, "",
if (!FormatPartition(DriveIndex, SelectedDrive.Partition[partition_index[PI_ESP]].Offset, cluster_size, FS_FAT32, "",
FP_QUICK | FP_FORCE | FP_LARGE_FAT32 | FP_NO_BOOT)) {
uprintf("Could not format EFI System Partition");
return FALSE;
}
Sleep(200);
// Need to have the ESP mounted to invoke bcdboot
ms_efi = AltMountVolume(DriveIndex, partition_offset[PI_ESP], FALSE);
ms_efi = AltMountVolume(DriveIndex, SelectedDrive.Partition[partition_index[PI_ESP]].Offset, FALSE);
if (ms_efi == NULL) {
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER);
return FALSE;
Expand Down

0 comments on commit 0f23c47

Please sign in to comment.