diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj b/Dalamud.Boot/Dalamud.Boot.vcxproj index 5955eac56..0629d4466 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj @@ -117,10 +117,6 @@ - - - - diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters index 0106f0589..ad673c2d4 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters @@ -1,10 +1,6 @@  - - {18be40ac-9367-46ff-b848-4c528aa97a8d} - lib - {dc468303-865e-43bd-908f-a3542c4bb669} @@ -56,12 +52,4 @@ Dalamud.Boot DLL - - - Library Files - - - Library Files - - \ No newline at end of file diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp index fec175972..cb2fa9226 100644 --- a/Dalamud.Boot/dllmain.cpp +++ b/Dalamud.Boot/dllmain.cpp @@ -68,6 +68,7 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam) void* entrypoint_vfn; int result = InitializeClrAndGetEntryPoint( + g_hModule, runtimeconfig_path, module_path, L"Dalamud.EntryPoint, Dalamud", diff --git a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj index 93dfa1cfa..ecd572daf 100644 --- a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj +++ b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj @@ -99,10 +99,6 @@ - - - - diff --git a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj.filters b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj.filters index 45bf1b970..75b1bf84e 100644 --- a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj.filters +++ b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj.filters @@ -13,9 +13,6 @@ {4faac519-3a73-4b2b-96e7-fb597f02c0be} ico;rc - - {6aff1bed-6979-4bc9-94e8-ddafb626e6bf} - @@ -55,12 +52,4 @@ Header Files - - - Library Files - - - Library Files - - \ No newline at end of file diff --git a/Dalamud.Injector.Boot/main.cpp b/Dalamud.Injector.Boot/main.cpp index f3f6980e6..cf5a95b5c 100644 --- a/Dalamud.Injector.Boot/main.cpp +++ b/Dalamud.Injector.Boot/main.cpp @@ -21,6 +21,7 @@ int wmain(int argc, wchar_t** argv) void* entrypoint_vfn; int result = InitializeClrAndGetEntryPoint( + GetModuleHandleW(nullptr), runtimeconfig_path, module_path, L"Dalamud.Injector.EntryPoint, Dalamud.Injector", diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index 8d7ba75b2..933edec26 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -634,17 +634,13 @@ namespace Dalamud.Injector private static void Inject(Process process, DalamudStartInfo startInfo) { - var nethostName = "nethost.dll"; var bootName = "Dalamud.Boot.dll"; - - var nethostPath = Path.GetFullPath(nethostName); var bootPath = Path.GetFullPath(bootName); // ====================================================== - using var injector = new Injector(process); + using var injector = new Injector(process, false); - injector.LoadLibrary(nethostPath, out _); injector.LoadLibrary(bootPath, out var bootModule); // ====================================================== diff --git a/Dalamud.Injector/Injector.cs b/Dalamud.Injector/Injector.cs index d8a622518..e5664388e 100644 --- a/Dalamud.Injector/Injector.cs +++ b/Dalamud.Injector/Injector.cs @@ -27,6 +27,7 @@ namespace Dalamud.Injector internal sealed class Injector : IDisposable { private readonly Process targetProcess; + private readonly bool disposeTargetProcess; private readonly ExternalMemory extMemory; private readonly CircularBuffer circularBuffer; private readonly PrivateMemoryBuffer memoryBuffer; @@ -41,9 +42,11 @@ namespace Dalamud.Injector /// Initializes a new instance of the class. /// /// Process to inject. - public Injector(Process targetProcess) + /// Dispose given process on disposing self. + public Injector(Process targetProcess, bool disposeTargetProcess = true) { this.targetProcess = targetProcess; + this.disposeTargetProcess = disposeTargetProcess; this.extMemory = new ExternalMemory(targetProcess); this.circularBuffer = new CircularBuffer(4096, this.extMemory); @@ -67,7 +70,8 @@ namespace Dalamud.Injector { GC.SuppressFinalize(this); - this.targetProcess?.Dispose(); + if (this.disposeTargetProcess) + this.targetProcess?.Dispose(); this.circularBuffer?.Dispose(); this.memoryBuffer?.Dispose(); } @@ -85,14 +89,9 @@ namespace Dalamud.Injector throw new Exception("Unable to allocate LoadLibraryW parameter"); this.CallRemoteFunction(this.loadLibraryShellPtr, lpParameter, out var err); - - if (err != 0) - throw new Exception($"LoadLibraryW(\"{modulePath}\") failure: {new Win32Exception((int)err).Message} ({err})"); - address = this.extMemory.Read(this.loadLibraryRetPtr); - if (address == IntPtr.Zero) - throw new Exception($"LoadLibraryW(\"{modulePath}\") failure: Error code unavailable"); + throw new Exception($"LoadLibraryW(\"{modulePath}\") failure: {new Win32Exception((int)err).Message} ({err})"); } /// @@ -110,12 +109,9 @@ namespace Dalamud.Injector throw new Exception("Unable to allocate GetProcAddress parameter ptr"); this.CallRemoteFunction(this.getProcAddressShellPtr, lpParameter, out var err); - if (err != 0) - throw new Exception($"GetProcAddress(0x{module:X}, \"{functionName}\") failure: {new Win32Exception((int)err).Message} ({err})"); - - this.extMemory.Read(this.getProcAddressRetPtr, out address); + address = this.extMemory.Read(this.getProcAddressRetPtr); if (address == IntPtr.Zero) - throw new Exception($"GetProcAddress(0x{module:X}, \"{functionName}\") failure: Error code unavailable"); + throw new Exception($"GetProcAddress(0x{module:X}, \"{functionName}\") failure: {new Win32Exception((int)err).Message} ({err})"); } /// diff --git a/lib/CoreCLR/CoreCLR.cpp b/lib/CoreCLR/CoreCLR.cpp index 265f1869e..53288f94f 100644 --- a/lib/CoreCLR/CoreCLR.cpp +++ b/lib/CoreCLR/CoreCLR.cpp @@ -2,12 +2,14 @@ #include "CoreCLR.h" #include +#include #include #include "nethost/nethost.h" -#pragma comment(lib, "nethost/libnethost.lib") - -CoreCLR::CoreCLR() {} +CoreCLR::CoreCLR(void* calling_module) + : m_calling_module(calling_module) +{ +} /* Core public functions */ int CoreCLR::load_hostfxr() @@ -18,19 +20,43 @@ int CoreCLR::load_hostfxr() int CoreCLR::load_hostfxr(const struct get_hostfxr_parameters* parameters) { // Get the path to CoreCLR's hostfxr + std::wstring calling_module_path(MAX_PATH, L'\0'); + + do + { + calling_module_path.resize(GetModuleFileNameW(static_cast(m_calling_module), &calling_module_path[0], static_cast(calling_module_path.size()))); + } + while (!calling_module_path.empty() && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + if (calling_module_path.empty()) + return -1; + + calling_module_path = (std::filesystem::path(calling_module_path).parent_path() / L"nethost.dll").wstring(); + + auto lib_nethost = reinterpret_cast(load_library(calling_module_path.c_str())); + if (!lib_nethost) + return -1; + + auto get_hostfxr_path = reinterpret_cast( + get_export(lib_nethost, "get_hostfxr_path")); + if (!get_hostfxr_path) + return -1; + wchar_t buffer[MAX_PATH]{}; size_t buffer_size = sizeof buffer / sizeof(wchar_t); if (int rc = get_hostfxr_path(buffer, &buffer_size, parameters); rc != 0) return rc; // Load hostfxr and get desired exports - auto lib = reinterpret_cast(load_library(buffer)); + auto lib_hostfxr = reinterpret_cast(load_library(buffer)); + if (!lib_hostfxr) + return -1; + m_hostfxr_initialize_for_runtime_config_fptr = reinterpret_cast( - get_export(lib, "hostfxr_initialize_for_runtime_config")); + get_export(lib_hostfxr, "hostfxr_initialize_for_runtime_config")); m_hostfxr_get_runtime_delegate_fptr = reinterpret_cast( - get_export(lib, "hostfxr_get_runtime_delegate")); + get_export(lib_hostfxr, "hostfxr_get_runtime_delegate")); m_hostfxr_close_fptr = reinterpret_cast( - get_export(lib, "hostfxr_close")); + get_export(lib_hostfxr, "hostfxr_close")); return m_hostfxr_initialize_for_runtime_config_fptr && m_hostfxr_get_runtime_delegate_fptr diff --git a/lib/CoreCLR/CoreCLR.h b/lib/CoreCLR/CoreCLR.h index 71c62d90e..fcce811ef 100644 --- a/lib/CoreCLR/CoreCLR.h +++ b/lib/CoreCLR/CoreCLR.h @@ -5,8 +5,10 @@ #include "nethost/nethost.h" class CoreCLR { - public: - explicit CoreCLR(); + void* const m_calling_module; + +public: + explicit CoreCLR(void* calling_module); ~CoreCLR() = default; int load_hostfxr(); @@ -32,7 +34,7 @@ class CoreCLR { void* reserved, void** delegate) const; - private: +private: /* HostFXR delegates. */ hostfxr_initialize_for_runtime_config_fn m_hostfxr_initialize_for_runtime_config_fptr{}; hostfxr_get_runtime_delegate_fn m_hostfxr_get_runtime_delegate_fptr{}; diff --git a/lib/CoreCLR/boot.cpp b/lib/CoreCLR/boot.cpp index 63636e709..acdba1909 100644 --- a/lib/CoreCLR/boot.cpp +++ b/lib/CoreCLR/boot.cpp @@ -26,6 +26,7 @@ void ConsoleTeardown() std::optional g_clr; int InitializeClrAndGetEntryPoint( + void* calling_module, std::wstring runtimeconfig_path, std::wstring module_path, std::wstring entrypoint_assembly_name, @@ -33,7 +34,7 @@ int InitializeClrAndGetEntryPoint( std::wstring entrypoint_delegate_type_name, void** entrypoint_fn) { - g_clr = CoreCLR(); + g_clr.emplace(calling_module); int result; SetEnvironmentVariable(L"DOTNET_MULTILEVEL_LOOKUP", L"0"); diff --git a/lib/CoreCLR/boot.h b/lib/CoreCLR/boot.h index 8f58042a1..f306563ad 100644 --- a/lib/CoreCLR/boot.h +++ b/lib/CoreCLR/boot.h @@ -2,6 +2,7 @@ void ConsoleSetup(const std::wstring console_name); void ConsoleTeardown(); int InitializeClrAndGetEntryPoint( + void* calling_module, std::wstring runtimeconfig_path, std::wstring module_path, std::wstring entrypoint_assembly_name, diff --git a/lib/CoreCLR/nethost/libnethost.lib b/lib/CoreCLR/nethost/libnethost.lib deleted file mode 100644 index 4291a5387..000000000 Binary files a/lib/CoreCLR/nethost/libnethost.lib and /dev/null differ diff --git a/lib/CoreCLR/nethost/nethost.h b/lib/CoreCLR/nethost/nethost.h index 31adde5e8..aff09b286 100644 --- a/lib/CoreCLR/nethost/nethost.h +++ b/lib/CoreCLR/nethost/nethost.h @@ -6,36 +6,6 @@ #include -#ifdef _WIN32 - #ifdef NETHOST_EXPORT - #define NETHOST_API __declspec(dllexport) - #else - // Consuming the nethost as a static library - // Shouldn't export attempt to dllimport. - #ifdef NETHOST_USE_AS_STATIC - #define NETHOST_API - #else - #define NETHOST_API __declspec(dllimport) - #endif - #endif - - #define NETHOST_CALLTYPE __stdcall - #ifdef _WCHAR_T_DEFINED - typedef wchar_t char_t; - #else - typedef unsigned short char_t; - #endif -#else - #ifdef NETHOST_EXPORT - #define NETHOST_API __attribute__((__visibility__("default"))) - #else - #define NETHOST_API - #endif - - #define NETHOST_CALLTYPE - typedef char char_t; -#endif - #ifdef __cplusplus extern "C" { #endif @@ -87,10 +57,10 @@ struct get_hostfxr_parameters { // The full search for the hostfxr library is done on every call. To minimize the need // to call this function multiple times, pass a large buffer (e.g. PATH_MAX). // -NETHOST_API int NETHOST_CALLTYPE get_hostfxr_path( - char_t * buffer, - size_t * buffer_size, - const struct get_hostfxr_parameters *parameters); +using get_hostfxr_path_type = int(__stdcall *)( + char_t* buffer, + size_t* buffer_size, + const struct get_hostfxr_parameters* parameters); #ifdef __cplusplus } // extern "C" diff --git a/lib/CoreCLR/nethost/nethost.lib b/lib/CoreCLR/nethost/nethost.lib deleted file mode 100644 index 4cd6f0382..000000000 Binary files a/lib/CoreCLR/nethost/nethost.lib and /dev/null differ