[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:
Pete Batard 2019-04-09 21:37:08 +01:00
parent b7ab196a97
commit d4a663991b
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
7 changed files with 95 additions and 58 deletions

View file

@ -1,7 +1,7 @@
/*
* Rufus: The Reliable USB Formatting Utility
* 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
* it under the terms of the GNU General Public License as published by
@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <math.h>
@ -144,17 +145,18 @@ void DumpBufferHex(void *buf, size_t size)
// Convert a windows error to human readable string
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;
error_code = GetLastError();
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),
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);
if (size == 0) {
format_error = GetLastError();
@ -163,6 +165,13 @@ static char err_string[256] = {0};
error_code, format_error);
else
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
@ -356,6 +365,7 @@ BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
break;
}
if (WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL)) {
LastWriteError = 0;
if (nNumberOfBytesToWrite == *lpNumberOfBytesWritten)
return TRUE;
// 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);
} else {
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 (!readFilePointer)
break;
if (nTry < nNumRetries) {
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)