diff --git a/src/drive.c b/src/drive.c index ee8c1b85..3d5da2cf 100644 --- a/src/drive.c +++ b/src/drive.c @@ -1363,8 +1363,10 @@ static BOOL ClearPartition(HANDLE hDrive, LARGE_INTEGER offset, DWORD size) if (buffer == NULL) return FALSE; - if (!SetFilePointerEx(hDrive, offset, NULL, FILE_BEGIN)) + if (!SetFilePointerEx(hDrive, offset, NULL, FILE_BEGIN)) { + free(buffer); return FALSE; + } r = WriteFileWithRetry(hDrive, buffer, size, &size, WRITE_RETRIES); free(buffer); diff --git a/src/ext2fs/.editorconfig b/src/ext2fs/.editorconfig index 817bf043..8993a986 100644 --- a/src/ext2fs/.editorconfig +++ b/src/ext2fs/.editorconfig @@ -1,2 +1,3 @@ [*] +indent_style = tab tab_width = 8 diff --git a/src/ext2fs/nt_io.c b/src/ext2fs/nt_io.c index 65abe4ee..7c34be17 100644 --- a/src/ext2fs/nt_io.c +++ b/src/ext2fs/nt_io.c @@ -31,6 +31,7 @@ #include "msapi_utf8.h" extern char* NtStatusError(NTSTATUS Status); +static DWORD LastWinError = 0; PF_TYPE_DECL(NTAPI, ULONG, RtlNtStatusToDosError, (NTSTATUS)); PF_TYPE_DECL(NTAPI, NTSTATUS, NtClose, (HANDLE)); @@ -95,7 +96,7 @@ io_manager nt_io_manager(void) typedef struct { ULONG WinError; int errnocode; -}ERROR_ENTRY; +} ERROR_ENTRY; static ERROR_ENTRY ErrorTable[] = { { ERROR_INVALID_FUNCTION, EINVAL }, @@ -149,6 +150,7 @@ static unsigned _MapDosError(IN ULONG WinError) { int i; + LastWinError = WinError; for (i = 0; i < (sizeof(ErrorTable)/sizeof(ErrorTable[0])); ++i) { if (WinError == ErrorTable[i].WinError) { return ErrorTable[i].errnocode; @@ -171,6 +173,12 @@ static __inline unsigned _MapNtStatus(IN NTSTATUS Status) return (pfRtlNtStatusToDosError == NULL) ? EFAULT: _MapDosError(pfRtlNtStatusToDosError(Status)); } +// Return the last Windows Error +DWORD ext2_last_winerror(DWORD default_error) +{ + return ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | (LastWinError ? LastWinError : default_error); +} + // // Helper functions // @@ -201,7 +209,6 @@ static NTSTATUS _OpenNtName(IN PCSTR Name, IN BOOLEAN Readonly, OUT PHANDLE Hand &ObjectAttributes, &IoStatusBlock, FILE_SHARE_WRITE | FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { - uprintf("_OpenNtName: [%x] %s", Status, NtStatusError(Status)); // Maybe was just mounted? wait 0.5 sec and retry. LARGE_INTEGER Interval; Interval.QuadPart = -5000000; // 0.5 sec. from now @@ -339,7 +346,9 @@ static BOOLEAN _Ext2OpenDevice(IN PCSTR Name, IN BOOLEAN ReadOnly, OUT PHANDLE H CHAR NormalizedDeviceName[512]; NTSTATUS Status; + LastWinError = 0; if (Name == NULL) { + LastWinError = ERROR_INVALID_PARAMETER; if (ARGUMENT_PRESENT(Errno)) *Errno = ENOENT; return FALSE; @@ -351,6 +360,7 @@ static BOOLEAN _Ext2OpenDevice(IN PCSTR Name, IN BOOLEAN ReadOnly, OUT PHANDLE H } else { Name = _NormalizeDeviceName(Name, NormalizedDeviceName); if (Name == NULL) { + LastWinError = ERROR_INVALID_PARAMETER; if (ARGUMENT_PRESENT(Errno)) *Errno = ENOENT; return FALSE; @@ -368,7 +378,7 @@ static BOOLEAN _Ext2OpenDevice(IN PCSTR Name, IN BOOLEAN ReadOnly, OUT PHANDLE H return TRUE; } -static BOOLEAN _BlockIo(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Bytes, IN OUT PCHAR Buffer, IN BOOLEAN Read, OUT unsigned* Errno) +static BOOLEAN _BlockIo(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Bytes, IN OUT PCHAR Buffer, IN BOOLEAN Read, OUT errcode_t *Errno OPTIONAL) { IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status = STATUS_DLL_NOT_FOUND; @@ -379,6 +389,7 @@ static BOOLEAN _BlockIo(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Byte assert((Bytes % 512) == 0); assert((Offset.LowPart % 512) == 0); + LastWinError = 0; // Perform io if(Read) { Status = pfNtReadFile(Handle, NULL, NULL, NULL, @@ -389,22 +400,23 @@ static BOOLEAN _BlockIo(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Byte } out: - if (NT_SUCCESS(Status)) { - *Errno = 0; - return TRUE; + if (!NT_SUCCESS(Status)) { + if (ARGUMENT_PRESENT(Errno)) + *Errno = _MapNtStatus(Status); + return FALSE; } - *Errno = _MapNtStatus(Status); - - return FALSE; + if (ARGUMENT_PRESENT(Errno)) + *Errno = 0; + return TRUE; } -static BOOLEAN _RawWrite(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Bytes, OUT const CHAR* Buffer, OUT unsigned* Errno) +static BOOLEAN _RawWrite(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Bytes, OUT const CHAR* Buffer, OUT errcode_t* Errno) { return _BlockIo(Handle, Offset, Bytes, (PCHAR)Buffer, FALSE, Errno); } -static BOOLEAN _RawRead(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Bytes, IN PCHAR Buffer, OUT unsigned* Errno) +static BOOLEAN _RawRead(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Bytes, IN PCHAR Buffer, OUT errcode_t* Errno) { return _BlockIo(Handle, Offset, Bytes, Buffer, TRUE, Errno); } @@ -425,13 +437,14 @@ static BOOLEAN _SetPartType(IN HANDLE Handle, IN UCHAR Type) // errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags) { + errcode_t errcode = 0; HANDLE h; BOOLEAN Readonly; *mount_flags = 0; - if (!_Ext2OpenDevice(file, TRUE, &h, &Readonly, NULL)) - return 0; + if (!_Ext2OpenDevice(file, TRUE, &h, &Readonly, &errcode)) + return errcode; *mount_flags &= _IsMounted(h) ? EXT2_MF_MOUNTED : 0; _CloseDisk(h); @@ -450,14 +463,13 @@ errcode_t ext2fs_check_mount_point(const char *file, int *mount_flags, char *mtp // different removable devices (e.g. UFD) may be remounted under the same path. errcode_t ext2fs_get_device_size2(const char *file, int blocksize, blk64_t *retblocks) { + errcode_t errcode; __int64 fs_size = 0; HANDLE h; BOOLEAN Readonly; - if (!_Ext2OpenDevice(file, TRUE, &h, &Readonly, NULL)) { - uprintf("FAILED TO OPEN '%s'", file); - return EACCES; - } + if (!_Ext2OpenDevice(file, TRUE, &h, &Readonly, &errcode)) + return errcode; _GetDeviceSize(h, &fs_size); _CloseDisk(h); @@ -604,7 +616,7 @@ static errcode_t nt_read_blk(io_channel channel, unsigned long block, int count, ULONG size; LARGE_INTEGER offset; PNT_PRIVATE_DATA nt_data = NULL; - unsigned errcode = 0; + errcode_t errcode = 0; EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); nt_data = (PNT_PRIVATE_DATA) channel->private_data; @@ -653,7 +665,7 @@ static errcode_t nt_write_blk(io_channel channel, unsigned long block, int count ULONG write_size; LARGE_INTEGER offset; PNT_PRIVATE_DATA nt_data = NULL; - unsigned errcode = 0; + errcode_t errcode = 0; EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); nt_data = (PNT_PRIVATE_DATA) channel->private_data; diff --git a/src/format.c b/src/format.c index 638e73f6..8ee7c69c 100644 --- a/src/format.c +++ b/src/format.c @@ -244,6 +244,8 @@ static BOOLEAN __stdcall ChkdskCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DW /* * Converts an UTF-8 label to a valid FAT/NTFS one + * TODO: Use IVdsService::QueryFileSystemTypes -> VDS_FILE_SYSTEM_TYPE_PROP + * to get the list of unauthorised and max length for each FS. */ static void ToValidLabel(char* Label, BOOL bFAT) { @@ -877,7 +879,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR // Figure out the volume size and block size r = ext2fs_get_device_size2(volume_name, KB, &size); if ((r != 0) || (size == 0)) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_READ_FAULT; + FormatStatus = ext2_last_winerror(ERROR_READ_FAULT); uprintf("Could not read device size: %s", error_message(r)); goto out; } @@ -922,7 +924,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR // Now that we have set our base features, initialize a virtual superblock r = ext2fs_initialize(volume_name, EXT2_FLAG_EXCLUSIVE | EXT2_FLAG_64BITS, &features, manager, &ext2fs); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_DATA; + FormatStatus = ext2_last_winerror(ERROR_INVALID_DATA); uprintf("Could not initialize %s features: %s", FSName, error_message(r)); goto out; } @@ -933,7 +935,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR r = io_channel_write_blk64(ext2fs->io, 0, 16, buf); safe_free(buf); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT; + FormatStatus = ext2_last_winerror(ERROR_WRITE_FAULT); uprintf("Could not zero %s superblock area: %s", FSName, error_message(r)); goto out; } @@ -951,7 +953,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR r = ext2fs_allocate_tables(ext2fs); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_DATA; + FormatStatus = ext2_last_winerror(ERROR_INVALID_DATA); uprintf("Could not allocate %s tables: %s", FSName, error_message(r)); goto out; } @@ -973,7 +975,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR * EXT2_BLOCK_SIZE(ext2fs->super), EXT2_BLOCK_SIZE(ext2fs->super)); r = ext2fs_zero_blocks2(ext2fs, cur, count, &cur, &count); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT; + FormatStatus = ext2_last_winerror(ERROR_WRITE_FAULT); uprintf("\r\nCould not zero inode set at position %llu (%d blocks): %s", cur, count, error_message(r)); goto out; } @@ -983,14 +985,14 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR // Create root and lost+found dirs r = ext2fs_mkdir(ext2fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 0); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_DIR_NOT_ROOT; + FormatStatus = ext2_last_winerror(ERROR_DIR_NOT_ROOT); uprintf("Failed to create %s root dir: %s", FSName, error_message(r)); goto out; } ext2fs->umask = 077; r = ext2fs_mkdir(ext2fs, EXT2_ROOT_INO, 0, "lost+found"); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_DIR_NOT_ROOT; + FormatStatus = ext2_last_winerror(ERROR_DIR_NOT_ROOT); uprintf("Failed to create %s 'lost+found' dir: %s", FSName, error_message(r)); goto out; } @@ -1002,14 +1004,14 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR r = ext2fs_mark_inode_bitmap2(ext2fs->inode_map, EXT2_BAD_INO); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT; + FormatStatus = ext2_last_winerror(ERROR_WRITE_FAULT); uprintf("Could not set inode bitmaps: %s", error_message(r)); goto out; } ext2fs_inode_alloc_stats(ext2fs, EXT2_BAD_INO, 1); r = ext2fs_update_bb_inode(ext2fs, NULL); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT; + FormatStatus = ext2_last_winerror(ERROR_WRITE_FAULT); uprintf("Could not set inode stats: %s", error_message(r)); goto out; } @@ -1025,7 +1027,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR r = ext2fs_add_journal_inode(ext2fs, journal_size, EXT2_MKJOURNAL_NO_MNT_CHECK | ((Flags & FP_QUICK) ? EXT2_MKJOURNAL_LAZYINIT : 0)); uprintfs("\r\n"); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT; + FormatStatus = ext2_last_winerror(ERROR_WRITE_FAULT); uprintf("Could not create %s journal: %s", FSName, error_message(r)); goto out; } @@ -1034,7 +1036,7 @@ BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR // Finally we can call close() to get the file system gets created r = ext2fs_close(ext2fs); if (r != 0) { - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT; + FormatStatus = ext2_last_winerror(ERROR_WRITE_FAULT); uprintf("Could not create %s volume: %s", FSName, error_message(r)); goto out; } @@ -2594,6 +2596,8 @@ DWORD WINAPI FormatThread(void* param) hLogicalVolume = INVALID_HANDLE_VALUE; // VDS wants us to unlock the phys + // TODO: IVdsDiskOnline::Offline? -> NOPE, NO_GO for removable media + // TODO: IVdsService::Refresh()? IVdsHwProvider::Reenumerate()?? if (use_vds) safe_unlockclose(hPhysicalDrive); diff --git a/src/rufus.rc b/src/rufus.rc index 2c3e6a76..a58ef446 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.6.1529" +CAPTION "Rufus 3.6.1530" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -394,8 +394,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,6,1529,0 - PRODUCTVERSION 3,6,1529,0 + FILEVERSION 3,6,1530,0 + PRODUCTVERSION 3,6,1530,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -413,13 +413,13 @@ BEGIN VALUE "Comments", "https://akeo.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.6.1529" + VALUE "FileVersion", "3.6.1530" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus-3.6.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.6.1529" + VALUE "ProductVersion", "3.6.1530" END END BLOCK "VarFileInfo" diff --git a/src/stdio.c b/src/stdio.c index 44ca3104..954289e8 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -1,6 +1,6 @@ /* * Rufus: The Reliable USB Formatting Utility - * Standard User I/O Routines (logging, status, etc.) + * Standard User I/O Routines (logging, status, error, etc.) * Copyright © 2011-2019 Pete Batard * * This program is free software: you can redistribute it and/or modify @@ -375,13 +375,11 @@ static const char *GetVdsError(DWORD error_code) 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."; + return "No disk/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."; + return "No disk/volume removal notification was received."; case 0x80042514: // VDS_E_PROVIDER_EXITING return "The provider is exiting."; case 0x00042517: // VDS_S_NO_NOTIFICATION @@ -401,7 +399,7 @@ static const char *GetVdsError(DWORD error_code) 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."; + return "The I/O 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 @@ -473,7 +471,7 @@ static const char *GetVdsError(DWORD error_code) 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."; + return "An unrecoverable error occurred in the provider."; case 0x80042576: // VDS_E_VOLUME_HIDDEN return "Cannot assign a mount point to a hidden volume."; case 0x00042577: // VDS_S_DISMOUNT_FAILED @@ -536,15 +534,12 @@ static const char *GetVdsError(DWORD error_code) 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."; + return "The operation cannot be performed on a disk that is offline or 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."; + return "The operation cannot be performed on a disk that contains a pagefile, hibernation or crashdump 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 @@ -564,19 +559,16 @@ static const char *GetVdsError(DWORD error_code) 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."; + return "The FORCE parameter MUST be set to TRUE in order to clean a disk that contains a data or 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."; + return "The requested 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