From 8bc4d362adf65d7afb22b6d4c40f7612961e0313 Mon Sep 17 00:00:00 2001 From: goat Date: Sat, 23 Jul 2022 20:25:05 +0200 Subject: [PATCH] feat: new VEH experience --- Dalamud.Boot/Dalamud.Boot.rc | 71 ++++++++ Dalamud.Boot/Dalamud.Boot.vcxproj | 9 +- Dalamud.Boot/Dalamud.Boot.vcxproj.filters | 9 +- Dalamud.Boot/dalamud.ico | Bin 0 -> 53179 bytes Dalamud.Boot/resource.h | 16 ++ Dalamud.Boot/veh.cpp | 192 ++++++++++++++++------ Dalamud.Boot/xivfixes.cpp | 11 +- Dalamud.Injector/EntryPoint.cs | 3 +- Dalamud/EntryPoint.cs | 8 +- Dalamud/Plugin/Internal/PluginManager.cs | 11 ++ 10 files changed, 269 insertions(+), 61 deletions(-) create mode 100644 Dalamud.Boot/Dalamud.Boot.rc create mode 100644 Dalamud.Boot/dalamud.ico create mode 100644 Dalamud.Boot/resource.h diff --git a/Dalamud.Boot/Dalamud.Boot.rc b/Dalamud.Boot/Dalamud.Boot.rc new file mode 100644 index 000000000..daa41a282 --- /dev/null +++ b/Dalamud.Boot/Dalamud.Boot.rc @@ -0,0 +1,71 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United Kingdom) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "dalamud.ico" + +#endif // English (United Kingdom) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj b/Dalamud.Boot/Dalamud.Boot.vcxproj index e71750f47..3733fe388 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj @@ -165,14 +165,21 @@ + + + + + + + - \ No newline at end of file + diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters index b527ec60c..27483eeed 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters @@ -138,5 +138,12 @@ MinHook + - \ No newline at end of file + + + + + + + diff --git a/Dalamud.Boot/dalamud.ico b/Dalamud.Boot/dalamud.ico new file mode 100644 index 0000000000000000000000000000000000000000..1cd63765d401c387188f8588076582da1369f71a GIT binary patch literal 53179 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 V`M7xULJmNEEY0jptBm2X{{ysvb7}wp literal 0 HcmV?d00001 diff --git a/Dalamud.Boot/resource.h b/Dalamud.Boot/resource.h new file mode 100644 index 000000000..51acf37df --- /dev/null +++ b/Dalamud.Boot/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Dalamud.Boot.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp index 887a189bb..6979b2564 100644 --- a/Dalamud.Boot/veh.cpp +++ b/Dalamud.Boot/veh.cpp @@ -1,10 +1,26 @@ #include "pch.h" +#include "resource.h" + #include "veh.h" +#include + #include "logging.h" #include "utils.h" +#pragma comment(lib, "comctl32.lib") + +#if defined _M_IX86 +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_IA64 +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif + PVOID g_veh_handle = nullptr; bool g_veh_do_full_dump = false; @@ -69,11 +85,11 @@ bool get_module_file_and_base(const DWORD64 address, DWORD64& module_base, std:: } -bool is_ffxiv_address(const DWORD64 address) +bool is_ffxiv_address(const wchar_t* module_name, const DWORD64 address) { DWORD64 module_base; if (std::filesystem::path module_path; get_module_file_and_base(address, module_base, module_path)) - return _wcsicmp(module_path.filename().c_str(), L"ffxiv_dx11.exe") == 0; + return _wcsicmp(module_path.filename().c_str(), module_name) == 0; return false; } @@ -118,53 +134,9 @@ std::wstring to_address_string(const DWORD64 address, const bool try_ptrderef = return value != 0 ? std::format(L"{} [{}]", addr_str, to_address_string(value, false)) : addr_str; } - -void print_exception_info(const EXCEPTION_POINTERS* ex, std::wostringstream& log) +void print_exception_info_extended(const EXCEPTION_POINTERS* ex, std::wostringstream& log) { - size_t rec_index = 0; - for (auto rec = ex->ExceptionRecord; rec; rec = rec->ExceptionRecord) - { - log << std::format(L"\nException Info #{}\n", ++rec_index); - log << std::format(L"Address: {:X}\n", rec->ExceptionCode); - log << std::format(L"Flags: {:X}\n", rec->ExceptionFlags); - log << std::format(L"Address: {:X}\n", reinterpret_cast(rec->ExceptionAddress)); - if (!rec->NumberParameters) - continue; - log << L"Parameters: "; - for (DWORD i = 0; i < rec->NumberParameters; ++i) - { - if (i != 0) - log << L", "; - log << std::format(L"{:X}", rec->ExceptionInformation[i]); - } - } - - log << L"\nCall Stack\n{"; - - STACKFRAME64 sf; - sf.AddrPC.Offset = ex->ContextRecord->Rip; - sf.AddrPC.Mode = AddrModeFlat; - sf.AddrStack.Offset = ex->ContextRecord->Rsp; - sf.AddrStack.Mode = AddrModeFlat; - sf.AddrFrame.Offset = ex->ContextRecord->Rbp; - sf.AddrFrame.Mode = AddrModeFlat; CONTEXT ctx = *ex->ContextRecord; - int frame_index = 0; - - log << std::format(L"\n [{}]\t{}", frame_index++, to_address_string(sf.AddrPC.Offset, false)); - - do - { - if (!StackWalk64(IMAGE_FILE_MACHINE_AMD64, GetCurrentProcess(), GetCurrentThread(), &sf, &ctx, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr)) - break; - - log << std::format(L"\n [{}]\t{}", frame_index++, to_address_string(sf.AddrPC.Offset, false)); - - } while (sf.AddrReturn.Offset != 0 && sf.AddrPC.Offset != sf.AddrReturn.Offset); - - log << L"\n}\n"; - - ctx = *ex->ContextRecord; log << L"\nRegisters\n{"; @@ -219,6 +191,70 @@ void print_exception_info(const EXCEPTION_POINTERS* ex, std::wostringstream& log log << L"\n}\n"; } +void print_exception_info(const EXCEPTION_POINTERS* ex, std::wostringstream& log) +{ + size_t rec_index = 0; + for (auto rec = ex->ExceptionRecord; rec; rec = rec->ExceptionRecord) + { + log << std::format(L"\nException Info #{}\n", ++rec_index); + log << std::format(L"Address: {:X}\n", rec->ExceptionCode); + log << std::format(L"Flags: {:X}\n", rec->ExceptionFlags); + log << std::format(L"Address: {:X}\n", reinterpret_cast(rec->ExceptionAddress)); + if (!rec->NumberParameters) + continue; + log << L"Parameters: "; + for (DWORD i = 0; i < rec->NumberParameters; ++i) + { + if (i != 0) + log << L", "; + log << std::format(L"{:X}", rec->ExceptionInformation[i]); + } + } + + log << L"\nCall Stack\n{"; + + STACKFRAME64 sf; + sf.AddrPC.Offset = ex->ContextRecord->Rip; + sf.AddrPC.Mode = AddrModeFlat; + sf.AddrStack.Offset = ex->ContextRecord->Rsp; + sf.AddrStack.Mode = AddrModeFlat; + sf.AddrFrame.Offset = ex->ContextRecord->Rbp; + sf.AddrFrame.Mode = AddrModeFlat; + CONTEXT ctx = *ex->ContextRecord; + int frame_index = 0; + + log << std::format(L"\n [{}]\t{}", frame_index++, to_address_string(sf.AddrPC.Offset, false)); + + do + { + if (!StackWalk64(IMAGE_FILE_MACHINE_AMD64, GetCurrentProcess(), GetCurrentThread(), &sf, &ctx, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr)) + break; + + log << std::format(L"\n [{}]\t{}", frame_index++, to_address_string(sf.AddrPC.Offset, false)); + + } while (sf.AddrReturn.Offset != 0 && sf.AddrPC.Offset != sf.AddrReturn.Offset); + + log << L"\n}\n"; +} + +HRESULT CALLBACK TaskDialogCallbackProc(HWND hwnd, + UINT uNotification, + WPARAM wParam, + LPARAM lParam, + LONG_PTR dwRefData) +{ + HRESULT hr = S_OK; + + switch (uNotification) + { + case TDN_CREATED: + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + break; + } + + return hr; +} + LONG exception_handler(EXCEPTION_POINTERS* ex) { static std::recursive_mutex s_exception_handler_mutex; @@ -226,7 +262,8 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) if (!is_whitelist_exception(ex->ExceptionRecord->ExceptionCode)) return EXCEPTION_CONTINUE_SEARCH; - if (!is_ffxiv_address(ex->ContextRecord->Rip)) + if (!is_ffxiv_address(L"ffxiv_dx11.exe", ex->ContextRecord->Rip) && + !is_ffxiv_address(L"cimgui.dll", ex->ContextRecord->Rip)) return EXCEPTION_CONTINUE_SEARCH; // block any other exceptions hitting the veh while the messagebox is open @@ -248,6 +285,8 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) SymRefreshModuleList(GetCurrentProcess()); print_exception_info(ex, log); + auto window_log_str = log.str(); + print_exception_info_extended(ex, log); MINIDUMP_EXCEPTION_INFORMATION ex_info; ex_info.ClientPointers = false; @@ -257,9 +296,9 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) auto miniDumpType = MiniDumpWithDataSegs; if (g_veh_do_full_dump) miniDumpType = MiniDumpWithFullMemory; - + HANDLE file = CreateFileW(dmp_path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, miniDumpType, &ex_info, nullptr, nullptr); + //MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, miniDumpType, &ex_info, nullptr, nullptr); CloseHandle(file); std::wstring message; @@ -289,7 +328,58 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) logging::E(std::format(L"Trapped in VEH handler: {}", message)); // show in another thread to prevent messagebox from pumping messages of current thread - std::thread([&]() { MessageBoxW(nullptr, message.c_str(), L"Dalamud Error", MB_ICONERROR | MB_TOPMOST | MB_OK); }).join(); + std::thread([&]() + { + int nButtonPressed = 0; + TASKDIALOGCONFIG config = {0}; + const TASKDIALOG_BUTTON buttons[] = { + {IDOK, L"Disable all plugins"}, + {IDABORT, L"Open help page"}, + }; + config.cbSize = sizeof(config); + config.hInstance = g_hModule; + config.dwCommonButtons = TDCBF_CLOSE_BUTTON; + config.pszMainIcon = MAKEINTRESOURCE(IDI_ICON1); + //config.hMainIcon = dalamud_icon; + config.pszMainInstruction = L"An error occurred"; + config.pszContent = message.c_str(); + config.pButtons = buttons; + config.cButtons = ARRAYSIZE(buttons); + config.pszExpandedInformation = window_log_str.c_str(); + config.pszWindowTitle = L"Dalamud Error"; + config.nDefaultButton = IDCLOSE; + config.cxWidth = 300; + + // Can't do this, xiv stops pumping messages here + //config.hwndParent = FindWindowA("FFXIVGAME", NULL); + + config.pfCallback = TaskDialogCallbackProc; + + TaskDialogIndirect(&config, &nButtonPressed, NULL, NULL); + switch (nButtonPressed) + { + case IDOK: + TCHAR szPath[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szPath))) + { + auto appdata = std::filesystem::path(szPath); + auto safemode_file_path = ( appdata / "XIVLauncher" / ".dalamud_safemode" ); + + std::ofstream ofs(safemode_file_path); + ofs << "STAY SAFE!!!"; + ofs.close(); + } + + break; + case IDABORT: + ShellExecute(0, 0, L"https://goatcorp.github.io/faq/", 0, 0 , SW_SHOW ); + break; + case IDCANCEL: + break; + default: + break; + } + }).join(); return EXCEPTION_CONTINUE_SEARCH; } diff --git a/Dalamud.Boot/xivfixes.cpp b/Dalamud.Boot/xivfixes.cpp index 13315669c..338938fc1 100644 --- a/Dalamud.Boot/xivfixes.cpp +++ b/Dalamud.Boot/xivfixes.cpp @@ -497,6 +497,7 @@ void xivfixes::clr_failfast_hijack(bool bApply) { static const char* LogTag = "[xivfixes:clr_failfast_hijack]"; static std::optional> s_HookClrFatalError; + static std::optional> s_HookSetUnhandledExceptionFilter; if (bApply) { @@ -506,7 +507,8 @@ void xivfixes::clr_failfast_hijack(bool bApply) } s_HookClrFatalError.emplace("kernel32.dll!RaiseFailFastException (import, backup_userdata_save)", "kernel32.dll", "RaiseFailFastException", 0); - + s_HookSetUnhandledExceptionFilter.emplace("kernel32.dll!SetUnhandledExceptionFilter (lpTopLevelExceptionFilter)", "kernel32.dll", "SetUnhandledExceptionFilter", 0); + s_HookClrFatalError->set_detour([](PEXCEPTION_RECORD pExceptionRecord, _In_opt_ PCONTEXT pContextRecord, _In_ DWORD dwFlags) @@ -516,6 +518,12 @@ void xivfixes::clr_failfast_hijack(bool bApply) return s_HookClrFatalError->call_original(pExceptionRecord, pContextRecord, dwFlags); }); + s_HookSetUnhandledExceptionFilter->set_detour([](LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) -> LPTOP_LEVEL_EXCEPTION_FILTER + { + logging::I("{} SetUnhandledExceptionFilter", LogTag); + return nullptr; + }); + logging::I("{} Enable", LogTag); } else @@ -523,6 +531,7 @@ void xivfixes::clr_failfast_hijack(bool bApply) if (s_HookClrFatalError) { logging::I("{} Disable ClrFatalError", LogTag); s_HookClrFatalError.reset(); + s_HookSetUnhandledExceptionFilter.reset(); } } } diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index 7bd4cdbe9..88a240c65 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -322,7 +322,8 @@ namespace Dalamud.Injector startInfo.BootWaitMessageBox |= args.Contains("--msgbox1") ? 1 : 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox2") ? 2 : 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox3") ? 4 : 0; - startInfo.BootVehEnabled = args.Contains("--veh"); + // startInfo.BootVehEnabled = args.Contains("--veh"); + startInfo.BootVehEnabled = true; startInfo.BootVehFull = args.Contains("--veh-full"); startInfo.NoLoadPlugins = args.Contains("--no-plugin"); startInfo.NoLoadThirdPartyPlugins = args.Contains("--no-third-plugin"); diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index f0b5b884d..cfc934f36 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -81,12 +81,8 @@ namespace Dalamud stackTrace = "Fail: " + e.ToString(); } - var msg = "An error within the game has occurred.\n\n" - + "This may be caused by a faulty plugin, a broken TexTools modification, any other third-party tool or simply a bug in the game.\n" - + "Please try \"Start Over\" or \"Download Index Backup\" in TexTools, an integrity check in the XIVLauncher settings, and disabling plugins you don't need.\n\n" - + "The log file is located at:\n" - + "{1}\n\n" - + "Press OK to exit the application.\n\nStack trace:\n{2}"; + var msg = "This may be caused by a faulty plugin, a broken TexTools modification, any other third-party tool or simply a bug in the game.\n\n" + + "Please attempt an integrity check in the XIVLauncher settings, and disabling plugins you don't need."; try { diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 8f8a2a963..fc98709ee 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -69,6 +69,17 @@ internal partial class PluginManager : IDisposable, IServiceType this.devPluginDirectory.Create(); this.SafeMode = EnvironmentConfiguration.DalamudNoPlugins || this.configuration.PluginSafeMode || this.startInfo.NoLoadPlugins; + + try + { + var appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + this.SafeMode = this.SafeMode || File.Exists(Path.Combine(appdata, "XIVLauncher", ".dalamud_safemode")); + } + catch (Exception ex) + { + Log.Error(ex, "Couldn't check safe mode file"); + } + if (this.SafeMode) { this.configuration.PluginSafeMode = false;