diff --git a/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs b/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs
new file mode 100644
index 000000000..b271ee4a4
--- /dev/null
+++ b/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Dalamud.Configuration.Internal
+{
+ ///
+ /// Environmental configuration settings.
+ ///
+ internal class EnvironmentConfiguration
+ {
+ ///
+ /// Gets a value indicating whether the DALAMUD_NOT_HAVE_INTERFACE setting has been enabled.
+ ///
+ public static bool DalamudNoInterface { get; } = GetEnvironmentVariable("DALAMUD_NOT_HAVE_INTERFACE");
+
+ ///
+ /// Gets a value indicating whether the XL_WINEONLINUX setting has been enabled.
+ ///
+ public static bool XlWineOnLinux { get; } = GetEnvironmentVariable("XL_WINEONLINUX");
+
+ ///
+ /// Gets a value indicating whether the DALAMUD_NOT_HAVE_PLUGINS setting has been enabled.
+ ///
+ public static bool DalamudNoPlugins { get; } = GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS");
+
+ ///
+ /// Gets a value indicating whether the DalamudForceCoreHook setting has been enabled.
+ ///
+ public static bool DalamudForceCoreHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_COREHOOK");
+
+ private static bool GetEnvironmentVariable(string name)
+ => bool.Parse(Environment.GetEnvironmentVariable(name) ?? "false");
+ }
+}
diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs
index 0fa16b0d9..fc501f029 100644
--- a/Dalamud/Dalamud.cs
+++ b/Dalamud/Dalamud.cs
@@ -186,7 +186,7 @@ namespace Dalamud
Log.Information("[T2] LOC OK!");
- if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_INTERFACE") ?? "false"))
+ if (!EnvironmentConfiguration.DalamudNoInterface)
{
try
{
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index 968cb2803..61aa4d6f2 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -64,6 +64,7 @@
+
@@ -93,6 +94,12 @@
+
+
+ PreserveNewest
+
+
+
diff --git a/Dalamud/Hooking/Hook.cs b/Dalamud/Hooking/Hook.cs
index feea082d7..0daa9c73c 100644
--- a/Dalamud/Hooking/Hook.cs
+++ b/Dalamud/Hooking/Hook.cs
@@ -1,6 +1,7 @@
using System;
using System.Reflection;
+using Dalamud.Configuration.Internal;
using Dalamud.Hooking.Internal;
using Dalamud.Memory;
using Reloaded.Hooks;
@@ -16,6 +17,8 @@ namespace Dalamud.Hooking
{
private readonly IntPtr address;
private readonly Reloaded.Hooks.Definitions.IHook hookImpl;
+ private readonly CoreHook.IHook coreHookImpl;
+ private readonly bool isCoreHook;
///
/// Initializes a new instance of the class.
@@ -24,8 +27,22 @@ namespace Dalamud.Hooking
/// A memory address to install a hook.
/// Callback function. Delegate must have a same original function prototype.
public Hook(IntPtr address, T detour)
+ : this(address, detour, false)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// Hook is not activated until Enable() method is called.
+ /// Please do not use CoreHook unless you have thoroughly troubleshot why Reloaded does not work.
+ ///
+ /// A memory address to install a hook.
+ /// Callback function. Delegate must have a same original function prototype.
+ /// Use the corehook hooking library instead of Reloaded.
+ public Hook(IntPtr address, T detour, bool useCoreHook)
{
address = HookManager.FollowJmp(address);
+ this.isCoreHook = useCoreHook || EnvironmentConfiguration.DalamudForceCoreHook;
var hasOtherHooks = HookManager.Originals.ContainsKey(address);
if (!hasOtherHooks)
@@ -35,7 +52,14 @@ namespace Dalamud.Hooking
}
this.address = address;
- this.hookImpl = ReloadedHooks.Instance.CreateHook(detour, address.ToInt64());
+ if (this.isCoreHook)
+ {
+ this.coreHookImpl = CoreHook.HookFactory.CreateHook(address, detour);
+ }
+ else
+ {
+ this.hookImpl = ReloadedHooks.Instance.CreateHook(detour, address.ToInt64());
+ }
HookManager.TrackedHooks.Add(new HookInfo(this, detour, Assembly.GetCallingAssembly()));
}
@@ -62,7 +86,14 @@ namespace Dalamud.Hooking
get
{
this.CheckDisposed();
- return this.hookImpl.OriginalFunction;
+ if (this.isCoreHook)
+ {
+ return this.coreHookImpl.Original;
+ }
+ else
+ {
+ return this.hookImpl.OriginalFunction;
+ }
}
}
@@ -74,7 +105,14 @@ namespace Dalamud.Hooking
get
{
this.CheckDisposed();
- return this.hookImpl.IsHookEnabled;
+ if (this.isCoreHook)
+ {
+ return this.coreHookImpl.Enabled;
+ }
+ else
+ {
+ return this.hookImpl.IsHookEnabled;
+ }
}
}
@@ -92,6 +130,19 @@ namespace Dalamud.Hooking
/// Callback function. Delegate must have a same original function prototype.
/// The hook with the supplied parameters.
public static Hook FromSymbol(string moduleName, string exportName, T detour)
+ => FromSymbol(moduleName, exportName, detour, false);
+
+ ///
+ /// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function.
+ /// The hook is not activated until Enable() method is called.
+ /// Please do not use CoreHook unless you have thoroughly troubleshot why Reloaded does not work.
+ ///
+ /// A name of the module currently loaded in the memory. (e.g. ws2_32.dll).
+ /// A name of the exported function name (e.g. send).
+ /// Callback function. Delegate must have a same original function prototype.
+ /// Use the corehook hooking library instead of Reloaded.
+ /// The hook with the supplied parameters.
+ public static Hook FromSymbol(string moduleName, string exportName, T detour, bool useCoreHook)
{
var moduleHandle = NativeFunctions.GetModuleHandleW(moduleName);
if (moduleHandle == IntPtr.Zero)
@@ -101,7 +152,7 @@ namespace Dalamud.Hooking
if (procAddress == IntPtr.Zero)
throw new Exception($"Could not get the address of {moduleName}::{exportName}");
- return new Hook(procAddress, detour);
+ return new Hook(procAddress, detour, useCoreHook);
}
///
@@ -112,10 +163,17 @@ namespace Dalamud.Hooking
if (this.IsDisposed)
return;
- this.IsDisposed = true;
+ if (this.isCoreHook)
+ {
+ this.Disable();
+ this.coreHookImpl.Dispose();
+ }
+ else
+ {
+ this.Disable();
+ }
- if (this.hookImpl.IsHookEnabled)
- this.hookImpl.Disable();
+ this.IsDisposed = true;
}
///
@@ -125,11 +183,19 @@ namespace Dalamud.Hooking
{
this.CheckDisposed();
- if (!this.hookImpl.IsHookActivated)
- this.hookImpl.Activate();
+ if (this.isCoreHook)
+ {
+ if (!this.coreHookImpl.Enabled)
+ this.coreHookImpl.Enabled = true;
+ }
+ else
+ {
+ if (!this.hookImpl.IsHookActivated)
+ this.hookImpl.Activate();
- if (!this.hookImpl.IsHookEnabled)
- this.hookImpl.Enable();
+ if (!this.hookImpl.IsHookEnabled)
+ this.hookImpl.Enable();
+ }
}
///
@@ -139,11 +205,19 @@ namespace Dalamud.Hooking
{
this.CheckDisposed();
- if (!this.hookImpl.IsHookActivated)
- return;
+ if (this.isCoreHook)
+ {
+ if (this.coreHookImpl.Enabled)
+ this.coreHookImpl.Enabled = false;
+ }
+ else
+ {
+ if (!this.hookImpl.IsHookActivated)
+ return;
- if (this.hookImpl.IsHookEnabled)
- this.hookImpl.Disable();
+ if (this.hookImpl.IsHookEnabled)
+ this.hookImpl.Disable();
+ }
}
///
diff --git a/Dalamud/Hooking/Internal/HookManager.cs b/Dalamud/Hooking/Internal/HookManager.cs
index 483a0e4af..1f67ee1e8 100644
--- a/Dalamud/Hooking/Internal/HookManager.cs
+++ b/Dalamud/Hooking/Internal/HookManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
+using Dalamud.Configuration.Internal;
using Dalamud.Logging.Internal;
using Dalamud.Memory;
using Iced.Intel;
@@ -40,7 +41,7 @@ namespace Dalamud.Hooking.Internal
bool Check1()
{
- return Environment.GetEnvironmentVariable("XL_WINEONLINUX") != null;
+ return EnvironmentConfiguration.XlWineOnLinux;
}
bool Check2()
diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index 351a5525a..ac40a30f0 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -56,8 +56,8 @@ namespace Dalamud.Plugin.Internal
if (!this.devPluginDirectory.Exists)
this.devPluginDirectory.Create();
- var noPlugins = bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS") ?? "false");
- if (this.SafeMode = noPlugins || configuration.PluginSafeMode)
+ this.SafeMode = EnvironmentConfiguration.DalamudNoPlugins || configuration.PluginSafeMode;
+ if (this.SafeMode)
{
configuration.PluginSafeMode = false;
configuration.Save();
diff --git a/Dalamud/Support/Troubleshooting.cs b/Dalamud/Support/Troubleshooting.cs
index 14440e48b..e2e892b77 100644
--- a/Dalamud/Support/Troubleshooting.cs
+++ b/Dalamud/Support/Troubleshooting.cs
@@ -74,6 +74,7 @@ namespace Dalamud.Support
DoPluginTest = configuration.DoPluginTest,
InterfaceLoaded = interfaceManager?.IsReady ?? false,
ThirdRepo = configuration.ThirdRepoList,
+ ForcedCoreHook = EnvironmentConfiguration.DalamudForceCoreHook,
};
var encodedPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload)));
@@ -112,6 +113,8 @@ namespace Dalamud.Support
public bool InterfaceLoaded { get; set; }
+ public bool ForcedCoreHook { get; set; }
+
public List ThirdRepo { get; set; }
}
}
diff --git a/Dalamud/corehook64.dll b/Dalamud/corehook64.dll
new file mode 100644
index 000000000..9b21a40d1
Binary files /dev/null and b/Dalamud/corehook64.dll differ