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