#include #include #include #include #include "err.h" #include "util.h" #include "win32.h" /* Strip trailing punctuation. */ static void Strip(wchar_t* s, size_t len = -1) { for (int i = len-1; i >= 0; i--) if (s[i] == '\r' || s[i] == '\n' || s[i] == '.') s[i] = 0; } Err::Err(ErrType t, const wchar_t* fmt) { switch (t) { case GENERIC: assert(wcscmp(fmt, L"%s.") != 0); what = fmt; break; case WINDOWS: { wchar_t* msg; DWORD lenMsg = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (wchar_t*)&msg, 0, nullptr); Strip(msg, lenMsg); what = std::wstring(lenMsg+wcslen(fmt), 0); Swprintf(what, fmt, msg); HeapFree(GetProcessHeap(), 0, msg); break; } case WININET: { DWORD code = GetLastError(); if (code == ERROR_INTERNET_EXTENDED_ERROR) { DWORD lenMsg; InternetGetLastResponseInfo(&code, nullptr, &lenMsg); std::wstring msg(lenMsg, 0); if (InternetGetLastResponseInfoW(&code, msg.data(), &lenMsg)) { what = std::wstring(lenMsg+wcslen(fmt), 0); Swprintf(what, fmt, msg.c_str()); } else what = Err(WINDOWS, fmt).what; } else { wchar_t* msg; DWORD lenMsg = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_FROM_HMODULE |FORMAT_MESSAGE_IGNORE_INSERTS, GetModuleHandle(L"wininet.dll"), code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (wchar_t*)&msg, 0, nullptr); Strip(msg, lenMsg); what = std::wstring(lenMsg+wcslen(fmt), 0); Swprintf(what, fmt, msg); HeapFree(GetProcessHeap(), 0, msg); } break; } case LIBXML2: { std::wstring msg = WideFromNarrow(xmlGetLastError()->message); what = std::wstring(msg.size()+wcslen(fmt), 0); Swprintf(what, fmt, msg.c_str()); break; } } } std::wstring What(std::exception_ptr ex) { try { std::rethrow_exception(ex); } catch (const Err& e) { return e.what; } catch (const std::exception& e) { return WideFromNarrow(e.what()); } catch (...) { return L"Unknown exception"; } } void OnTerminate() { EBMessageBox(What(), L"Fatal Error", MB_ICONERROR); }