/* * 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 errcode, format_error; errcode = GetLastError(); static_sprintf(err_string, "[0x%08lX] ", errcode); size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, HRESULT_CODE(errcode), 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 static_sprintf(err_string, "Windows error code 0x%08lX (FormatMessage error code 0x%08lX)", errcode, format_error); else static_sprintf(err_string, "Unknown error 0x%08lX", errcode); } SetLastError(errcode); // Make sure we don't change the errorcode on exit return err_string; }
std::string FormattedMessageLoader::GetFormattedMessage( IErrorReporter& reporter, DWORD messageId) { this->RequireValid(); return FormatMessageU(reporter, this->hModule, messageId, nullptr); }
std::string FormattedMessageLoader::GetFormattedMessage( IErrorReporter& reporter, DWORD messageId, std::vector<std::wstring> const& arguments) { this->RequireValid(); std::vector<DWORD_PTR> argumentPtrs; argumentPtrs.reserve(arguments.size()); std::transform(arguments.cbegin(), arguments.cend(), std::back_inserter(argumentPtrs), [](std::wstring const& str) { return reinterpret_cast<DWORD_PTR>(str.c_str()); }); auto argPtr = reinterpret_cast<va_list*>(argumentPtrs.data()); if (arguments.empty()) { argPtr = nullptr; } return FormatMessageU(reporter, this->hModule, messageId, argPtr); }