mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[misc] refactor partition creation
This commit is contained in:
parent
164d4b0ab0
commit
0f23c47184
6 changed files with 229 additions and 247 deletions
388
src/drive.c
388
src/drive.c
|
@ -74,7 +74,7 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryVolumeInformationFile, (HANDLE, PIO_STATUS_
|
||||||
RUFUS_DRIVE_INFO SelectedDrive;
|
RUFUS_DRIVE_INFO SelectedDrive;
|
||||||
extern BOOL write_as_esp;
|
extern BOOL write_as_esp;
|
||||||
extern windows_version_t WindowsVersion;
|
extern windows_version_t WindowsVersion;
|
||||||
uint64_t partition_offset[PI_MAX];
|
int partition_index[PI_MAX];
|
||||||
uint64_t persistence_size = 0;
|
uint64_t persistence_size = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -392,7 +392,7 @@ char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTr
|
||||||
if (PartitionOffset == 0) {
|
if (PartitionOffset == 0) {
|
||||||
i = 0;
|
i = 0;
|
||||||
} else if (matching_drive) {
|
} else if (matching_drive) {
|
||||||
for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.PartitionOffset[i]); i++);
|
for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.Partition[i].Offset); i++);
|
||||||
if (i >= MAX_PARTITIONS) {
|
if (i >= MAX_PARTITIONS) {
|
||||||
suprintf("Error: Could not find a partition at offset %lld on this disk", PartitionOffset);
|
suprintf("Error: Could not find a partition at offset %lld on this disk", PartitionOffset);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -428,11 +428,11 @@ char* GetExtPartitionName(DWORD DriveIndex, uint64_t PartitionOffset)
|
||||||
if (DriveIndex != SelectedDrive.DeviceNumber)
|
if (DriveIndex != SelectedDrive.DeviceNumber)
|
||||||
goto out;
|
goto out;
|
||||||
CheckDriveIndex(DriveIndex);
|
CheckDriveIndex(DriveIndex);
|
||||||
for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.PartitionOffset[i]); i++);
|
for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != SelectedDrive.Partition[i].Offset); i++);
|
||||||
if (i >= MAX_PARTITIONS)
|
if (i >= MAX_PARTITIONS)
|
||||||
goto out;
|
goto out;
|
||||||
static_sprintf(volume_name, "\\\\.\\PhysicalDrive%lu %I64u %I64u", DriveIndex,
|
static_sprintf(volume_name, "\\\\.\\PhysicalDrive%lu %I64u %I64u", DriveIndex,
|
||||||
SelectedDrive.PartitionOffset[i], SelectedDrive.PartitionSize[i]);
|
SelectedDrive.Partition[i].Offset, SelectedDrive.Partition[i].Size);
|
||||||
ret = safe_strdup(volume_name);
|
ret = safe_strdup(volume_name);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1868,8 +1868,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
SelectedDrive.nPartitions = 0;
|
SelectedDrive.nPartitions = 0;
|
||||||
memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset));
|
memset(SelectedDrive.Partition, 0, sizeof(SelectedDrive.Partition));
|
||||||
memset(SelectedDrive.PartitionSize, 0, sizeof(SelectedDrive.PartitionSize));
|
|
||||||
// Populate the filesystem data
|
// Populate the filesystem data
|
||||||
FileSystemName[0] = 0;
|
FileSystemName[0] = 0;
|
||||||
volume_name = GetLogicalName(DriveIndex, 0, TRUE, FALSE);
|
volume_name = GetLogicalName(DriveIndex, 0, TRUE, FALSE);
|
||||||
|
@ -1961,8 +1960,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < MAX_PARTITIONS) {
|
if (i < MAX_PARTITIONS) {
|
||||||
SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart;
|
SelectedDrive.Partition[i].Offset = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart;
|
||||||
SelectedDrive.PartitionSize[i] = DriveLayout->PartitionEntry[i].PartitionLength.QuadPart;
|
SelectedDrive.Partition[i].Size = DriveLayout->PartitionEntry[i].PartitionLength.QuadPart;
|
||||||
}
|
}
|
||||||
suprintf(" Type: %s (0x%02x)\r\n Detected File System: %s\r\n"
|
suprintf(" Type: %s (0x%02x)\r\n Detected File System: %s\r\n"
|
||||||
" Size: %s (%lld bytes)\r\n Start Sector: %lld, Boot: %s",
|
" Size: %s (%lld bytes)\r\n Start Sector: %lld, Boot: %s",
|
||||||
|
@ -1992,12 +1991,13 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
||||||
DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart);
|
DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart);
|
||||||
for (i = 0; i < DriveLayout->PartitionCount; i++) {
|
for (i = 0; i < DriveLayout->PartitionCount; i++) {
|
||||||
if (i < MAX_PARTITIONS) {
|
if (i < MAX_PARTITIONS) {
|
||||||
SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart;
|
SelectedDrive.Partition[i].Offset = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart;
|
||||||
SelectedDrive.PartitionSize[i] = DriveLayout->PartitionEntry[i].PartitionLength.QuadPart;
|
SelectedDrive.Partition[i].Size = DriveLayout->PartitionEntry[i].PartitionLength.QuadPart;
|
||||||
|
wcscpy(SelectedDrive.Partition[i].Name, DriveLayout->PartitionEntry[i].Gpt.Name);
|
||||||
}
|
}
|
||||||
SelectedDrive.nPartitions++;
|
SelectedDrive.nPartitions++;
|
||||||
isUefiNtfs = (wcscmp(DriveLayout->PartitionEntry[i].Gpt.Name, L"UEFI:NTFS") == 0);
|
isUefiNtfs = (wcscmp(DriveLayout->PartitionEntry[i].Gpt.Name, L"UEFI:NTFS") == 0);
|
||||||
suprintf("Partition %d%s:\r\n Type: %s", i+1, isUefiNtfs ? " (UEFI:NTFS)" : "",
|
suprintf("Partition %d%s:\r\n Type: %s", i + 1, isUefiNtfs ? " (UEFI:NTFS)" : "",
|
||||||
GetGPTPartitionType(&DriveLayout->PartitionEntry[i].Gpt.PartitionType));
|
GetGPTPartitionType(&DriveLayout->PartitionEntry[i].Gpt.PartitionType));
|
||||||
if (DriveLayout->PartitionEntry[i].Gpt.Name[0] != 0)
|
if (DriveLayout->PartitionEntry[i].Gpt.Name[0] != 0)
|
||||||
suprintf(" Name: '%S'", DriveLayout->PartitionEntry[i].Gpt.Name);
|
suprintf(" Name: '%S'", DriveLayout->PartitionEntry[i].Gpt.Name);
|
||||||
|
@ -2232,15 +2232,17 @@ BOOL RemountVolume(char* drive_name, BOOL bSilent)
|
||||||
* (especially IOCTL_DISK_UPDATE_PROPERTIES is *USELESS*), and therefore the OS will try to
|
* (especially IOCTL_DISK_UPDATE_PROPERTIES is *USELESS*), and therefore the OS will try to
|
||||||
* read the file system data at an old location, even if the partition has just been deleted.
|
* read the file system data at an old location, even if the partition has just been deleted.
|
||||||
*/
|
*/
|
||||||
static BOOL ClearPartition(HANDLE hDrive, LARGE_INTEGER offset, DWORD size)
|
static BOOL ClearPartition(HANDLE hDrive, uint64_t offset, DWORD size)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
uint8_t* buffer = calloc(size, 1);
|
uint8_t* buffer = calloc(size, 1);
|
||||||
|
LARGE_INTEGER li_offset;
|
||||||
|
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!SetFilePointerEx(hDrive, offset, NULL, FILE_BEGIN)) {
|
li_offset.QuadPart = offset;
|
||||||
|
if (!SetFilePointerEx(hDrive, li_offset, NULL, FILE_BEGIN)) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2260,17 +2262,14 @@ static BOOL ClearPartition(HANDLE hDrive, LARGE_INTEGER offset, DWORD size)
|
||||||
BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions)
|
BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions)
|
||||||
{
|
{
|
||||||
const char* PartitionTypeName[] = { "MBR", "GPT", "SFD" };
|
const char* PartitionTypeName[] = { "MBR", "GPT", "SFD" };
|
||||||
const wchar_t *extra_part_name = L"", *main_part_name = write_as_esp ? L"EFI System Partition" : L"Main Data Partition";
|
|
||||||
const LONGLONG main_part_size = write_as_esp ? MAX_ISO_TO_ESP_SIZE * MB : SelectedDrive.DiskSize;
|
|
||||||
const LONGLONG bytes_per_track = ((LONGLONG)SelectedDrive.SectorsPerTrack) * SelectedDrive.SectorSize;
|
const LONGLONG bytes_per_track = ((LONGLONG)SelectedDrive.SectorsPerTrack) * SelectedDrive.SectorSize;
|
||||||
const DWORD size_to_clear = MAX_SECTORS_TO_CLEAR * SelectedDrive.SectorSize;
|
const DWORD size_to_clear = MAX_SECTORS_TO_CLEAR * SelectedDrive.SectorSize;
|
||||||
uint8_t* buffer;
|
uint8_t* buffer;
|
||||||
|
uint64_t last_offset = SelectedDrive.DiskSize;
|
||||||
size_t uefi_ntfs_size = 0;
|
size_t uefi_ntfs_size = 0;
|
||||||
|
DWORD pi = 0, mi, i, size, bufsize;
|
||||||
CREATE_DISK CreateDisk = { PARTITION_STYLE_RAW, { { 0 } } };
|
CREATE_DISK CreateDisk = { PARTITION_STYLE_RAW, { { 0 } } };
|
||||||
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = { 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;
|
|
||||||
// Go for a 260 MB sized ESP by default to keep everyone happy, including 4K sector users:
|
// Go for a 260 MB sized ESP by default to keep everyone happy, including 4K sector users:
|
||||||
// https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions
|
// 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
|
// and folks using MacOS: https://github.com/pbatard/rufus/issues/979
|
||||||
|
@ -2288,17 +2287,19 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
|
|
||||||
if (extra_partitions & XP_UEFI_NTFS) {
|
if (extra_partitions & XP_UEFI_NTFS) {
|
||||||
uefi_ntfs_size = GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA, "uefi-ntfs.img");
|
uefi_ntfs_size = GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA, "uefi-ntfs.img");
|
||||||
if (uefi_ntfs_size == 0)
|
if (uefi_ntfs_size == 0) {
|
||||||
|
uprintf("Could not access embedded 'uefi-ntfs.img'");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memset(partition_offset, 0, sizeof(partition_offset));
|
|
||||||
memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset));
|
|
||||||
memset(SelectedDrive.PartitionSize, 0, sizeof(SelectedDrive.PartitionSize));
|
|
||||||
|
|
||||||
// Compute the start offset of our first partition
|
memset(partition_index, 0, sizeof(partition_index));
|
||||||
|
memset(SelectedDrive.Partition, 0, sizeof(SelectedDrive.Partition));
|
||||||
|
|
||||||
|
// Compute the starting offset of the first partition
|
||||||
if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_OLD_BIOS_FIXES))) {
|
if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_OLD_BIOS_FIXES))) {
|
||||||
// Go with the MS 1 MB wastage at the beginning...
|
// Go with the MS 1 MB wastage at the beginning...
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = MB;
|
SelectedDrive.Partition[pi].Offset = 1 * MB;
|
||||||
} else {
|
} else {
|
||||||
// Some folks appear to think that 'Fixes for old BIOSes' is some kind of magic
|
// 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.
|
// wand and are adamant to try to apply them when creating *MODERN* VHD drives.
|
||||||
|
@ -2308,11 +2309,10 @@ 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
|
// 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.
|
// cylinder size that is itself aligned to the cluster size.
|
||||||
// If this actually breaks old systems, please send your complaints to IBM.
|
// If this actually breaks old systems, please send your complaints to IBM.
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart =
|
SelectedDrive.Partition[pi].Offset = HI_ALIGN_X_TO_Y(bytes_per_track, ClusterSize);
|
||||||
((bytes_per_track + (ClusterSize - 1)) / ClusterSize) * ClusterSize;
|
|
||||||
// GRUB2 no longer fits in the usual 31½ KB that the above computation provides
|
// GRUB2 no longer fits in the usual 31½ KB that the above computation provides
|
||||||
// so just unconditionally double that size and get on with it.
|
// so just unconditionally double that size and get on with it.
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart *= 2;
|
SelectedDrive.Partition[pi].Offset *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Having the ESP up front may help (and is the Microsoft recommended way) but this
|
// Having the ESP up front may help (and is the Microsoft recommended way) but this
|
||||||
|
@ -2321,22 +2321,16 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
if (((SelectedDrive.MediaType == FixedMedia) || (WindowsVersion.BuildNumber > 15000)) &&
|
if (((SelectedDrive.MediaType == FixedMedia) || (WindowsVersion.BuildNumber > 15000)) &&
|
||||||
(extra_partitions & XP_ESP)) {
|
(extra_partitions & XP_ESP)) {
|
||||||
assert(partition_style == PARTITION_STYLE_GPT);
|
assert(partition_style == PARTITION_STYLE_GPT);
|
||||||
extra_part_name = L"EFI System Partition";
|
partition_index[PI_ESP] = pi;
|
||||||
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = esp_size;
|
wcscpy(SelectedDrive.Partition[pi].Name, L"EFI System Partition");
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_GENERIC_ESP;
|
SelectedDrive.Partition[pi].Size = esp_size;
|
||||||
uprintf("● Creating %S (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart,
|
SelectedDrive.Partition[pi + 1].Offset = SelectedDrive.Partition[pi].Offset + SelectedDrive.Partition[pi].Size;
|
||||||
SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE));
|
// Align next partition to track and cluster
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
SelectedDrive.Partition[pi + 1].Offset = HI_ALIGN_X_TO_Y(SelectedDrive.Partition[pi + 1].Offset, bytes_per_track);
|
||||||
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, extra_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
if (ClusterSize % SelectedDrive.SectorSize == 0)
|
||||||
// Zero the first sectors from this partition to avoid file system caching issues
|
SelectedDrive.Partition[pi + 1].Offset = LO_ALIGN_X_TO_Y(SelectedDrive.Partition[pi + 1].Offset, ClusterSize);
|
||||||
if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear))
|
assert(SelectedDrive.Partition[pi + 1].Offset >= SelectedDrive.Partition[pi].Offset + SelectedDrive.Partition[pi].Size);
|
||||||
uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString());
|
pi++;
|
||||||
SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart;
|
|
||||||
SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart;
|
|
||||||
partition_offset[PI_ESP] = SelectedDrive.PartitionOffset[pn];
|
|
||||||
pn++;
|
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn - 1].StartingOffset.QuadPart +
|
|
||||||
DriveLayoutEx.PartitionEntry[pn - 1].PartitionLength.QuadPart;
|
|
||||||
// Clear the extra partition we processed
|
// Clear the extra partition we processed
|
||||||
extra_partitions &= ~(XP_ESP);
|
extra_partitions &= ~(XP_ESP);
|
||||||
}
|
}
|
||||||
|
@ -2344,192 +2338,165 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
// If required, set the MSR partition (GPT only - must be created before the data part)
|
// If required, set the MSR partition (GPT only - must be created before the data part)
|
||||||
if (extra_partitions & XP_MSR) {
|
if (extra_partitions & XP_MSR) {
|
||||||
assert(partition_style == PARTITION_STYLE_GPT);
|
assert(partition_style == PARTITION_STYLE_GPT);
|
||||||
extra_part_name = L"Microsoft Reserved Partition";
|
wcscpy(SelectedDrive.Partition[pi].Name, L"Microsoft Reserved Partition");
|
||||||
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = 128*MB;
|
SelectedDrive.Partition[pi].Size = 128 * MB;
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MICROSOFT_RESERVED;
|
SelectedDrive.Partition[pi + 1].Offset = SelectedDrive.Partition[pi].Offset + SelectedDrive.Partition[pi].Size;
|
||||||
uprintf("● Creating %S (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart,
|
SelectedDrive.Partition[pi + 1].Offset = HI_ALIGN_X_TO_Y(SelectedDrive.Partition[pi + 1].Offset, bytes_per_track);
|
||||||
SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE));
|
if (ClusterSize % SelectedDrive.SectorSize == 0)
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
SelectedDrive.Partition[pi + 1].Offset = LO_ALIGN_X_TO_Y(SelectedDrive.Partition[pi + 1].Offset, ClusterSize);
|
||||||
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, extra_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
assert(SelectedDrive.Partition[pi + 1].Offset >= SelectedDrive.Partition[pi].Offset + SelectedDrive.Partition[pi].Size);
|
||||||
// Zero the first sectors from this partition to avoid file system caching issues
|
pi++;
|
||||||
if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear))
|
|
||||||
uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString());
|
|
||||||
SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart;
|
|
||||||
SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart;
|
|
||||||
pn++;
|
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart +
|
|
||||||
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
|
||||||
// Clear the extra partition we processed
|
|
||||||
extra_partitions &= ~(XP_MSR);
|
extra_partitions &= ~(XP_MSR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our main data partition
|
// Reserve an entry for the main partition
|
||||||
if (write_as_esp) {
|
partition_index[PI_MAIN] = pi++;
|
||||||
// Align ESP to 64 MB while leaving at least 32 MB free space
|
// Shorthand for the main index.
|
||||||
esp_size = max(esp_size, ((((LONGLONG)img_report.projected_size / MB) + 96) / 64) * 64 * MB);
|
mi = partition_index[PI_MAIN];
|
||||||
main_part_size_in_sectors = (esp_size - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) /
|
wcscpy(SelectedDrive.Partition[mi].Name, write_as_esp ? L"EFI System Partition" : L"Main Data Partition");
|
||||||
SelectedDrive.SectorSize;
|
|
||||||
} else {
|
|
||||||
main_part_size_in_sectors = (main_part_size - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) /
|
|
||||||
// Need 33 sectors at the end for secondary GPT
|
|
||||||
SelectedDrive.SectorSize - ((partition_style == PARTITION_STYLE_GPT) ? 33 : 0);
|
|
||||||
}
|
|
||||||
if (extra_partitions) {
|
if (extra_partitions) {
|
||||||
// Adjust the size according to extra partitions (which we always align to a track)
|
// Adjust the size according to extra partitions (which we always align to a track)
|
||||||
if (extra_partitions & XP_ESP) {
|
// TODO: Should we align these to cluster as well?
|
||||||
extra_part_name = L"EFI System";
|
if (extra_partitions & XP_PERSISTENCE) {
|
||||||
extra_part_size_in_tracks = (esp_size + bytes_per_track - 1) / bytes_per_track;
|
|
||||||
} else if (extra_partitions & XP_UEFI_NTFS) {
|
|
||||||
extra_part_name = L"UEFI:NTFS";
|
|
||||||
extra_part_size_in_tracks = (max(MIN_EXTRA_PART_SIZE, uefi_ntfs_size) + bytes_per_track - 1) / bytes_per_track;
|
|
||||||
} else if ((extra_partitions & XP_CASPER)) {
|
|
||||||
assert(persistence_size != 0);
|
assert(persistence_size != 0);
|
||||||
extra_part_name = L"Linux Persistence";
|
partition_index[PI_CASPER] = pi;
|
||||||
extra_part_size_in_tracks = persistence_size / bytes_per_track;
|
wcscpy(SelectedDrive.Partition[pi].Name, L"Linux Persistence");
|
||||||
} else if (extra_partitions & XP_COMPAT) {
|
SelectedDrive.Partition[pi++].Size = HI_ALIGN_X_TO_Y(persistence_size, bytes_per_track);
|
||||||
extra_part_name = L"BIOS Compatibility";
|
|
||||||
extra_part_size_in_tracks = 1; // One track for the extra partition
|
|
||||||
} else {
|
|
||||||
assert(FALSE);
|
|
||||||
}
|
}
|
||||||
// NB: Because we already subtracted the backup GPT size from the main partition size and
|
if (extra_partitions & XP_ESP) {
|
||||||
// this extra partition is indexed on main size, it does not overflow into the backup GPT.
|
partition_index[PI_ESP] = pi;
|
||||||
main_part_size_in_sectors = ((main_part_size_in_sectors / SelectedDrive.SectorsPerTrack) -
|
wcscpy(SelectedDrive.Partition[pi].Name, L"EFI System Partition");
|
||||||
extra_part_size_in_tracks) * SelectedDrive.SectorsPerTrack;
|
SelectedDrive.Partition[pi++].Size = HI_ALIGN_X_TO_Y(esp_size, bytes_per_track);
|
||||||
|
} else if (extra_partitions & XP_UEFI_NTFS) {
|
||||||
|
partition_index[PI_UEFI_NTFS] = pi;
|
||||||
|
wcscpy(SelectedDrive.Partition[pi].Name, L"UEFI:NTFS");
|
||||||
|
SelectedDrive.Partition[pi++].Size = HI_ALIGN_X_TO_Y(uefi_ntfs_size, bytes_per_track);
|
||||||
|
} else if (extra_partitions & XP_COMPAT) {
|
||||||
|
wcscpy(SelectedDrive.Partition[pi].Name, L"BIOS Compatibility");
|
||||||
|
SelectedDrive.Partition[pi++].Size = bytes_per_track; // One track for the extra partition
|
||||||
|
}
|
||||||
|
assert(pi <= MAX_PARTITIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the offsets of the extra partitions (which we always align to a track)
|
||||||
|
last_offset = SelectedDrive.DiskSize;
|
||||||
|
if (partition_style == PARTITION_STYLE_GPT)
|
||||||
|
last_offset -= 33 * SelectedDrive.SectorSize;
|
||||||
|
for (i = pi - 1; i > mi; i--) {
|
||||||
|
assert(SelectedDrive.Partition[i].Size < last_offset);
|
||||||
|
SelectedDrive.Partition[i].Offset = LO_ALIGN_X_TO_Y(last_offset - SelectedDrive.Partition[i].Size, bytes_per_track);
|
||||||
|
last_offset = SelectedDrive.Partition[i].Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// With the above, Compute the main partition size (which we align to a track)
|
||||||
|
assert(last_offset > SelectedDrive.Partition[mi].Offset);
|
||||||
|
SelectedDrive.Partition[mi].Size = LO_ALIGN_X_TO_Y(last_offset - SelectedDrive.Partition[mi].Offset, bytes_per_track);
|
||||||
// Try to make sure that the main partition size is a multiple of the cluster size
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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...
|
// may include garbage leftover data from a previous reformat...
|
||||||
if (ClusterSize % SelectedDrive.SectorSize == 0) {
|
if (ClusterSize % SelectedDrive.SectorSize == 0)
|
||||||
main_part_size_in_sectors = (((main_part_size_in_sectors * SelectedDrive.SectorSize) /
|
SelectedDrive.Partition[mi].Size = LO_ALIGN_X_TO_Y(SelectedDrive.Partition[mi].Size, ClusterSize);
|
||||||
ClusterSize) * ClusterSize) / SelectedDrive.SectorSize;
|
if (SelectedDrive.Partition[mi].Size <= 0) {
|
||||||
}
|
uprintf("Error: Invalid %S size", SelectedDrive.Partition[mi].Name);
|
||||||
if (main_part_size_in_sectors <= 0) {
|
|
||||||
uprintf("Error: Invalid %S size", main_part_name);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
uprintf("● Creating %S (offset: %lld, size: %s)", main_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart,
|
|
||||||
SizeToHumanReadable(main_part_size_in_sectors * SelectedDrive.SectorSize, TRUE, FALSE));
|
|
||||||
// Zero the beginning of this partition to avoid conflicting leftovers
|
|
||||||
if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear))
|
|
||||||
uprintf("Could not zero %S: %s", main_part_name, WindowsErrorString());
|
|
||||||
|
|
||||||
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = main_part_size_in_sectors * SelectedDrive.SectorSize;
|
// Build the DriveLayoutEx table
|
||||||
if (partition_style == PARTITION_STYLE_MBR) {
|
for (i = 0; i < pi; i++) {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.BootIndicator = (boot_type != BT_NON_BOOTABLE);
|
uprintf("● Creating %S%s (offset: %lld, size: %s)", SelectedDrive.Partition[i].Name,
|
||||||
switch (file_system) {
|
(wcsstr(SelectedDrive.Partition[i].Name, L"Partition") == NULL) ? " Partition" : "",
|
||||||
case FS_FAT16:
|
SelectedDrive.Partition[i].Offset,
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x0e; // FAT16 LBA
|
SizeToHumanReadable(SelectedDrive.Partition[i].Size, TRUE, FALSE));
|
||||||
break;
|
// Zero the first sectors of the partition to avoid file system caching issues
|
||||||
case FS_NTFS:
|
if (!ClearPartition(hDrive, SelectedDrive.Partition[i].Offset,
|
||||||
case FS_EXFAT:
|
(DWORD)MIN(size_to_clear, SelectedDrive.Partition[i].Size)))
|
||||||
case FS_UDF:
|
uprintf("Could not zero %S: %s", SelectedDrive.Partition[i].Name, WindowsErrorString());
|
||||||
case FS_REFS:
|
DriveLayoutEx.PartitionEntry[i].PartitionStyle = partition_style;
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x07;
|
DriveLayoutEx.PartitionEntry[i].StartingOffset.QuadPart = SelectedDrive.Partition[i].Offset;
|
||||||
break;
|
DriveLayoutEx.PartitionEntry[i].PartitionLength.QuadPart = SelectedDrive.Partition[i].Size;
|
||||||
case FS_EXT2:
|
DriveLayoutEx.PartitionEntry[i].PartitionNumber = i + 1;
|
||||||
case FS_EXT3:
|
DriveLayoutEx.PartitionEntry[i].RewritePartition = TRUE;
|
||||||
case FS_EXT4:
|
if (partition_style == PARTITION_STYLE_MBR) {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x83;
|
if (i == mi) {
|
||||||
break;
|
DriveLayoutEx.PartitionEntry[i].Mbr.BootIndicator = (boot_type != BT_NON_BOOTABLE);
|
||||||
case FS_FAT32:
|
switch (file_system) {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x0c; // FAT32 LBA
|
case FS_FAT16:
|
||||||
break;
|
DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x0e; // FAT16 LBA
|
||||||
default:
|
break;
|
||||||
uprintf("Unsupported file system");
|
case FS_NTFS:
|
||||||
return FALSE;
|
case FS_EXFAT:
|
||||||
}
|
case FS_UDF:
|
||||||
} else {
|
case FS_REFS:
|
||||||
if (write_as_esp)
|
DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x07;
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_GENERIC_ESP;
|
break;
|
||||||
else if (IS_EXT(file_system))
|
case FS_EXT2:
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_LINUX_DATA;
|
case FS_EXT3:
|
||||||
else
|
case FS_EXT4:
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MICROSOFT_DATA;
|
DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x83;
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
break;
|
||||||
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, main_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
case FS_FAT32:
|
||||||
}
|
DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x0c; // FAT32 LBA
|
||||||
SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart;
|
break;
|
||||||
SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart;
|
default:
|
||||||
partition_offset[PI_MAIN] = SelectedDrive.PartitionOffset[pn];
|
uprintf("Unsupported file system");
|
||||||
pn++;
|
return FALSE;
|
||||||
|
}
|
||||||
// Set the optional extra partition
|
}
|
||||||
if (extra_partitions) {
|
// May override the the type of main partition if write_as_esp is active
|
||||||
// Should end on a track boundary
|
if ((wcscmp(SelectedDrive.Partition[i].Name, L"EFI System Partition") == 0) ||
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart +
|
(wcscmp(SelectedDrive.Partition[i].Name, L"UEFI:NTFS") == 0))
|
||||||
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0xef;
|
||||||
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = (extra_partitions & XP_UEFI_NTFS) ? uefi_ntfs_size :
|
else if (wcscmp(SelectedDrive.Partition[i].Name, L"Linux Persistence") == 0)
|
||||||
extra_part_size_in_tracks * bytes_per_track;
|
DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = 0x83;
|
||||||
uprintf("● Creating %S Partition (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart,
|
else if (wcscmp(SelectedDrive.Partition[i].Name, L"BIOS Compatibility") == 0)
|
||||||
SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE));
|
DriveLayoutEx.PartitionEntry[i].Mbr.PartitionType = RUFUS_EXTRA_PARTITION_TYPE;
|
||||||
SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart;
|
} else {
|
||||||
SelectedDrive.PartitionSize[pn] = DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart;
|
assert(partition_style == PARTITION_STYLE_GPT);
|
||||||
if (extra_partitions & XP_CASPER)
|
if (wcscmp(SelectedDrive.Partition[i].Name, L"UEFI:NTFS") == 0) {
|
||||||
partition_offset[PI_CASPER] = SelectedDrive.PartitionOffset[pn];
|
DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_GENERIC_ESP;
|
||||||
else if (extra_partitions & XP_ESP)
|
|
||||||
partition_offset[PI_ESP] = SelectedDrive.PartitionOffset[pn];
|
|
||||||
|
|
||||||
if (partition_style == PARTITION_STYLE_GPT) {
|
|
||||||
if (extra_partitions & XP_ESP)
|
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_GENERIC_ESP;
|
|
||||||
else if (extra_partitions & XP_CASPER)
|
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_LINUX_DATA;
|
|
||||||
else
|
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MICROSOFT_DATA;
|
|
||||||
if (extra_partitions & XP_UEFI_NTFS) {
|
|
||||||
// Prevent a drive letter from being assigned to the UEFI:NTFS partition
|
// Prevent a drive letter from being assigned to the UEFI:NTFS partition
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.Attributes = GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER;
|
DriveLayoutEx.PartitionEntry[i].Gpt.Attributes = GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER;
|
||||||
#if !defined(_DEBUG)
|
#if !defined(_DEBUG)
|
||||||
// Also make the partition read-only for release versions
|
// Also make the partition read-only for release versions
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.Attributes += GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY;
|
DriveLayoutEx.PartitionEntry[i].Gpt.Attributes += GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY;
|
||||||
#endif
|
#endif
|
||||||
}
|
} else if (wcscmp(SelectedDrive.Partition[i].Name, L"EFI System Partition") == 0)
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_GENERIC_ESP;
|
||||||
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, (extra_partitions & XP_ESP) ? L"EFI System Partition" : extra_part_name,
|
else if (wcscmp(SelectedDrive.Partition[i].Name, L"Linux Persistence") == 0)
|
||||||
ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_LINUX_DATA;
|
||||||
} else {
|
else if (wcscmp(SelectedDrive.Partition[i].Name, L"Microsoft Reserved Partition") == 0)
|
||||||
if (extra_partitions & (XP_UEFI_NTFS | XP_ESP)) {
|
DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_MICROSOFT_RESERVED;
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0xef;
|
else
|
||||||
} else if (extra_partitions & XP_CASPER) {
|
DriveLayoutEx.PartitionEntry[i].Gpt.PartitionType = PARTITION_MICROSOFT_DATA;
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x83;
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[i].Gpt.PartitionId));
|
||||||
} else if (extra_partitions & XP_COMPAT) {
|
wcscpy(DriveLayoutEx.PartitionEntry[i].Gpt.Name, SelectedDrive.Partition[i].Name);
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = RUFUS_EXTRA_PARTITION_TYPE;
|
|
||||||
// Set the one track compatibility partition to be all hidden sectors
|
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.HiddenSectors = SelectedDrive.SectorsPerTrack;
|
|
||||||
} else {
|
|
||||||
assert(FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to write the UEFI:NTFS partition before we refresh the disk
|
|
||||||
if (extra_partitions & XP_UEFI_NTFS) {
|
|
||||||
uprintf("Writing %S data...", extra_part_name);
|
|
||||||
if (!SetFilePointerEx(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, NULL, FILE_BEGIN)) {
|
|
||||||
uprintf("Could not set position");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA, "uefi-ntfs.img", &bufsize, FALSE);
|
|
||||||
if (buffer == NULL) {
|
|
||||||
uprintf("Could not access source image");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if(!WriteFileWithRetry(hDrive, buffer, bufsize, &size, WRITE_RETRIES)) {
|
|
||||||
uprintf("Write error: %s", WindowsErrorString());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pn++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the remaining partition data
|
// We need to write the UEFI:NTFS partition before we refresh the disk
|
||||||
for (i = 0; i < pn; i++) {
|
if (extra_partitions & XP_UEFI_NTFS) {
|
||||||
DriveLayoutEx.PartitionEntry[i].PartitionNumber = i + 1;
|
LARGE_INTEGER li;
|
||||||
DriveLayoutEx.PartitionEntry[i].PartitionStyle = partition_style;
|
uprintf("Writing UEFI:NTFS data...", SelectedDrive.Partition[partition_index[PI_UEFI_NTFS]].Name);
|
||||||
DriveLayoutEx.PartitionEntry[i].RewritePartition = TRUE;
|
li.QuadPart = SelectedDrive.Partition[partition_index[PI_UEFI_NTFS]].Offset;
|
||||||
|
if (!SetFilePointerEx(hDrive, li, NULL, FILE_BEGIN)) {
|
||||||
|
uprintf(" Could not set position");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA,
|
||||||
|
"uefi-ntfs.img", &bufsize, FALSE);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
uprintf(" Could not access source image");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if(!WriteFileWithRetry(hDrive, buffer, bufsize, &size, WRITE_RETRIES)) {
|
||||||
|
uprintf(" Write error: %s", WindowsErrorString());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (partition_style) {
|
switch (partition_style) {
|
||||||
|
@ -2558,7 +2525,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
CreateDisk.Gpt.MaxPartitionCount = MAX_PARTITIONS;
|
CreateDisk.Gpt.MaxPartitionCount = MAX_PARTITIONS;
|
||||||
|
|
||||||
DriveLayoutEx.PartitionStyle = PARTITION_STYLE_GPT;
|
DriveLayoutEx.PartitionStyle = PARTITION_STYLE_GPT;
|
||||||
DriveLayoutEx.PartitionCount = pn;
|
DriveLayoutEx.PartitionCount = pi;
|
||||||
// At the very least, a GPT disk has 34 reserved sectors at the beginning and 33 at the end.
|
// At the very least, a GPT disk has 34 reserved sectors at the beginning and 33 at the end.
|
||||||
DriveLayoutEx.Type.Gpt.StartingUsableOffset.QuadPart = 34 * SelectedDrive.SectorSize;
|
DriveLayoutEx.Type.Gpt.StartingUsableOffset.QuadPart = 34 * SelectedDrive.SectorSize;
|
||||||
DriveLayoutEx.Type.Gpt.UsableLength.QuadPart = SelectedDrive.DiskSize - (34+33) * SelectedDrive.SectorSize;
|
DriveLayoutEx.Type.Gpt.UsableLength.QuadPart = SelectedDrive.DiskSize - (34+33) * SelectedDrive.SectorSize;
|
||||||
|
@ -2569,8 +2536,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
|
|
||||||
// If you don't call IOCTL_DISK_CREATE_DISK, the IOCTL_DISK_SET_DRIVE_LAYOUT_EX call will fail
|
// If you don't call IOCTL_DISK_CREATE_DISK, the IOCTL_DISK_SET_DRIVE_LAYOUT_EX call will fail
|
||||||
size = sizeof(CreateDisk);
|
size = sizeof(CreateDisk);
|
||||||
r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK, (BYTE*)&CreateDisk, size, NULL, 0, &size, NULL);
|
if (!DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK, (BYTE*)&CreateDisk, size, NULL, 0, &size, NULL)) {
|
||||||
if (!r) {
|
|
||||||
uprintf("Could not reset disk: %s", WindowsErrorString());
|
uprintf("Could not reset disk: %s", WindowsErrorString());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2578,9 +2544,9 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
// "The goggles, they do nothing!"
|
// "The goggles, they do nothing!"
|
||||||
RefreshDriveLayout(hDrive);
|
RefreshDriveLayout(hDrive);
|
||||||
|
|
||||||
size = sizeof(DriveLayoutEx) - ((partition_style == PARTITION_STYLE_GPT)?((4-pn)*sizeof(PARTITION_INFORMATION_EX)):0);
|
size = sizeof(DriveLayoutEx) - ((partition_style == PARTITION_STYLE_GPT) ?
|
||||||
r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, (BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL);
|
((4 - pi) * sizeof(PARTITION_INFORMATION_EX)) : 0);
|
||||||
if (!r) {
|
if (!DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, (BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL)) {
|
||||||
uprintf("Could not set drive layout: %s", WindowsErrorString());
|
uprintf("Could not set drive layout: %s", WindowsErrorString());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
14
src/drive.h
14
src/drive.h
|
@ -36,12 +36,13 @@
|
||||||
#define XP_ESP 0x02
|
#define XP_ESP 0x02
|
||||||
#define XP_UEFI_NTFS 0x04
|
#define XP_UEFI_NTFS 0x04
|
||||||
#define XP_COMPAT 0x08
|
#define XP_COMPAT 0x08
|
||||||
#define XP_CASPER 0x10
|
#define XP_PERSISTENCE 0x10
|
||||||
|
|
||||||
#define PI_MAIN 0
|
#define PI_MAIN 0
|
||||||
#define PI_ESP 1
|
#define PI_ESP 1
|
||||||
#define PI_CASPER 2
|
#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
|
// The following should match VDS_FSOF_FLAGS as much as possible
|
||||||
#define FP_FORCE 0x00000001
|
#define FP_FORCE 0x00000001
|
||||||
|
@ -362,8 +363,11 @@ typedef struct {
|
||||||
MEDIA_TYPE MediaType;
|
MEDIA_TYPE MediaType;
|
||||||
int PartitionStyle;
|
int PartitionStyle;
|
||||||
int nPartitions; // number of partitions we actually care about
|
int nPartitions; // number of partitions we actually care about
|
||||||
uint64_t PartitionOffset[MAX_PARTITIONS];
|
struct {
|
||||||
uint64_t PartitionSize[MAX_PARTITIONS];
|
wchar_t Name[36];
|
||||||
|
uint64_t Offset;
|
||||||
|
uint64_t Size;
|
||||||
|
} Partition[MAX_PARTITIONS];
|
||||||
int FSType;
|
int FSType;
|
||||||
char proposed_label[16];
|
char proposed_label[16];
|
||||||
BOOL has_protective_mbr;
|
BOOL has_protective_mbr;
|
||||||
|
@ -374,7 +378,7 @@ typedef struct {
|
||||||
} ClusterSize[FS_MAX];
|
} ClusterSize[FS_MAX];
|
||||||
} RUFUS_DRIVE_INFO;
|
} RUFUS_DRIVE_INFO;
|
||||||
extern RUFUS_DRIVE_INFO SelectedDrive;
|
extern RUFUS_DRIVE_INFO SelectedDrive;
|
||||||
extern uint64_t partition_offset[PI_MAX];
|
extern int partition_index[PI_MAX];
|
||||||
|
|
||||||
BOOL SetAutoMount(BOOL enable);
|
BOOL SetAutoMount(BOOL enable);
|
||||||
BOOL GetAutoMount(BOOL* enabled);
|
BOOL GetAutoMount(BOOL* enabled);
|
||||||
|
|
53
src/format.c
53
src/format.c
|
@ -972,7 +972,7 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that we have sufficient space for the SBR
|
// 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) {
|
if (br_size + size > max_size) {
|
||||||
uprintf(" SBR size is too large - You may need to uncheck 'Add fixes for old BIOSes'.");
|
uprintf(" SBR size is too large - You may need to uncheck 'Add fixes for old BIOSes'.");
|
||||||
if (sub_type == BT_MAX)
|
if (sub_type == BT_MAX)
|
||||||
|
@ -1456,23 +1456,32 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
large_drive = (SelectedDrive.DiskSize > (1*TB));
|
large_drive = (SelectedDrive.DiskSize > (1*TB));
|
||||||
if (large_drive)
|
if (large_drive)
|
||||||
uprintf("Notice: Large drive detected (may produce short writes)");
|
uprintf("Notice: Large drive detected (may produce short writes)");
|
||||||
|
|
||||||
// Find out if we need to add any extra partitions
|
// 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))
|
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
|
extra_partitions |= XP_ESP | XP_MSR;
|
||||||
// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-and-gpt-faq#disks-that-require-an-msr
|
// If we have a bootable image with UEFI bootloaders and the target file system is NTFS or exFAT
|
||||||
extra_partitions = XP_ESP | XP_MSR;
|
// or the UEFI:NTFS option is selected, we add the UEFI:NTFS partition...
|
||||||
else if ( ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) &&
|
else if (((boot_type == BT_IMAGE) && IS_EFI_BOOTABLE(img_report)) && ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) ||
|
||||||
((boot_type == BT_UEFI_NTFS) || ((boot_type == BT_IMAGE) && IS_EFI_BOOTABLE(img_report) &&
|
(boot_type == BT_UEFI_NTFS)) {
|
||||||
((target_type == TT_UEFI) || (windows_to_go) || (allow_dual_uefi_bios) ||
|
extra_partitions |= XP_UEFI_NTFS;
|
||||||
(img_report.has_4GB_file) || (img_report.needs_ntfs)))) )
|
// ...but only if we're not dealing with a Windows image in installer mode with target
|
||||||
extra_partitions = XP_UEFI_NTFS;
|
// system set to BIOS and without dual BIOS+UEFI boot enabled.
|
||||||
else if ((boot_type == BT_IMAGE) && !write_as_image && HAS_PERSISTENCE(img_report) && persistence_size)
|
if ((boot_type == BT_IMAGE) && HAS_BOOTMGR_BIOS(img_report) && (!windows_to_go) &&
|
||||||
extra_partitions = XP_CASPER;
|
(target_type == TT_BIOS) && (!allow_dual_uefi_bios))
|
||||||
else if (IsChecked(IDC_OLD_BIOS_FIXES))
|
extra_partitions &= ~XP_UEFI_NTFS;
|
||||||
extra_partitions = XP_COMPAT;
|
}
|
||||||
|
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
|
// 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...
|
// 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;
|
actual_lock_drive = FALSE;
|
||||||
// Windows 11 is a lot more proactive in locking ESPs and MSRs than previous versions
|
// 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...
|
// were, meaning that we also can't lock the drive without incurring errors...
|
||||||
|
@ -1710,13 +1719,13 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
if (write_as_esp || write_as_ext) {
|
if (write_as_esp || write_as_ext) {
|
||||||
// Can't format ESPs or ext2/ext3 partitions unless we mount them ourselves
|
// 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) {
|
if (volume_name == NULL) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER);
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} 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");
|
uprintf("Logical drive was not found - aborting");
|
||||||
if (!IS_ERROR(FormatStatus))
|
if (!IS_ERROR(FormatStatus))
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_TIMEOUT;
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_TIMEOUT;
|
||||||
|
@ -1727,12 +1736,12 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
|
|
||||||
// Format Casper partition if required. Do it before we format anything with
|
// Format Casper partition if required. Do it before we format anything with
|
||||||
// a file system that Windows will recognize, to avoid concurrent access.
|
// 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);
|
uint32_t ext_version = ReadSetting32(SETTING_USE_EXT_VERSION);
|
||||||
if ((ext_version < 2) || (ext_version > 4))
|
if ((ext_version < 2) || (ext_version > 4))
|
||||||
ext_version = 3;
|
ext_version = 3;
|
||||||
uprintf("Using %s-like method to enable persistence", img_report.uses_casper ? "Ubuntu" : "Debian");
|
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 ? "casper-rw" : "persistence",
|
||||||
(img_report.uses_casper ? 0 : FP_CREATE_PERSISTENCE_CONF) |
|
(img_report.uses_casper ? 0 : FP_CREATE_PERSISTENCE_CONF) |
|
||||||
(IsChecked(IDC_QUICK_FORMAT) ? FP_QUICK : 0))) {
|
(IsChecked(IDC_QUICK_FORMAT) ? FP_QUICK : 0))) {
|
||||||
|
@ -1757,7 +1766,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
if (write_as_esp)
|
if (write_as_esp)
|
||||||
Flags |= FP_LARGE_FAT32;
|
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) {
|
if (!ret) {
|
||||||
// Error will be set by FormatPartition() in FormatStatus
|
// Error will be set by FormatPartition() in FormatStatus
|
||||||
uprintf("Format error: %s", StrError(FormatStatus, TRUE));
|
uprintf("Format error: %s", StrError(FormatStatus, TRUE));
|
||||||
|
@ -1790,7 +1799,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
// Try to continue
|
// Try to continue
|
||||||
CHECK_FOR_USER_CANCEL;
|
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) {
|
if (volume_name == NULL) {
|
||||||
uprintf("Could not get volume name");
|
uprintf("Could not get volume name");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NO_VOLUME_ID;
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NO_VOLUME_ID;
|
||||||
|
@ -1848,7 +1857,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
} else {
|
} else {
|
||||||
// We still have a lock, which we need to modify the volume boot record
|
// We still have a lock, which we need to modify the volume boot record
|
||||||
// => no need to reacquire the lock...
|
// => 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)) {
|
if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) {
|
||||||
uprintf("Could not re-mount volume for partition boot record access");
|
uprintf("Could not re-mount volume for partition boot record access");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
||||||
|
@ -1999,7 +2008,7 @@ out:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IS_ERROR(FormatStatus)) {
|
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 (volume_name != NULL) {
|
||||||
if (MountVolume(drive_name, volume_name))
|
if (MountVolume(drive_name, volume_name))
|
||||||
uprintf("Re-mounted volume as %c: after error", toupper(drive_name[0]));
|
uprintf("Re-mounted volume as %c: after error", toupper(drive_name[0]));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Rufus: The Reliable USB Formatting Utility
|
* Rufus: The Reliable USB Formatting Utility
|
||||||
* Constants and defines missing from various toolchains
|
* Constants and defines missing from various toolchains
|
||||||
* Copyright © 2016-2022 Pete Batard <pete@akeo.ie>
|
* Copyright © 2016-2024 Pete Batard <pete@akeo.ie>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -31,6 +31,9 @@
|
||||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
#endif
|
#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__)
|
#if defined(__GNUC__)
|
||||||
#define ALIGNED(m) __attribute__ ((__aligned__(m)))
|
#define ALIGNED(m) __attribute__ ((__aligned__(m)))
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 4.5.2109"
|
CAPTION "Rufus 4.5.2110"
|
||||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||||
|
@ -392,8 +392,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 4,5,2109,0
|
FILEVERSION 4,5,2110,0
|
||||||
PRODUCTVERSION 4,5,2109,0
|
PRODUCTVERSION 4,5,2110,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -411,13 +411,13 @@ BEGIN
|
||||||
VALUE "Comments", "https://rufus.ie"
|
VALUE "Comments", "https://rufus.ie"
|
||||||
VALUE "CompanyName", "Akeo Consulting"
|
VALUE "CompanyName", "Akeo Consulting"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "4.5.2109"
|
VALUE "FileVersion", "4.5.2110"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||||
VALUE "OriginalFilename", "rufus-4.5.exe"
|
VALUE "OriginalFilename", "rufus-4.5.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "4.5.2109"
|
VALUE "ProductVersion", "4.5.2110"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Rufus: The Reliable USB Formatting Utility
|
* Rufus: The Reliable USB Formatting Utility
|
||||||
* Windows User Experience
|
* Windows User Experience
|
||||||
* Copyright © 2022-2023 Pete Batard <pete@akeo.ie>
|
* Copyright © 2022-2024 Pete Batard <pete@akeo.ie>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -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
|
// 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
|
// 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."
|
// 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)) {
|
FP_QUICK | FP_FORCE | FP_LARGE_FAT32 | FP_NO_BOOT)) {
|
||||||
uprintf("Could not format EFI System Partition");
|
uprintf("Could not format EFI System Partition");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
// Need to have the ESP mounted to invoke bcdboot
|
// 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) {
|
if (ms_efi == NULL) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER);
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in a new issue