diff options
author | Daniel Wilhelm <shieldwed@outlook.com> | 2016-10-29 11:41:53 +0200 |
---|---|---|
committer | Daniel Wilhelm <shieldwed@outlook.com> | 2016-10-29 11:41:53 +0200 |
commit | 7302bb4484d517a72cdffbd13ec7a9f2324cde01 (patch) | |
tree | 17d2964c6768d49510206836a496fb1802a63e08 /zen/sys_error.h | |
parent | 8.5 (diff) | |
download | FreeFileSync-7302bb4484d517a72cdffbd13ec7a9f2324cde01.tar.gz FreeFileSync-7302bb4484d517a72cdffbd13ec7a9f2324cde01.tar.bz2 FreeFileSync-7302bb4484d517a72cdffbd13ec7a9f2324cde01.zip |
8.6
Diffstat (limited to 'zen/sys_error.h')
-rw-r--r-- | zen/sys_error.h | 48 |
1 files changed, 40 insertions, 8 deletions
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 <WinINet.h> #elif defined ZEN_LINUX || defined ZEN_MAC #include <cstring> #include <cerrno> @@ -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<LPWSTR>(&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<LPWSTR>(&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<LPWSTR>(&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<std::wstring>(ec), formatSystemErrorRaw(ec)); + return formatSystemError(functionName, numberTo<std::wstring>(ec), formatSystemErrorRaw(ec)); } |