mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[core] use offset rather than index to identify a partition
* Also fix potential bcdboot invocation failure by introducing a new AltGetLogicalName() call. * Also use the AltMount calls for ext# formatting
This commit is contained in:
parent
1fa0aaf325
commit
94e2015edf
4 changed files with 133 additions and 112 deletions
156
src/drive.c
156
src/drive.c
|
@ -86,7 +86,7 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryVolumeInformationFile, (HANDLE, PIO_STATUS_
|
||||||
*/
|
*/
|
||||||
RUFUS_DRIVE_INFO SelectedDrive;
|
RUFUS_DRIVE_INFO SelectedDrive;
|
||||||
BOOL installed_uefi_ntfs;
|
BOOL installed_uefi_ntfs;
|
||||||
DWORD partition_index[3];
|
uint64_t partition_offset[3];
|
||||||
uint64_t persistence_size = 0;
|
uint64_t persistence_size = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -245,22 +245,18 @@ out:
|
||||||
/*
|
/*
|
||||||
* Return the path to access a partition on a specific disk, or NULL on error.
|
* Return the path to access a partition on a specific disk, or NULL on error.
|
||||||
* The string is allocated and must be freed (to ensure concurrent access)
|
* The string is allocated and must be freed (to ensure concurrent access)
|
||||||
|
* If PartitionOffset is 0, the offset is ignored and the first partition found is returned.
|
||||||
*/
|
*/
|
||||||
char* GetPartitionName(DWORD DriveIndex, DWORD PartitionIndex)
|
char* GetPartitionName(DWORD DriveIndex, uint64_t PartitionOffset)
|
||||||
{
|
{
|
||||||
BOOL success = FALSE;
|
|
||||||
char partition_name[32];
|
char partition_name[32];
|
||||||
|
DWORD i = MAX_PARTITIONS + 1;
|
||||||
|
|
||||||
CheckDriveIndex(DriveIndex);
|
CheckDriveIndex(DriveIndex);
|
||||||
if (PartitionIndex >= MAX_PARTITIONS)
|
for (i = 1; (i <= MAX_PARTITIONS) && (PartitionOffset != 0) && (SelectedDrive.PartitionOffset[i - 1] != PartitionOffset); i++);
|
||||||
goto out;
|
static_sprintf(partition_name, "\\Device\\Harddisk%lu\\Partition%lu", DriveIndex, i);
|
||||||
if (PartitionIndex == 0)
|
|
||||||
PartitionIndex = 1;
|
|
||||||
|
|
||||||
static_sprintf(partition_name, "\\Device\\Harddisk%lu\\Partition%lu", DriveIndex, PartitionIndex);
|
|
||||||
success = TRUE;
|
|
||||||
out:
|
out:
|
||||||
return (success) ? safe_strdup(partition_name) : NULL;
|
return (i <= MAX_PARTITIONS) ? safe_strdup(partition_name) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -278,11 +274,10 @@ HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, B
|
||||||
/*
|
/*
|
||||||
* Return the GUID volume name for the disk and partition specified, or NULL if not found.
|
* Return the GUID volume name for the disk and partition specified, or NULL if not found.
|
||||||
* See http://msdn.microsoft.com/en-us/library/cc542456.aspx
|
* See http://msdn.microsoft.com/en-us/library/cc542456.aspx
|
||||||
* PartitionIndex starts at 1 (for the first partition). If PartitionIndex is zero, then
|
* If PartitionOffset is 0, the offset is ignored and the first partition found is returned.
|
||||||
* the first partition found by this function (which *MAY NOT* be the actual first partition)
|
* The returned string is allocated and must be freed.
|
||||||
* is returned. The returned string is allocated and must be freed.
|
|
||||||
*/
|
*/
|
||||||
char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingBackslash, BOOL bSilent)
|
char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent)
|
||||||
{
|
{
|
||||||
static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" };
|
static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" };
|
||||||
static const char* volume_start = "\\\\?\\";
|
static const char* volume_start = "\\\\?\\";
|
||||||
|
@ -294,13 +289,11 @@ char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingB
|
||||||
UINT drive_type;
|
UINT drive_type;
|
||||||
StrArray found_name;
|
StrArray found_name;
|
||||||
uint64_t found_offset[MAX_PARTITIONS] = { 0 };
|
uint64_t found_offset[MAX_PARTITIONS] = { 0 };
|
||||||
uint32_t i, j, k;
|
uint32_t i, j;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
StrArrayCreate(&found_name, MAX_PARTITIONS);
|
StrArrayCreate(&found_name, MAX_PARTITIONS);
|
||||||
CheckDriveIndex(DriveIndex);
|
CheckDriveIndex(DriveIndex);
|
||||||
if (PartitionIndex > MAX_PARTITIONS)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
for (i = 0; hDrive == INVALID_HANDLE_VALUE; i++) {
|
for (i = 0; hDrive == INVALID_HANDLE_VALUE; i++) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
|
@ -391,33 +384,14 @@ char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingB
|
||||||
if (found_name.Index == 0)
|
if (found_name.Index == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
// Now process all the volumes we found, and find the one that matches our partition index
|
// Now process all the volumes we found, and try to match one with our partition offset
|
||||||
if (PartitionIndex == 0) {
|
for (i = 0; (i < found_name.Index) && (PartitionOffset != 0) && (PartitionOffset != found_offset[i]); i++);
|
||||||
i = 0;
|
|
||||||
} else for (i = 0, k = 0; i < found_name.Index; i++) {
|
if (i < found_name.Index)
|
||||||
for (j = 0; j < found_name.Index; j++) {
|
|
||||||
if (found_offset[i] > found_offset[j])
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
if (k == ((int)PartitionIndex) - 1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i < found_name.Index) {
|
|
||||||
ret = safe_strdup(found_name.String[i]);
|
ret = safe_strdup(found_name.String[i]);
|
||||||
} else {
|
else
|
||||||
// Some volumes, such as ESPs, are not listed by Windows, be it with VDS or other APIs.
|
// NB: We need to re-add DRIVE_INDEX_MIN for this call since CheckDriveIndex() substracted it
|
||||||
// For these, we return the "\\?\GLOBALROOT\Device\HarddiskVolume#" identifier that
|
ret = AltGetLogicalName(DriveIndex + DRIVE_INDEX_MIN, PartitionOffset, bKeepTrailingBackslash, bSilent);
|
||||||
// matches our "Harddisk#Partition#", as reported by QueryDosDevice().
|
|
||||||
static_sprintf(path, "Harddisk%luPartition%lu", DriveIndex, PartitionIndex);
|
|
||||||
static_strcpy(volume_name, groot_name);
|
|
||||||
if (!QueryDosDeviceA(path, &volume_name[groot_len], (DWORD)(MAX_PATH - groot_len)) || (strlen(volume_name) < 20)) {
|
|
||||||
uprintf("Could not find the DOS volume name for '%s': %s", path, WindowsErrorString());
|
|
||||||
} else {
|
|
||||||
if (bKeepTrailingBackslash)
|
|
||||||
static_strcat(volume_name, "\\");
|
|
||||||
ret = safe_strdup(volume_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (hVolume != INVALID_HANDLE_VALUE)
|
if (hVolume != INVALID_HANDLE_VALUE)
|
||||||
|
@ -426,6 +400,40 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alternative version of the above, needed because some volumes, such as ESPs, are not listed
|
||||||
|
* by Windows, be it with VDS or other APIs.
|
||||||
|
* For these, we return the "\\?\GLOBALROOT\Device\HarddiskVolume#" identifier that matches
|
||||||
|
* our "Harddisk#Partition#", as reported by QueryDosDevice().
|
||||||
|
* The returned string is allocated and must be freed.
|
||||||
|
*/
|
||||||
|
char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent)
|
||||||
|
{
|
||||||
|
DWORD i;
|
||||||
|
char *ret = NULL, volume_name[MAX_PATH], path[MAX_PATH];
|
||||||
|
|
||||||
|
CheckDriveIndex(DriveIndex);
|
||||||
|
|
||||||
|
// Match the offset to a partition index
|
||||||
|
for (i = 0; (i < MAX_PARTITIONS) && (PartitionOffset != 0) && (PartitionOffset != SelectedDrive.PartitionOffset[i]); i++);
|
||||||
|
if (i >= MAX_PARTITIONS) {
|
||||||
|
suprintf("Error: Could not find a partition at offset %lld on this disk", PartitionOffset);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
static_sprintf(path, "Harddisk%luPartition%lu", DriveIndex, i + 1);
|
||||||
|
static_strcpy(volume_name, groot_name);
|
||||||
|
if (!QueryDosDeviceA(path, &volume_name[groot_len], (DWORD)(MAX_PATH - groot_len)) || (strlen(volume_name) < 20)) {
|
||||||
|
suprintf("Could not find the DOS volume name for '%s': %s", path, WindowsErrorString());
|
||||||
|
} else {
|
||||||
|
if (bKeepTrailingBackslash)
|
||||||
|
static_strcat(volume_name, "\\");
|
||||||
|
ret = safe_strdup(volume_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call on VDS to refresh the drive layout
|
* Call on VDS to refresh the drive layout
|
||||||
*/
|
*/
|
||||||
|
@ -720,7 +728,7 @@ out:
|
||||||
|
|
||||||
|
|
||||||
/* Wait for a logical drive to reappear - Used when a drive has just been repartitioned */
|
/* Wait for a logical drive to reappear - Used when a drive has just been repartitioned */
|
||||||
BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex)
|
BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset)
|
||||||
{
|
{
|
||||||
uint64_t EndTime;
|
uint64_t EndTime;
|
||||||
char* LogicalPath = NULL;
|
char* LogicalPath = NULL;
|
||||||
|
@ -729,7 +737,7 @@ BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex)
|
||||||
// make sure we don't spend more than DRIVE_ACCESS_TIMEOUT in wait.
|
// make sure we don't spend more than DRIVE_ACCESS_TIMEOUT in wait.
|
||||||
EndTime = GetTickCount64() + DRIVE_ACCESS_TIMEOUT;
|
EndTime = GetTickCount64() + DRIVE_ACCESS_TIMEOUT;
|
||||||
do {
|
do {
|
||||||
LogicalPath = GetLogicalName(DriveIndex, PartitionIndex, FALSE, TRUE);
|
LogicalPath = GetLogicalName(DriveIndex, PartitionOffset, FALSE, TRUE);
|
||||||
// Need to filter out GlobalRoot devices as we don't want to wait on those
|
// Need to filter out GlobalRoot devices as we don't want to wait on those
|
||||||
if ((LogicalPath != NULL) && (strncmp(LogicalPath, groot_name, groot_len) != 0)) {
|
if ((LogicalPath != NULL) && (strncmp(LogicalPath, groot_name, groot_len) != 0)) {
|
||||||
free(LogicalPath);
|
free(LogicalPath);
|
||||||
|
@ -749,10 +757,10 @@ BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex)
|
||||||
* Returns INVALID_HANDLE_VALUE on error or NULL if no logical path exists (typical
|
* Returns INVALID_HANDLE_VALUE on error or NULL if no logical path exists (typical
|
||||||
* of unpartitioned drives)
|
* of unpartitioned drives)
|
||||||
*/
|
*/
|
||||||
HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare)
|
HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare)
|
||||||
{
|
{
|
||||||
HANDLE hLogical = INVALID_HANDLE_VALUE;
|
HANDLE hLogical = INVALID_HANDLE_VALUE;
|
||||||
char* LogicalPath = GetLogicalName(DriveIndex, PartitionIndex, FALSE, FALSE);
|
char* LogicalPath = GetLogicalName(DriveIndex, PartitionOffset, FALSE, FALSE);
|
||||||
|
|
||||||
if (LogicalPath == NULL) {
|
if (LogicalPath == NULL) {
|
||||||
uprintf("No logical drive found (unpartitioned?)");
|
uprintf("No logical drive found (unpartitioned?)");
|
||||||
|
@ -767,10 +775,10 @@ HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive,
|
||||||
/*
|
/*
|
||||||
* Similar to the above, but use the partition name instead
|
* Similar to the above, but use the partition name instead
|
||||||
*/
|
*/
|
||||||
HANDLE GetPartitionHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare)
|
HANDLE GetPartitionHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare)
|
||||||
{
|
{
|
||||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||||
char* volume_name = GetPartitionName(DriveIndex, PartitionIndex);
|
char* volume_name = GetPartitionName(DriveIndex, PartitionOffset);
|
||||||
|
|
||||||
if (volume_name == NULL) {
|
if (volume_name == NULL) {
|
||||||
uprintf("Could not get partition volume name");
|
uprintf("Could not get partition volume name");
|
||||||
|
@ -1158,6 +1166,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));
|
||||||
// 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);
|
||||||
|
@ -1246,6 +1255,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (i < MAX_PARTITIONS)
|
||||||
|
SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart;
|
||||||
// NB: MinGW's gcc 4.9.2 broke "%lld" printout on XP so we use the inttypes.h "PRI##" qualifiers
|
// NB: MinGW's gcc 4.9.2 broke "%lld" printout on XP so we use the inttypes.h "PRI##" qualifiers
|
||||||
suprintf(" Type: %s (0x%02x)\r\n Size: %s (%" PRIi64 " bytes)\r\n Start Sector: %" PRIi64 ", Boot: %s",
|
suprintf(" Type: %s (0x%02x)\r\n Size: %s (%" PRIi64 " bytes)\r\n Start Sector: %" PRIi64 ", Boot: %s",
|
||||||
((part_type==0x07||super_floppy_disk)&&(FileSystemName[0]!=0))?FileSystemName:GetPartitionType(part_type), super_floppy_disk?0:part_type,
|
((part_type==0x07||super_floppy_disk)&&(FileSystemName[0]!=0))?FileSystemName:GetPartitionType(part_type), super_floppy_disk?0:part_type,
|
||||||
|
@ -1271,6 +1282,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
||||||
suprintf("Max parts: %d, Start Offset: %" PRIi64 ", Usable = %" PRIi64 " bytes",
|
suprintf("Max parts: %d, Start Offset: %" PRIi64 ", Usable = %" PRIi64 " bytes",
|
||||||
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)
|
||||||
|
SelectedDrive.PartitionOffset[i] = DriveLayout->PartitionEntry[i].StartingOffset.QuadPart;
|
||||||
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\r\n Name: '%S'", i+1, isUefiNtfs ? " (UEFI:NTFS)" : "",
|
suprintf("Partition %d%s:\r\n Type: %s\r\n Name: '%S'", i+1, isUefiNtfs ? " (UEFI:NTFS)" : "",
|
||||||
|
@ -1401,33 +1414,33 @@ BOOL MountVolume(char* drive_name, char *volume_name)
|
||||||
/*
|
/*
|
||||||
* Alternate version of MountVolume required for ESP's, since Windows (including VDS) does
|
* Alternate version of MountVolume required for ESP's, since Windows (including VDS) does
|
||||||
* *NOT* provide any means of mounting these volume but through DefineDosDevice(). Also
|
* *NOT* provide any means of mounting these volume but through DefineDosDevice(). Also
|
||||||
* note the bcdboot is very finicky about what it may or may not handle, even if the
|
* note that bcdboot is very finicky about what it may or may not handle, even if the
|
||||||
* mount was successful (e.g. '\Device\HarddiskVolume###' vs 'Device\HarddiskVolume###').
|
* mount was successful (e.g. '\Device\HarddiskVolume###' vs 'Device\HarddiskVolume###').
|
||||||
* Returned string is static (no concurrency) and should not be freed.
|
* Returned string is static (no concurrency) and must not be freed.
|
||||||
*/
|
*/
|
||||||
char* AltMountVolume(DWORD DriveIndex, DWORD PartitionIndex)
|
char* AltMountVolume(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bSilent)
|
||||||
{
|
{
|
||||||
char* ret = NULL, *volume_name = NULL;
|
char* ret = NULL, *volume_name = NULL;
|
||||||
static char mounted_drive[] = "?:";
|
static char mounted_drive[] = "?:";
|
||||||
|
|
||||||
mounted_drive[0] = GetUnusedDriveLetter();
|
mounted_drive[0] = GetUnusedDriveLetter();
|
||||||
if (mounted_drive[0] == 0) {
|
if (mounted_drive[0] == 0) {
|
||||||
uprintf("Could not find an unused drive letter");
|
suprintf("Could not find an unused drive letter");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
volume_name = GetLogicalName(DriveIndex, PartitionIndex, FALSE, TRUE);
|
// Can't use a regular volume GUID for ESPs...
|
||||||
|
volume_name = AltGetLogicalName(DriveIndex, PartitionOffset, FALSE, TRUE);
|
||||||
if ((volume_name == NULL) || (strncmp(volume_name, groot_name, groot_len) != 0)) {
|
if ((volume_name == NULL) || (strncmp(volume_name, groot_name, groot_len) != 0)) {
|
||||||
uprintf("Unexpected volume name: '%s'", volume_name);
|
suprintf("Unexpected volume name: '%s'", volume_name);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcdboot sure won't like it if you forget the starting '\'
|
suprintf("Mounting '%s' as '%s'", &volume_name[14], mounted_drive);
|
||||||
|
// bcdboot doesn't like it if you forget the starting '\'
|
||||||
if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, mounted_drive, &volume_name[14])) {
|
if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, mounted_drive, &volume_name[14])) {
|
||||||
uprintf("Could not mount '%s' to '%s': %s", &volume_name[14], mounted_drive, WindowsErrorString());
|
suprintf("Mount operation failed: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uprintf("Successfully mounted '%s' (Partition %d) as '%s'", &volume_name[14], PartitionIndex, mounted_drive);
|
|
||||||
ret = mounted_drive;
|
ret = mounted_drive;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1438,15 +1451,15 @@ out:
|
||||||
/*
|
/*
|
||||||
* Unmount a volume that was mounted by AltmountVolume()
|
* Unmount a volume that was mounted by AltmountVolume()
|
||||||
*/
|
*/
|
||||||
BOOL AltUnmountVolume(const char* drive_name)
|
BOOL AltUnmountVolume(const char* drive_name, BOOL bSilent)
|
||||||
{
|
{
|
||||||
if (drive_name == NULL)
|
if (drive_name == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive_name, NULL)) {
|
if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive_name, NULL)) {
|
||||||
uprintf("Could not unmount '%s': %s", drive_name, WindowsErrorString());
|
suprintf("Could not unmount '%s': %s", drive_name, WindowsErrorString());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
uprintf("Successfully unmounted '%s'", drive_name);
|
suprintf("Successfully unmounted '%s'", drive_name);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1536,7 +1549,8 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
if (uefi_ntfs_size == 0)
|
if (uefi_ntfs_size == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
memset(partition_index, 0, sizeof(partition_index));
|
memset(partition_offset, 0, sizeof(partition_offset));
|
||||||
|
memset(SelectedDrive.PartitionOffset, 0, sizeof(SelectedDrive.PartitionOffset));
|
||||||
|
|
||||||
// Compute the start offset of our first partition
|
// Compute the start offset of our first partition
|
||||||
if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_OLD_BIOS_FIXES))) {
|
if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_OLD_BIOS_FIXES))) {
|
||||||
|
@ -1560,6 +1574,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
// Zero the first sectors from this partition to avoid file system caching issues
|
// Zero the first sectors from this partition to avoid file system caching issues
|
||||||
if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear))
|
if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear))
|
||||||
uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString());
|
uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString());
|
||||||
|
SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart;
|
||||||
pn++;
|
pn++;
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart +
|
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart +
|
||||||
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
||||||
|
@ -1641,15 +1656,12 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
||||||
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, main_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, main_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
||||||
}
|
}
|
||||||
|
SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart;
|
||||||
|
partition_offset[PI_MAIN] = SelectedDrive.PartitionOffset[pn];
|
||||||
pn++;
|
pn++;
|
||||||
partition_index[PI_MAIN] = pn;
|
|
||||||
|
|
||||||
// Set the optional extra partition
|
// Set the optional extra partition
|
||||||
if (extra_partitions) {
|
if (extra_partitions) {
|
||||||
if (extra_partitions & XP_CASPER)
|
|
||||||
partition_index[PI_CASPER] = pn + 1;
|
|
||||||
else if (extra_partitions & XP_ESP)
|
|
||||||
partition_index[PI_ESP] = pn + 1;
|
|
||||||
// Should end on a track boundary
|
// Should end on a track boundary
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart +
|
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart +
|
||||||
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
||||||
|
@ -1657,6 +1669,12 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
extra_part_size_in_tracks * bytes_per_track;
|
extra_part_size_in_tracks * bytes_per_track;
|
||||||
uprintf("● Creating %S Partition (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart,
|
uprintf("● Creating %S Partition (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart,
|
||||||
SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE));
|
SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE));
|
||||||
|
SelectedDrive.PartitionOffset[pn] = DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart;
|
||||||
|
if (extra_partitions & XP_CASPER)
|
||||||
|
partition_offset[PI_CASPER] = SelectedDrive.PartitionOffset[pn];
|
||||||
|
else if (extra_partitions & XP_ESP)
|
||||||
|
partition_offset[PI_ESP] = SelectedDrive.PartitionOffset[pn];
|
||||||
|
|
||||||
if (partition_style == PARTITION_STYLE_GPT) {
|
if (partition_style == PARTITION_STYLE_GPT) {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = (extra_partitions & XP_ESP) ? PARTITION_SYSTEM_GUID : PARTITION_BASIC_DATA_GUID;
|
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = (extra_partitions & XP_ESP) ? PARTITION_SYSTEM_GUID : PARTITION_BASIC_DATA_GUID;
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
||||||
|
|
20
src/drive.h
20
src/drive.h
|
@ -350,6 +350,7 @@ 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];
|
||||||
int FSType;
|
int FSType;
|
||||||
char proposed_label[16];
|
char proposed_label[16];
|
||||||
BOOL has_protective_mbr;
|
BOOL has_protective_mbr;
|
||||||
|
@ -360,18 +361,19 @@ 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 DWORD partition_index[3];
|
extern uint64_t partition_offset[3];
|
||||||
|
|
||||||
BOOL SetAutoMount(BOOL enable);
|
BOOL SetAutoMount(BOOL enable);
|
||||||
BOOL GetAutoMount(BOOL* enabled);
|
BOOL GetAutoMount(BOOL* enabled);
|
||||||
char* GetPhysicalName(DWORD DriveIndex);
|
char* GetPhysicalName(DWORD DriveIndex);
|
||||||
char* GetPartitionName(DWORD DriveIndex, DWORD PartitionIndex);
|
char* GetPartitionName(DWORD DriveIndex, uint64_t PartitionOffset);
|
||||||
BOOL DeletePartitions(DWORD DriveIndex);
|
BOOL DeletePartitions(DWORD DriveIndex);
|
||||||
HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
|
HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
|
||||||
char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
||||||
BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex);
|
char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
||||||
HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
|
BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset);
|
||||||
HANDLE GetPartitionHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
|
HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
|
||||||
|
HANDLE GetPartitionHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
|
||||||
int GetDriveNumber(HANDLE hDrive, char* path);
|
int GetDriveNumber(HANDLE hDrive, char* path);
|
||||||
BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters);
|
BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters);
|
||||||
UINT GetDriveTypeFromIndex(DWORD DriveIndex);
|
UINT GetDriveTypeFromIndex(DWORD DriveIndex);
|
||||||
|
@ -384,14 +386,14 @@ BOOL AnalyzePBR(HANDLE hLogicalVolume);
|
||||||
BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize, BOOL bSilent);
|
BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize, BOOL bSilent);
|
||||||
BOOL UnmountVolume(HANDLE hDrive);
|
BOOL UnmountVolume(HANDLE hDrive);
|
||||||
BOOL MountVolume(char* drive_name, char *drive_guid);
|
BOOL MountVolume(char* drive_name, char *drive_guid);
|
||||||
BOOL AltUnmountVolume(const char* drive_name);
|
BOOL AltUnmountVolume(const char* drive_name, BOOL bSilent);
|
||||||
char* AltMountVolume(DWORD DriveIndex, DWORD PartitionIndex);
|
char* AltMountVolume(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bSilent);
|
||||||
BOOL RemountVolume(char* drive_name);
|
BOOL RemountVolume(char* drive_name);
|
||||||
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);
|
||||||
BOOL InitializeDisk(HANDLE hDrive);
|
BOOL InitializeDisk(HANDLE hDrive);
|
||||||
BOOL RefreshDriveLayout(HANDLE hDrive);
|
BOOL RefreshDriveLayout(HANDLE hDrive);
|
||||||
const char* GetPartitionType(BYTE Type);
|
const char* GetPartitionType(BYTE Type);
|
||||||
const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex);
|
const char* GetExtFsLabel(DWORD DriveIndex, uint64_t PartitionOffset);
|
||||||
BOOL GetDevices(DWORD devnum);
|
BOOL GetDevices(DWORD devnum);
|
||||||
BOOL CyclePort(int index);
|
BOOL CyclePort(int index);
|
||||||
int CycleDevice(int index);
|
int CycleDevice(int index);
|
||||||
|
|
59
src/format.c
59
src/format.c
|
@ -373,7 +373,7 @@ static DWORD GetFATSizeSectors(DWORD DskSize, DWORD ReservedSecCnt, DWORD SecPer
|
||||||
* Large FAT32 volume formatting from fat32format by Tom Thornhill
|
* Large FAT32 volume formatting from fat32format by Tom Thornhill
|
||||||
* http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
|
* http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
|
||||||
*/
|
*/
|
||||||
static BOOL FormatFAT32(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
|
static BOOL FormatFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
@ -420,7 +420,7 @@ static BOOL FormatFAT32(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSiz
|
||||||
VolumeId = GetVolumeID();
|
VolumeId = GetVolumeID();
|
||||||
|
|
||||||
// Open the drive and lock it
|
// Open the drive and lock it
|
||||||
hLogicalVolume = GetLogicalHandle(DriveIndex, PartitionIndex, TRUE, TRUE, FALSE);
|
hLogicalVolume = GetLogicalHandle(DriveIndex, PartitionOffset, TRUE, TRUE, FALSE);
|
||||||
if (IS_ERROR(FormatStatus))
|
if (IS_ERROR(FormatStatus))
|
||||||
goto out;
|
goto out;
|
||||||
if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL))
|
if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL))
|
||||||
|
@ -651,7 +651,7 @@ static BOOL FormatFAT32(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSiz
|
||||||
PrintInfoDebug(0, MSG_221);
|
PrintInfoDebug(0, MSG_221);
|
||||||
// Handle must be closed for SetVolumeLabel to work
|
// Handle must be closed for SetVolumeLabel to work
|
||||||
safe_closehandle(hLogicalVolume);
|
safe_closehandle(hLogicalVolume);
|
||||||
VolumeName = GetLogicalName(DriveIndex, PartitionIndex, TRUE, TRUE);
|
VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE);
|
||||||
if ((VolumeName == NULL) || (!SetVolumeLabelA(VolumeName, Label))) {
|
if ((VolumeName == NULL) || (!SetVolumeLabelA(VolumeName, Label))) {
|
||||||
uprintf("Could not set label: %s", WindowsErrorString());
|
uprintf("Could not set label: %s", WindowsErrorString());
|
||||||
// Non fatal error
|
// Non fatal error
|
||||||
|
@ -819,14 +819,16 @@ errcode_t ext2fs_print_progress(int64_t cur_value, int64_t max_value)
|
||||||
return IS_ERROR(FormatStatus) ? EXT2_ET_CANCEL_REQUESTED : 0;
|
return IS_ERROR(FormatStatus) ? EXT2_ET_CANCEL_REQUESTED : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex)
|
const char* GetExtFsLabel(DWORD DriveIndex, uint64_t PartitionOffset)
|
||||||
{
|
{
|
||||||
static char label[EXT2_LABEL_LEN + 1];
|
static char label[EXT2_LABEL_LEN + 1];
|
||||||
errcode_t r;
|
errcode_t r;
|
||||||
ext2_filsys ext2fs = NULL;
|
ext2_filsys ext2fs = NULL;
|
||||||
io_manager manager = nt_io_manager();
|
io_manager manager = nt_io_manager();
|
||||||
char* volume_name = GetPartitionName(DriveIndex, PartitionIndex);
|
char* volume_name = AltMountVolume(DriveIndex, PartitionOffset, TRUE);
|
||||||
|
|
||||||
|
if (volume_name == NULL)
|
||||||
|
return NULL;
|
||||||
r = ext2fs_open(volume_name, EXT2_FLAG_SKIP_MMP, 0, 0, manager, &ext2fs);
|
r = ext2fs_open(volume_name, EXT2_FLAG_SKIP_MMP, 0, 0, manager, &ext2fs);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN);
|
strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN);
|
||||||
|
@ -834,11 +836,11 @@ const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex)
|
||||||
}
|
}
|
||||||
if (ext2fs != NULL)
|
if (ext2fs != NULL)
|
||||||
ext2fs_close(ext2fs);
|
ext2fs_close(ext2fs);
|
||||||
free(volume_name);
|
AltUnmountVolume(volume_name, TRUE);
|
||||||
return (r == 0) ? label : NULL;
|
return (r == 0) ? label : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
|
BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
|
||||||
{
|
{
|
||||||
// Mostly taken from mke2fs.conf
|
// Mostly taken from mke2fs.conf
|
||||||
const float reserve_ratio = 0.05f;
|
const float reserve_ratio = 0.05f;
|
||||||
|
@ -877,7 +879,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR
|
||||||
}
|
}
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
#else
|
#else
|
||||||
volume_name = GetPartitionName(DriveIndex, PartitionIndex);
|
volume_name = AltMountVolume(DriveIndex, PartitionOffset, FALSE);
|
||||||
#endif
|
#endif
|
||||||
if ((volume_name == NULL) | (strlen(FSName) != 4) || (strncmp(FSName, "ext", 3) != 0)) {
|
if ((volume_name == NULL) | (strlen(FSName) != 4) || (strncmp(FSName, "ext", 3) != 0)) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER;
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER;
|
||||||
|
@ -1097,14 +1099,14 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR
|
||||||
out:
|
out:
|
||||||
ext2fs_free(ext2fs);
|
ext2fs_free(ext2fs);
|
||||||
free(buf);
|
free(buf);
|
||||||
free(volume_name);
|
AltUnmountVolume(volume_name, FALSE);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call on VDS to format a partition
|
* Call on VDS to format a partition
|
||||||
*/
|
*/
|
||||||
static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
|
static BOOL FormatDriveVds(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE, bFoundVolume = FALSE;
|
BOOL r = FALSE, bFoundVolume = FALSE;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -1122,7 +1124,7 @@ static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD Cluster
|
||||||
PrintInfoDebug(0, MSG_222, FSName);
|
PrintInfoDebug(0, MSG_222, FSName);
|
||||||
}
|
}
|
||||||
LastRefresh = 0;
|
LastRefresh = 0;
|
||||||
VolumeName = GetLogicalName(DriveIndex, PartitionIndex, TRUE, TRUE);
|
VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE);
|
||||||
wVolumeName = utf8_to_wchar(VolumeName);
|
wVolumeName = utf8_to_wchar(VolumeName);
|
||||||
if (wVolumeName == NULL) {
|
if (wVolumeName == NULL) {
|
||||||
uprintf("Could not read volume name");
|
uprintf("Could not read volume name");
|
||||||
|
@ -1350,7 +1352,7 @@ out:
|
||||||
/*
|
/*
|
||||||
* Call on fmifs.dll's FormatEx() to format the drive
|
* Call on fmifs.dll's FormatEx() to format the drive
|
||||||
*/
|
*/
|
||||||
static BOOL FormatDrive(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
|
static BOOL FormatDrive(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
PF_DECL(FormatEx);
|
PF_DECL(FormatEx);
|
||||||
|
@ -1364,10 +1366,10 @@ static BOOL FormatDrive(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSiz
|
||||||
} else {
|
} else {
|
||||||
PrintInfoDebug(0, MSG_222, FSName);
|
PrintInfoDebug(0, MSG_222, FSName);
|
||||||
}
|
}
|
||||||
VolumeName = GetLogicalName(DriveIndex, PartitionIndex, TRUE, TRUE);
|
VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE);
|
||||||
wVolumeName = utf8_to_wchar(VolumeName);
|
wVolumeName = utf8_to_wchar(VolumeName);
|
||||||
if (wVolumeName == NULL) {
|
if (wVolumeName == NULL) {
|
||||||
uprintf("Could not read volume name\n");
|
uprintf("Could not read volume name");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1429,9 +1431,9 @@ out:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL FormatPartition(DWORD DriveIndex, DWORD PartitionIndex, DWORD UnitAllocationSize, USHORT FSType, LPCSTR Label, DWORD Flags)
|
static BOOL FormatPartition(DWORD DriveIndex, uint64_t PartitionOffset, DWORD UnitAllocationSize, USHORT FSType, LPCSTR Label, DWORD Flags)
|
||||||
{
|
{
|
||||||
if ((DriveIndex < 0x80) || (DriveIndex > 0x100) || (PartitionIndex >= MAX_PARTITIONS) || (FSType >= FS_MAX) ||
|
if ((DriveIndex < 0x80) || (DriveIndex > 0x100) || (FSType >= FS_MAX) ||
|
||||||
// The following validates that UnitAllocationSize is a power of 2
|
// The following validates that UnitAllocationSize is a power of 2
|
||||||
((UnitAllocationSize != 0) && (UnitAllocationSize & (UnitAllocationSize - 1)))) {
|
((UnitAllocationSize != 0) && (UnitAllocationSize & (UnitAllocationSize - 1)))) {
|
||||||
ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER;
|
ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER;
|
||||||
|
@ -1439,13 +1441,13 @@ static BOOL FormatPartition(DWORD DriveIndex, DWORD PartitionIndex, DWORD UnitAl
|
||||||
}
|
}
|
||||||
actual_fs_type = FSType;
|
actual_fs_type = FSType;
|
||||||
if ((FSType == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32) || (Flags & FP_LARGE_FAT32)))
|
if ((FSType == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32) || (Flags & FP_LARGE_FAT32)))
|
||||||
return FormatFAT32(DriveIndex, PartitionIndex, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags);
|
return FormatFAT32(DriveIndex, PartitionOffset, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags);
|
||||||
else if (FSType >= FS_EXT2)
|
else if (FSType >= FS_EXT2)
|
||||||
return FormatExtFs(DriveIndex, PartitionIndex, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags);
|
return FormatExtFs(DriveIndex, PartitionOffset, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags);
|
||||||
else if (use_vds)
|
else if (use_vds)
|
||||||
return FormatDriveVds(DriveIndex, PartitionIndex, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags);
|
return FormatDriveVds(DriveIndex, PartitionOffset, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags);
|
||||||
else
|
else
|
||||||
return FormatDrive(DriveIndex, PartitionIndex, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags);
|
return FormatDrive(DriveIndex, PartitionOffset, UnitAllocationSize, FileSystemLabel[FSType], Label, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2159,7 +2161,7 @@ static 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_index[PI_ESP], cluster_size, FS_FAT32, "",
|
if (!FormatPartition(DriveIndex, partition_offset[PI_ESP], 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;
|
||||||
|
@ -2169,7 +2171,7 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
|
||||||
|
|
||||||
if (use_esp) {
|
if (use_esp) {
|
||||||
// Need to have the ESP mounted to invoke bcdboot
|
// Need to have the ESP mounted to invoke bcdboot
|
||||||
ms_efi = AltMountVolume(DriveIndex, partition_index[PI_ESP]);
|
ms_efi = AltMountVolume(DriveIndex, partition_offset[PI_ESP], 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;
|
||||||
|
@ -2192,7 +2194,7 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
|
||||||
|
|
||||||
if (use_esp) {
|
if (use_esp) {
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
AltUnmountVolume(ms_efi);
|
AltUnmountVolume(ms_efi, FALSE);
|
||||||
}
|
}
|
||||||
PrintInfo(0, MSG_267, 99.9f);
|
PrintInfo(0, MSG_267, 99.9f);
|
||||||
UpdateProgress(OP_DOS, 99.9f);
|
UpdateProgress(OP_DOS, 99.9f);
|
||||||
|
@ -2679,7 +2681,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
// Wait for the logical drive we just created to appear
|
// Wait for the logical drive we just created to appear
|
||||||
uprintf("Waiting for logical drive to reappear...");
|
uprintf("Waiting for logical drive to reappear...");
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
if (!WaitForLogical(DriveIndex, partition_index[PI_MAIN])) {
|
if (!WaitForLogical(DriveIndex, partition_offset[PI_MAIN])) {
|
||||||
uprintf("Logical drive was not found - aborting");
|
uprintf("Logical drive was not found - aborting");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NO_VOLUME_ID;
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NO_VOLUME_ID;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2693,7 +2695,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
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_index[PI_CASPER], 0, FS_EXT2 + (ext_version - 2),
|
if (!FormatPartition(DriveIndex, partition_offset[PI_CASPER], 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))) {
|
||||||
|
@ -2716,7 +2718,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
if ((fs_type == FS_NTFS) && (enable_ntfs_compression))
|
if ((fs_type == FS_NTFS) && (enable_ntfs_compression))
|
||||||
Flags |= FP_COMPRESSION;
|
Flags |= FP_COMPRESSION;
|
||||||
|
|
||||||
ret = FormatPartition(DriveIndex, partition_index[PI_MAIN], ClusterSize, fs_type, label, Flags);
|
ret = FormatPartition(DriveIndex, partition_offset[PI_MAIN], 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));
|
||||||
|
@ -2747,7 +2749,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_index[PI_MAIN], TRUE, TRUE);
|
volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], 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;
|
||||||
|
@ -2800,8 +2802,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...
|
||||||
// TODO: Shouldn't PI always be 1 here?
|
hLogicalVolume = GetLogicalHandle(DriveIndex, partition_offset[PI_MAIN], FALSE, TRUE, FALSE);
|
||||||
hLogicalVolume = GetLogicalHandle(DriveIndex, partition_index[PI_MAIN], 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;
|
||||||
|
|
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 3.7.1561"
|
CAPTION "Rufus 3.7.1562"
|
||||||
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
|
||||||
|
@ -394,8 +394,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 3,7,1561,0
|
FILEVERSION 3,7,1562,0
|
||||||
PRODUCTVERSION 3,7,1561,0
|
PRODUCTVERSION 3,7,1562,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -413,13 +413,13 @@ BEGIN
|
||||||
VALUE "Comments", "https://akeo.ie"
|
VALUE "Comments", "https://akeo.ie"
|
||||||
VALUE "CompanyName", "Akeo Consulting"
|
VALUE "CompanyName", "Akeo Consulting"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "3.7.1561"
|
VALUE "FileVersion", "3.7.1562"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus-3.7.exe"
|
VALUE "OriginalFilename", "rufus-3.7.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "3.7.1561"
|
VALUE "ProductVersion", "3.7.1562"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
Loading…
Reference in a new issue