From e3d5a2f07adf4b90aeda0e7d9b57b4c008da7513 Mon Sep 17 00:00:00 2001 From: Soreepeong Date: Thu, 1 Sep 2022 10:50:45 +0900 Subject: [PATCH] DalamudCrashHandler: log dll descr/version on crash too --- DalamudCrashHandler/DalamudCrashHandler.cpp | 65 ++++++++++++++++++- .../DalamudCrashHandler.vcxproj | 4 +- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp index 2ff12946c..e6ca46fe6 100644 --- a/DalamudCrashHandler/DalamudCrashHandler.cpp +++ b/DalamudCrashHandler/DalamudCrashHandler.cpp @@ -31,6 +31,69 @@ HANDLE g_hProcess = nullptr; bool g_bSymbolsAvailable = false; +std::wstring describe_module(const std::filesystem::path& path) { + DWORD verHandle = 0; + std::vector block; + block.resize(GetFileVersionInfoSizeW(path.c_str(), &verHandle)); + if (block.empty()) { + if (GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND) + return L""; + return std::format(L"", GetLastError()); + } + if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(block.size()), block.data())) + return std::format(L"", GetLastError()); + + UINT size = 0; + + std::wstring version = L"v?.?.?.?"; + if (LPVOID lpBuffer; VerQueryValueW(block.data(), L"\\", &lpBuffer, &size)) { + const auto& v = *static_cast(lpBuffer); + if (v.dwSignature != 0xfeef04bd || sizeof v > size) { + version = L""; + } else { + if (v.dwFileVersionMS == v.dwProductVersionMS && v.dwFileVersionLS == v.dwProductVersionLS) { + version = std::format(L"v{}.{}.{}.{}", + (v.dwProductVersionMS >> 16) & 0xFFFF, + (v.dwProductVersionMS >> 0) & 0xFFFF, + (v.dwProductVersionLS >> 16) & 0xFFFF, + (v.dwProductVersionLS >> 0) & 0xFFFF); + } else { + version = std::format(L"file=v{}.{}.{}.{} prod=v{}.{}.{}.{}", + (v.dwFileVersionMS >> 16) & 0xFFFF, + (v.dwFileVersionMS >> 0) & 0xFFFF, + (v.dwFileVersionLS >> 16) & 0xFFFF, + (v.dwFileVersionLS >> 0) & 0xFFFF, + (v.dwProductVersionMS >> 16) & 0xFFFF, + (v.dwProductVersionMS >> 0) & 0xFFFF, + (v.dwProductVersionLS >> 16) & 0xFFFF, + (v.dwProductVersionLS >> 0) & 0xFFFF); + } + } + } + + std::wstring description = L""; + if (LPVOID lpBuffer; VerQueryValueW(block.data(), L"\\VarFileInfo\\Translation", &lpBuffer, &size)) { + struct LANGANDCODEPAGE { + WORD wLanguage; + WORD wCodePage; + }; + const auto langs = std::span(reinterpret_cast(lpBuffer), size / sizeof(LANGANDCODEPAGE)); + for (const auto& lang : langs) { + if (!VerQueryValueW(block.data(), std::format(L"\\StringFileInfo\\{:04x}{:04x}\\FileDescription", lang.wLanguage, lang.wCodePage).c_str(), &lpBuffer, &size)) + continue; + auto currName = std::wstring_view(static_cast(lpBuffer), size); + while (!currName.empty() && currName.back() == L'\0') + currName = currName.substr(0, currName.size() - 1); + if (currName.empty()) + continue; + description = currName; + break; + } + } + + return std::format(L"{} {}", description, version); +} + const std::map& get_remote_modules() { static const auto data = [] { std::map data; @@ -265,7 +328,7 @@ void print_exception_info_extended(const EXCEPTION_POINTERS& ex, const CONTEXT& log << L"\nModules\n{"; for (const auto& [hModule, path] : get_remote_module_paths()) - log << std::format(L"\n {:08X}\t{}", reinterpret_cast(hModule), path.wstring()); + log << std::format(L"\n {:08X}\t{}\t{}", reinterpret_cast(hModule), path.wstring(), describe_module(path)); log << L"\n}\n"; } diff --git a/DalamudCrashHandler/DalamudCrashHandler.vcxproj b/DalamudCrashHandler/DalamudCrashHandler.vcxproj index 4541462b7..c3cc7fa18 100644 --- a/DalamudCrashHandler/DalamudCrashHandler.vcxproj +++ b/DalamudCrashHandler/DalamudCrashHandler.vcxproj @@ -50,7 +50,7 @@ Console true - Winhttp.lib;Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + Version.lib;Winhttp.lib;Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) @@ -93,4 +93,4 @@ - + \ No newline at end of file