mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[core] partitioning improvements
* Improve report and make sure we zero leftovers from the start of a partition * Also add VDS error codes * Also fix Coverity warnings
This commit is contained in:
parent
1c39a80d72
commit
5f9e65707f
7 changed files with 521 additions and 58 deletions
98
src/drive.c
98
src/drive.c
|
@ -1348,16 +1348,28 @@ BOOL RemountVolume(char* drive_name)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MinGW is unhappy about accessing partitions beside the first unless we redef */
|
/*
|
||||||
typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
|
* Zero the first 'size' bytes of a partition. This is needed because we haven't found a way to
|
||||||
DWORD PartitionStyle;
|
* properly reset Windows's cached view of a drive partitioning short of cycling the USB port
|
||||||
DWORD PartitionCount;
|
* (especially IOCTL_DISK_UPDATE_PROPERTIES is *USELESS*), and therefore the OS will try to
|
||||||
union {
|
* read the file system data at an old location, even if the partition has just been deleted.
|
||||||
DRIVE_LAYOUT_INFORMATION_MBR Mbr;
|
* TODO: We should do something like this is DeletePartitions() too.
|
||||||
DRIVE_LAYOUT_INFORMATION_GPT Gpt;
|
*/
|
||||||
} Type;
|
static BOOL ClearPartition(HANDLE hDrive, LARGE_INTEGER offset, DWORD size)
|
||||||
PARTITION_INFORMATION_EX PartitionEntry[MAX_PARTITIONS];
|
{
|
||||||
} DRIVE_LAYOUT_INFORMATION_EX4,*PDRIVE_LAYOUT_INFORMATION_EX4;
|
BOOL r = FALSE;
|
||||||
|
uint8_t* buffer = calloc(size, 1);
|
||||||
|
|
||||||
|
if (buffer == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!SetFilePointerEx(hDrive, offset, NULL, FILE_BEGIN))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
r = WriteFileWithRetry(hDrive, buffer, size, &size, WRITE_RETRIES);
|
||||||
|
free(buffer);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a partition table
|
* Create a partition table
|
||||||
|
@ -1369,15 +1381,16 @@ typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
|
||||||
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;
|
const wchar_t *extra_part_name = L"", *main_part_name = L"Main Data Partition";
|
||||||
unsigned char* buffer;
|
const LONGLONG bytes_per_track = ((LONGLONG)SelectedDrive.SectorsPerTrack) * SelectedDrive.SectorSize;
|
||||||
|
const DWORD size_to_clear = MAX_SECTORS_TO_CLEAR * SelectedDrive.SectorSize;
|
||||||
|
uint8_t* buffer;
|
||||||
size_t uefi_ntfs_size = 0;
|
size_t uefi_ntfs_size = 0;
|
||||||
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;
|
BOOL r;
|
||||||
DWORD i, size, bufsize, pn = 0;
|
DWORD i, size, bufsize, pn = 0;
|
||||||
LONGLONG main_part_size_in_sectors, extra_part_size_in_tracks = 0, ms_esp_size;
|
LONGLONG main_part_size_in_sectors, extra_part_size_in_tracks = 0, ms_esp_size;
|
||||||
const LONGLONG bytes_per_track = ((LONGLONG)SelectedDrive.SectorsPerTrack) * SelectedDrive.SectorSize;
|
|
||||||
|
|
||||||
PrintInfoDebug(0, MSG_238, PartitionTypeName[partition_style]);
|
PrintInfoDebug(0, MSG_238, PartitionTypeName[partition_style]);
|
||||||
|
|
||||||
|
@ -1403,7 +1416,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
|
|
||||||
// If required, set the ESP (which Microsoft wants to be the first)
|
// If required, set the ESP (which Microsoft wants to be the first)
|
||||||
if (extra_partitions & XP_ESP) {
|
if (extra_partitions & XP_ESP) {
|
||||||
uprintf("● Creating EFI System Partition");
|
extra_part_name = L"EFI System Partition";
|
||||||
// The size of the ESP depends on the minimum size we're able to format in FAT32, which
|
// The size of the ESP depends on the minimum size we're able to format in FAT32, which
|
||||||
// in turn depends on the cluster size used, which in turn depends on the disk sector size.
|
// in turn depends on the cluster size used, which in turn depends on the disk sector size.
|
||||||
// Plus some people are complaining that the *OFFICIAL MINIMUM SIZE* as documented by Microsoft at
|
// Plus some people are complaining that the *OFFICIAL MINIMUM SIZE* as documented by Microsoft at
|
||||||
|
@ -1415,15 +1428,18 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
ms_esp_size = 1200 * MB; // That'll teach you to have a nonstandard disk!
|
ms_esp_size = 1200 * MB; // That'll teach you to have a nonstandard disk!
|
||||||
extra_part_size_in_tracks = (ms_esp_size + bytes_per_track - 1) / bytes_per_track;
|
extra_part_size_in_tracks = (ms_esp_size + bytes_per_track - 1) / bytes_per_track;
|
||||||
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = extra_part_size_in_tracks * bytes_per_track;
|
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = extra_part_size_in_tracks * bytes_per_track;
|
||||||
|
uprintf("● Creating %S Partition (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart,
|
||||||
|
SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE));
|
||||||
if (partition_style == PARTITION_STYLE_GPT) {
|
if (partition_style == PARTITION_STYLE_GPT) {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_SYSTEM_GUID;
|
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_SYSTEM_GUID;
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
||||||
// coverity[strcpy_overrun]
|
wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, extra_part_name);
|
||||||
wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, L"EFI System Partition");
|
|
||||||
} else {
|
} else {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0xef;
|
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0xef;
|
||||||
}
|
}
|
||||||
|
// Zero the first sectors from this partition to avoid file system caching issues
|
||||||
|
if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear))
|
||||||
|
uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString());
|
||||||
pn++;
|
pn++;
|
||||||
partition_index[PI_ESP] = pn;
|
partition_index[PI_ESP] = pn;
|
||||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn - 1].StartingOffset.QuadPart +
|
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn - 1].StartingOffset.QuadPart +
|
||||||
|
@ -1431,24 +1447,18 @@ 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 ((partition_style == PARTITION_STYLE_GPT) && (extra_partitions & XP_MSR)) {
|
if (extra_partitions & XP_MSR) {
|
||||||
uprintf("● Creating MSR Partition");
|
assert (partition_style == PARTITION_STYLE_GPT);
|
||||||
|
extra_part_name = L"Microsoft Reserved Partition";
|
||||||
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = 128*MB;
|
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = 128*MB;
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MSFT_RESERVED_GUID;
|
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MSFT_RESERVED_GUID;
|
||||||
|
uprintf("● Creating %S Partition (offset: %lld, size: %s)", extra_part_name, DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart,
|
||||||
|
SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE));
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
||||||
// coverity[strcpy_overrun]
|
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, extra_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
||||||
wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, L"Microsoft Reserved Partition");
|
// Zero the first sectors from this partition to avoid file system caching issues
|
||||||
|
if (!ClearPartition(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, size_to_clear))
|
||||||
// We must zero the beginning of this partition, else we get FAT leftovers and stuff
|
uprintf("Could not zero %S: %s", extra_part_name, WindowsErrorString());
|
||||||
if (SetFilePointerEx(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, NULL, FILE_BEGIN)) {
|
|
||||||
bufsize = 65536; // 64K should be enough for everyone
|
|
||||||
buffer = calloc(bufsize, 1);
|
|
||||||
if (buffer != NULL) {
|
|
||||||
if (!WriteFileWithRetry(hDrive, buffer, bufsize, &size, WRITE_RETRIES))
|
|
||||||
uprintf(" Could not zero MSR: %s", WindowsErrorString());
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
||||||
|
@ -1460,10 +1470,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
main_part_size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) /
|
main_part_size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) /
|
||||||
// Need 33 sectors at the end for secondary GPT
|
// Need 33 sectors at the end for secondary GPT
|
||||||
SelectedDrive.SectorSize - ((partition_style == PARTITION_STYLE_GPT)?33:0);
|
SelectedDrive.SectorSize - ((partition_style == PARTITION_STYLE_GPT)?33:0);
|
||||||
if (!extra_partitions) {
|
if (extra_partitions) {
|
||||||
uprintf("● Creating Main Data Partition: %lld tracks (%s)", main_part_size_in_sectors / SelectedDrive.SectorsPerTrack,
|
|
||||||
SizeToHumanReadable(main_part_size_in_sectors * SelectedDrive.SectorSize, TRUE, FALSE));
|
|
||||||
} else {
|
|
||||||
// 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_UEFI_NTFS) {
|
if (extra_partitions & XP_UEFI_NTFS) {
|
||||||
extra_part_name = L"UEFI:NTFS";
|
extra_part_name = L"UEFI:NTFS";
|
||||||
|
@ -1475,18 +1482,21 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
} else if (extra_partitions & XP_COMPAT) {
|
} else if (extra_partitions & XP_COMPAT) {
|
||||||
extra_part_name = L"BIOS Compatibility";
|
extra_part_name = L"BIOS Compatibility";
|
||||||
extra_part_size_in_tracks = 1; // One track for the extra partition
|
extra_part_size_in_tracks = 1; // One track for the extra partition
|
||||||
|
} else {
|
||||||
|
assert(FALSE);
|
||||||
}
|
}
|
||||||
main_part_size_in_sectors = ((main_part_size_in_sectors / SelectedDrive.SectorsPerTrack) -
|
main_part_size_in_sectors = ((main_part_size_in_sectors / SelectedDrive.SectorsPerTrack) -
|
||||||
extra_part_size_in_tracks) * SelectedDrive.SectorsPerTrack;
|
extra_part_size_in_tracks) * SelectedDrive.SectorsPerTrack;
|
||||||
uprintf("● Creating Main Data Partition: %lld tracks (%s)", main_part_size_in_sectors / SelectedDrive.SectorsPerTrack,
|
|
||||||
SizeToHumanReadable(main_part_size_in_sectors * SelectedDrive.SectorSize, TRUE, FALSE));
|
|
||||||
uprintf("● Creating %S Partition: %lld tracks (%s)", extra_part_name, extra_part_size_in_tracks,
|
|
||||||
SizeToHumanReadable(extra_part_size_in_tracks * bytes_per_track, TRUE, FALSE));
|
|
||||||
}
|
}
|
||||||
if (main_part_size_in_sectors <= 0) {
|
if (main_part_size_in_sectors <= 0) {
|
||||||
uprintf("Error: Invalid Main Partition size!");
|
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;
|
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = main_part_size_in_sectors * SelectedDrive.SectorSize;
|
||||||
if (partition_style == PARTITION_STYLE_MBR) {
|
if (partition_style == PARTITION_STYLE_MBR) {
|
||||||
|
@ -1516,7 +1526,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
} else {
|
} else {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
|
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
||||||
wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, L"Basic Data");
|
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, main_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
||||||
}
|
}
|
||||||
pn++;
|
pn++;
|
||||||
partition_index[PI_MAIN] = pn;
|
partition_index[PI_MAIN] = pn;
|
||||||
|
@ -1531,10 +1541,12 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
||||||
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = (extra_partitions & XP_UEFI_NTFS)?uefi_ntfs_size:
|
DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = (extra_partitions & XP_UEFI_NTFS)?uefi_ntfs_size:
|
||||||
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,
|
||||||
|
SizeToHumanReadable(DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart, TRUE, FALSE));
|
||||||
if (partition_style == PARTITION_STYLE_GPT) {
|
if (partition_style == PARTITION_STYLE_GPT) {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
|
DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId));
|
||||||
wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, extra_part_name);
|
wcsncpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, extra_part_name, ARRAYSIZE(DriveLayoutEx.PartitionEntry[pn].Gpt.Name));
|
||||||
} else {
|
} else {
|
||||||
if (extra_partitions & XP_UEFI_NTFS) {
|
if (extra_partitions & XP_UEFI_NTFS) {
|
||||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0xef;
|
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0xef;
|
||||||
|
|
11
src/drive.h
11
src/drive.h
|
@ -318,6 +318,17 @@ interface IVdsAsync {
|
||||||
#define IVdsAsync_Release(This) (This)->lpVtbl->Release(This)
|
#define IVdsAsync_Release(This) (This)->lpVtbl->Release(This)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* MinGW is unhappy about accessing partitions beside the first unless we redef */
|
||||||
|
typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
|
||||||
|
DWORD PartitionStyle;
|
||||||
|
DWORD PartitionCount;
|
||||||
|
union {
|
||||||
|
DRIVE_LAYOUT_INFORMATION_MBR Mbr;
|
||||||
|
DRIVE_LAYOUT_INFORMATION_GPT Gpt;
|
||||||
|
} Type;
|
||||||
|
PARTITION_INFORMATION_EX PartitionEntry[MAX_PARTITIONS];
|
||||||
|
} DRIVE_LAYOUT_INFORMATION_EX4, *PDRIVE_LAYOUT_INFORMATION_EX4;
|
||||||
|
|
||||||
static __inline BOOL UnlockDrive(HANDLE hDrive) {
|
static __inline BOOL UnlockDrive(HANDLE hDrive) {
|
||||||
DWORD size;
|
DWORD size;
|
||||||
return DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL);
|
return DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL);
|
||||||
|
|
15
src/iso.c
15
src/iso.c
|
@ -1277,7 +1277,7 @@ BOOL DumpFatDir(const char* path, int32_t cluster)
|
||||||
void* buf;
|
void* buf;
|
||||||
char *target = NULL, *name = NULL;
|
char *target = NULL, *name = NULL;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
HANDLE handle;
|
HANDLE handle = NULL;
|
||||||
DWORD size, written;
|
DWORD size, written;
|
||||||
libfat_diritem_t diritem = { 0 };
|
libfat_diritem_t diritem = { 0 };
|
||||||
libfat_dirpos_t dirpos = { cluster, -1, 0 };
|
libfat_dirpos_t dirpos = { cluster, -1, 0 };
|
||||||
|
@ -1351,28 +1351,28 @@ BOOL DumpFatDir(const char* path, int32_t cluster)
|
||||||
handle = CreateFileU(target, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
|
handle = CreateFileU(target, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
|
||||||
NULL, CREATE_ALWAYS, diritem.attributes, NULL);
|
NULL, CREATE_ALWAYS, diritem.attributes, NULL);
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
uprintf("Unable to create '%s': %s", target, WindowsErrorString());
|
uprintf("Could not create '%s': %s", target, WindowsErrorString());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
written = 0;
|
written = 0;
|
||||||
s = libfat_clustertosector(lf_fs, dirpos.cluster);
|
s = libfat_clustertosector(lf_fs, dirpos.cluster);
|
||||||
while ((s != 0) && (s < 0xFFFFFFFFULL) && (written < diritem.size)) {
|
while ((s != 0) && (s < 0xFFFFFFFFULL) && (written < diritem.size)) {
|
||||||
if (FormatStatus) goto out;
|
if (FormatStatus)
|
||||||
|
goto out;
|
||||||
buf = libfat_get_sector(lf_fs, s);
|
buf = libfat_get_sector(lf_fs, s);
|
||||||
size = MIN(LIBFAT_SECTOR_SIZE, diritem.size - written);
|
size = MIN(LIBFAT_SECTOR_SIZE, diritem.size - written);
|
||||||
if (!WriteFileWithRetry(handle, buf, size, &size, WRITE_RETRIES) ||
|
if (!WriteFileWithRetry(handle, buf, size, &size, WRITE_RETRIES) ||
|
||||||
(size != MIN(LIBFAT_SECTOR_SIZE, diritem.size - written))) {
|
(size != MIN(LIBFAT_SECTOR_SIZE, diritem.size - written))) {
|
||||||
uprintf("Error writing '%s': %s", target, WindowsErrorString());
|
uprintf("Could not write '%s': %s", target, WindowsErrorString());
|
||||||
CloseHandle(handle);
|
break;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
written += size;
|
written += size;
|
||||||
s = libfat_nextsector(lf_fs, s);
|
s = libfat_nextsector(lf_fs, s);
|
||||||
// Trust me, you *REALLY* want to invoke libfat_flush() here
|
// Trust me, you *REALLY* want to invoke libfat_flush() here
|
||||||
libfat_flush(lf_fs);
|
libfat_flush(lf_fs);
|
||||||
}
|
}
|
||||||
CloseHandle(handle);
|
safe_closehandle(handle);
|
||||||
if (props.is_conf)
|
if (props.is_conf)
|
||||||
fix_config(target, NULL, NULL, &props);
|
fix_config(target, NULL, NULL, &props);
|
||||||
}
|
}
|
||||||
|
@ -1395,6 +1395,7 @@ out:
|
||||||
if (p_iso != NULL)
|
if (p_iso != NULL)
|
||||||
iso9660_close(p_iso);
|
iso9660_close(p_iso);
|
||||||
}
|
}
|
||||||
|
safe_closehandle(handle);
|
||||||
safe_free(name);
|
safe_free(name);
|
||||||
safe_free(target);
|
safe_free(target);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1038,8 +1038,10 @@ static __inline char* getenvU(const char* varname)
|
||||||
// _wgetenv() is *BROKEN* in MS compilers => use GetEnvironmentVariableW()
|
// _wgetenv() is *BROKEN* in MS compilers => use GetEnvironmentVariableW()
|
||||||
DWORD dwSize = GetEnvironmentVariableW(wvarname, wbuf, 0);
|
DWORD dwSize = GetEnvironmentVariableW(wvarname, wbuf, 0);
|
||||||
wbuf = calloc(dwSize, sizeof(wchar_t));
|
wbuf = calloc(dwSize, sizeof(wchar_t));
|
||||||
if (wbuf == NULL)
|
if (wbuf == NULL) {
|
||||||
|
wfree(varname);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
dwSize = GetEnvironmentVariableW(wvarname, wbuf, dwSize);
|
dwSize = GetEnvironmentVariableW(wvarname, wbuf, dwSize);
|
||||||
if (dwSize != 0)
|
if (dwSize != 0)
|
||||||
ret = wchar_to_utf8(wbuf);
|
ret = wchar_to_utf8(wbuf);
|
||||||
|
|
|
@ -1529,7 +1529,7 @@ static void InitDialog(HWND hDlg)
|
||||||
CharUpperBuffU(uppercase_select[0], sizeof(uppercase_select[0]));
|
CharUpperBuffU(uppercase_select[0], sizeof(uppercase_select[0]));
|
||||||
CharUpperBuffU(uppercase_select[1], sizeof(uppercase_select[1]));
|
CharUpperBuffU(uppercase_select[1], sizeof(uppercase_select[1]));
|
||||||
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECT), uppercase_select[0]);
|
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECT), uppercase_select[0]);
|
||||||
strcpy(uppercase_cancel, lmprintf(MSG_007));
|
static_strcpy(uppercase_cancel, lmprintf(MSG_007));
|
||||||
CharUpperBuffU(uppercase_cancel, sizeof(uppercase_cancel));
|
CharUpperBuffU(uppercase_cancel, sizeof(uppercase_cancel));
|
||||||
|
|
||||||
CreateSmallButtons(hDlg);
|
CreateSmallButtons(hDlg);
|
||||||
|
|
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.6.1528"
|
CAPTION "Rufus 3.6.1529"
|
||||||
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,6,1528,0
|
FILEVERSION 3,6,1529,0
|
||||||
PRODUCTVERSION 3,6,1528,0
|
PRODUCTVERSION 3,6,1529,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.6.1528"
|
VALUE "FileVersion", "3.6.1529"
|
||||||
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.6.exe"
|
VALUE "OriginalFilename", "rufus-3.6.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "3.6.1528"
|
VALUE "ProductVersion", "3.6.1529"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
439
src/stdio.c
439
src/stdio.c
|
@ -153,6 +153,439 @@ void DumpBufferHex(void *buf, size_t size)
|
||||||
uprintf("%s\n", line);
|
uprintf("%s\n", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count on Microsoft to add a new API while not bothering updating the existing error facilities,
|
||||||
|
// so that the new error messages have to be handled manually. Now, since I don't have all day:
|
||||||
|
// 1. Copy text from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-vds/5102cc53-3143-4268-ba4c-6ea39e999ab4
|
||||||
|
// 2. awk '{l[NR%7]=$0} {if (NR%7==0) printf "\tcase %s:\t// %s\n\t\treturn \"%s\";\n", l[1], l[3], l[6]}' vds.txt
|
||||||
|
// 3. Filter out the crap we don't need.
|
||||||
|
static const char *GetVdsError(DWORD error_code)
|
||||||
|
{
|
||||||
|
switch (error_code) {
|
||||||
|
case 0x80042400: // VDS_E_NOT_SUPPORTED
|
||||||
|
return "The operation is not supported by the object.";
|
||||||
|
case 0x80042401: // VDS_E_INITIALIZED_FAILED
|
||||||
|
return "VDS or the provider failed to initialize.";
|
||||||
|
case 0x80042402: // VDS_E_INITIALIZE_NOT_CALLED
|
||||||
|
return "VDS did not call the hardware provider's initialization method.";
|
||||||
|
case 0x80042403: // VDS_E_ALREADY_REGISTERED
|
||||||
|
return "The provider is already registered.";
|
||||||
|
case 0x80042404: // VDS_E_ANOTHER_CALL_IN_PROGRESS
|
||||||
|
return "A concurrent second call is made on an object before the first call is completed.";
|
||||||
|
case 0x80042405: // VDS_E_OBJECT_NOT_FOUND
|
||||||
|
return "The specified object was not found.";
|
||||||
|
case 0x80042406: // VDS_E_INVALID_SPACE
|
||||||
|
return "The specified space is neither free nor valid.";
|
||||||
|
case 0x80042407: // VDS_E_PARTITION_LIMIT_REACHED
|
||||||
|
return "No more partitions can be created on the specified disk.";
|
||||||
|
case 0x80042408: // VDS_E_PARTITION_NOT_EMPTY
|
||||||
|
return "The extended partition is not empty.";
|
||||||
|
case 0x80042409: // VDS_E_OPERATION_PENDING
|
||||||
|
return "The operation is still in progress.";
|
||||||
|
case 0x8004240A: // VDS_E_OPERATION_DENIED
|
||||||
|
return "The operation is not permitted on the specified disk, partition, or volume.";
|
||||||
|
case 0x8004240B: // VDS_E_OBJECT_DELETED
|
||||||
|
return "The object no longer exists.";
|
||||||
|
case 0x8004240C: // VDS_E_CANCEL_TOO_LATE
|
||||||
|
return "The operation can no longer be canceled.";
|
||||||
|
case 0x8004240D: // VDS_E_OPERATION_CANCELED
|
||||||
|
return "The operation has already been canceled.";
|
||||||
|
case 0x8004240E: // VDS_E_CANNOT_EXTEND
|
||||||
|
return "The file system does not support extending this volume.";
|
||||||
|
case 0x8004240F: // VDS_E_NOT_ENOUGH_SPACE
|
||||||
|
return "There is not enough space to complete the operation.";
|
||||||
|
case 0x80042410: // VDS_E_NOT_ENOUGH_DRIVE
|
||||||
|
return "There are not enough free disk drives in the subsystem to complete the operation.";
|
||||||
|
case 0x80042411: // VDS_E_BAD_COOKIE
|
||||||
|
return "The cookie was not found.";
|
||||||
|
case 0x80042412: // VDS_E_NO_MEDIA
|
||||||
|
return "There is no removable media in the drive.";
|
||||||
|
case 0x80042413: // VDS_E_DEVICE_IN_USE
|
||||||
|
return "The device is currently in use.";
|
||||||
|
case 0x80042414: // VDS_E_DISK_NOT_EMPTY
|
||||||
|
return "The disk contains partitions or volumes.";
|
||||||
|
case 0x80042415: // VDS_E_INVALID_OPERATION
|
||||||
|
return "The specified operation is not valid.";
|
||||||
|
case 0x80042416: // VDS_E_PATH_NOT_FOUND
|
||||||
|
return "The specified path was not found.";
|
||||||
|
case 0x80042417: // VDS_E_DISK_NOT_INITIALIZED
|
||||||
|
return "The specified disk has not been initialized.";
|
||||||
|
case 0x80042418: // VDS_E_NOT_AN_UNALLOCATED_DISK
|
||||||
|
return "The specified disk is not an unallocated disk.";
|
||||||
|
case 0x80042419: // VDS_E_UNRECOVERABLE_ERROR
|
||||||
|
return "An unrecoverable error occurred. The service MUST shut down.";
|
||||||
|
case 0x0004241A: // VDS_S_DISK_PARTIALLY_CLEANED
|
||||||
|
return "The clean operation was not a full clean or was canceled before it could be completed.";
|
||||||
|
case 0x8004241B: // VDS_E_DMADMIN_SERVICE_CONNECTION_FAILED
|
||||||
|
return "The provider failed to connect to the LDMA service.";
|
||||||
|
case 0x8004241C: // VDS_E_PROVIDER_INITIALIZATION_FAILED
|
||||||
|
return "The provider failed to initialize.";
|
||||||
|
case 0x8004241D: // VDS_E_OBJECT_EXISTS
|
||||||
|
return "The object already exists.";
|
||||||
|
case 0x8004241E: // VDS_E_NO_DISKS_FOUND
|
||||||
|
return "No disks were found on the target machine.";
|
||||||
|
case 0x8004241F: // VDS_E_PROVIDER_CACHE_CORRUPT
|
||||||
|
return "The cache for a provider is corrupt.";
|
||||||
|
case 0x80042420: // VDS_E_DMADMIN_METHOD_CALL_FAILED
|
||||||
|
return "A method call to the LDMA service failed.";
|
||||||
|
case 0x00042421: // VDS_S_PROVIDER_ERROR_LOADING_CACHE
|
||||||
|
return "The provider encountered errors while loading the cache.";
|
||||||
|
case 0x80042422: // VDS_E_PROVIDER_VOL_DEVICE_NAME_NOT_FOUND
|
||||||
|
return "The device form of the volume pathname could not be retrieved.";
|
||||||
|
case 0x80042423: // VDS_E_PROVIDER_VOL_OPEN
|
||||||
|
return "Failed to open the volume device";
|
||||||
|
case 0x80042424: // VDS_E_DMADMIN_CORRUPT_NOTIFICATION
|
||||||
|
return "A corrupt notification was sent from the LDMA service.";
|
||||||
|
case 0x80042425: // VDS_E_INCOMPATIBLE_FILE_SYSTEM
|
||||||
|
return "The file system is incompatible with the specified operation.";
|
||||||
|
case 0x80042426: // VDS_E_INCOMPATIBLE_MEDIA
|
||||||
|
return "The media is incompatible with the specified operation.";
|
||||||
|
case 0x80042427: // VDS_E_ACCESS_DENIED
|
||||||
|
return "Access is denied. A VDS operation MUST run elevated.";
|
||||||
|
case 0x80042428: // VDS_E_MEDIA_WRITE_PROTECTED
|
||||||
|
return "The media is write-protected.";
|
||||||
|
case 0x80042429: // VDS_E_BAD_LABEL
|
||||||
|
return "The volume label is not valid.";
|
||||||
|
case 0x8004242A: // VDS_E_CANT_QUICK_FORMAT
|
||||||
|
return "The volume cannot be quick-formatted.";
|
||||||
|
case 0x8004242B: // VDS_E_IO_ERROR
|
||||||
|
return "An I/O error occurred during the operation.";
|
||||||
|
case 0x8004242C: // VDS_E_VOLUME_TOO_SMALL
|
||||||
|
return "The volume size is too small.";
|
||||||
|
case 0x8004242D: // VDS_E_VOLUME_TOO_BIG
|
||||||
|
return "The volume size is too large.";
|
||||||
|
case 0x8004242E: // VDS_E_CLUSTER_SIZE_TOO_SMALL
|
||||||
|
return "The cluster size is too small.";
|
||||||
|
case 0x8004242F: // VDS_E_CLUSTER_SIZE_TOO_BIG
|
||||||
|
return "The cluster size is too large.";
|
||||||
|
case 0x80042430: // VDS_E_CLUSTER_COUNT_BEYOND_32BITS
|
||||||
|
return "The number of clusters is too large to be represented as a 32-bit integer.";
|
||||||
|
case 0x80042431: // VDS_E_OBJECT_STATUS_FAILED
|
||||||
|
return "The component that the object represents has failed.";
|
||||||
|
case 0x80042432: // VDS_E_VOLUME_INCOMPLETE
|
||||||
|
return "The volume is incomplete.";
|
||||||
|
case 0x80042433: // VDS_E_EXTENT_SIZE_LESS_THAN_MIN
|
||||||
|
return "The specified extent size is too small.";
|
||||||
|
case 0x00042434: // VDS_S_UPDATE_BOOTFILE_FAILED
|
||||||
|
return "The operation was successful, but VDS failed to update the boot options.";
|
||||||
|
case 0x00042436: // VDS_S_BOOT_PARTITION_NUMBER_CHANGE
|
||||||
|
case 0x80042436: // VDS_E_BOOT_PARTITION_NUMBER_CHANGE
|
||||||
|
return "The boot partition's partition number will change as a result of the operation.";
|
||||||
|
case 0x80042437: // VDS_E_NO_FREE_SPACE
|
||||||
|
return "The specified disk does not have enough free space to complete the operation.";
|
||||||
|
case 0x80042438: // VDS_E_ACTIVE_PARTITION
|
||||||
|
return "An active partition was detected on the selected disk.";
|
||||||
|
case 0x80042439: // VDS_E_PARTITION_OF_UNKNOWN_TYPE
|
||||||
|
return "The partition information cannot be read.";
|
||||||
|
case 0x8004243A: // VDS_E_LEGACY_VOLUME_FORMAT
|
||||||
|
return "A partition with an unknown type was detected on the specified disk.";
|
||||||
|
case 0x8004243C: // VDS_E_MIGRATE_OPEN_VOLUME
|
||||||
|
return "A volume on the specified disk could not be opened.";
|
||||||
|
case 0x8004243D: // VDS_E_VOLUME_NOT_ONLINE
|
||||||
|
return "The volume is not online.";
|
||||||
|
case 0x8004243E: // VDS_E_VOLUME_NOT_HEALTHY
|
||||||
|
return "The volume is failing or has failed.";
|
||||||
|
case 0x8004243F: // VDS_E_VOLUME_SPANS_DISKS
|
||||||
|
return "The volume spans multiple disks.";
|
||||||
|
case 0x80042440: // VDS_E_REQUIRES_CONTIGUOUS_DISK_SPACE
|
||||||
|
return "The volume does not consist of a single disk extent.";
|
||||||
|
case 0x80042441: // VDS_E_BAD_PROVIDER_DATA
|
||||||
|
return "A provider returned bad data.";
|
||||||
|
case 0x80042442: // VDS_E_PROVIDER_FAILURE
|
||||||
|
return "A provider failed to complete an operation.";
|
||||||
|
case 0x00042443: // VDS_S_VOLUME_COMPRESS_FAILED
|
||||||
|
return "The file system was formatted successfully but could not be compressed.";
|
||||||
|
case 0x80042444: // VDS_E_PACK_OFFLINE
|
||||||
|
return "The pack is offline.";
|
||||||
|
case 0x80042445: // VDS_E_VOLUME_NOT_A_MIRROR
|
||||||
|
return "The volume is not a mirror.";
|
||||||
|
case 0x80042446: // VDS_E_NO_EXTENTS_FOR_VOLUME
|
||||||
|
return "No extents were found for the volume.";
|
||||||
|
case 0x80042447: // VDS_E_DISK_NOT_LOADED_TO_CACHE
|
||||||
|
return "The migrated disk failed to load to the cache.";
|
||||||
|
case 0x80042448: // VDS_E_INTERNAL_ERROR
|
||||||
|
return "VDS encountered an internal error.";
|
||||||
|
case 0x8004244A: // VDS_E_PROVIDER_TYPE_NOT_SUPPORTED
|
||||||
|
return "The method call is not supported for the specified provider type.";
|
||||||
|
case 0x8004244B: // VDS_E_DISK_NOT_ONLINE
|
||||||
|
return "One or more of the specified disks are not online.";
|
||||||
|
case 0x8004244C: // VDS_E_DISK_IN_USE_BY_VOLUME
|
||||||
|
return "One or more extents of the disk are already being used by the volume.";
|
||||||
|
case 0x0004244D: // VDS_S_IN_PROGRESS
|
||||||
|
return "The asynchronous operation is in progress.";
|
||||||
|
case 0x8004244E: // VDS_E_ASYNC_OBJECT_FAILURE
|
||||||
|
return "Failure initializing the asynchronous object.";
|
||||||
|
case 0x8004244F: // VDS_E_VOLUME_NOT_MOUNTED
|
||||||
|
return "The volume is not mounted.";
|
||||||
|
case 0x80042450: // VDS_E_PACK_NOT_FOUND
|
||||||
|
return "The pack was not found.";
|
||||||
|
case 0x80042453: // VDS_E_OBJECT_OUT_OF_SYNC
|
||||||
|
return "The reference to the object might be stale.";
|
||||||
|
case 0x80042454: // VDS_E_MISSING_DISK
|
||||||
|
return "The specified disk could not be found.";
|
||||||
|
case 0x80042455: // VDS_E_DISK_PNP_REG_CORRUPT
|
||||||
|
return "The provider's list of PnP registered disks has become corrupted.";
|
||||||
|
case 0x80042457: // VDS_E_NO_DRIVELETTER_FLAG
|
||||||
|
return "The provider does not support the VDS_VF_NO DRIVELETTER volume flag.";
|
||||||
|
case 0x80042459: // VDS_E_REVERT_ON_CLOSE_SET
|
||||||
|
return "Some volume flags are already set.";
|
||||||
|
case 0x0004245B: // VDS_S_UNABLE_TO_GET_GPT_ATTRIBUTES
|
||||||
|
return "Unable to retrieve the GPT attributes for this volume.";
|
||||||
|
case 0x8004245C: // VDS_E_VOLUME_TEMPORARILY_DISMOUNTED
|
||||||
|
return "The volume is already dismounted temporarily.";
|
||||||
|
case 0x8004245D: // VDS_E_VOLUME_PERMANENTLY_DISMOUNTED
|
||||||
|
return "The volume is already permanently dismounted.";
|
||||||
|
case 0x8004245E: // VDS_E_VOLUME_HAS_PATH
|
||||||
|
return "The volume cannot be dismounted permanently because it still has an access path.";
|
||||||
|
case 0x8004245F: // VDS_E_TIMEOUT
|
||||||
|
return "The operation timed out.";
|
||||||
|
case 0x80042461: // VDS_E_LDM_TIMEOUT
|
||||||
|
return "The operation timed out in the LDMA service. Retry the operation.";
|
||||||
|
case 0x80042462: // VDS_E_REVERT_ON_CLOSE_MISMATCH
|
||||||
|
return "The flags to be cleared do not match the flags that were set previously.";
|
||||||
|
case 0x80042463: // VDS_E_RETRY
|
||||||
|
return "The operation failed. Retry the operation.";
|
||||||
|
case 0x80042464: // VDS_E_ONLINE_PACK_EXISTS
|
||||||
|
return "The operation failed, because an online pack object already exists.";
|
||||||
|
case 0x80042468: // VDS_E_MAX_USABLE_MBR
|
||||||
|
return "Only the first 2TB are usable on large MBR disks.";
|
||||||
|
case 0x80042500: // VDS_E_NO_SOFTWARE_PROVIDERS_LOADED
|
||||||
|
return "There are no software providers loaded.";
|
||||||
|
case 0x80042501: // VDS_E_DISK_NOT_MISSING
|
||||||
|
return "The disk is not missing.";
|
||||||
|
case 0x80042502: // VDS_E_NO_VOLUME_LAYOUT
|
||||||
|
return "The volume's layout could not be retrieved.";
|
||||||
|
case 0x80042503: // VDS_E_CORRUPT_VOLUME_INFO
|
||||||
|
return "The volume's driver information is corrupted.";
|
||||||
|
case 0x80042504: // VDS_E_INVALID_ENUMERATOR
|
||||||
|
return "The enumerator is corrupted";
|
||||||
|
case 0x80042505: // VDS_E_DRIVER_INTERNAL_ERROR
|
||||||
|
return "An internal error occurred in the volume management driver.";
|
||||||
|
case 0x80042507: // VDS_E_VOLUME_INVALID_NAME
|
||||||
|
return "The volume name is not valid.";
|
||||||
|
case 0x00042508: // VDS_S_DISK_IS_MISSING
|
||||||
|
return "The disk is missing and not all information could be returned.";
|
||||||
|
case 0x80042509: // VDS_E_CORRUPT_PARTITION_INFO
|
||||||
|
return "The disk's partition information is corrupted.";
|
||||||
|
case 0x0004250A: // VDS_S_NONCONFORMANT_PARTITION_INFO
|
||||||
|
return "The disk's partition information does not conform to what is expected on a dynamic disk.";
|
||||||
|
case 0x8004250B: // VDS_E_CORRUPT_EXTENT_INFO
|
||||||
|
return "The disk's extent information is corrupted.";
|
||||||
|
case 0x0004250E: // VDS_S_SYSTEM_PARTITION
|
||||||
|
return "Warning: There was a failure while checking for the system partition.";
|
||||||
|
case 0x8004250F: // VDS_E_BAD_PNP_MESSAGE
|
||||||
|
return "The PNP service sent a corrupted notification to the provider.";
|
||||||
|
case 0x80042510: // VDS_E_NO_PNP_DISK_ARRIVE
|
||||||
|
return "No disk arrival notification was received.";
|
||||||
|
case 0x80042511: // VDS_E_NO_PNP_VOLUME_ARRIVE
|
||||||
|
return "No volume arrival notification was received.";
|
||||||
|
case 0x80042512: // VDS_E_NO_PNP_DISK_REMOVE
|
||||||
|
return "No disk removal notification was received.";
|
||||||
|
case 0x80042513: // VDS_E_NO_PNP_VOLUME_REMOVE
|
||||||
|
return "No volume removal notification was received.";
|
||||||
|
case 0x80042514: // VDS_E_PROVIDER_EXITING
|
||||||
|
return "The provider is exiting.";
|
||||||
|
case 0x00042517: // VDS_S_NO_NOTIFICATION
|
||||||
|
return "No volume arrival notification was received.";
|
||||||
|
case 0x80042519: // VDS_E_INVALID_DISK
|
||||||
|
return "The specified disk is not valid.";
|
||||||
|
case 0x8004251A: // VDS_E_INVALID_PACK
|
||||||
|
return "The specified disk pack is not valid.";
|
||||||
|
case 0x8004251B: // VDS_E_VOLUME_ON_DISK
|
||||||
|
return "This operation is not allowed on disks with volumes.";
|
||||||
|
case 0x8004251C: // VDS_E_DRIVER_INVALID_PARAM
|
||||||
|
return "The driver returned an invalid parameter error.";
|
||||||
|
case 0x8004253D: // VDS_E_DRIVER_OBJECT_NOT_FOUND
|
||||||
|
return "The object was not found in the driver cache.";
|
||||||
|
case 0x8004253E: // VDS_E_PARTITION_NOT_CYLINDER_ALIGNED
|
||||||
|
return "The disk layout contains partitions which are not cylinder aligned.";
|
||||||
|
case 0x8004253F: // VDS_E_DISK_LAYOUT_PARTITIONS_TOO_SMALL
|
||||||
|
return "The disk layout contains partitions which are less than the minimum required size.";
|
||||||
|
case 0x80042540: // VDS_E_DISK_IO_FAILING
|
||||||
|
return "The IO to the disk is failing.";
|
||||||
|
case 0x80042543: // VDS_E_GPT_ATTRIBUTES_INVALID
|
||||||
|
return "Invalid GPT attributes were specified.";
|
||||||
|
case 0x8004254D: // VDS_E_UNEXPECTED_DISK_LAYOUT_CHANGE
|
||||||
|
return "An unexpected layout change occurred external to the volume manager.";
|
||||||
|
case 0x8004254E: // VDS_E_INVALID_VOLUME_LENGTH
|
||||||
|
return "The volume length is invalid.";
|
||||||
|
case 0x8004254F: // VDS_E_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE
|
||||||
|
return "The volume length is not a multiple of the sector size.";
|
||||||
|
case 0x80042550: // VDS_E_VOLUME_NOT_RETAINED
|
||||||
|
return "The volume does not have a retained partition association.";
|
||||||
|
case 0x80042551: // VDS_E_VOLUME_RETAINED
|
||||||
|
return "The volume already has a retained partition association.";
|
||||||
|
case 0x80042553: // VDS_E_ALIGN_BEYOND_FIRST_CYLINDER
|
||||||
|
return "The specified alignment is beyond the first cylinder.";
|
||||||
|
case 0x80042554: // VDS_E_ALIGN_NOT_SECTOR_SIZE_MULTIPLE
|
||||||
|
return "The specified alignment is not a multiple of the sector size.";
|
||||||
|
case 0x80042555: // VDS_E_ALIGN_NOT_ZERO
|
||||||
|
return "The specified partition type cannot be created with a non-zero alignment.";
|
||||||
|
case 0x80042556: // VDS_E_CACHE_CORRUPT
|
||||||
|
return "The service's cache has become corrupt.";
|
||||||
|
case 0x80042557: // VDS_E_CANNOT_CLEAR_VOLUME_FLAG
|
||||||
|
return "The specified volume flag cannot be cleared.";
|
||||||
|
case 0x80042558: // VDS_E_DISK_BEING_CLEANED
|
||||||
|
return "The operation is not allowed on a disk that is in the process of being cleaned.";
|
||||||
|
case 0x8004255A: // VDS_E_DISK_REMOVEABLE
|
||||||
|
return "The operation is not supported on removable media.";
|
||||||
|
case 0x8004255B: // VDS_E_DISK_REMOVEABLE_NOT_EMPTY
|
||||||
|
return "The operation is not supported on a non-empty removable disk.";
|
||||||
|
case 0x8004255C: // VDS_E_DRIVE_LETTER_NOT_FREE
|
||||||
|
return "The specified drive letter is not free to be assigned.";
|
||||||
|
case 0x8004255E: // VDS_E_INVALID_DRIVE_LETTER
|
||||||
|
return "The specified drive letter is not valid.";
|
||||||
|
case 0x8004255F: // VDS_E_INVALID_DRIVE_LETTER_COUNT
|
||||||
|
return "The specified number of drive letters to retrieve is not valid.";
|
||||||
|
case 0x80042560: // VDS_E_INVALID_FS_FLAG
|
||||||
|
return "The specified file system flag is not valid.";
|
||||||
|
case 0x80042561: // VDS_E_INVALID_FS_TYPE
|
||||||
|
return "The specified file system is not valid.";
|
||||||
|
case 0x80042562: // VDS_E_INVALID_OBJECT_TYPE
|
||||||
|
return "The specified object type is not valid.";
|
||||||
|
case 0x80042563: // VDS_E_INVALID_PARTITION_LAYOUT
|
||||||
|
return "The specified partition layout is invalid.";
|
||||||
|
case 0x80042564: // VDS_E_INVALID_PARTITION_STYLE
|
||||||
|
return "VDS only supports MBR or GPT partition style disks.";
|
||||||
|
case 0x80042565: // VDS_E_INVALID_PARTITION_TYPE
|
||||||
|
return "The specified partition type is not valid for this operation.";
|
||||||
|
case 0x80042566: // VDS_E_INVALID_PROVIDER_CLSID
|
||||||
|
case 0x80042567: // VDS_E_INVALID_PROVIDER_ID
|
||||||
|
case 0x8004256A: // VDS_E_INVALID_PROVIDER_VERSION_GUID
|
||||||
|
return "A NULL GUID was passed to the provider.";
|
||||||
|
case 0x80042568: // VDS_E_INVALID_PROVIDER_NAME
|
||||||
|
return "The specified provider name is invalid.";
|
||||||
|
case 0x80042569: // VDS_E_INVALID_PROVIDER_TYPE
|
||||||
|
return "The specified provider type is invalid.";
|
||||||
|
case 0x8004256B: // VDS_E_INVALID_PROVIDER_VERSION_STRING
|
||||||
|
return "The specified provider version string is invalid.";
|
||||||
|
case 0x8004256C: // VDS_E_INVALID_QUERY_PROVIDER_FLAG
|
||||||
|
return "The specified query provider flag is invalid.";
|
||||||
|
case 0x8004256D: // VDS_E_INVALID_SERVICE_FLAG
|
||||||
|
return "The specified service flag is invalid.";
|
||||||
|
case 0x8004256E: // VDS_E_INVALID_VOLUME_FLAG
|
||||||
|
return "The specified volume flag is invalid.";
|
||||||
|
case 0x8004256F: // VDS_E_PARTITION_NOT_OEM
|
||||||
|
return "The operation is only supported on an OEM, ESP, or unknown partition.";
|
||||||
|
case 0x80042570: // VDS_E_PARTITION_PROTECTED
|
||||||
|
return "Cannot delete a protected partition without the force protected parameter set.";
|
||||||
|
case 0x80042571: // VDS_E_PARTITION_STYLE_MISMATCH
|
||||||
|
return "The specified partition style is not the same as the disk's partition style.";
|
||||||
|
case 0x80042572: // VDS_E_PROVIDER_INTERNAL_ERROR
|
||||||
|
return "An internal error has occurred in the provider.";
|
||||||
|
case 0x80042575: // VDS_E_UNRECOVERABLE_PROVIDER_ERROR
|
||||||
|
return "An unrecoverable error occurred in a provider.";
|
||||||
|
case 0x80042576: // VDS_E_VOLUME_HIDDEN
|
||||||
|
return "Cannot assign a mount point to a hidden volume.";
|
||||||
|
case 0x00042577: // VDS_S_DISMOUNT_FAILED
|
||||||
|
case 0x00042578: // VDS_S_REMOUNT_FAILED
|
||||||
|
return "Failed to dismount/remount the volume after setting the volume flags.";
|
||||||
|
case 0x80042579: // VDS_E_FLAG_ALREADY_SET
|
||||||
|
return "Cannot set the specified flag as revert-on-close because it is already set.";
|
||||||
|
case 0x8004257B: // VDS_E_DISTINCT_VOLUME
|
||||||
|
return "The input volume id cannot be the id of the volume that is the target of the operation.";
|
||||||
|
case 0x00042583: // VDS_S_FS_LOCK
|
||||||
|
return "Failed to obtain a file system lock.";
|
||||||
|
case 0x80042584: // VDS_E_READONLY
|
||||||
|
return "The volume is read only.";
|
||||||
|
case 0x80042585: // VDS_E_INVALID_VOLUME_TYPE
|
||||||
|
return "The volume type is invalid for this operation.";
|
||||||
|
case 0x80042588: // VDS_E_VOLUME_MIRRORED
|
||||||
|
return "This operation is not supported on a mirrored volume.";
|
||||||
|
case 0x80042589: // VDS_E_VOLUME_SIMPLE_SPANNED
|
||||||
|
return "The operation is only supported on simple or spanned volumes.";
|
||||||
|
case 0x8004258C: // VDS_E_PARTITION_MSR
|
||||||
|
case 0x8004258D: // VDS_E_PARTITION_LDM
|
||||||
|
return "The operation is not supported on this type of partitions.";
|
||||||
|
case 0x0004258E: // VDS_S_WINPE_BOOTENTRY
|
||||||
|
return "The boot entries cannot be updated automatically on WinPE.";
|
||||||
|
case 0x8004258F: // VDS_E_ALIGN_NOT_A_POWER_OF_TWO
|
||||||
|
return "The alignment is not a power of two.";
|
||||||
|
case 0x80042590: // VDS_E_ALIGN_IS_ZERO
|
||||||
|
return "The alignment is zero.";
|
||||||
|
case 0x80042593: // VDS_E_FS_NOT_DETERMINED
|
||||||
|
return "The default file system could not be determined.";
|
||||||
|
case 0x80042595: // VDS_E_DISK_NOT_OFFLINE
|
||||||
|
return "This disk is already online.";
|
||||||
|
case 0x80042596: // VDS_E_FAILED_TO_ONLINE_DISK
|
||||||
|
return "The online operation failed.";
|
||||||
|
case 0x80042597: // VDS_E_FAILED_TO_OFFLINE_DISK
|
||||||
|
return "The offline operation failed.";
|
||||||
|
case 0x80042598: // VDS_E_BAD_REVISION_NUMBER
|
||||||
|
return "The operation could not be completed because the specified revision number is not supported.";
|
||||||
|
case 0x00042700: // VDS_S_NAME_TRUNCATED
|
||||||
|
return "The name was set successfully but had to be truncated.";
|
||||||
|
case 0x80042701: // VDS_E_NAME_NOT_UNIQUE
|
||||||
|
return "The specified name is not unique.";
|
||||||
|
case 0x8004270F: // VDS_E_NO_DISK_PATHNAME
|
||||||
|
return "The disk's path could not be retrieved. Some operations on the disk might fail.";
|
||||||
|
case 0x80042711: // VDS_E_NO_VOLUME_PATHNAME
|
||||||
|
return "The path could not be retrieved for one or more volumes.";
|
||||||
|
case 0x80042712: // VDS_E_PROVIDER_CACHE_OUTOFSYNC
|
||||||
|
return "The provider's cache is not in sync with the driver cache.";
|
||||||
|
case 0x80042713: // VDS_E_NO_IMPORT_TARGET
|
||||||
|
return "No import target was set for the subsystem.";
|
||||||
|
case 0x00042714: // VDS_S_ALREADY_EXISTS
|
||||||
|
return "The object already exists.";
|
||||||
|
case 0x00042715: // VDS_S_PROPERTIES_INCOMPLETE
|
||||||
|
return "Some, but not all, of the properties were successfully retrieved.";
|
||||||
|
case 0x80042803: // VDS_E_UNABLE_TO_FIND_BOOT_DISK
|
||||||
|
return "Volume disk extent information could not be retrieved for the boot volume.";
|
||||||
|
case 0x80042807: // VDS_E_BOOT_DISK
|
||||||
|
return "Disk attributes cannot be changed on the boot disk.";
|
||||||
|
case 0x00042808: // VDS_S_DISK_MOUNT_FAILED
|
||||||
|
case 0x00042809: // VDS_S_DISK_DISMOUNT_FAILED
|
||||||
|
return "One or more of the volumes on the disk could not be mounted/dismounted.";
|
||||||
|
case 0x8004280A: // VDS_E_DISK_IS_OFFLINE
|
||||||
|
return "The operation cannot be performed on a disk that is offline.";
|
||||||
|
case 0x8004280B: // VDS_E_DISK_IS_READ_ONLY
|
||||||
|
return "The operation cannot be performed on a disk that is read-only.";
|
||||||
|
case 0x8004280C: // VDS_E_PAGEFILE_DISK
|
||||||
|
return "The operation cannot be performed on a disk that contains a pagefile volume.";
|
||||||
|
case 0x8004280D: // VDS_E_HIBERNATION_FILE_DISK
|
||||||
|
return "The operation cannot be performed on a disk that contains a hibernation file volume.";
|
||||||
|
case 0x8004280E: // VDS_E_CRASHDUMP_DISK
|
||||||
|
return "The operation cannot be performed on a disk that contains a crashdump file volume.";
|
||||||
|
case 0x8004280F: // VDS_E_UNABLE_TO_FIND_SYSTEM_DISK
|
||||||
|
return "A system error occurred while retrieving the system disk information.";
|
||||||
|
case 0x80042810: // VDS_E_INCORRECT_SYSTEM_VOLUME_EXTENT_INFO
|
||||||
|
return "Multiple disk extents reported for the system volume - system error.";
|
||||||
|
case 0x80042811: // VDS_E_SYSTEM_DISK
|
||||||
|
return "Disk attributes cannot be changed on the current system disk or BIOS disk 0.";
|
||||||
|
case 0x80042823: // VDS_E_SECTOR_SIZE_ERROR
|
||||||
|
return "The sector size MUST be non-zero, a power of 2, and less than the maximum sector size.";
|
||||||
|
case 0x80042907: // VDS_E_SUBSYSTEM_ID_IS_NULL
|
||||||
|
return "The provider returned a NULL subsystem identification string.";
|
||||||
|
case 0x8004290C: // VDS_E_REBOOT_REQUIRED
|
||||||
|
return "A reboot is required before any further operations are initiated.";
|
||||||
|
case 0x8004290D: // VDS_E_VOLUME_GUID_PATHNAME_NOT_ALLOWED
|
||||||
|
return "Volume GUID pathnames are not valid input to this method.";
|
||||||
|
case 0x8004290E: // VDS_E_BOOT_PAGEFILE_DRIVE_LETTER
|
||||||
|
return "Assigning or removing drive letters on the current boot or pagefile volume is not allowed.";
|
||||||
|
case 0x8004290F: // VDS_E_DELETE_WITH_CRITICAL
|
||||||
|
return "Delete is not allowed on a critical volume.";
|
||||||
|
case 0x80042910: // VDS_E_CLEAN_WITH_DATA
|
||||||
|
return "The FORCE parameter MUST be set to TRUE in order to clean a disk that contains a data volume.";
|
||||||
|
case 0x80042911: // VDS_E_CLEAN_WITH_OEM
|
||||||
|
return "The FORCE parameter MUST be set to TRUE in order to clean a disk that contains an OEM volume.";
|
||||||
|
case 0x80042912: // VDS_E_CLEAN_WITH_CRITICAL
|
||||||
|
return "Clean is not allowed on a critical disk.";
|
||||||
|
case 0x80042913: // VDS_E_FORMAT_CRITICAL
|
||||||
|
return "Format is not allowed on a critical volume.";
|
||||||
|
case 0x80042914: // VDS_E_NTFS_FORMAT_NOT_SUPPORTED
|
||||||
|
return "The NTFS file system format is not supported on this volume.";
|
||||||
|
case 0x80042915: // VDS_E_FAT32_FORMAT_NOT_SUPPORTED
|
||||||
|
return "The FAT32 file system format is not supported on this volume.";
|
||||||
|
case 0x80042916: // VDS_E_FAT_FORMAT_NOT_SUPPORTED
|
||||||
|
return "The FAT file system format is not supported on this volume.";
|
||||||
|
case 0x80042917: // VDS_E_FORMAT_NOT_SUPPORTED
|
||||||
|
return "The volume is not formattable.";
|
||||||
|
case 0x80042918: // VDS_E_COMPRESSION_NOT_SUPPORTED
|
||||||
|
return "The specified file system does not support compression.";
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Convert a windows error to human readable string
|
// Convert a windows error to human readable string
|
||||||
const char *WindowsErrorString(void)
|
const char *WindowsErrorString(void)
|
||||||
{
|
{
|
||||||
|
@ -162,6 +595,11 @@ const char *WindowsErrorString(void)
|
||||||
DWORD error_code, format_error;
|
DWORD error_code, format_error;
|
||||||
|
|
||||||
error_code = GetLastError();
|
error_code = GetLastError();
|
||||||
|
// Check for VDS error codes
|
||||||
|
if ((SCODE_FACILITY(error_code) == FACILITY_ITF) && (GetVdsError(error_code) != NULL)) {
|
||||||
|
static_sprintf(err_string, "[0x%08lX] %s", error_code, GetVdsError(error_code));
|
||||||
|
return err_string;
|
||||||
|
}
|
||||||
|
|
||||||
static_sprintf(err_string, "[0x%08lX] ", error_code);
|
static_sprintf(err_string, "[0x%08lX] ", error_code);
|
||||||
presize = (DWORD)strlen(err_string);
|
presize = (DWORD)strlen(err_string);
|
||||||
|
@ -272,7 +710,6 @@ const char* _StrError(DWORD error_code)
|
||||||
return lmprintf(MSG_050);
|
return lmprintf(MSG_050);
|
||||||
}
|
}
|
||||||
if (SCODE_FACILITY(error_code) != FACILITY_STORAGE) {
|
if (SCODE_FACILITY(error_code) != FACILITY_STORAGE) {
|
||||||
// uprintf("StrError: non storage - %08X (%X)\n", error_code, SCODE_FACILITY(error_code));
|
|
||||||
SetLastError(error_code);
|
SetLastError(error_code);
|
||||||
return WindowsErrorString();
|
return WindowsErrorString();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue