diff --git a/Dalamud.Boot/DalamudStartInfo.cpp b/Dalamud.Boot/DalamudStartInfo.cpp index 985332966..52f201fea 100644 --- a/Dalamud.Boot/DalamudStartInfo.cpp +++ b/Dalamud.Boot/DalamudStartInfo.cpp @@ -123,6 +123,7 @@ void from_json(const nlohmann::json& json, DalamudStartInfo& config) { config.BootVehEnabled = json.value("BootVehEnabled", config.BootVehEnabled); config.BootVehFull = json.value("BootVehFull", config.BootVehFull); config.BootEnableEtw = json.value("BootEnableEtw", config.BootEnableEtw); + config.BootDisableLegacyCorruptedStateExceptions = json.value("BootDisableLegacyCorruptedStateExceptions", config.BootDisableLegacyCorruptedStateExceptions); config.BootDotnetOpenProcessHookMode = json.value("BootDotnetOpenProcessHookMode", config.BootDotnetOpenProcessHookMode); if (const auto it = json.find("BootEnabledGameFixes"); it != json.end() && it->is_array()) { config.BootEnabledGameFixes.clear(); @@ -148,6 +149,7 @@ void DalamudStartInfo::from_envvars() { BootVehEnabled = utils::get_env(L"DALAMUD_IS_VEH"); BootVehFull = utils::get_env(L"DALAMUD_IS_VEH_FULL"); BootEnableEtw = utils::get_env(L"DALAMUD_ENABLE_ETW"); + BootDisableLegacyCorruptedStateExceptions = utils::get_env(L"DALAMUD_DISABLE_LEGACY_CORRUPTED_STATE_EXCEPTIONS"); BootDotnetOpenProcessHookMode = static_cast(utils::get_env(L"DALAMUD_DOTNET_OPENPROCESS_HOOKMODE")); for (const auto& item : utils::get_env_list(L"DALAMUD_GAMEFIX_LIST")) BootEnabledGameFixes.insert(unicode::convert(item, &unicode::lower)); diff --git a/Dalamud.Boot/DalamudStartInfo.h b/Dalamud.Boot/DalamudStartInfo.h index cc31ba2c5..d5a6a6aec 100644 --- a/Dalamud.Boot/DalamudStartInfo.h +++ b/Dalamud.Boot/DalamudStartInfo.h @@ -17,7 +17,7 @@ struct DalamudStartInfo { DirectHook = 1, }; friend void from_json(const nlohmann::json&, DotNetOpenProcessHookMode&); - + enum class ClientLanguage : int { Japanese, English, @@ -61,6 +61,7 @@ struct DalamudStartInfo { bool BootVehEnabled = false; bool BootVehFull = false; bool BootEnableEtw = false; + bool BootDisableLegacyCorruptedStateExceptions = false; DotNetOpenProcessHookMode BootDotnetOpenProcessHookMode = DotNetOpenProcessHookMode::ImportHooks; std::set BootEnabledGameFixes{}; std::set BootUnhookDlls{}; diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp index 5c7c00b68..f608c626e 100644 --- a/Dalamud.Boot/dllmain.cpp +++ b/Dalamud.Boot/dllmain.cpp @@ -11,7 +11,7 @@ HINSTANCE g_hGameInstance = GetModuleHandleW(nullptr); HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { g_startInfo.from_envvars(); - + std::string jsonParseError; try { from_json(nlohmann::json::parse(std::string_view(static_cast(lpParam))), g_startInfo); @@ -21,7 +21,7 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { if (g_startInfo.BootShowConsole) ConsoleSetup(L"Dalamud Boot"); - + logging::update_dll_load_status(true); const auto logFilePath = unicode::convert(g_startInfo.BootLogPath); @@ -29,16 +29,16 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { auto attemptFallbackLog = false; if (logFilePath.empty()) { attemptFallbackLog = true; - + logging::I("No log file path given; not logging to file."); } else { try { logging::start_file_logging(logFilePath, !g_startInfo.BootShowConsole); logging::I("Logging to file: {}", logFilePath); - + } catch (const std::exception& e) { attemptFallbackLog = true; - + logging::E("Couldn't open log file: {}", logFilePath); logging::E("Error: {} / {}", errno, e.what()); } @@ -59,15 +59,15 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { SYSTEMTIME st; GetLocalTime(&st); logFilePath += std::format(L"Dalamud.Boot.{:04}{:02}{:02}.{:02}{:02}{:02}.{:03}.{}.log", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, GetCurrentProcessId()); - + try { logging::start_file_logging(logFilePath, !g_startInfo.BootShowConsole); logging::I("Logging to fallback log file: {}", logFilePath); - + } catch (const std::exception& e) { if (!g_startInfo.BootShowConsole && !g_startInfo.BootDisableFallbackConsole) ConsoleSetup(L"Dalamud Boot - Fallback Console"); - + logging::E("Couldn't open fallback log file: {}", logFilePath); logging::E("Error: {} / {}", errno, e.what()); } @@ -83,7 +83,7 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { } else { logging::E("Failed to initialize MinHook (status={}({}))", MH_StatusToString(mhStatus), static_cast(mhStatus)); } - + logging::I("Dalamud.Boot Injectable, (c) 2021 XIVLauncher Contributors"); logging::I("Built at: " __DATE__ "@" __TIME__); @@ -117,6 +117,7 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { const auto result = InitializeClrAndGetEntryPoint( g_hModule, g_startInfo.BootEnableEtw, + !g_startInfo.BootDisableLegacyCorruptedStateExceptions, runtimeconfig_path, module_path, L"Dalamud.EntryPoint, Dalamud", @@ -174,11 +175,11 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese case DLL_PROCESS_DETACH: // do not show debug message boxes on abort() here _set_abort_behavior(0, _WRITE_ABORT_MSG); - + // process is terminating; don't bother cleaning up if (lpReserved) return TRUE; - + logging::update_dll_load_status(false); xivfixes::apply_all(false); diff --git a/Dalamud.Common/DalamudStartInfo.cs b/Dalamud.Common/DalamudStartInfo.cs index c3cc33a12..ca81d1281 100644 --- a/Dalamud.Common/DalamudStartInfo.cs +++ b/Dalamud.Common/DalamudStartInfo.cs @@ -120,10 +120,15 @@ public record DalamudStartInfo public bool BootVehFull { get; set; } /// - /// Gets or sets a value indicating whether or not ETW should be enabled. + /// Gets or sets a value indicating whether ETW should be enabled. /// public bool BootEnableEtw { get; set; } + /// + /// Gets or sets a value indicating whether to enable legacy corrupted state exceptions. + /// + public bool BootDisableLegacyCorruptedStateExceptions { get; set; } + /// /// Gets or sets a value choosing the OpenProcess hookmode. /// diff --git a/Dalamud.Injector.Boot/main.cpp b/Dalamud.Injector.Boot/main.cpp index df4120009..50555a09a 100644 --- a/Dalamud.Injector.Boot/main.cpp +++ b/Dalamud.Injector.Boot/main.cpp @@ -27,6 +27,7 @@ int wmain(int argc, wchar_t** argv) const auto result = InitializeClrAndGetEntryPoint( GetModuleHandleW(nullptr), false, + false, runtimeconfig_path, module_path, L"Dalamud.Injector.EntryPoint, Dalamud.Injector", diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index 6507436c2..9e7033c4d 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -94,6 +94,7 @@ namespace Dalamud.Injector args.Remove("--msgbox2"); args.Remove("--msgbox3"); args.Remove("--etw"); + args.Remove("--no-legacy-corrupted-state-exceptions"); args.Remove("--veh"); args.Remove("--veh-full"); args.Remove("--no-plugin"); @@ -399,6 +400,7 @@ namespace Dalamud.Injector // Set boot defaults startInfo.BootShowConsole = args.Contains("--console"); startInfo.BootEnableEtw = args.Contains("--etw"); + startInfo.BootDisableLegacyCorruptedStateExceptions = args.Contains("--no-legacy-corrupted-state-exceptions"); startInfo.BootLogPath = GetLogPath(startInfo.LogPath, "dalamud.boot", startInfo.LogName); startInfo.BootEnabledGameFixes = new() { @@ -470,6 +472,7 @@ namespace Dalamud.Injector Console.WriteLine("Verbose logging:\t[-v]"); Console.WriteLine("Show Console:\t[--console] [--crash-handler-console]"); Console.WriteLine("Enable ETW:\t[--etw]"); + Console.WriteLine("Disable legacy corrupted state exceptions:\t[--no-legacy-corrupted-state-exceptions]"); Console.WriteLine("Enable VEH:\t[--veh], [--veh-full], [--unhandled-exception=default|stalldebug|none]"); Console.WriteLine("Show messagebox:\t[--msgbox1], [--msgbox2], [--msgbox3]"); Console.WriteLine("No plugins:\t[--no-plugin] [--no-3rd-plugin]"); diff --git a/lib/CoreCLR/boot.cpp b/lib/CoreCLR/boot.cpp index 54276aad1..723a1ed21 100644 --- a/lib/CoreCLR/boot.cpp +++ b/lib/CoreCLR/boot.cpp @@ -30,6 +30,7 @@ std::optional g_clr; HRESULT InitializeClrAndGetEntryPoint( void* calling_module, bool enable_etw, + bool enable_legacy_corrupted_state_exception_policy, std::wstring runtimeconfig_path, std::wstring module_path, std::wstring entrypoint_assembly_name, @@ -41,8 +42,13 @@ HRESULT InitializeClrAndGetEntryPoint( int result; SetEnvironmentVariable(L"DOTNET_MULTILEVEL_LOOKUP", L"0"); - SetEnvironmentVariable(L"COMPlus_legacyCorruptedStateExceptionsPolicy", L"1"); - SetEnvironmentVariable(L"DOTNET_legacyCorruptedStateExceptionsPolicy", L"1"); + + if (enable_legacy_corrupted_state_exception_policy) + { + SetEnvironmentVariable(L"COMPlus_legacyCorruptedStateExceptionsPolicy", L"1"); + SetEnvironmentVariable(L"DOTNET_legacyCorruptedStateExceptionsPolicy", L"1"); + } + SetEnvironmentVariable(L"COMPLUS_ForceENC", L"1"); SetEnvironmentVariable(L"DOTNET_ForceENC", L"1"); diff --git a/lib/CoreCLR/boot.h b/lib/CoreCLR/boot.h index 33bc58bbf..b227a3438 100644 --- a/lib/CoreCLR/boot.h +++ b/lib/CoreCLR/boot.h @@ -4,6 +4,7 @@ void ConsoleTeardown(); HRESULT InitializeClrAndGetEntryPoint( void* calling_module, bool enable_etw, + bool enable_legacy_corrupted_state_exception_policy, std::wstring runtimeconfig_path, std::wstring module_path, std::wstring entrypoint_assembly_name,