mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[core] report write errors more explicitly
* Also issue a port cycle on ERROR_NOT_READY * Also run a check for conflicting processes during write retries
This commit is contained in:
parent
b7ab196a97
commit
d4a663991b
7 changed files with 95 additions and 58 deletions
69
src/format.c
69
src/format.c
|
@ -54,7 +54,7 @@
|
||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
DWORD FormatStatus = 0;
|
DWORD FormatStatus = 0, LastWriteError = 0;
|
||||||
badblocks_report report = { 0 };
|
badblocks_report report = { 0 };
|
||||||
static uint64_t LastRefresh = 0;
|
static uint64_t LastRefresh = 0;
|
||||||
static float format_percent = 0.0f;
|
static float format_percent = 0.0f;
|
||||||
|
@ -843,7 +843,8 @@ static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi
|
||||||
if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize) {
|
if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize) {
|
||||||
if (j < WRITE_RETRIES) {
|
if (j < WRITE_RETRIES) {
|
||||||
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000);
|
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000);
|
||||||
Sleep(WRITE_TIMEOUT);
|
// Don't sit idly but use the downtime to check for conflicting processes...
|
||||||
|
Sleep(CheckDriveAccess(WRITE_TIMEOUT, FALSE));
|
||||||
} else
|
} else
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -856,7 +857,7 @@ static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi
|
||||||
if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize) {
|
if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize) {
|
||||||
if (j < WRITE_RETRIES) {
|
if (j < WRITE_RETRIES) {
|
||||||
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000);
|
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000);
|
||||||
Sleep(WRITE_TIMEOUT);
|
Sleep(CheckDriveAccess(WRITE_TIMEOUT, FALSE));
|
||||||
} else {
|
} else {
|
||||||
// Windows seems to be an ass about keeping a lock on a backup GPT,
|
// Windows seems to be an ass about keeping a lock on a backup GPT,
|
||||||
// so we try to be lenient about not being able to clear it.
|
// so we try to be lenient about not being able to clear it.
|
||||||
|
@ -1799,15 +1800,15 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
|
|
||||||
// At this stage we have both a handle and a lock to the physical drive
|
// At this stage we have both a handle and a lock to the physical drive
|
||||||
if (!GetDriveLetters(DriveIndex, drive_letters)) {
|
if (!GetDriveLetters(DriveIndex, drive_letters)) {
|
||||||
uprintf("Failed to get a drive letter\n");
|
uprintf("Failed to get a drive letter");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (drive_letters[0] == 0) {
|
if (drive_letters[0] == 0) {
|
||||||
uprintf("No drive letter was assigned...\n");
|
uprintf("No drive letter was assigned...");
|
||||||
drive_name[0] = GetUnusedDriveLetter();
|
drive_name[0] = GetUnusedDriveLetter();
|
||||||
if (drive_name[0] == 0) {
|
if (drive_name[0] == 0) {
|
||||||
uprintf("Could not find a suitable drive letter\n");
|
uprintf("Could not find a suitable drive letter");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1819,18 +1820,18 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
if (bt == BT_IMAGE) {
|
if (bt == BT_IMAGE) {
|
||||||
// If we are using an image, check that it isn't located on the drive we are trying to format
|
// If we are using an image, check that it isn't located on the drive we are trying to format
|
||||||
if ((PathGetDriveNumberU(image_path) + 'A') == drive_letters[i-1]) {
|
if ((PathGetDriveNumberU(image_path) + 'A') == drive_letters[i-1]) {
|
||||||
uprintf("ABORTED: Cannot use an image that is located on the target drive!\n");
|
uprintf("ABORTED: Cannot use an image that is located on the target drive!");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!DeleteVolumeMountPointA(drive_name)) {
|
if (!DeleteVolumeMountPointA(drive_name)) {
|
||||||
uprintf("Failed to delete mountpoint %s: %s\n", drive_name, WindowsErrorString());
|
uprintf("Failed to delete mountpoint %s: %", drive_name, WindowsErrorString());
|
||||||
// Try to continue. We will bail out if this causes an issue.
|
// Try to continue. We will bail out if this causes an issue.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uprintf("Will use '%c:' as volume mountpoint\n", drive_name[0]);
|
uprintf("Will use '%c:' as volume mountpoint", drive_name[0]);
|
||||||
|
|
||||||
// It kind of blows, but we have to relinquish access to the physical drive
|
// It kind of blows, but we have to relinquish access to the physical drive
|
||||||
// for VDS to be able to delete the partitions that reside on it...
|
// for VDS to be able to delete the partitions that reside on it...
|
||||||
|
@ -1848,14 +1849,14 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
// ...and get a lock to the logical drive so that we can actually write something
|
// ...and get a lock to the logical drive so that we can actually write something
|
||||||
hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE, !lock_drive);
|
hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE, !lock_drive);
|
||||||
if (hLogicalVolume == INVALID_HANDLE_VALUE) {
|
if (hLogicalVolume == INVALID_HANDLE_VALUE) {
|
||||||
uprintf("Could not lock volume\n");
|
uprintf("Could not lock volume");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
||||||
goto out;
|
goto out;
|
||||||
} else if (hLogicalVolume == NULL) {
|
} else if (hLogicalVolume == NULL) {
|
||||||
// NULL is returned for cases where the drive is not yet partitioned
|
// NULL is returned for cases where the drive is not yet partitioned
|
||||||
uprintf("Drive does not appear to be partitioned\n");
|
uprintf("Drive does not appear to be partitioned");
|
||||||
} else if (!UnmountVolume(hLogicalVolume)) {
|
} else if (!UnmountVolume(hLogicalVolume)) {
|
||||||
uprintf("Trying to continue regardless...\n");
|
uprintf("Trying to continue regardless...");
|
||||||
}
|
}
|
||||||
CHECK_FOR_USER_CANCEL;
|
CHECK_FOR_USER_CANCEL;
|
||||||
|
|
||||||
|
@ -1877,8 +1878,8 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
if ((bt != BT_IMAGE) || (img_report.is_iso && !write_as_image)) {
|
if ((bt != BT_IMAGE) || (img_report.is_iso && !write_as_image)) {
|
||||||
if ((!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, use_large_fat32)) ||
|
if ((!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, use_large_fat32)) ||
|
||||||
(!InitializeDisk(hPhysicalDrive))) {
|
(!InitializeDisk(hPhysicalDrive))) {
|
||||||
uprintf("Could not reset partitions\n");
|
uprintf("Could not reset partitions");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_PARTITION_FAILURE;
|
FormatStatus = (LastWriteError != 0) ? LastWriteError : (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1897,16 +1898,16 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
|
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
|
||||||
log_fd = fopenU(logfile, "w+");
|
log_fd = fopenU(logfile, "w+");
|
||||||
if (log_fd == NULL) {
|
if (log_fd == NULL) {
|
||||||
uprintf("Could not create log file for bad blocks check\n");
|
uprintf("Could not create log file for bad blocks check");
|
||||||
} else {
|
} else {
|
||||||
fprintf(log_fd, APPLICATION_NAME " bad blocks check started on: %04d.%02d.%02d %02d:%02d:%02d\n",
|
fprintf(log_fd, APPLICATION_NAME " bad blocks check started on: %04d.%02d.%02d %02d:%02d:%02d",
|
||||||
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
|
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
|
||||||
fflush(log_fd);
|
fflush(log_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, (sel >= 2) ? 4 : sel +1,
|
if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, (sel >= 2) ? 4 : sel +1,
|
||||||
(sel < 2) ? 0 : sel - 2, &report, log_fd)) {
|
(sel < 2) ? 0 : sel - 2, &report, log_fd)) {
|
||||||
uprintf("Bad blocks: Check failed.\n");
|
uprintf("Bad blocks: Check failed.");
|
||||||
if (!IS_ERROR(FormatStatus))
|
if (!IS_ERROR(FormatStatus))
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_BADBLOCKS_FAILURE);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_BADBLOCKS_FAILURE);
|
||||||
ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, FALSE);
|
ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, FALSE);
|
||||||
|
@ -1914,7 +1915,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
DeleteFileU(logfile);
|
DeleteFileU(logfile);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
uprintf("Bad Blocks: Check completed, %d bad block%s found. (%d/%d/%d errors)\n",
|
uprintf("Bad Blocks: Check completed, %d bad block%s found. (%d/%d/%d errors)",
|
||||||
report.bb_count, (report.bb_count==1)?"":"s",
|
report.bb_count, (report.bb_count==1)?"":"s",
|
||||||
report.num_read_errors, report.num_write_errors, report.num_corruption_errors);
|
report.num_read_errors, report.num_write_errors, report.num_corruption_errors);
|
||||||
r = IDOK;
|
r = IDOK;
|
||||||
|
@ -1923,7 +1924,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
report.num_corruption_errors);
|
report.num_corruption_errors);
|
||||||
fprintf(log_fd, bb_msg);
|
fprintf(log_fd, bb_msg);
|
||||||
GetLocalTime(<);
|
GetLocalTime(<);
|
||||||
fprintf(log_fd, APPLICATION_NAME " bad blocks check ended on: %04d.%02d.%02d %02d:%02d:%02d\n",
|
fprintf(log_fd, APPLICATION_NAME " bad blocks check ended on: %04d.%02d.%02d %02d:%02d:%02d",
|
||||||
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
|
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
|
||||||
fclose(log_fd);
|
fclose(log_fd);
|
||||||
r = MessageBoxExU(hMainDialog, lmprintf(MSG_012, bb_msg, logfile),
|
r = MessageBoxExU(hMainDialog, lmprintf(MSG_012, bb_msg, logfile),
|
||||||
|
@ -1942,7 +1943,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
// Especially after destructive badblocks test, you must zero the MBR/GPT completely
|
// Especially after destructive badblocks test, you must zero the MBR/GPT completely
|
||||||
// before repartitioning. Else, all kind of bad things happen.
|
// before repartitioning. Else, all kind of bad things happen.
|
||||||
if (!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, use_large_fat32)) {
|
if (!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, use_large_fat32)) {
|
||||||
uprintf("unable to zero MBR/GPT\n");
|
uprintf("unable to zero MBR/GPT");
|
||||||
if (!IS_ERROR(FormatStatus))
|
if (!IS_ERROR(FormatStatus))
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1969,7 +1970,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
if (GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_type, sizeof(fs_type), TRUE)) {
|
if (GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_type, sizeof(fs_type), TRUE)) {
|
||||||
guid_volume = GetLogicalName(DriveIndex, TRUE, TRUE);
|
guid_volume = GetLogicalName(DriveIndex, TRUE, TRUE);
|
||||||
if ((guid_volume != NULL) && (MountVolume(drive_name, guid_volume)))
|
if ((guid_volume != NULL) && (MountVolume(drive_name, guid_volume)))
|
||||||
uprintf("Remounted %s as %C:\n", guid_volume, drive_name[0]);
|
uprintf("Remounted %s as %C:", guid_volume, drive_name[0]);
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1978,7 +1979,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
CHECK_FOR_USER_CANCEL;
|
CHECK_FOR_USER_CANCEL;
|
||||||
|
|
||||||
if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (tt==TT_UEFI), extra_partitions)) {
|
if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (tt==TT_UEFI), extra_partitions)) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE;
|
FormatStatus = (LastWriteError != 0) ? LastWriteError : (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
UpdateProgress(OP_PARTITION, -1.0f);
|
UpdateProgress(OP_PARTITION, -1.0f);
|
||||||
|
@ -1987,7 +1988,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) {
|
if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) {
|
||||||
PrintInfoDebug(0, MSG_227);
|
PrintInfoDebug(0, MSG_227);
|
||||||
if (!CloseHandle(hLogicalVolume)) {
|
if (!CloseHandle(hLogicalVolume)) {
|
||||||
uprintf("Could not close volume: %s\n", WindowsErrorString());
|
uprintf("Could not close volume: %s", WindowsErrorString());
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1995,7 +1996,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
hLogicalVolume = INVALID_HANDLE_VALUE;
|
hLogicalVolume = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
// 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...\n");
|
uprintf("Waiting for logical drive to reappear...");
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
if (!WaitForLogical(DriveIndex))
|
if (!WaitForLogical(DriveIndex))
|
||||||
uprintf("Logical drive was not found!"); // We try to continue even if this fails, just in case
|
uprintf("Logical drive was not found!"); // We try to continue even if this fails, just in case
|
||||||
|
@ -2006,7 +2007,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
ret = use_large_fat32?FormatFAT32(DriveIndex):FormatDrive(DriveIndex);
|
ret = use_large_fat32?FormatFAT32(DriveIndex):FormatDrive(DriveIndex);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
// Error will be set by FormatDrive() in FormatStatus
|
// Error will be set by FormatDrive() in FormatStatus
|
||||||
uprintf("Format error: %s\n", StrError(FormatStatus, TRUE));
|
uprintf("Format error: %s", StrError(FormatStatus, TRUE));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2027,11 +2028,11 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
|
|
||||||
guid_volume = GetLogicalName(DriveIndex, TRUE, TRUE);
|
guid_volume = GetLogicalName(DriveIndex, TRUE, TRUE);
|
||||||
if (guid_volume == NULL) {
|
if (guid_volume == NULL) {
|
||||||
uprintf("Could not get GUID volume name\n");
|
uprintf("Could not get GUID volume name");
|
||||||
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;
|
||||||
}
|
}
|
||||||
uprintf("Found volume GUID %s\n", guid_volume);
|
uprintf("Found volume GUID %s, guid_volume");
|
||||||
|
|
||||||
if (!MountVolume(drive_name, guid_volume)) {
|
if (!MountVolume(drive_name, guid_volume)) {
|
||||||
uprintf("Could not remount %s as %C: %s\n", guid_volume, drive_name[0], WindowsErrorString());
|
uprintf("Could not remount %s as %C: %s\n", guid_volume, drive_name[0], WindowsErrorString());
|
||||||
|
@ -2076,7 +2077,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
// => no need to reacquire the lock...
|
// => no need to reacquire the lock...
|
||||||
hLogicalVolume = GetLogicalHandle(DriveIndex, FALSE, TRUE, FALSE);
|
hLogicalVolume = GetLogicalHandle(DriveIndex, 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\n");
|
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;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -2116,7 +2117,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
} else if (bt == BT_GRUB4DOS) {
|
} else if (bt == BT_GRUB4DOS) {
|
||||||
grub4dos_dst[0] = drive_name[0];
|
grub4dos_dst[0] = drive_name[0];
|
||||||
IGNORE_RETVAL(_chdirU(app_dir));
|
IGNORE_RETVAL(_chdirU(app_dir));
|
||||||
uprintf("Installing: %s (Grub4DOS loader) %s\n", grub4dos_dst,
|
uprintf("Installing: %s (Grub4DOS loader) %s", grub4dos_dst,
|
||||||
IsFileInDB(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr")?"✓":"✗");
|
IsFileInDB(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr")?"✓":"✗");
|
||||||
if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE))
|
if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE))
|
||||||
uprintf("Failed to copy file: %s", WindowsErrorString());
|
uprintf("Failed to copy file: %s", WindowsErrorString());
|
||||||
|
@ -2139,10 +2140,10 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
}
|
}
|
||||||
if (HAS_KOLIBRIOS(img_report)) {
|
if (HAS_KOLIBRIOS(img_report)) {
|
||||||
kolibri_dst[0] = drive_name[0];
|
kolibri_dst[0] = drive_name[0];
|
||||||
uprintf("Installing: %s (KolibriOS loader)\n", kolibri_dst);
|
uprintf("Installing: %s (KolibriOS loader)", kolibri_dst);
|
||||||
if (ExtractISOFile(image_path, "HD_Load/USB_Boot/MTLD_F32", kolibri_dst,
|
if (ExtractISOFile(image_path, "HD_Load/USB_Boot/MTLD_F32", kolibri_dst,
|
||||||
FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM) == 0) {
|
FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM) == 0) {
|
||||||
uprintf("Warning: loader installation failed - KolibriOS will not boot!\n");
|
uprintf("Warning: loader installation failed - KolibriOS will not boot!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// EFI mode selected, with no 'boot###.efi' but Windows 7 x64's 'bootmgr.efi' (bit #0)
|
// EFI mode selected, with no 'boot###.efi' but Windows 7 x64's 'bootmgr.efi' (bit #0)
|
||||||
|
@ -2152,12 +2153,12 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
efi_dst[0] = drive_name[0];
|
efi_dst[0] = drive_name[0];
|
||||||
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0;
|
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0;
|
||||||
if (!CreateDirectoryA(efi_dst, 0)) {
|
if (!CreateDirectoryA(efi_dst, 0)) {
|
||||||
uprintf("Could not create directory '%s': %s\n", efi_dst, WindowsErrorString());
|
uprintf("Could not create directory '%s': %s", efi_dst, WindowsErrorString());
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
} else {
|
} else {
|
||||||
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\';
|
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\';
|
||||||
if (!WimExtractFile(img_report.wininst_path[0], 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) {
|
if (!WimExtractFile(img_report.wininst_path[0], 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) {
|
||||||
uprintf("Failed to setup Win7 EFI boot\n");
|
uprintf("Failed to setup Win7 EFI boot");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2199,7 +2200,7 @@ out:
|
||||||
guid_volume = GetLogicalName(DriveIndex, TRUE, FALSE);
|
guid_volume = GetLogicalName(DriveIndex, TRUE, FALSE);
|
||||||
if (guid_volume != NULL) {
|
if (guid_volume != NULL) {
|
||||||
if (MountVolume(drive_name, guid_volume))
|
if (MountVolume(drive_name, guid_volume))
|
||||||
uprintf("Re-mounted volume as %C: after error\n", drive_name[0]);
|
uprintf("Re-mounted volume as %C: after error", drive_name[0]);
|
||||||
free(guid_volume);
|
free(guid_volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
Copyright (C) 2009 Henrik Carlqvist
|
Copyright (C) 2009 Henrik Carlqvist
|
||||||
Modified for Rufus/Windows (C) 2011-2016 Pete Batard
|
Modified for Rufus/Windows (C) 2011-2019 Pete Batard
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -47,8 +47,10 @@ int64_t write_sectors(HANDLE hDrive, uint64_t SectorSize,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LastWriteError = 0;
|
||||||
if(!WriteFile(hDrive, pBuf, Size, &Size, NULL))
|
if(!WriteFile(hDrive, pBuf, Size, &Size, NULL))
|
||||||
{
|
{
|
||||||
|
LastWriteError = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|GetLastError();
|
||||||
uprintf("write_sectors: Write error %s\n", WindowsErrorString());
|
uprintf("write_sectors: Write error %s\n", WindowsErrorString());
|
||||||
uprintf(" StartSector: 0x%08" PRIx64 ", nSectors: 0x%" PRIx64 ", SectorSize: 0x%" PRIx64 "\n", StartSector, nSectors, SectorSize);
|
uprintf(" StartSector: 0x%08" PRIx64 ", nSectors: 0x%" PRIx64 ", SectorSize: 0x%" PRIx64 "\n", StartSector, nSectors, SectorSize);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -60,7 +62,8 @@ int64_t write_sectors(HANDLE hDrive, uint64_t SectorSize,
|
||||||
uprintf("Warning: Possible short write\n");
|
uprintf("Warning: Possible short write\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uprintf("write_sectors:write error\n");
|
uprintf("write_sectors: Write error\n");
|
||||||
|
LastWriteError = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
||||||
uprintf(" Wrote: %d, Expected: %" PRIu64 "\n", Size, nSectors*SectorSize);
|
uprintf(" Wrote: %d, Expected: %" PRIu64 "\n", Size, nSectors*SectorSize);
|
||||||
uprintf(" StartSector: 0x%08" PRIx64 ", nSectors: 0x%" PRIx64 ", SectorSize: 0x%" PRIx64 "\n", StartSector, nSectors, SectorSize);
|
uprintf(" StartSector: 0x%08" PRIx64 ", nSectors: 0x%" PRIx64 ", SectorSize: 0x%" PRIx64 "\n", StartSector, nSectors, SectorSize);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -679,7 +679,7 @@ BYTE SearchProcess(char* HandleName, DWORD dwTimeOut, BOOL bPartialMatch, BOOL b
|
||||||
if (res == WAIT_TIMEOUT) {
|
if (res == WAIT_TIMEOUT) {
|
||||||
// Timeout - kill the thread
|
// Timeout - kill the thread
|
||||||
TerminateThread(handle, 0);
|
TerminateThread(handle, 0);
|
||||||
uprintf("Warning: Conflicting process search failed to complete due to timeout");
|
uprintf("Warning: Search for conflicting processes was interrupted due to timeout");
|
||||||
} else if (res != WAIT_OBJECT_0) {
|
} else if (res != WAIT_OBJECT_0) {
|
||||||
TerminateThread(handle, 0);
|
TerminateThread(handle, 0);
|
||||||
uprintf("Warning: Failed to wait for conflicting process search thread: %s", WindowsErrorString());
|
uprintf("Warning: Failed to wait for conflicting process search thread: %s", WindowsErrorString());
|
||||||
|
|
39
src/rufus.c
39
src/rufus.c
|
@ -1783,18 +1783,21 @@ static void SaveISO(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for conflicting processes accessing the drive, and if any,
|
// Check for conflicting processes accessing the drive.
|
||||||
// ask the user whether they want to proceed.
|
// If bPrompt is true, ask the user whether they want to proceed.
|
||||||
// Parameter is the maximum amount of time we allow for this call to execute (in ms)
|
// dwTimeOut is the maximum amount of time we allow for this call to execute (in ms)
|
||||||
static BOOL CheckDriveAccess(DWORD dwTimeOut)
|
// If bPrompt is false, the return value is the amount of time remaining before
|
||||||
|
// dwTimeOut would expire (or zero if we spent more than dwTimeout in this procedure).
|
||||||
|
// If bPrompt is true, the return value is 0 on error, non-zero on success.
|
||||||
|
DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
BOOL ret = FALSE, proceed = TRUE;
|
DWORD ret = 0, proceed = TRUE;
|
||||||
BYTE access_mask;
|
BYTE access_mask;
|
||||||
char *PhysicalPath = NULL, DevPath[MAX_PATH];
|
char *PhysicalPath = NULL, DevPath[MAX_PATH];
|
||||||
char drive_letter[27], drive_name[] = "?:";
|
char drive_letter[27], drive_name[] = "?:";
|
||||||
char title[128];
|
char title[128];
|
||||||
uint64_t cur_time, end_time = GetTickCount64() + dwTimeOut;
|
uint64_t start_time = GetTickCount64(), cur_time, end_time = start_time + dwTimeOut;
|
||||||
|
|
||||||
// Get the current selected device
|
// Get the current selected device
|
||||||
DWORD DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList));
|
DWORD DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList));
|
||||||
|
@ -1802,7 +1805,8 @@ static BOOL CheckDriveAccess(DWORD dwTimeOut)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// "Checking for conflicting processes..."
|
// "Checking for conflicting processes..."
|
||||||
PrintInfo(0, MSG_278);
|
if (bPrompt)
|
||||||
|
PrintInfo(0, MSG_278);
|
||||||
|
|
||||||
// Search for any blocking processes against the physical drive
|
// Search for any blocking processes against the physical drive
|
||||||
PhysicalPath = GetPhysicalName(DeviceNum);
|
PhysicalPath = GetPhysicalName(DeviceNum);
|
||||||
|
@ -1839,11 +1843,16 @@ static BOOL CheckDriveAccess(DWORD dwTimeOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prompt the user if we detected blocking processes
|
// Prompt the user if we detected blocking processes
|
||||||
if (!proceed) {
|
if (bPrompt && !proceed) {
|
||||||
ComboBox_GetTextU(hDeviceList, title, sizeof(title));
|
ComboBox_GetTextU(hDeviceList, title, sizeof(title));
|
||||||
proceed = Notification(MSG_WARNING_QUESTION, NULL, NULL, title, lmprintf(MSG_132));
|
proceed = Notification(MSG_WARNING_QUESTION, NULL, NULL, title, lmprintf(MSG_132));
|
||||||
}
|
}
|
||||||
ret = proceed;
|
if (bPrompt) {
|
||||||
|
ret = (DWORD)proceed;
|
||||||
|
} else {
|
||||||
|
ret = (DWORD)(GetTickCount64() - start_time);
|
||||||
|
ret = (dwTimeOut > ret) ? (dwTimeOut - ret) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
PrintInfo(0, MSG_210);
|
PrintInfo(0, MSG_210);
|
||||||
|
@ -2207,6 +2216,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
// Disable all controls except Cancel
|
// Disable all controls except Cancel
|
||||||
EnableControls(FALSE);
|
EnableControls(FALSE);
|
||||||
FormatStatus = 0;
|
FormatStatus = 0;
|
||||||
|
LastWriteError = 0;
|
||||||
StrArrayClear(&BlockingProcess);
|
StrArrayClear(&BlockingProcess);
|
||||||
format_op_in_progress = TRUE;
|
format_op_in_progress = TRUE;
|
||||||
no_confirmation_on_cancel = FALSE;
|
no_confirmation_on_cancel = FALSE;
|
||||||
|
@ -2604,7 +2614,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CheckDriveAccess(2000))
|
if (!CheckDriveAccess(CHECK_DRIVE_TIMEOUT, TRUE))
|
||||||
goto aborted_start;
|
goto aborted_start;
|
||||||
|
|
||||||
GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp));
|
GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp));
|
||||||
|
@ -2712,10 +2722,19 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (SCODE_CODE(FormatStatus) == ERROR_NOT_READY) {
|
||||||
|
// A port cycle usually helps with a device not ready
|
||||||
|
int index = ComboBox_GetCurSel(hDeviceList);
|
||||||
|
if (index >= 0) {
|
||||||
|
uprintf("Device not ready → Trying to cycle port...");
|
||||||
|
ResetDevice(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
Notification(MSG_ERROR, NULL, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus, FALSE)));
|
Notification(MSG_ERROR, NULL, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus, FALSE)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FormatStatus = 0;
|
FormatStatus = 0;
|
||||||
|
LastWriteError = 0;
|
||||||
format_op_in_progress = FALSE;
|
format_op_in_progress = FALSE;
|
||||||
return (INT_PTR)TRUE;
|
return (INT_PTR)TRUE;
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
#define WRITE_TIMEOUT 5000 // How long we should wait between write retries (in ms)
|
#define WRITE_TIMEOUT 5000 // How long we should wait between write retries (in ms)
|
||||||
#define SEARCH_PROCESS_TIMEOUT 10000 // How long we should search for conflicting processes before giving up (in ms)
|
#define SEARCH_PROCESS_TIMEOUT 10000 // How long we should search for conflicting processes before giving up (in ms)
|
||||||
#define NET_SESSION_TIMEOUT 3500 // How long we should wait to connect, send or receive internet data
|
#define NET_SESSION_TIMEOUT 3500 // How long we should wait to connect, send or receive internet data
|
||||||
|
#define CHECK_DRIVE_TIMEOUT 2000
|
||||||
#define MARQUEE_TIMER_REFRESH 10 // Time between progress bar marquee refreshes, in ms
|
#define MARQUEE_TIMER_REFRESH 10 // Time between progress bar marquee refreshes, in ms
|
||||||
#define FS_DEFAULT FS_FAT32
|
#define FS_DEFAULT FS_FAT32
|
||||||
#define SINGLE_CLUSTERSIZE_DEFAULT 0x00000100
|
#define SINGLE_CLUSTERSIZE_DEFAULT 0x00000100
|
||||||
|
@ -445,7 +446,7 @@ extern HWND hMainDialog, hLogDialog, hStatus, hDeviceList, hCapacity;
|
||||||
extern HWND hPartitionScheme, hTargetSystem, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog;
|
extern HWND hPartitionScheme, hTargetSystem, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog;
|
||||||
extern HWND hInfo, hProgress, hDiskID;
|
extern HWND hInfo, hProgress, hDiskID;
|
||||||
extern WORD selected_langid;
|
extern WORD selected_langid;
|
||||||
extern DWORD FormatStatus, DownloadStatus, MainThreadId;
|
extern DWORD FormatStatus, DownloadStatus, MainThreadId, LastWriteError;
|
||||||
extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, iso_op_in_progress, format_op_in_progress, right_to_left_mode;
|
extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, iso_op_in_progress, format_op_in_progress, right_to_left_mode;
|
||||||
extern BOOL allow_dual_uefi_bios, large_drive, usb_debug;
|
extern BOOL allow_dual_uefi_bios, large_drive, usb_debug;
|
||||||
extern int64_t iso_blocking_status;
|
extern int64_t iso_blocking_status;
|
||||||
|
@ -571,6 +572,7 @@ extern char* GetCurrentMUI(void);
|
||||||
extern void SetAlertPromptMessages(void);
|
extern void SetAlertPromptMessages(void);
|
||||||
extern BOOL SetAlertPromptHook(void);
|
extern BOOL SetAlertPromptHook(void);
|
||||||
extern void ClrAlertPromptHook(void);
|
extern void ClrAlertPromptHook(void);
|
||||||
|
extern DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt);
|
||||||
extern BYTE SearchProcess(char* HandleName, DWORD dwTimeout, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet);
|
extern BYTE SearchProcess(char* HandleName, DWORD dwTimeout, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet);
|
||||||
extern BOOL EnablePrivileges(void);
|
extern BOOL EnablePrivileges(void);
|
||||||
extern void FlashTaskbar(HANDLE handle);
|
extern void FlashTaskbar(HANDLE handle);
|
||||||
|
|
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.1514"
|
CAPTION "Rufus 3.6.1515"
|
||||||
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,1514,0
|
FILEVERSION 3,6,1515,0
|
||||||
PRODUCTVERSION 3,6,1514,0
|
PRODUCTVERSION 3,6,1515,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.1514"
|
VALUE "FileVersion", "3.6.1515"
|
||||||
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.1514"
|
VALUE "ProductVersion", "3.6.1515"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
22
src/stdio.c
22
src/stdio.c
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Rufus: The Reliable USB Formatting Utility
|
* Rufus: The Reliable USB Formatting Utility
|
||||||
* Standard User I/O Routines (logging, status, etc.)
|
* Standard User I/O Routines (logging, status, etc.)
|
||||||
* Copyright © 2011-2017 Pete Batard <pete@akeo.ie>
|
* Copyright © 2011-2019 Pete Batard <pete@akeo.ie>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
@ -144,17 +145,18 @@ void DumpBufferHex(void *buf, size_t size)
|
||||||
// Convert a windows error to human readable string
|
// Convert a windows error to human readable string
|
||||||
const char *WindowsErrorString(void)
|
const char *WindowsErrorString(void)
|
||||||
{
|
{
|
||||||
static char err_string[256] = {0};
|
static char err_string[256] = { 0 };
|
||||||
|
|
||||||
DWORD size;
|
DWORD size, presize;
|
||||||
DWORD error_code, format_error;
|
DWORD error_code, format_error;
|
||||||
|
|
||||||
error_code = GetLastError();
|
error_code = GetLastError();
|
||||||
|
|
||||||
static_sprintf(err_string, "[0x%08lX] ", error_code);
|
static_sprintf(err_string, "[0x%08lX] ", error_code);
|
||||||
|
presize = (DWORD)strlen(err_string);
|
||||||
|
|
||||||
size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, HRESULT_CODE(error_code),
|
size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, HRESULT_CODE(error_code),
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[strlen(err_string)],
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[presize],
|
||||||
sizeof(err_string)-(DWORD)strlen(err_string), NULL);
|
sizeof(err_string)-(DWORD)strlen(err_string), NULL);
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
format_error = GetLastError();
|
format_error = GetLastError();
|
||||||
|
@ -163,6 +165,13 @@ static char err_string[256] = {0};
|
||||||
error_code, format_error);
|
error_code, format_error);
|
||||||
else
|
else
|
||||||
static_sprintf(err_string, "Unknown error 0x%08lX", error_code);
|
static_sprintf(err_string, "Unknown error 0x%08lX", error_code);
|
||||||
|
} else {
|
||||||
|
// Microsoft may suffix CRLF to error messages, which we need to remove...
|
||||||
|
assert(presize > 2);
|
||||||
|
size += presize - 2;
|
||||||
|
// Cannot underflow if the above assert passed since our first char is neither of the following
|
||||||
|
while ((err_string[size] == 0x0D) || (err_string[size] == 0x0A) || (err_string[size] == 0x20))
|
||||||
|
err_string[size--] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastError(error_code); // Make sure we don't change the errorcode on exit
|
SetLastError(error_code); // Make sure we don't change the errorcode on exit
|
||||||
|
@ -356,6 +365,7 @@ BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL)) {
|
if (WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL)) {
|
||||||
|
LastWriteError = 0;
|
||||||
if (nNumberOfBytesToWrite == *lpNumberOfBytesWritten)
|
if (nNumberOfBytesToWrite == *lpNumberOfBytesWritten)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
// Some large drives return 0, even though all the data was written - See github #787 */
|
// Some large drives return 0, even though all the data was written - See github #787 */
|
||||||
|
@ -366,13 +376,15 @@ BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
|
||||||
uprintf("Wrote %d bytes but requested %d", *lpNumberOfBytesWritten, nNumberOfBytesToWrite);
|
uprintf("Wrote %d bytes but requested %d", *lpNumberOfBytesWritten, nNumberOfBytesToWrite);
|
||||||
} else {
|
} else {
|
||||||
uprintf("Write error [0x%08X]", GetLastError());
|
uprintf("Write error [0x%08X]", GetLastError());
|
||||||
|
LastWriteError = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|GetLastError();
|
||||||
}
|
}
|
||||||
// If we can't reposition for the next run, just abort
|
// If we can't reposition for the next run, just abort
|
||||||
if (!readFilePointer)
|
if (!readFilePointer)
|
||||||
break;
|
break;
|
||||||
if (nTry < nNumRetries) {
|
if (nTry < nNumRetries) {
|
||||||
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000);
|
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000);
|
||||||
Sleep(WRITE_TIMEOUT);
|
// Don't sit idly but use the downtime to check for conflicting processes...
|
||||||
|
Sleep(CheckDriveAccess(WRITE_TIMEOUT, FALSE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SCODE_CODE(GetLastError()) == ERROR_SUCCESS)
|
if (SCODE_CODE(GetLastError()) == ERROR_SUCCESS)
|
||||||
|
|
Loading…
Reference in a new issue