From 7302bb4484d517a72cdffbd13ec7a9f2324cde01 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Sat, 29 Oct 2016 11:41:53 +0200 Subject: 8.6 --- zen/sys_error.h | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) (limited to 'zen/sys_error.h') diff --git a/zen/sys_error.h b/zen/sys_error.h index 5897b413..4798b959 100644 --- a/zen/sys_error.h +++ b/zen/sys_error.h @@ -13,8 +13,8 @@ #include "scope_guard.h" #ifdef ZEN_WIN - #include "win.h" //includes "windows.h" - + #include "win.h" //tame WinINet.h include + #include #elif defined ZEN_LINUX || defined ZEN_MAC #include #include @@ -50,6 +50,22 @@ private: +#ifdef _MSC_VER +#define THROW_LAST_SYS_ERROR(functionName) \ + do \ + { \ + const ErrorCode ecInternal = getLastError(); \ + throw SysError(formatSystemError(functionName, ecInternal)); \ + \ + __pragma(warning(suppress: 4127)) /*"conditional expression is constant"*/ \ + } while (false) + +#else //same thing witout "__pragma": +#define THROW_LAST_SYS_ERROR(functionName) \ + do { const ErrorCode ecInternal = getLastError(); throw SysError(formatSystemError(functionName, ecInternal)); } while (false) +#endif + + @@ -78,10 +94,26 @@ std::wstring formatSystemErrorRaw(ErrorCode ec) //return empty string on error ZEN_ON_SCOPE_EXIT(::SetLastError(currentError)); //this function must not change active system error variable! LPWSTR buffer = nullptr; - if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_MAX_WIDTH_MASK | - FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders - FORMAT_MESSAGE_ALLOCATE_BUFFER, nullptr, ec, 0, reinterpret_cast(&buffer), 0, nullptr) != 0) + const DWORD rv = [&] + { + if (INTERNET_ERROR_BASE <= ec && ec <= INTERNET_ERROR_LAST) + return ::FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | + FORMAT_MESSAGE_MAX_WIDTH_MASK | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_ALLOCATE_BUFFER, ::GetModuleHandle(L"WinINet.dll"), ec, 0, reinterpret_cast(&buffer), 0, nullptr); + else + return ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_MAX_WIDTH_MASK | + FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders + FORMAT_MESSAGE_ALLOCATE_BUFFER, //_In_ DWORD dwFlags, + nullptr, //_In_opt_ LPCVOID lpSource, + ec, //_In_ DWORD dwMessageId, + 0, //_In_ DWORD dwLanguageId, + reinterpret_cast(&buffer), //_Out_ LPTSTR lpBuffer, + 0, //_In_ DWORD nSize, + nullptr); //_In_opt_ va_list *Arguments + }(); + if (rv != 0) if (buffer) //"don't trust nobody" { ZEN_ON_SCOPE_EXIT(::LocalFree(buffer)); @@ -102,9 +134,9 @@ std::wstring formatSystemErrorRaw(ErrorCode ec) //return empty string on error std::wstring formatSystemError(const std::wstring& functionName, long long lastError) = delete; //intentional overload ambiguity to catch usage errors with HRESULT! inline -std::wstring formatSystemError(const std::wstring& functionName, ErrorCode ec) +std::wstring formatSystemError(const std::wstring& functionName, ErrorCode ec) { - return formatSystemError(functionName, numberTo(ec), formatSystemErrorRaw(ec)); + return formatSystemError(functionName, numberTo(ec), formatSystemErrorRaw(ec)); } -- cgit