mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Print dotnet stack trace on veh error msgbox, and use precompiled headers.
This commit is contained in:
parent
2c99778eeb
commit
e64cc7e687
16 changed files with 298 additions and 170 deletions
|
|
@ -32,6 +32,8 @@
|
||||||
<IntDir>obj\$(Configuration)\</IntDir>
|
<IntDir>obj\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
|
@ -81,21 +83,38 @@
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\lib\CoreCLR\boot.cpp" />
|
<ClCompile Include="..\lib\CoreCLR\boot.cpp">
|
||||||
<ClCompile Include="..\lib\CoreCLR\CoreCLR.cpp" />
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||||
<ClCompile Include="..\lib\CoreCLR\pch.cpp" />
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||||
<ClCompile Include="dllmain.cpp" />
|
</ClCompile>
|
||||||
<ClCompile Include="rewrite_entrypoint.cpp" />
|
<ClCompile Include="..\lib\CoreCLR\CoreCLR.cpp">
|
||||||
<ClCompile Include="veh.cpp" />
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="dllmain.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="rewrite_entrypoint.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="veh.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\lib\CoreCLR\boot.h" />
|
<ClInclude Include="..\lib\CoreCLR\boot.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\CoreCLR.h" />
|
<ClInclude Include="..\lib\CoreCLR\CoreCLR.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\core\coreclr_delegates.h" />
|
<ClInclude Include="..\lib\CoreCLR\core\coreclr_delegates.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\core\hostfxr.h" />
|
<ClInclude Include="..\lib\CoreCLR\core\hostfxr.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\framework.h" />
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\nethost\nethost.h" />
|
<ClInclude Include="..\lib\CoreCLR\nethost\nethost.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="veh.h" />
|
<ClInclude Include="veh.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,59 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Library Files">
|
<Filter Include="Library Files">
|
||||||
<UniqueIdentifier>{18be40ac-9367-46ff-b848-4c528aa97a8d}</UniqueIdentifier>
|
<UniqueIdentifier>{18be40ac-9367-46ff-b848-4c528aa97a8d}</UniqueIdentifier>
|
||||||
<Extensions>lib</Extensions>
|
<Extensions>lib</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="CoreCLR">
|
||||||
|
<UniqueIdentifier>{dc468303-865e-43bd-908f-a3542c4bb669}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Dalamud.Boot DLL">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="dllmain.cpp">
|
<ClCompile Include="dllmain.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Dalamud.Boot DLL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\lib\CoreCLR\pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Dalamud.Boot DLL</Filter>
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\lib\CoreCLR\boot.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\lib\CoreCLR\CoreCLR.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="veh.cpp">
|
<ClCompile Include="veh.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Dalamud.Boot DLL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="rewrite_entrypoint.cpp">
|
<ClCompile Include="rewrite_entrypoint.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Dalamud.Boot DLL</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\lib\CoreCLR\CoreCLR.cpp">
|
||||||
|
<Filter>CoreCLR</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\lib\CoreCLR\boot.cpp">
|
||||||
|
<Filter>CoreCLR</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\lib\CoreCLR\core\coreclr_delegates.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\core\hostfxr.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\nethost\nethost.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\CoreCLR.h">
|
<ClInclude Include="..\lib\CoreCLR\CoreCLR.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>CoreCLR</Filter>
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\framework.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\pch.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\lib\CoreCLR\boot.h">
|
<ClInclude Include="..\lib\CoreCLR\boot.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>CoreCLR</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\lib\CoreCLR\core\coreclr_delegates.h">
|
||||||
|
<Filter>CoreCLR</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\lib\CoreCLR\core\hostfxr.h">
|
||||||
|
<Filter>CoreCLR</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\lib\CoreCLR\nethost\nethost.h">
|
||||||
|
<Filter>CoreCLR</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="veh.h">
|
<ClInclude Include="veh.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Dalamud.Boot DLL</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pch.h">
|
||||||
|
<Filter>Dalamud.Boot DLL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,5 @@
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#include "pch.h"
|
||||||
#define DllExport extern "C" __declspec(dllexport)
|
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <Windows.h>
|
|
||||||
#include "..\lib\CoreCLR\CoreCLR.h"
|
|
||||||
#include "..\lib\CoreCLR\boot.h"
|
|
||||||
#include "veh.h"
|
#include "veh.h"
|
||||||
|
|
||||||
HMODULE g_hModule;
|
HMODULE g_hModule;
|
||||||
|
|
@ -69,7 +64,7 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam)
|
||||||
std::wstring runtimeconfig_path = _wcsdup(fs_module_path.replace_filename(L"Dalamud.runtimeconfig.json").c_str());
|
std::wstring runtimeconfig_path = _wcsdup(fs_module_path.replace_filename(L"Dalamud.runtimeconfig.json").c_str());
|
||||||
std::wstring module_path = _wcsdup(fs_module_path.replace_filename(L"Dalamud.dll").c_str());
|
std::wstring module_path = _wcsdup(fs_module_path.replace_filename(L"Dalamud.dll").c_str());
|
||||||
|
|
||||||
// =========================================================================== //
|
// ============================== CLR ========================================= //
|
||||||
|
|
||||||
void* entrypoint_vfn;
|
void* entrypoint_vfn;
|
||||||
int result = InitializeClrAndGetEntryPoint(
|
int result = InitializeClrAndGetEntryPoint(
|
||||||
|
|
@ -86,10 +81,6 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam)
|
||||||
typedef void (CORECLR_DELEGATE_CALLTYPE* custom_component_entry_point_fn)(LPVOID);
|
typedef void (CORECLR_DELEGATE_CALLTYPE* custom_component_entry_point_fn)(LPVOID);
|
||||||
custom_component_entry_point_fn entrypoint_fn = reinterpret_cast<custom_component_entry_point_fn>(entrypoint_vfn);
|
custom_component_entry_point_fn entrypoint_fn = reinterpret_cast<custom_component_entry_point_fn>(entrypoint_vfn);
|
||||||
|
|
||||||
printf("Initializing Dalamud... ");
|
|
||||||
entrypoint_fn(lpParam);
|
|
||||||
printf("Done!\n");
|
|
||||||
|
|
||||||
// ============================== VEH ======================================== //
|
// ============================== VEH ======================================== //
|
||||||
|
|
||||||
printf("Initializing VEH... ");
|
printf("Initializing VEH... ");
|
||||||
|
|
@ -108,7 +99,11 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam)
|
||||||
printf("VEH was disabled manually\n");
|
printf("VEH was disabled manually\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================== //
|
// ============================== Dalamud ==================================== //
|
||||||
|
|
||||||
|
printf("Initializing Dalamud... ");
|
||||||
|
entrypoint_fn(lpParam);
|
||||||
|
printf("Done!\n");
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
fclose(stdin);
|
fclose(stdin);
|
||||||
|
|
|
||||||
41
Dalamud.Boot/pch.h
Normal file
41
Dalamud.Boot/pch.h
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
// pch.h: This is a precompiled header file.
|
||||||
|
// Files listed below are compiled only once, improving build performance for future builds.
|
||||||
|
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
||||||
|
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
||||||
|
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
||||||
|
|
||||||
|
#ifndef PCH_H
|
||||||
|
#define PCH_H
|
||||||
|
|
||||||
|
// Exclude rarely-used stuff from Windows headers
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
// Windows Header Files
|
||||||
|
#include <windows.h>
|
||||||
|
#include <DbgHelp.h>
|
||||||
|
#include <PathCch.h>
|
||||||
|
#include <Psapi.h>
|
||||||
|
#include <Shlobj.h>
|
||||||
|
#include <TlHelp32.h>
|
||||||
|
|
||||||
|
// C++ Standard Libraries
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <format>
|
||||||
|
#include <fstream>
|
||||||
|
#include <span>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
// https://github.com/dotnet/coreclr
|
||||||
|
#include "..\lib\CoreCLR\CoreCLR.h"
|
||||||
|
#include "..\lib\CoreCLR\boot.h"
|
||||||
|
|
||||||
|
// Commonly used macros
|
||||||
|
#define DllExport extern "C" __declspec(dllexport)
|
||||||
|
|
||||||
|
// Global variables
|
||||||
|
extern HMODULE g_hModule;
|
||||||
|
extern std::optional<CoreCLR> g_clr;
|
||||||
|
|
||||||
|
#endif //PCH_H
|
||||||
|
|
@ -1,15 +1,5 @@
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#include "pch.h"
|
||||||
#define DllExport extern "C" __declspec(dllexport)
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <span>
|
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <PathCch.h>
|
|
||||||
#include <Psapi.h>
|
|
||||||
|
|
||||||
extern HMODULE g_hModule;
|
|
||||||
DllExport DWORD WINAPI Initialize(LPVOID lpParam);
|
DllExport DWORD WINAPI Initialize(LPVOID lpParam);
|
||||||
|
|
||||||
struct RewrittenEntryPointParameters {
|
struct RewrittenEntryPointParameters {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#include "pch.h"
|
||||||
|
|
||||||
#include "veh.h"
|
#include "veh.h"
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <DbgHelp.h>
|
|
||||||
#include <format>
|
|
||||||
#include <string>
|
|
||||||
#include <TlHelp32.h>
|
|
||||||
|
|
||||||
bool is_whitelist_exception(const DWORD code)
|
bool is_whitelist_exception(const DWORD code)
|
||||||
{
|
{
|
||||||
|
|
@ -51,14 +45,16 @@ bool is_whitelist_exception(const DWORD code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool get_module_file_and_base(const DWORD64 address, DWORD64* module_base, std::filesystem::path& module_file)
|
bool get_module_file_and_base(const DWORD64 address, DWORD64& module_base, std::filesystem::path& module_file)
|
||||||
{
|
{
|
||||||
HMODULE handle;
|
HMODULE handle;
|
||||||
if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCSTR>(address), &handle))
|
if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCSTR>(address), &handle))
|
||||||
{
|
{
|
||||||
if (wchar_t path[1024]; GetModuleFileNameW(handle, path, sizeof path / 2) > 0)
|
std::wstring path(PATHCCH_MAX_CCH, L'\0');
|
||||||
|
path.resize(GetModuleFileNameW(handle, &path[0], static_cast<DWORD>(path.size())));
|
||||||
|
if (!path.empty())
|
||||||
{
|
{
|
||||||
*module_base = reinterpret_cast<DWORD64>(handle);
|
module_base = reinterpret_cast<DWORD64>(handle);
|
||||||
module_file = path;
|
module_file = path;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -70,22 +66,24 @@ 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 DWORD64 address)
|
||||||
{
|
{
|
||||||
DWORD64 module_base;
|
DWORD64 module_base;
|
||||||
if (std::filesystem::path module_path; get_module_file_and_base(address, &module_base, module_path))
|
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(), L"ffxiv_dx11.exe") == 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool get_sym_from_addr(const DWORD64 address, DWORD64* displacement, std::wstring& symbol_name)
|
bool get_sym_from_addr(const DWORD64 address, DWORD64& displacement, std::wstring& symbol_name)
|
||||||
{
|
{
|
||||||
char buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(wchar_t)];
|
union {
|
||||||
auto symbol = reinterpret_cast<PSYMBOL_INFOW>(buffer);
|
char buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(wchar_t)]{};
|
||||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
SYMBOL_INFOW symbol;
|
||||||
symbol->MaxNameLen = MAX_SYM_NAME;
|
};
|
||||||
|
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
symbol.MaxNameLen = MAX_SYM_NAME;
|
||||||
|
|
||||||
if (SymFromAddrW(GetCurrentProcess(), address, displacement, symbol))
|
if (SymFromAddrW(GetCurrentProcess(), address, &displacement, &symbol) && symbol.Name[0])
|
||||||
{
|
{
|
||||||
symbol_name.assign(_wcsdup(symbol->Name));
|
symbol_name = symbol.Name;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -96,7 +94,7 @@ std::wstring to_address_string(const DWORD64 address, const bool try_ptrderef =
|
||||||
{
|
{
|
||||||
DWORD64 module_base;
|
DWORD64 module_base;
|
||||||
std::filesystem::path module_path;
|
std::filesystem::path module_path;
|
||||||
bool is_mod_addr = get_module_file_and_base(address, &module_base, module_path);
|
bool is_mod_addr = get_module_file_and_base(address, module_base, module_path);
|
||||||
|
|
||||||
DWORD64 value = 0;
|
DWORD64 value = 0;
|
||||||
if(try_ptrderef && address > 0x10000 && address < 0x7FFFFFFE0000)
|
if(try_ptrderef && address > 0x10000 && address < 0x7FFFFFFE0000)
|
||||||
|
|
@ -109,14 +107,32 @@ std::wstring to_address_string(const DWORD64 address, const bool try_ptrderef =
|
||||||
std::format(L"{:X}", address);
|
std::format(L"{:X}", address);
|
||||||
|
|
||||||
DWORD64 displacement;
|
DWORD64 displacement;
|
||||||
if (std::wstring symbol; get_sym_from_addr(address, &displacement, symbol))
|
if (std::wstring symbol; get_sym_from_addr(address, displacement, symbol))
|
||||||
return std::format(L"{}\t({})", addr_str, displacement != 0 ? std::format(L"{}+0x{:X}", symbol, displacement) : std::format(L"{}", symbol));
|
return std::format(L"{}\t({})", addr_str, displacement != 0 ? std::format(L"{}+0x{:X}", symbol, displacement) : std::format(L"{}", symbol));
|
||||||
return value != 0 ? std::format(L"{} [{}]", addr_str, to_address_string(value, false)) : addr_str;
|
return value != 0 ? std::format(L"{} [{}]", addr_str, to_address_string(value, false)) : addr_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void print_exception_info(const EXCEPTION_POINTERS* ex, std::wofstream& log)
|
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<size_t>(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{";
|
log << L"\nCall Stack\n{";
|
||||||
|
|
||||||
STACKFRAME64 sf;
|
STACKFRAME64 sf;
|
||||||
|
|
@ -140,7 +156,7 @@ void print_exception_info(const EXCEPTION_POINTERS* ex, std::wofstream& log)
|
||||||
|
|
||||||
} while (sf.AddrReturn.Offset != 0 && sf.AddrPC.Offset != sf.AddrReturn.Offset);
|
} while (sf.AddrReturn.Offset != 0 && sf.AddrPC.Offset != sf.AddrReturn.Offset);
|
||||||
|
|
||||||
log << L"\n}" << std::endl;
|
log << L"\n}\n";
|
||||||
|
|
||||||
ctx = *ex->ContextRecord;
|
ctx = *ex->ContextRecord;
|
||||||
|
|
||||||
|
|
@ -167,15 +183,15 @@ void print_exception_info(const EXCEPTION_POINTERS* ex, std::wofstream& log)
|
||||||
|
|
||||||
log << L"\n}" << std::endl;
|
log << L"\n}" << std::endl;
|
||||||
|
|
||||||
if(ctx.Rsp <= 0x10000 || ctx.Rsp >= 0x7FFFFFFE0000)
|
if(0x10000 < ctx.Rsp && ctx.Rsp < 0x7FFFFFFE0000)
|
||||||
return;
|
{
|
||||||
|
|
||||||
log << L"\nStack\n{";
|
log << L"\nStack\n{";
|
||||||
|
|
||||||
for(DWORD64 i = 0; i < 16; i++)
|
for(DWORD64 i = 0; i < 16; i++)
|
||||||
log << std::format(L"\n [RSP+{:X}]\t{}", i * 8, to_address_string(*reinterpret_cast<DWORD64*>(ctx.Rsp + i * 8ull)));
|
log << std::format(L"\n [RSP+{:X}]\t{}", i * 8, to_address_string(*reinterpret_cast<DWORD64*>(ctx.Rsp + i * 8ull)));
|
||||||
|
|
||||||
log << L"\n}" << std::endl;
|
log << L"\n}\n";
|
||||||
|
}
|
||||||
|
|
||||||
log << L"\nModules\n{";
|
log << L"\nModules\n{";
|
||||||
|
|
||||||
|
|
@ -194,17 +210,12 @@ void print_exception_info(const EXCEPTION_POINTERS* ex, std::wofstream& log)
|
||||||
CloseHandle(snap);
|
CloseHandle(snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
log << L"\n}" << std::endl;
|
log << L"\n}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool g_veh_message_open;
|
|
||||||
|
|
||||||
LONG exception_handler(EXCEPTION_POINTERS* ex)
|
LONG exception_handler(EXCEPTION_POINTERS* ex)
|
||||||
{
|
{
|
||||||
//block any further exceptions while the message box is open
|
static std::mutex s_exception_handler_mutex;
|
||||||
if (g_veh_message_open)
|
|
||||||
for (;;) Sleep(1);
|
|
||||||
|
|
||||||
if (!is_whitelist_exception(ex->ExceptionRecord->ExceptionCode))
|
if (!is_whitelist_exception(ex->ExceptionRecord->ExceptionCode))
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
|
@ -212,20 +223,21 @@ LONG exception_handler(EXCEPTION_POINTERS* ex)
|
||||||
if (!is_ffxiv_address(ex->ContextRecord->Rip))
|
if (!is_ffxiv_address(ex->ContextRecord->Rip))
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
|
||||||
|
// block any other exceptions hitting the veh while the messagebox is open
|
||||||
|
const auto lock = std::lock_guard(s_exception_handler_mutex);
|
||||||
|
|
||||||
DWORD64 module_base;
|
DWORD64 module_base;
|
||||||
std::filesystem::path module_path;
|
std::filesystem::path module_path;
|
||||||
|
|
||||||
get_module_file_and_base(reinterpret_cast<DWORD64>(&exception_handler), &module_base, module_path);
|
get_module_file_and_base(reinterpret_cast<DWORD64>(&exception_handler), module_base, module_path);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::wstring dmp_path = _wcsdup(module_path.replace_filename(L"dalamud_appcrashd.dmp").wstring().c_str());
|
std::wstring dmp_path = module_path.replace_filename(L"dalamud_appcrashd.dmp").wstring();
|
||||||
#else
|
#else
|
||||||
std::wstring dmp_path = _wcsdup(module_path.replace_filename(L"dalamud_appcrash.dmp").wstring().c_str());
|
std::wstring dmp_path = module_path.replace_filename(L"dalamud_appcrash.dmp").wstring();
|
||||||
#endif
|
#endif
|
||||||
std::wstring log_path = _wcsdup(module_path.replace_filename(L"dalamud_appcrash.log").wstring().c_str());
|
std::wstring log_path = module_path.replace_filename(L"dalamud_appcrash.log").wstring();
|
||||||
|
|
||||||
std::wofstream log;
|
|
||||||
log.open(log_path, std::ios::trunc);
|
|
||||||
|
|
||||||
|
std::wostringstream log;
|
||||||
log << std::format(L"Unhandled native exception occurred at {}", to_address_string(ex->ContextRecord->Rip, false)) << std::endl;
|
log << std::format(L"Unhandled native exception occurred at {}", to_address_string(ex->ContextRecord->Rip, false)) << std::endl;
|
||||||
log << std::format(L"Code: {:X}", ex->ExceptionRecord->ExceptionCode) << std::endl;
|
log << std::format(L"Code: {:X}", ex->ExceptionRecord->ExceptionCode) << std::endl;
|
||||||
log << std::format(L"Dump at: {}", dmp_path) << std::endl;
|
log << std::format(L"Dump at: {}", dmp_path) << std::endl;
|
||||||
|
|
@ -234,8 +246,6 @@ LONG exception_handler(EXCEPTION_POINTERS* ex)
|
||||||
SymRefreshModuleList(GetCurrentProcess());
|
SymRefreshModuleList(GetCurrentProcess());
|
||||||
print_exception_info(ex, log);
|
print_exception_info(ex, log);
|
||||||
|
|
||||||
log.close();
|
|
||||||
|
|
||||||
MINIDUMP_EXCEPTION_INFORMATION ex_info;
|
MINIDUMP_EXCEPTION_INFORMATION ex_info;
|
||||||
ex_info.ClientPointers = false;
|
ex_info.ClientPointers = false;
|
||||||
ex_info.ExceptionPointers = ex;
|
ex_info.ExceptionPointers = ex;
|
||||||
|
|
@ -245,31 +255,42 @@ LONG exception_handler(EXCEPTION_POINTERS* ex)
|
||||||
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpWithDataSegs, &ex_info, nullptr, nullptr);
|
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpWithDataSegs, &ex_info, nullptr, nullptr);
|
||||||
CloseHandle(file);
|
CloseHandle(file);
|
||||||
|
|
||||||
auto msg = L"An error within the game has occurred.\n\n"
|
void* fn;
|
||||||
|
if (const auto err = static_cast<DWORD>(g_clr->get_function_pointer(
|
||||||
|
L"Dalamud.EntryPoint, Dalamud",
|
||||||
|
L"VehCallback",
|
||||||
|
L"Dalamud.EntryPoint+VehDelegate, Dalamud",
|
||||||
|
nullptr, nullptr, &fn)))
|
||||||
|
{
|
||||||
|
const auto msg = L"An error within the game has occurred.\n\n"
|
||||||
L"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"
|
L"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"
|
||||||
L"Please try \"Start Over\" in TexTools, an integrity check in the XIVLauncher settings and disabling plugins you don't need.\n\n"
|
L"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"
|
||||||
L"The log file is located at:\n"
|
L"The log file is located at:\n"
|
||||||
L"{1}\n\n"
|
L"{1}\n\n"
|
||||||
L"Press OK to exit the application.";
|
L"Press OK to exit the application.\n\nFailed to read stack trace: {2:08x}";
|
||||||
|
|
||||||
auto formatted = std::format(msg, dmp_path, log_path);
|
// show in another thread to prevent messagebox from pumping messages of current thread
|
||||||
|
std::thread([&]() {
|
||||||
// block any other exceptions hitting the veh while the messagebox is open
|
MessageBoxW(nullptr, std::format(msg, dmp_path, log_path, err).c_str(), L"Dalamud Error", MB_OK | MB_ICONERROR | MB_TOPMOST);
|
||||||
g_veh_message_open = true;
|
}).join();
|
||||||
MessageBoxW(nullptr, formatted.c_str(), L"Dalamud Error", MB_OK | MB_ICONERROR | MB_TOPMOST);
|
}
|
||||||
g_veh_message_open = false;
|
else
|
||||||
|
{
|
||||||
|
((void(__stdcall*)(const void*, const void*, const void*))fn)(dmp_path.c_str(), log_path.c_str(), log.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PVOID g_veh_handle;
|
PVOID g_veh_handle = nullptr;
|
||||||
|
|
||||||
bool veh::add_handler()
|
bool veh::add_handler()
|
||||||
{
|
{
|
||||||
if (g_veh_handle)
|
if (g_veh_handle)
|
||||||
return false;
|
return false;
|
||||||
g_veh_handle = AddVectoredExceptionHandler(0, exception_handler);
|
g_veh_handle = AddVectoredExceptionHandler(1, exception_handler);
|
||||||
|
SetUnhandledExceptionFilter(nullptr);
|
||||||
return g_veh_handle != nullptr;
|
return g_veh_handle != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,15 +90,12 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\lib\CoreCLR\boot.cpp" />
|
<ClCompile Include="..\lib\CoreCLR\boot.cpp" />
|
||||||
<ClCompile Include="..\lib\CoreCLR\CoreCLR.cpp" />
|
<ClCompile Include="..\lib\CoreCLR\CoreCLR.cpp" />
|
||||||
<ClCompile Include="..\lib\CoreCLR\pch.cpp" />
|
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\lib\CoreCLR\boot.h" />
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\CoreCLR.h" />
|
<ClInclude Include="..\lib\CoreCLR\CoreCLR.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\core\coreclr_delegates.h" />
|
<ClInclude Include="..\lib\CoreCLR\core\coreclr_delegates.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\core\hostfxr.h" />
|
<ClInclude Include="..\lib\CoreCLR\core\hostfxr.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\framework.h" />
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\nethost\nethost.h" />
|
<ClInclude Include="..\lib\CoreCLR\nethost\nethost.h" />
|
||||||
<ClInclude Include="..\lib\CoreCLR\pch.h" />
|
<ClInclude Include="..\lib\CoreCLR\pch.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\lib\CoreCLR\pch.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\lib\CoreCLR\boot.cpp">
|
<ClCompile Include="..\lib\CoreCLR\boot.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
@ -42,15 +39,9 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\lib\CoreCLR\framework.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\pch.h">
|
<ClInclude Include="..\lib\CoreCLR\pch.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\lib\CoreCLR\boot.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\lib\CoreCLR\CoreCLR.h">
|
<ClInclude Include="..\lib\CoreCLR\CoreCLR.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,14 @@ namespace Dalamud
|
||||||
/// <param name="infoPtr">Pointer to a serialized <see cref="DalamudStartInfo"/> data.</param>
|
/// <param name="infoPtr">Pointer to a serialized <see cref="DalamudStartInfo"/> data.</param>
|
||||||
public delegate void InitDelegate(IntPtr infoPtr);
|
public delegate void InitDelegate(IntPtr infoPtr);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate used from VEH handler on exception which CoreCLR will fast fail by default.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dumpPath">Path to minidump file created in UTF-16.</param>
|
||||||
|
/// <param name="logPath">Path to log file to create in UTF-16.</param>
|
||||||
|
/// <param name="log">Log text in UTF-16.</param>
|
||||||
|
public delegate void VehDelegate(IntPtr dumpPath, IntPtr logPath, IntPtr log);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize Dalamud.
|
/// Initialize Dalamud.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -46,6 +54,57 @@ namespace Dalamud
|
||||||
new Thread(() => RunThread(info)).Start();
|
new Thread(() => RunThread(info)).Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Show error message along with stack trace and exit.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dumpPath">Path to minidump file created in UTF-16.</param>
|
||||||
|
/// <param name="logPath">Path to log file to create in UTF-16.</param>
|
||||||
|
/// <param name="log">Log text in UTF-16.</param>
|
||||||
|
public static void VehCallback(IntPtr dumpPath, IntPtr logPath, IntPtr log)
|
||||||
|
{
|
||||||
|
string stackTrace;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stackTrace = Environment.StackTrace;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
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}";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(
|
||||||
|
Marshal.PtrToStringUni(logPath),
|
||||||
|
"Stack trace:\n" + stackTrace + "\n\n" + Marshal.PtrToStringUni(log));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
msg += "\n\nAdditionally, failed to write file: " + e.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show in another thread to prevent messagebox from pumping messages of current thread.
|
||||||
|
var msgThread = new Thread(() =>
|
||||||
|
{
|
||||||
|
Utility.Util.Fatal(
|
||||||
|
msg.Format(
|
||||||
|
Marshal.PtrToStringUni(dumpPath),
|
||||||
|
Marshal.PtrToStringUni(logPath),
|
||||||
|
stackTrace),
|
||||||
|
"Dalamud Error",
|
||||||
|
false);
|
||||||
|
});
|
||||||
|
msgThread.Start();
|
||||||
|
msgThread.Join();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize all Dalamud subsystems and start running on the main thread.
|
/// Initialize all Dalamud subsystems and start running on the main thread.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -326,11 +326,13 @@ namespace Dalamud.Utility
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">MessageBox body.</param>
|
/// <param name="message">MessageBox body.</param>
|
||||||
/// <param name="caption">MessageBox caption (title).</param>
|
/// <param name="caption">MessageBox caption (title).</param>
|
||||||
public static void Fatal(string message, string caption)
|
/// <param name="exit">Specify whether to exit immediately.</param>
|
||||||
|
public static void Fatal(string message, string caption, bool exit = true)
|
||||||
{
|
{
|
||||||
var flags = NativeFunctions.MessageBoxType.Ok | NativeFunctions.MessageBoxType.IconError;
|
var flags = NativeFunctions.MessageBoxType.Ok | NativeFunctions.MessageBoxType.IconError | NativeFunctions.MessageBoxType.Topmost;
|
||||||
_ = NativeFunctions.MessageBoxW(Process.GetCurrentProcess().MainWindowHandle, message, caption, flags);
|
_ = NativeFunctions.MessageBoxW(Process.GetCurrentProcess().MainWindowHandle, message, caption, flags);
|
||||||
|
|
||||||
|
if (exit)
|
||||||
Environment.Exit(-1);
|
Environment.Exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,17 @@ bool CoreCLR::load_runtime(const std::wstring& runtime_config_path, const struct
|
||||||
hdt_load_assembly_and_get_function_pointer,
|
hdt_load_assembly_and_get_function_pointer,
|
||||||
reinterpret_cast<void**>(&m_load_assembly_and_get_function_pointer_fptr));
|
reinterpret_cast<void**>(&m_load_assembly_and_get_function_pointer_fptr));
|
||||||
|
|
||||||
if (result != 0 || m_load_assembly_and_get_function_pointer_fptr == nullptr)
|
if (result != 0 || m_load_assembly_and_get_function_pointer_fptr == nullptr) {
|
||||||
|
m_hostfxr_close_fptr(context);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = m_hostfxr_get_runtime_delegate_fptr(
|
||||||
|
context,
|
||||||
|
hdt_get_function_pointer,
|
||||||
|
reinterpret_cast<void**>(&m_get_function_pointer_fptr));
|
||||||
|
|
||||||
|
if (result != 0 || m_get_function_pointer_fptr == nullptr)
|
||||||
{
|
{
|
||||||
m_hostfxr_close_fptr(context);
|
m_hostfxr_close_fptr(context);
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -99,6 +109,22 @@ int CoreCLR::load_assembly_and_get_function_pointer(
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int CoreCLR::get_function_pointer(
|
||||||
|
const wchar_t* type_name,
|
||||||
|
const wchar_t* method_name,
|
||||||
|
const wchar_t* delegate_type_name,
|
||||||
|
void* load_context,
|
||||||
|
void* reserved,
|
||||||
|
void** delegate) const
|
||||||
|
{
|
||||||
|
int result = m_get_function_pointer_fptr(type_name, method_name, delegate_type_name, load_context, reserved, delegate);
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
delegate = nullptr;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* Helpers */
|
/* Helpers */
|
||||||
uint64_t CoreCLR::load_library(const wchar_t* path)
|
uint64_t CoreCLR::load_library(const wchar_t* path)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,20 @@ class CoreCLR {
|
||||||
const wchar_t* delegate_type_name,
|
const wchar_t* delegate_type_name,
|
||||||
void* reserved,
|
void* reserved,
|
||||||
void** delegate) const;
|
void** delegate) const;
|
||||||
|
int get_function_pointer(
|
||||||
|
const wchar_t* type_name,
|
||||||
|
const wchar_t* method_name,
|
||||||
|
const wchar_t* delegate_type_name,
|
||||||
|
void* load_context,
|
||||||
|
void* reserved,
|
||||||
|
void** delegate) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* HostFXR delegates. */
|
/* HostFXR delegates. */
|
||||||
hostfxr_initialize_for_runtime_config_fn m_hostfxr_initialize_for_runtime_config_fptr{};
|
hostfxr_initialize_for_runtime_config_fn m_hostfxr_initialize_for_runtime_config_fptr{};
|
||||||
hostfxr_get_runtime_delegate_fn m_hostfxr_get_runtime_delegate_fptr{};
|
hostfxr_get_runtime_delegate_fn m_hostfxr_get_runtime_delegate_fptr{};
|
||||||
hostfxr_close_fn m_hostfxr_close_fptr{};
|
hostfxr_close_fn m_hostfxr_close_fptr{};
|
||||||
|
get_function_pointer_fn m_get_function_pointer_fptr = nullptr;
|
||||||
load_assembly_and_get_function_pointer_fn m_load_assembly_and_get_function_pointer_fptr = nullptr;
|
load_assembly_and_get_function_pointer_fn m_load_assembly_and_get_function_pointer_fptr = nullptr;
|
||||||
|
|
||||||
/* Helper functions. */
|
/* Helper functions. */
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ void ConsoleTeardown()
|
||||||
FreeConsole();
|
FreeConsole();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<CoreCLR> g_clr;
|
||||||
|
|
||||||
int InitializeClrAndGetEntryPoint(
|
int InitializeClrAndGetEntryPoint(
|
||||||
std::wstring runtimeconfig_path,
|
std::wstring runtimeconfig_path,
|
||||||
std::wstring module_path,
|
std::wstring module_path,
|
||||||
|
|
@ -31,8 +33,9 @@ int InitializeClrAndGetEntryPoint(
|
||||||
std::wstring entrypoint_delegate_type_name,
|
std::wstring entrypoint_delegate_type_name,
|
||||||
void** entrypoint_fn)
|
void** entrypoint_fn)
|
||||||
{
|
{
|
||||||
|
g_clr = CoreCLR();
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
CoreCLR clr;
|
|
||||||
SetEnvironmentVariable(L"DOTNET_MULTILEVEL_LOOKUP", L"0");
|
SetEnvironmentVariable(L"DOTNET_MULTILEVEL_LOOKUP", L"0");
|
||||||
//SetEnvironmentVariable(L"COMPlus_legacyCorruptedStateExceptionsPolicy", L"1");
|
//SetEnvironmentVariable(L"COMPlus_legacyCorruptedStateExceptionsPolicy", L"1");
|
||||||
SetEnvironmentVariable(L"DOTNET_legacyCorruptedStateExceptionsPolicy", L"1");
|
SetEnvironmentVariable(L"DOTNET_legacyCorruptedStateExceptionsPolicy", L"1");
|
||||||
|
|
@ -85,7 +88,7 @@ int InitializeClrAndGetEntryPoint(
|
||||||
};
|
};
|
||||||
|
|
||||||
printf("Loading hostfxr... ");
|
printf("Loading hostfxr... ");
|
||||||
if ((result = clr.load_hostfxr(&init_parameters)) != 0)
|
if ((result = g_clr->load_hostfxr(&init_parameters)) != 0)
|
||||||
{
|
{
|
||||||
printf("\nError: Failed to load the `hostfxr` library (err=%d)\n", result);
|
printf("\nError: Failed to load the `hostfxr` library (err=%d)\n", result);
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -102,7 +105,7 @@ int InitializeClrAndGetEntryPoint(
|
||||||
};
|
};
|
||||||
|
|
||||||
printf("Loading coreclr... ");;
|
printf("Loading coreclr... ");;
|
||||||
if ((result = clr.load_runtime(runtimeconfig_path, &runtime_parameters)) != 0)
|
if ((result = g_clr->load_runtime(runtimeconfig_path, &runtime_parameters)) != 0)
|
||||||
{
|
{
|
||||||
printf("\nError: Failed to load coreclr (err=%d)\n", result);
|
printf("\nError: Failed to load coreclr (err=%d)\n", result);
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -112,7 +115,7 @@ int InitializeClrAndGetEntryPoint(
|
||||||
// =========================================================================== //
|
// =========================================================================== //
|
||||||
|
|
||||||
printf("Loading module... ");
|
printf("Loading module... ");
|
||||||
if ((result = clr.load_assembly_and_get_function_pointer(
|
if ((result = g_clr->load_assembly_and_get_function_pointer(
|
||||||
module_path.c_str(),
|
module_path.c_str(),
|
||||||
entrypoint_assembly_name.c_str(),
|
entrypoint_assembly_name.c_str(),
|
||||||
entrypoint_method_name.c_str(),
|
entrypoint_method_name.c_str(),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Exclude rarely-used stuff from Windows headers
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
|
|
||||||
// Windows Header Files
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
// pch.h: This is a precompiled header file.
|
|
||||||
// Files listed below are compiled only once, improving build performance for future builds.
|
|
||||||
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
|
||||||
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
|
||||||
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
|
||||||
|
|
||||||
#ifndef PCH_H
|
|
||||||
#define PCH_H
|
|
||||||
|
|
||||||
// add headers that you want to pre-compile here
|
|
||||||
#include "framework.h"
|
|
||||||
|
|
||||||
#endif //PCH_H
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue