/* * Rufus: The Reliable USB Formatting Utility * Standard User I/O Routines (logging, status, etc.) * Copyright © 2011-2016 Pete Batard * * 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifdef _CRTDBG_MAP_ALLOC #include #include #endif #include #include #include #include #include #include #include #include "msapi_utf8.h" #include "rufus.h" #include "resource.h" #include "localization.h" /* * Globals */ HWND hStatus; #ifdef RUFUS_DEBUG void _uprintf(const char *format, ...) { static char buf[4096]; char* p = buf; va_list args; int n; va_start(args, format); n = safe_vsnprintf(p, sizeof(buf)-3, format, args); // buf-3 is room for CR/LF/NUL va_end(args); p += (n < 0)?sizeof(buf)-3:n; while((p>buf) && (isspaceU(p[-1]))) *--p = '\0'; *p++ = '\r'; *p++ = '\n'; *p = '\0'; // Send output to Windows debug facility OutputDebugStringA(buf); if ((hLog != NULL) && (hLog != INVALID_HANDLE_VALUE)) { // Send output to our log Window Edit_SetSel(hLog, MAX_LOG_SIZE, MAX_LOG_SIZE); Edit_ReplaceSelU(hLog, buf); // Make sure the message scrolls into view // (Or see code commented in LogProc:WM_SHOWWINDOW for a less forceful scroll) SendMessage(hLog, EM_LINESCROLL, 0, SendMessage(hLog, EM_GETLINECOUNT, 0, 0)); } } #endif void DumpBufferHex(void *buf, size_t size) { unsigned char* buffer = (unsigned char*)buf; size_t i, j, k; char line[80] = ""; for (i=0; i 126)) { sprintf(&line[strlen(line)], "."); } else { sprintf(&line[strlen(line)], "%c", buffer[i+j]); } } } } uprintf("%s\n", line); } /* * Convert a windows error to human readable string * uses retval as errorcode, or, if 0, use GetLastError() */ const char *WindowsErrorString(void) { static char err_string[256] = {0}; DWORD size; DWORD error_code, format_error; error_code = GetLastError(); safe_sprintf(err_string, sizeof(err_string), "[0x%08X] ", 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)], sizeof(err_string)-(DWORD)strlen(err_string), NULL); if (size == 0) { format_error = GetLastError(); if ((format_error) && (format_error != 0x13D)) // 0x13D, decode error, is returned for unknown codes safe_sprintf(err_string, sizeof(err_string), "Windows error code 0x%08X (FormatMessage error code 0x%08X)", error_code, format_error); else safe_sprintf(err_string, sizeof(err_string), "Unknown error 0x%08X", error_code); } SetLastError(error_code); // Make sure we don't change the errorcode on exit return err_string; } char* GuidToString(const GUID* guid) { static char guid_string[MAX_GUID_STRING_LENGTH]; if (guid == NULL) return NULL; sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", (unsigned int)guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); return guid_string; } // find upper power of 2 static __inline uint16_t upo2(uint16_t v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v++; return v; } // Convert a size to human readable char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units) { int suffix; static char str_size[32]; const char* dir = ((right_to_left_mode)&&(!copy_to_log))?RIGHT_TO_LEFT_MARK:""; double hr_size = (double)size; double t; uint16_t i_size; char **_msg_table = copy_to_log?default_msg_table:msg_table; const double divider = fake_units?1000.0:1024.0; for (suffix=0; suffix 1) && (!SetFilePointerEx(hFile, liFilePointer, NULL, FILE_BEGIN))) { uprintf(" Could not set file pointer - aborting"); break; } if (WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL)) { if (nNumberOfBytesToWrite == *lpNumberOfBytesWritten) return TRUE; uprintf(" Wrote %d bytes but requested %d%s", *lpNumberOfBytesWritten, nNumberOfBytesToWrite, nTry < nNumRetries ? retry_msg : ""); } else { uprintf(" Write error [0x%8X]%s", GetLastError(), nTry < nNumRetries ? retry_msg : ""); } // If we can't reposition for the next run, just abort if (!readFilePointer) break; Sleep(200); } if (SCODE_CODE(GetLastError()) == ERROR_SUCCESS) SetLastError(ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT); return FALSE; }