diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 79fe912dd..336b1ed3d 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -48,6 +48,7 @@ + diff --git a/Dalamud/Game/Internal/DXGI/DXHookD3D11.cs b/Dalamud/Game/Internal/DXGI/DXHookD3D11.cs new file mode 100644 index 000000000..92739ae6e --- /dev/null +++ b/Dalamud/Game/Internal/DXGI/DXHookD3D11.cs @@ -0,0 +1,89 @@ +using SharpDX.Direct3D; +using SharpDX.Direct3D11; +using SharpDX.DXGI; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Dalamud.Game.Internal.DXGI +{ + public class DXHookD3D11 + { + const int DXGI_SWAPCHAIN_METHOD_COUNT = 18; + const int D3D11_DEVICE_METHOD_COUNT = 43; + + public static SharpDX.DXGI.SwapChainDescription CreateSwapChainDescription(IntPtr renderForm) + { + return new SharpDX.DXGI.SwapChainDescription + { + BufferCount = 1, + Flags = SharpDX.DXGI.SwapChainFlags.None, + IsWindowed = true, + ModeDescription = new SharpDX.DXGI.ModeDescription(100, 100, new Rational(60, 1), SharpDX.DXGI.Format.R8G8B8A8_UNorm), + OutputHandle = renderForm, + SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), + SwapEffect = SharpDX.DXGI.SwapEffect.Discard, + Usage = SharpDX.DXGI.Usage.RenderTargetOutput + }; + } + + protected IntPtr[] GetVTblAddresses(IntPtr pointer, int numberOfMethods) + { + return GetVTblAddresses(pointer, 0, numberOfMethods); + } + + protected IntPtr[] GetVTblAddresses(IntPtr pointer, int startIndex, int numberOfMethods) + { + List vtblAddresses = new List(); + IntPtr vTable = Marshal.ReadIntPtr(pointer); + for (int i = startIndex; i < startIndex + numberOfMethods; i++) + vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size)); // using IntPtr.Size allows us to support both 32 and 64-bit processes + + return vtblAddresses.ToArray(); + } + + List _d3d11VTblAddresses = null; + List _dxgiSwapChainVTblAddresses = null; + + #region Internal device resources + SharpDX.Direct3D11.Device _device; + SharpDX.DXGI.SwapChain _swapChain; + SharpDX.Windows.RenderForm _renderForm; + #endregion + + #region Main device resources + public SharpDX.Windows.RenderForm RenderForm { get => _renderForm; set => _renderForm = value; } + #endregion + + public IntPtr Hook() + { + + if (_d3d11VTblAddresses == null) + { + _d3d11VTblAddresses = new List(); + _dxgiSwapChainVTblAddresses = new List(); + + #region Get Device and SwapChain method addresses + // Create temporary device + swapchain and determine method addresses + RenderForm = new SharpDX.Windows.RenderForm(); + SharpDX.Direct3D11.Device.CreateWithSwapChain( + DriverType.Hardware, + DeviceCreationFlags.BgraSupport, + CreateSwapChainDescription(RenderForm.Handle), + out _device, + out _swapChain + ); + if (_device != null && _swapChain != null) + { + _d3d11VTblAddresses.AddRange(GetVTblAddresses(_device.NativePointer, D3D11_DEVICE_METHOD_COUNT)); + _dxgiSwapChainVTblAddresses.AddRange(GetVTblAddresses(_swapChain.NativePointer, DXGI_SWAPCHAIN_METHOD_COUNT)); + } + _device.Dispose(); + _swapChain.Dispose(); + #endregion + } + + return _dxgiSwapChainVTblAddresses[8]; + } + } +} diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs index 4b1be233f..a5d585fcd 100644 --- a/Dalamud/Interface/InterfaceManager.cs +++ b/Dalamud/Interface/InterfaceManager.cs @@ -27,7 +27,7 @@ namespace Dalamud.Interface private readonly Hook presentHook; - private SwapChainAddressResolver Address { get; } + private DXHookD3D11 dXHookD3D11 = new DXHookD3D11(); private RawDX11Scene scene; @@ -38,16 +38,15 @@ namespace Dalamud.Interface public InterfaceManager(SigScanner scanner) { - Address = new SwapChainAddressResolver(); - Address.Setup(scanner); + IntPtr addr = dXHookD3D11.Hook(); Log.Verbose("===== S W A P C H A I N ====="); - Log.Verbose("Present address {Present}", Address.Present); + Log.Verbose("Present address {Present}", addr); this.presentHook = - new Hook(Address.Present, - new PresentDelegate(PresentDetour), - this); + new Hook(addr, + new PresentDelegate(PresentDetour), + this); } public void Enable()