Added DirectX hooks
Warning: DX9 doesn't support resizing (TODO), DX12 has not beed tested and is not finished. No OpenGL support for now.merge-requests/28/head
parent
bb9c516775
commit
2ba8cae64e
|
@ -0,0 +1,40 @@
|
|||
#include "Base_Hook.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "Hook_Manager.h"
|
||||
|
||||
#include "../detours/detours.h"
|
||||
|
||||
Base_Hook::~Base_Hook()
|
||||
{
|
||||
UnhookAll();
|
||||
}
|
||||
|
||||
void Base_Hook::BeginHook()
|
||||
{
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
}
|
||||
|
||||
void Base_Hook::EndHook()
|
||||
{
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
void Base_Hook::UnhookAll()
|
||||
{
|
||||
if (_hooked_funcs.size())
|
||||
{
|
||||
BeginHook();
|
||||
std::for_each(_hooked_funcs.begin(), _hooked_funcs.end(), [](std::pair<void**, void*>& hook) {
|
||||
DetourDetach(hook.first, hook.second);
|
||||
});
|
||||
EndHook();
|
||||
_hooked_funcs.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Base_Hook::HookFuncs(std::pair<void**, void*> hook)
|
||||
{
|
||||
DetourAttach(hook.first, hook.second);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef __INCLUDED_BASE_HOOK_H__
|
||||
#define __INCLUDED_BASE_HOOK_H__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define VC_EXTRALEAN
|
||||
#include <Windows.h>
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
class Base_Hook
|
||||
{
|
||||
protected:
|
||||
std::vector<std::pair<void**, void*>> _hooked_funcs;
|
||||
|
||||
HMODULE _dll;
|
||||
bool _hooked;
|
||||
|
||||
Base_Hook(const Base_Hook&) = delete;
|
||||
Base_Hook(Base_Hook&&) = delete;
|
||||
Base_Hook& operator =(const Base_Hook&) = delete;
|
||||
Base_Hook& operator =(Base_Hook&&) = delete;
|
||||
|
||||
public:
|
||||
Base_Hook() {}
|
||||
virtual ~Base_Hook();
|
||||
|
||||
void BeginHook();
|
||||
void EndHook();
|
||||
void UnhookAll();
|
||||
|
||||
void HookFuncs(std::pair<void**, void*> hook);
|
||||
|
||||
template<typename T, typename ...Args>
|
||||
void HookFuncs(std::pair<T*, T> funcs, Args... args)
|
||||
{
|
||||
_hooked_funcs.emplace_back(std::move(funcs));
|
||||
HookFuncs(funcs);
|
||||
HookFuncs(args...);
|
||||
}
|
||||
};
|
||||
|
||||
#endif//__INCLUDED_BASE_HOOK_H__
|
|
@ -0,0 +1,208 @@
|
|||
#include "../dll/base.h"
|
||||
#include "DX10_Hook.h"
|
||||
#include "Hook_Manager.h"
|
||||
|
||||
#include "../detours/detours.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <impls/imgui_impl_win32.h>
|
||||
#include <impls/imgui_impl_dx10.h>
|
||||
|
||||
// This is created by DX10_Hook::Create, and deleted by the Hook_Manager if not used
|
||||
static DX10_Hook* hook;
|
||||
|
||||
void DX10_Hook::hook_dx10(UINT SDKVersion)
|
||||
{
|
||||
if (!_hooked)
|
||||
{
|
||||
PRINT_DEBUG("Hooked DirectX 10\n");
|
||||
_hooked = true;
|
||||
Hook_Manager::Inst().FoundHook(this);
|
||||
|
||||
IDXGISwapChain* pSwapChain;
|
||||
ID3D10Device* pDevice;
|
||||
DXGI_SWAP_CHAIN_DESC SwapChainDesc = {};
|
||||
SwapChainDesc.BufferCount = 2;
|
||||
SwapChainDesc.BufferDesc.Width = 800;
|
||||
SwapChainDesc.BufferDesc.Height = 600;
|
||||
SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
|
||||
SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
SwapChainDesc.OutputWindow = GetForegroundWindow();
|
||||
SwapChainDesc.SampleDesc.Count = 1;
|
||||
SwapChainDesc.SampleDesc.Quality = 0;
|
||||
SwapChainDesc.Windowed = TRUE;
|
||||
|
||||
D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, SDKVersion, &SwapChainDesc, &pSwapChain, &pDevice);
|
||||
|
||||
loadFunctions(pDevice, pSwapChain);
|
||||
|
||||
UnhookAll();
|
||||
BeginHook();
|
||||
HookFuncs(
|
||||
std::make_pair<void**, void*>(&(PVOID&)DX10_Hook::Present , &DX10_Hook::MyPresent),
|
||||
std::make_pair<void**, void*>(&(PVOID&)DX10_Hook::ResizeTarget , &DX10_Hook::MyResizeTarget),
|
||||
std::make_pair<void**, void*>(&(PVOID&)DX10_Hook::ResizeBuffers, &DX10_Hook::MyResizeBuffers)
|
||||
);
|
||||
EndHook();
|
||||
|
||||
pDevice->Release();
|
||||
pSwapChain->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void DX10_Hook::resetRenderState()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
mainRenderTargetView->Release();
|
||||
|
||||
ImGui_ImplDX10_Shutdown();
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DX10_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
pSwapChain->GetDesc(&desc);
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
if (FAILED(pSwapChain->GetDevice(__uuidof(ID3D10Device), (PVOID*)& pDevice)))
|
||||
return;
|
||||
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.IniFilename = NULL;
|
||||
|
||||
ID3D10Texture2D* pBackBuffer;
|
||||
|
||||
pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)& pBackBuffer);
|
||||
pDevice->CreateRenderTargetView(pBackBuffer, NULL, &mainRenderTargetView);
|
||||
pBackBuffer->Release();
|
||||
|
||||
Hook_Manager::Inst().ChangeGameWindow(desc.OutputWindow);
|
||||
ImGui_ImplWin32_Init(desc.OutputWindow);
|
||||
ImGui_ImplDX10_Init(pDevice);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
ImGui_ImplDX10_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
Hook_Manager::Inst().CallOverlayProc(desc.BufferDesc.Width, desc.BufferDesc.Height);
|
||||
|
||||
ImGui::EndFrame();
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
pDevice->OMSetRenderTargets(1, &mainRenderTargetView, NULL);
|
||||
ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// DirectX 10 Initialization functions
|
||||
//HRESULT WINAPI DX10_Hook::MyD3D10CreateDevice(IDXGIAdapter* pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, UINT SDKVersion, ID3D10Device** ppDevice)
|
||||
//{
|
||||
// auto res = _D3D10CreateDevice(pAdapter, DriverType, Software, Flags, SDKVersion, ppDevice);
|
||||
//
|
||||
// if (SUCCEEDED(res))
|
||||
// hook->hook_dx10(SDKVersion);
|
||||
//
|
||||
// return res;
|
||||
//}
|
||||
|
||||
HRESULT WINAPI DX10_Hook::MyD3D10CreateDeviceAndSwapChain(IDXGIAdapter* pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, UINT SDKVersion,
|
||||
DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IDXGISwapChain** ppSwapChain, ID3D10Device** ppDevice)
|
||||
{
|
||||
auto res = hook->D3D10CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice);
|
||||
|
||||
if (SUCCEEDED(res))
|
||||
hook->hook_dx10(SDKVersion);
|
||||
|
||||
return res;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX10_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
hook->prepareForOverlay(_this);
|
||||
return (_this->*hook->Present)(SyncInterval, Flags);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX10_Hook::MyResizeTarget(IDXGISwapChain* _this, const DXGI_MODE_DESC* pNewTargetParameters)
|
||||
{
|
||||
hook->resetRenderState();
|
||||
return (_this->*hook->ResizeTarget)(pNewTargetParameters);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX10_Hook::MyResizeBuffers(IDXGISwapChain* _this, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags)
|
||||
{
|
||||
hook->resetRenderState();
|
||||
return (_this->*hook->ResizeBuffers)(BufferCount, Width, Height, NewFormat, SwapChainFlags);
|
||||
}
|
||||
|
||||
DX10_Hook::DX10_Hook():
|
||||
initialized(false),
|
||||
pDevice(nullptr),
|
||||
mainRenderTargetView(nullptr)
|
||||
{
|
||||
_dll = GetModuleHandle(DLL_NAME);
|
||||
_hooked = false;
|
||||
// Hook to D3D10CreateDevice and D3D10CreateDeviceAndSwapChain so we know when it gets called.
|
||||
// If its called, then DX10 will be used to render the overlay.
|
||||
//_D3D10CreateDevice = (decltype(_D3D10CreateDevice))GetProcAddress(_dll, "D3D10CreateDevice");
|
||||
D3D10CreateDeviceAndSwapChain = (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D10CreateDeviceAndSwapChain");
|
||||
|
||||
BeginHook();
|
||||
HookFuncs(
|
||||
//std::make_pair<void**, void*>(&(PVOID&)_D3D10CreateDevice, &DX10_Hook::MyD3D10CreateDevice),
|
||||
std::make_pair<void**, void*>(&(PVOID&)D3D10CreateDeviceAndSwapChain, &DX10_Hook::MyD3D10CreateDeviceAndSwapChain)
|
||||
);
|
||||
EndHook();
|
||||
}
|
||||
|
||||
DX10_Hook::~DX10_Hook()
|
||||
{
|
||||
PRINT_DEBUG("DX10 Hook removed\n");
|
||||
|
||||
if (_hooked)
|
||||
{
|
||||
ImGui_ImplDX10_Shutdown();
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
hook = nullptr;
|
||||
}
|
||||
|
||||
void DX10_Hook::Create()
|
||||
{
|
||||
if (hook == nullptr)
|
||||
{
|
||||
hook = new DX10_Hook;
|
||||
// Register the hook to the Hook Manager
|
||||
Hook_Manager::Inst().AddHook(hook);
|
||||
}
|
||||
}
|
||||
|
||||
void DX10_Hook::loadFunctions(ID3D10Device *pDevice, IDXGISwapChain *pSwapChain)
|
||||
{
|
||||
void** vTable = *reinterpret_cast<void***>(pDevice);
|
||||
|
||||
#define LOAD_FUNC(X) (void*&)X = vTable[(int)ID3D10DeviceVTable::X]
|
||||
|
||||
#undef LOAD_FUNC
|
||||
|
||||
vTable = *reinterpret_cast<void***>(pSwapChain);
|
||||
#define LOAD_FUNC(X) (void*&)X = vTable[(int)IDXGISwapChainVTable::X]
|
||||
LOAD_FUNC(Present);
|
||||
LOAD_FUNC(ResizeBuffers);
|
||||
LOAD_FUNC(ResizeTarget);
|
||||
#undef LOAD_FUNC
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef __INCLUDED_DX10_HOOK_H__
|
||||
#define __INCLUDED_DX10_HOOK_H__
|
||||
|
||||
#include <d3d10.h>
|
||||
#include "DirectX_VTables.h"
|
||||
#include "Base_Hook.h"
|
||||
|
||||
class DX10_Hook : public Base_Hook
|
||||
{
|
||||
public:
|
||||
static constexpr const char DLL_NAME[] = "d3d10.dll";
|
||||
|
||||
private:
|
||||
// Variables
|
||||
bool initialized;
|
||||
ID3D10Device* pDevice;
|
||||
ID3D10RenderTargetView* mainRenderTargetView;
|
||||
|
||||
// Functions
|
||||
DX10_Hook();
|
||||
virtual ~DX10_Hook();
|
||||
|
||||
void hook_dx10(UINT SDKVersion);
|
||||
void resetRenderState();
|
||||
void prepareForOverlay(IDXGISwapChain *pSwapChain);
|
||||
|
||||
// Hook to render functions
|
||||
static HRESULT STDMETHODCALLTYPE MyPresent(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags);
|
||||
static HRESULT STDMETHODCALLTYPE MyResizeTarget(IDXGISwapChain* _this, const DXGI_MODE_DESC* pNewTargetParameters);
|
||||
static HRESULT STDMETHODCALLTYPE MyResizeBuffers(IDXGISwapChain* _this, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
|
||||
|
||||
decltype(&IDXGISwapChain::Present) Present;
|
||||
decltype(&IDXGISwapChain::ResizeBuffers) ResizeBuffers;
|
||||
decltype(&IDXGISwapChain::ResizeTarget) ResizeTarget;
|
||||
|
||||
// Hook functions so we know we use DX10
|
||||
//static decltype(D3D10CreateDevice) MyD3D10CreateDevice;
|
||||
static decltype(D3D10CreateDeviceAndSwapChain) MyD3D10CreateDeviceAndSwapChain;
|
||||
|
||||
//decltype(D3D10CreateDevice)* _D3D10CreateDevice;
|
||||
decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain;
|
||||
|
||||
public:
|
||||
static void Create(); // Initialize DX10 Hook.
|
||||
|
||||
void loadFunctions(ID3D10Device *pDevice, IDXGISwapChain *pSwapChain);
|
||||
};
|
||||
|
||||
#endif//__INCLUDED_DX10_HOOK_H__
|
|
@ -0,0 +1,224 @@
|
|||
#include "../dll/base.h"
|
||||
#include "DX11_Hook.h"
|
||||
#include "Hook_Manager.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <impls/imgui_impl_win32.h>
|
||||
#include <impls/imgui_impl_dx11.h>
|
||||
|
||||
// This is created by DX11_Hook::Create, and deleted by the Hook_Manager if not used
|
||||
static DX11_Hook* hook;
|
||||
|
||||
HRESULT GetDeviceAndCtxFromSwapchain(IDXGISwapChain* pSwapChain, ID3D11Device** ppDevice, ID3D11DeviceContext** ppContext)
|
||||
{
|
||||
HRESULT ret = pSwapChain->GetDevice(__uuidof(ID3D11Device), (PVOID*)ppDevice);
|
||||
|
||||
if (SUCCEEDED(ret))
|
||||
(*ppDevice)->GetImmediateContext(ppContext);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DX11_Hook::hook_dx11(UINT SDKVersion)
|
||||
{
|
||||
if (!_hooked)
|
||||
{
|
||||
PRINT_DEBUG("Hooked DirectX 11\n");
|
||||
_hooked = true;
|
||||
Hook_Manager::Inst().FoundHook(this);
|
||||
|
||||
IDXGISwapChain* pSwapChain;
|
||||
ID3D11Device* pDevice;
|
||||
DXGI_SWAP_CHAIN_DESC SwapChainDesc = {};
|
||||
SwapChainDesc.BufferCount = 2;
|
||||
SwapChainDesc.BufferDesc.Width = 800;
|
||||
SwapChainDesc.BufferDesc.Height = 600;
|
||||
SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
|
||||
SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
SwapChainDesc.OutputWindow = GetForegroundWindow();
|
||||
SwapChainDesc.SampleDesc.Count = 1;
|
||||
SwapChainDesc.SampleDesc.Quality = 0;
|
||||
SwapChainDesc.Windowed = TRUE;
|
||||
|
||||
D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, NULL, SDKVersion, &SwapChainDesc, &pSwapChain, &pDevice, NULL, NULL);
|
||||
|
||||
loadFunctions(pDevice, pSwapChain);
|
||||
|
||||
UnhookAll();
|
||||
BeginHook();
|
||||
HookFuncs(
|
||||
std::make_pair<void**, void*>(&(PVOID&)DX11_Hook::Present , &DX11_Hook::MyPresent),
|
||||
std::make_pair<void**, void*>(&(PVOID&)DX11_Hook::ResizeTarget , &DX11_Hook::MyResizeTarget),
|
||||
std::make_pair<void**, void*>(&(PVOID&)DX11_Hook::ResizeBuffers, &DX11_Hook::MyResizeBuffers)
|
||||
);
|
||||
EndHook();
|
||||
|
||||
pDevice->Release();
|
||||
pSwapChain->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void DX11_Hook::resetRenderState()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
mainRenderTargetView->Release();
|
||||
pContext->Release();
|
||||
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DX11_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
pSwapChain->GetDesc(&desc);
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
ID3D11Device* pDevice = nullptr;
|
||||
if (FAILED(GetDeviceAndCtxFromSwapchain(pSwapChain, &pDevice, &pContext)))
|
||||
return;
|
||||
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.IniFilename = NULL;
|
||||
|
||||
ID3D11Texture2D* pBackBuffer;
|
||||
|
||||
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)& pBackBuffer);
|
||||
pDevice->CreateRenderTargetView(pBackBuffer, NULL, &mainRenderTargetView);
|
||||
pBackBuffer->Release();
|
||||
|
||||
Hook_Manager::Inst().ChangeGameWindow(desc.OutputWindow);
|
||||
ImGui_ImplWin32_Init(desc.OutputWindow);
|
||||
ImGui_ImplDX11_Init(pDevice, pContext);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
Hook_Manager::Inst().CallOverlayProc(desc.BufferDesc.Width, desc.BufferDesc.Height);
|
||||
|
||||
ImGui::EndFrame();
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
pContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// DirectX 11 Initialization functions
|
||||
//HRESULT WINAPI DX11_Hook::MyD3D11CreateDevice(__in_opt IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags,
|
||||
// __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, __out_opt ID3D11Device** ppDevice,
|
||||
// __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, __out_opt ID3D11DeviceContext** ppImmediateContext)
|
||||
//{
|
||||
// auto res = _D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext);
|
||||
//
|
||||
// if (SUCCEEDED(res))
|
||||
// hook->hook_dx11(SDKVersion);
|
||||
//
|
||||
// return res;
|
||||
//}
|
||||
|
||||
HRESULT WINAPI DX11_Hook::MyD3D11CreateDeviceAndSwapChain(__in_opt IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags,
|
||||
__in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion,
|
||||
__in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, __out_opt IDXGISwapChain** ppSwapChain, __out_opt ID3D11Device** ppDevice,
|
||||
__out_opt D3D_FEATURE_LEVEL* pFeatureLevel, __out_opt ID3D11DeviceContext** ppImmediateContext)
|
||||
{
|
||||
auto res = hook->D3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext);
|
||||
|
||||
if (SUCCEEDED(res))
|
||||
hook->hook_dx11(SDKVersion);
|
||||
|
||||
return res;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX11_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
hook->prepareForOverlay(_this);
|
||||
|
||||
return (_this->*hook->Present)(SyncInterval, Flags);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX11_Hook::MyResizeTarget(IDXGISwapChain* _this, const DXGI_MODE_DESC* pNewTargetParameters)
|
||||
{
|
||||
hook->resetRenderState();
|
||||
return (_this->*hook->ResizeTarget)(pNewTargetParameters);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX11_Hook::MyResizeBuffers(IDXGISwapChain* _this, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags)
|
||||
{
|
||||
hook->resetRenderState();
|
||||
return (_this->*hook->ResizeBuffers)(BufferCount, Width, Height, NewFormat, SwapChainFlags);
|
||||
}
|
||||
|
||||
DX11_Hook::DX11_Hook():
|
||||
initialized(false),
|
||||
pContext(nullptr),
|
||||
mainRenderTargetView(nullptr)
|
||||
{
|
||||
_dll = GetModuleHandle(DLL_NAME);
|
||||
_hooked = false;
|
||||
// Hook to D3D11CreateDevice and D3D11CreateDeviceAndSwapChain so we know when it gets called.
|
||||
// If its called, then DX11 will be used to render the overlay.
|
||||
//_D3D11CreateDevice = (decltype(_D3D11CreateDevice))GetProcAddress(_dll, "D3D11CreateDevice");
|
||||
D3D11CreateDeviceAndSwapChain = (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D11CreateDeviceAndSwapChain");
|
||||
|
||||
BeginHook();
|
||||
HookFuncs(
|
||||
//std::make_pair<void**, void*>(&(PVOID&)_D3D11CreateDevice, &DX11_Hook::MyD3D11CreateDevice),
|
||||
std::make_pair<void**, void*>(&(PVOID&)D3D11CreateDeviceAndSwapChain, &DX11_Hook::MyD3D11CreateDeviceAndSwapChain)
|
||||
);
|
||||
EndHook();
|
||||
|
||||
}
|
||||
|
||||
DX11_Hook::~DX11_Hook()
|
||||
{
|
||||
PRINT_DEBUG("DX11 Hook removed\n");
|
||||
|
||||
if (_hooked)
|
||||
{
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
hook = nullptr;
|
||||
}
|
||||
|
||||
void DX11_Hook::Create()
|
||||
{
|
||||
if (hook == nullptr)
|
||||
{
|
||||
hook = new DX11_Hook;
|
||||
// Register the hook to the Hook Manager
|
||||
Hook_Manager::Inst().AddHook(hook);
|
||||
}
|
||||
}
|
||||
|
||||
void DX11_Hook::loadFunctions(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
|
||||
{
|
||||
void** vTable = *reinterpret_cast<void***>(pDevice);
|
||||
|
||||
#define LOAD_FUNC(X) (void*&)X = vTable[(int)ID3D11DeviceVTable::X]
|
||||
|
||||
#undef LOAD_FUNC
|
||||
|
||||
vTable = *reinterpret_cast<void***>(pSwapChain);
|
||||
#define LOAD_FUNC(X) (void*&)X = vTable[(int)IDXGISwapChainVTable::X]
|
||||
LOAD_FUNC(Present);
|
||||
LOAD_FUNC(ResizeBuffers);
|
||||
LOAD_FUNC(ResizeTarget);
|
||||
#undef LOAD_FUNC
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef __INCLUDED_DX11_HOOK_H__
|
||||
#define __INCLUDED_DX11_HOOK_H__
|
||||
|
||||
#include <d3d11.h>
|
||||
#include "DirectX_VTables.h"
|
||||
#include "Base_Hook.h"
|
||||
|
||||
class DX11_Hook : public Base_Hook
|
||||
{
|
||||
public:
|
||||
static constexpr const char DLL_NAME[] = "d3d11.dll";
|
||||
|
||||
private:
|
||||
// Variables
|
||||
bool initialized;
|
||||
ID3D11DeviceContext* pContext;
|
||||
ID3D11RenderTargetView* mainRenderTargetView;
|
||||
|
||||
// Functions
|
||||
DX11_Hook();
|
||||
virtual ~DX11_Hook();
|
||||
|
||||
void hook_dx11(UINT SDKVersion);
|
||||
void resetRenderState();
|
||||
void prepareForOverlay(IDXGISwapChain* pSwapChain);
|
||||
|
||||
// Hook to render functions
|
||||
static HRESULT STDMETHODCALLTYPE MyPresent(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags);
|
||||
static HRESULT STDMETHODCALLTYPE MyResizeTarget(IDXGISwapChain* _this, const DXGI_MODE_DESC* pNewTargetParameters);
|
||||
static HRESULT STDMETHODCALLTYPE MyResizeBuffers(IDXGISwapChain* _this, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
|
||||
|
||||
decltype(&IDXGISwapChain::Present) Present;
|
||||
decltype(&IDXGISwapChain::ResizeBuffers) ResizeBuffers;
|
||||
decltype(&IDXGISwapChain::ResizeTarget) ResizeTarget;
|
||||
|
||||
// Hook functions so we know we use DX11
|
||||
//static decltype(D3D11CreateDevice) MyD3D11CreateDevice;
|
||||
static decltype(D3D11CreateDeviceAndSwapChain) MyD3D11CreateDeviceAndSwapChain;
|
||||
|
||||
//decltype(D3D11CreateDevice)* D3D11CreateDevice;
|
||||
decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain;
|
||||
|
||||
public:
|
||||
static void Create(); // Initialize DX11 Hook.
|
||||
|
||||
void loadFunctions(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain);
|
||||
};
|
||||
|
||||
#endif//__INCLUDED_DX11_HOOK_H__
|
|
@ -0,0 +1,186 @@
|
|||
#include "../dll/base.h"
|
||||
#include "DX12_Hook.h"
|
||||
#include "Hook_Manager.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <impls/imgui_impl_win32.h>
|
||||
#include <impls/imgui_impl_dx12.h>
|
||||
|
||||
// This is created by DX12_Hook::Create, and deleted by the Hook_Manager if not used
|
||||
static DX12_Hook* hook;
|
||||
|
||||
void DX12_Hook::hook_dx12(D3D_FEATURE_LEVEL MinimumFeatureLevel)
|
||||
{
|
||||
if (!_hooked)
|
||||
{
|
||||
PRINT_DEBUG("Hooked DirectX 12\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DX12_Hook::resetRenderState()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
pCmdAlloc->Release();
|
||||
pCmdList->Release();
|
||||
pDescriptorHeap->Release();
|
||||
|
||||
ImGui_ImplDX12_Shutdown();
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DX12_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
pSwapChain->GetDesc(&desc);
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC d3d12_desc = {};
|
||||
ID3D12Device* pDevice;
|
||||
|
||||
HRESULT ret = pSwapChain->GetDevice(__uuidof(ID3D12Device), (PVOID*)&pDevice);
|
||||
|
||||
d3d12_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
d3d12_desc.NumDescriptors = 1;
|
||||
d3d12_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
d3d12_desc.NodeMask = 1;
|
||||
if (pDevice->CreateDescriptorHeap(&d3d12_desc, IID_PPV_ARGS(&pDescriptorHeap)) != S_OK)
|
||||
{
|
||||
pDevice->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
SIZE_T rtvDescriptorSize = pDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = pDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
mainRenderTargetDescriptor = rtvHandle;
|
||||
|
||||
pDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&pCmdAlloc));
|
||||
|
||||
pDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, pCmdAlloc, NULL, IID_PPV_ARGS(&pCmdList));
|
||||
|
||||
Hook_Manager::Inst().ChangeGameWindow(desc.OutputWindow);
|
||||
ImGui_ImplWin32_Init(desc.OutputWindow);
|
||||
ImGui_ImplDX12_Init(pDevice, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
pDescriptorHeap->GetCPUDescriptorHandleForHeapStart(),
|
||||
pDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
ImGui_ImplDX12_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
Hook_Manager::Inst().CallOverlayProc(desc.BufferDesc.Width, desc.BufferDesc.Height);
|
||||
|
||||
ImGui::EndFrame();
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
pCmdAlloc->Reset();
|
||||
pCmdList->Reset(pCmdAlloc, NULL);
|
||||
//pCmdList->ClearRenderTargetView(mainRenderTargetDescriptor, (float*)& clear_color, 0, NULL);
|
||||
pCmdList->OMSetRenderTargets(1, &mainRenderTargetDescriptor, FALSE, NULL);
|
||||
pCmdList->SetDescriptorHeaps(1, &pDescriptorHeap);
|
||||
ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), pCmdList);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// DirectX 12 Initialization functions
|
||||
HRESULT WINAPI DX12_Hook::MyD3D12CreateDevice(
|
||||
_In_opt_ IUnknown* pAdapter,
|
||||
D3D_FEATURE_LEVEL MinimumFeatureLevel,
|
||||
_In_ REFIID riid, // Expected: ID3D12Device
|
||||
_COM_Outptr_opt_ void** ppDevice)
|
||||
{
|
||||
auto res = hook->D3D12CreateDevice(pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
||||
|
||||
if (SUCCEEDED(res))
|
||||
hook->hook_dx12(MinimumFeatureLevel);
|
||||
|
||||
return res;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX12_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
hook->prepareForOverlay(_this);
|
||||
|
||||
return (_this->*hook->Present)(SyncInterval, Flags);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX12_Hook::MyResizeTarget(IDXGISwapChain* _this, const DXGI_MODE_DESC* pNewTargetParameters)
|
||||
{
|
||||
hook->resetRenderState();
|
||||
return (_this->*hook->ResizeTarget)(pNewTargetParameters);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX12_Hook::MyResizeBuffers(IDXGISwapChain* _this, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags)
|
||||
{
|
||||
hook->resetRenderState();
|
||||
return (_this->*hook->ResizeBuffers)(BufferCount, Width, Height, NewFormat, SwapChainFlags);
|
||||
}
|
||||
|
||||
DX12_Hook::DX12_Hook():
|
||||
initialized(false),
|
||||
pCmdAlloc(nullptr),
|
||||
pCmdList(nullptr),
|
||||
pDescriptorHeap(nullptr)
|
||||
{
|
||||
_dll = GetModuleHandle(DLL_NAME);
|
||||
_hooked = false;
|
||||
// Hook to D3D11CreateDevice and D3D11CreateDeviceAndSwapChain so we know when it gets called.
|
||||
// If its called, then DX11 will be used to render the overlay.
|
||||
D3D12CreateDevice = (decltype(D3D12CreateDevice))GetProcAddress(_dll, "D3D12CreateDevice");
|
||||
|
||||
BeginHook();
|
||||
HookFuncs(
|
||||
std::make_pair<void**, void*>(&(PVOID&)D3D12CreateDevice, &DX12_Hook::MyD3D12CreateDevice)
|
||||
);
|
||||
EndHook();
|
||||
|
||||
}
|
||||
|
||||
DX12_Hook::~DX12_Hook()
|
||||
{
|
||||
PRINT_DEBUG("DX11 Hook removed\n");
|
||||
|
||||
if (_hooked)
|
||||
{
|
||||
ImGui_ImplDX12_Shutdown();
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
hook = nullptr;
|
||||
}
|
||||
|
||||
void DX12_Hook::Create()
|
||||
{
|
||||
if (hook == nullptr)
|
||||
{
|
||||
hook = new DX12_Hook;
|
||||
// Register the hook to the Hook Manager
|
||||
Hook_Manager::Inst().AddHook(hook);
|
||||
}
|
||||
}
|
||||
|
||||
void DX12_Hook::loadFunctions(ID3D12Device *pDevice, IDXGISwapChain *pSwapChain)
|
||||
{
|
||||
void** vTable = *reinterpret_cast<void***>(pDevice);
|
||||
|
||||
/*
|
||||
#define LOAD_FUNC(X) (void*&)X = vTable[(int)ID3D12DeviceVTable::X]
|
||||
|
||||
#undef LOAD_FUNC
|
||||
*/
|
||||
vTable = *reinterpret_cast<void***>(pSwapChain);
|
||||
#define LOAD_FUNC(X) (void*&)X = vTable[(int)IDXGISwapChainVTable::X]
|
||||
LOAD_FUNC(Present);
|
||||
LOAD_FUNC(ResizeBuffers);
|
||||
LOAD_FUNC(ResizeTarget);
|
||||
#undef LOAD_FUNC
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef __INCLUDED_DX12_HOOK_H__
|
||||
#define __INCLUDED_DX12_HOOK_H__
|
||||
|
||||
#include <d3d12.h>
|
||||
#include "DirectX_VTables.h"
|
||||
#include "Base_Hook.h"
|
||||
|
||||
class DX12_Hook : public Base_Hook
|
||||
{
|
||||
public:
|
||||
static constexpr const char DLL_NAME[] = "d3d12.dll";
|
||||
|
||||
private:
|
||||
// Variables
|
||||
bool initialized;
|
||||
ID3D12CommandAllocator* pCmdAlloc;
|
||||
ID3D12GraphicsCommandList* pCmdList;
|
||||
ID3D12DescriptorHeap* pDescriptorHeap;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE mainRenderTargetDescriptor;
|
||||
|
||||
// Functions
|
||||
DX12_Hook();
|
||||
virtual ~DX12_Hook();
|
||||
|
||||
void hook_dx12(D3D_FEATURE_LEVEL MinimumFeatureLevel);
|
||||
void resetRenderState();
|
||||
void prepareForOverlay(IDXGISwapChain* pSwapChain);
|
||||
|
||||
// Hook to render functions
|
||||
static HRESULT STDMETHODCALLTYPE MyPresent(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags);
|
||||
static HRESULT STDMETHODCALLTYPE MyResizeTarget(IDXGISwapChain* _this, const DXGI_MODE_DESC* pNewTargetParameters);
|
||||
static HRESULT STDMETHODCALLTYPE MyResizeBuffers(IDXGISwapChain* _this, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
|
||||
|
||||
decltype(&IDXGISwapChain::Present) Present;
|
||||
decltype(&IDXGISwapChain::ResizeBuffers) ResizeBuffers;
|
||||
decltype(&IDXGISwapChain::ResizeTarget) ResizeTarget;
|
||||
|
||||
// Hook functions so we know we use DX11
|
||||
static decltype(D3D12CreateDevice) MyD3D12CreateDevice;
|
||||
|
||||
decltype(D3D12CreateDevice)* D3D12CreateDevice;
|
||||
|
||||
public:
|
||||
static void Create(); // Initialize DX11 Hook.
|
||||
|
||||
void loadFunctions(ID3D12Device *pDevice, IDXGISwapChain *pSwapChain);
|
||||
};
|
||||
|
||||
#endif//__INCLUDED_DX12_HOOK_H__
|
|
@ -0,0 +1,204 @@
|
|||
#include "../dll/base.h"
|
||||
#include "DX9_Hook.h"
|
||||
#include "Hook_Manager.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <impls/imgui_impl_win32.h>
|
||||
#include <impls/imgui_impl_dx9.h>
|
||||
|
||||
static DX9_Hook* hook;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
///////// /////////
|
||||
///////// This hook doesn't support game resize for now /////////
|
||||
///////// /////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
void DX9_Hook::hook_dx9(UINT SDKVersion)
|
||||
{
|
||||
if (!_hooked)
|
||||
{
|
||||
PRINT_DEBUG("Hooked DirectX 9\n");
|
||||
_hooked = true;
|
||||
Hook_Manager::Inst().FoundHook(this);
|
||||
|
||||
IDirect3D9Ex* pD3D;
|
||||
IDirect3DDevice9Ex* pDevice;
|
||||
|
||||
Direct3DCreate9Ex(SDKVersion, &pD3D);
|
||||
|
||||
D3DPRESENT_PARAMETERS params = {};
|
||||
params.BackBufferWidth = 1;
|
||||
params.BackBufferHeight = 1;
|
||||
params.hDeviceWindow = GetForegroundWindow();
|
||||
|
||||
pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, &pDevice);
|
||||
|
||||
loadFunctions(pDevice);
|
||||
|
||||
UnhookAll();
|
||||
BeginHook();
|
||||
HookFuncs(
|
||||
//std::make_pair<void**, void*>(&(PVOID&)Reset, &DX9_Hook::MyReset),
|
||||
std::make_pair<void**, void*>(&(PVOID&)Present, &DX9_Hook::MyPresent),
|
||||
std::make_pair<void**, void*>(&(PVOID&)PresentEx, &DX9_Hook::MyPresentEx)
|
||||
//std::make_pair<void**, void*>(&(PVOID&)EndScene, &DX9_Hook::MyEndScene)
|
||||
);
|
||||
EndHook();
|
||||
|
||||
pDevice->Release();
|
||||
pD3D->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void DX9_Hook::resetRenderState()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
initialized = false;
|
||||
|
||||
ImGui_ImplDX9_Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void DX9_Hook::prepareForOverlay(IDirect3DDevice9 *pDevice)
|
||||
{
|
||||
IDirect3DSwapChain9* pSwapChain;
|
||||
pDevice->GetSwapChain(0, &pSwapChain);
|
||||
D3DPRESENT_PARAMETERS PresentParameters;
|
||||
pSwapChain->GetPresentParameters(&PresentParameters);
|
||||
|
||||
pSwapChain->Release();
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.IniFilename = NULL;
|
||||
|
||||
D3DDEVICE_CREATION_PARAMETERS param;
|
||||
pDevice->GetCreationParameters(¶m);
|
||||
|
||||
Hook_Manager::Inst().ChangeGameWindow(param.hFocusWindow);
|
||||
ImGui_ImplWin32_Init(param.hFocusWindow);
|
||||
ImGui_ImplDX9_Init(pDevice);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
ImGui_ImplDX9_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
Hook_Manager::Inst().CallOverlayProc(PresentParameters.BackBufferWidth, PresentParameters.BackBufferHeight);
|
||||
|
||||
ImGui::EndFrame();
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// DirectX 9 Initialization functions
|
||||
IDirect3D9* DX9_Hook::MyDirect3DCreate9(UINT SDKVersion)
|
||||
{
|
||||
auto res = hook->Direct3DCreate9(SDKVersion);
|
||||
|
||||
if( res != nullptr )
|
||||
hook->hook_dx9(SDKVersion);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT DX9_Hook::MyDirect3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppDevice)
|
||||
{
|
||||
auto res = hook->Direct3DCreate9Ex(SDKVersion, ppDevice);
|
||||
|
||||
if (SUCCEEDED(res))
|
||||
hook->hook_dx9(SDKVersion);
|
||||
|
||||
return res;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX9_Hook::MyReset(IDirect3DDevice9* _this, D3DPRESENT_PARAMETERS* pPresentationParameters)
|
||||
{
|
||||
hook->resetRenderState();
|
||||
return (_this->*hook->Reset)(pPresentationParameters);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX9_Hook::MyEndScene(IDirect3DDevice9* _this)
|
||||
{
|
||||
//if( !hook->uses_present )
|
||||
hook->prepareForOverlay(_this);
|
||||
return (_this->*hook->EndScene)();
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX9_Hook::MyPresent(IDirect3DDevice9* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
|
||||
{
|
||||
hook->prepareForOverlay(_this);
|
||||
return (_this->*hook->Present)(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DX9_Hook::MyPresentEx(IDirect3DDevice9Ex* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags)
|
||||
{
|
||||
hook->prepareForOverlay(_this);
|
||||
return (_this->*hook->PresentEx)(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
|
||||
}
|
||||
|
||||
|
||||
DX9_Hook::DX9_Hook():
|
||||
initialized(false),
|
||||
uses_present(false)
|
||||
{
|
||||
_dll = GetModuleHandle(DLL_NAME);
|
||||
_hooked = false;
|
||||
// Hook to Direct3DCreate9 and Direct3DCreate9Ex so we know when it gets called.
|
||||
// If its called, then DX9 will be used to render the overlay.
|
||||
Direct3DCreate9 = (decltype(Direct3DCreate9))GetProcAddress(_dll, "Direct3DCreate9");
|
||||
Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(_dll, "Direct3DCreate9Ex");
|
||||
|
||||
BeginHook();
|
||||
HookFuncs(
|
||||
std::make_pair<void**, void*>(&(PVOID&)Direct3DCreate9, &DX9_Hook::MyDirect3DCreate9),
|
||||
std::make_pair<void**, void*>(&(PVOID&)Direct3DCreate9Ex, &DX9_Hook::MyDirect3DCreate9Ex)
|
||||
);
|
||||
EndHook();
|
||||
}
|
||||
|
||||
DX9_Hook::~DX9_Hook()
|
||||
{
|
||||
PRINT_DEBUG("DX9 Hook removed\n");
|
||||
|
||||
if (_hooked)
|
||||
{
|
||||
ImGui_ImplDX9_Shutdown();
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
hook = nullptr;
|
||||
}
|
||||
|
||||
void DX9_Hook::Create()
|
||||
{
|
||||
if( hook == nullptr )
|
||||
{
|
||||
hook = new DX9_Hook;
|
||||
// Register the hook to the Hook Manager
|
||||
Hook_Manager::Inst().AddHook(hook);
|
||||
}
|
||||
}
|
||||
|
||||
void DX9_Hook::loadFunctions(IDirect3DDevice9Ex* obj)
|
||||
{
|
||||
void** vTable = *reinterpret_cast<void***>(obj);
|
||||
|
||||
#define LOAD_FUNC(X) (void*&)X = vTable[(int)IDirect3DDevice9VTable::X]
|
||||
LOAD_FUNC(Reset);
|
||||
LOAD_FUNC(EndScene);
|
||||
LOAD_FUNC(Present);
|
||||
LOAD_FUNC(PresentEx);
|
||||
#undef LOAD_FUNC
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef __INCLUDED_DX9_HOOK_H__
|
||||
#define __INCLUDED_DX9_HOOK_H__
|
||||
|
||||
#include <d3d9.h>
|
||||
#include "DirectX_VTables.h"
|
||||
#include "Base_Hook.h"
|
||||
|
||||
class DX9_Hook : public Base_Hook
|
||||
{
|
||||
public:
|
||||
static constexpr const char DLL_NAME[] = "d3d9.dll";
|
||||
|
||||
private:
|
||||
// Variables
|
||||
bool initialized;
|
||||
bool uses_present;
|
||||
|
||||
// Functions
|
||||
DX9_Hook();
|
||||
virtual ~DX9_Hook();
|
||||
|
||||
void hook_dx9(UINT SDKVersion);
|
||||
void resetRenderState();
|
||||
void prepareForOverlay(IDirect3DDevice9* pDevice);
|
||||
|
||||
// Hook to render functions
|
||||
decltype(&IDirect3DDevice9::Reset) Reset;
|
||||
decltype(&IDirect3DDevice9::EndScene) EndScene;
|
||||
decltype(&IDirect3DDevice9::Present) Present;
|
||||
decltype(&IDirect3DDevice9Ex::PresentEx) PresentEx;
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE MyReset(IDirect3DDevice9* _this, D3DPRESENT_PARAMETERS* pPresentationParameters);
|
||||
static HRESULT STDMETHODCALLTYPE MyEndScene(IDirect3DDevice9 *_this);
|
||||
static HRESULT STDMETHODCALLTYPE MyPresent(IDirect3DDevice9* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion);
|
||||
static HRESULT STDMETHODCALLTYPE MyPresentEx(IDirect3DDevice9Ex* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags);
|
||||
|
||||
// Hook functions so we know we use DX9
|
||||
static decltype(Direct3DCreate9) MyDirect3DCreate9;
|
||||
static decltype(Direct3DCreate9Ex) MyDirect3DCreate9Ex;
|
||||
|
||||
decltype(Direct3DCreate9)* Direct3DCreate9;
|
||||
decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex;
|
||||
|
||||
public:
|
||||
static void Create(); // Initialize DX9 Hook.
|
||||
|
||||
void loadFunctions(IDirect3DDevice9Ex *obj);
|
||||
};
|
||||
|
||||
#endif//__INCLUDED_DX9_HOOK_H__
|
|
@ -0,0 +1,330 @@
|
|||
#pragma once
|
||||
|
||||
#include <DXGI.h>
|
||||
|
||||
enum class IDXGISwapChainVTable
|
||||
{
|
||||
// IUnknown
|
||||
QueryInterface,
|
||||
AddRef,
|
||||
Release,
|
||||
|
||||
// IDXGIObject
|
||||
SetPrivateData,
|
||||
SetPrivateDataInterface,
|
||||
GetPrivateData,
|
||||
GetParent,
|
||||
|
||||
// IDXGIDeviceSubObject
|
||||
GetDevice,
|
||||
|
||||
// IDXGISwapChain
|
||||
Present,
|
||||
GetBuffer,
|
||||
SetFullscreenState,
|
||||
GetFullscreenState,
|
||||
GetDesc,
|
||||
ResizeBuffers,
|
||||
ResizeTarget,
|
||||
GetContainingOutput,
|
||||
GetFrameStatistics,
|
||||
GetLastPresentCount,
|
||||
};
|
||||
|
||||
enum class ID3D11DeviceVTable
|
||||
{
|
||||
// IUnknown
|
||||
QueryInterface,
|
||||
AddRef,
|
||||
Release,
|
||||
|
||||
// ID3D11Device
|
||||
CreateBuffer,
|
||||
CreateTexture1D,
|
||||
CreateTexture2D,
|
||||
CreateTexture3D,
|
||||
CreateShaderResourceView,
|
||||
CreateUnorderedAccessView,
|
||||
CreateRenderTargetView,
|
||||
CreateDepthStencilView,
|
||||
CreateInputLayout,
|
||||
CreateVertexShader,
|
||||
CreateGeometryShader,
|
||||
CreateGeometryShaderWithStreamOutput,
|
||||
CreatePixelShader,
|
||||
CreateHullShader,
|
||||
CreateDomainShader,
|
||||
CreateComputeShader,
|
||||
CreateClassLinkage,
|
||||
CreateBlendState,
|
||||
CreateDepthStencilState,
|
||||
CreateRasterizerState,
|
||||
CreateSamplerState,
|
||||
CreateQuery,
|
||||
CreatePredicate,
|
||||
CreateCounter,
|
||||
CreateDeferredContext,
|
||||
OpenSharedResource,
|
||||
CheckFormatSupport,
|
||||
CheckMultisampleQualityLevels,
|
||||
CheckCounterInfo,
|
||||
CheckCounter,
|
||||
CheckFeatureSupport,
|
||||
GetPrivateData,
|
||||
SetPrivateData,
|
||||
SetPrivateDataInterface,
|
||||
GetFeatureLevel,
|
||||
GetCreationFlags,
|
||||
GetDeviceRemovedReason,
|
||||
GetImmediateContext,
|
||||
SetExceptionMode,
|
||||
GetExceptionMode,
|
||||
};
|
||||
|
||||
enum class ID3D10DeviceVTable
|
||||
{
|
||||
// IUnknown
|
||||
QueryInterface,
|
||||
AddRef,
|
||||
Release,
|
||||
|
||||
// ID3D10Device
|
||||
VSSetConstantBuffers,
|
||||
PSSetShaderResources,
|
||||
PSSetShader,
|
||||
PSSetSamplers,
|
||||
VSSetShader,
|
||||
DrawIndexed,
|
||||
Draw,
|
||||
PSSetConstantBuffers,
|
||||
IASetInputLayout,
|
||||
IASetVertexBuffers,
|
||||
IASetIndexBuffer,
|
||||
DrawIndexedInstanced,
|
||||
DrawInstanced,
|
||||
GSSetConstantBuffers,
|
||||
GSSetShader,
|
||||
IASetPrimitiveTopology,
|
||||
VSSetShaderResources,
|
||||
VSSetSamplers,
|
||||
SetPredication,
|
||||
GSSetShaderResources,
|
||||
GSSetSamplers,
|
||||
OMSetRenderTargets,
|
||||
OMSetBlendState,
|
||||
OMSetDepthStencilState,
|
||||
SOSetTargets,
|
||||
DrawAuto,
|
||||
RSSetState,
|
||||
RSSetViewports,
|
||||
RSSetScissorRects,
|
||||
CopySubresourceRegion,
|
||||
CopyResource,
|
||||
UpdateSubresource,
|
||||
ClearRenderTargetView,
|
||||
ClearDepthStencilView,
|
||||
GenerateMips,
|
||||
ResolveSubresource,
|
||||
VSGetConstantBuffers,
|
||||
PSGetShaderResources,
|
||||
PSGetShader,
|
||||
PSGetSamplers,
|
||||
VSGetShader,
|
||||
PSGetConstantBuffers,
|
||||
IAGetInputLayout,
|
||||
IAGetVertexBuffers,
|
||||
IAGetIndexBuffer,
|
||||
GSGetConstantBuffers,
|
||||
GSGetShader,
|
||||
IAGetPrimitiveTopology,
|
||||
VSGetShaderResources,
|
||||
VSGetSamplers,
|
||||
GetPredication,
|
||||
GSGetShaderResources,
|
||||
GSGetSamplers,
|
||||
OMGetRenderTargets,
|
||||
OMGetBlendState,
|
||||
OMGetDepthStencilState,
|
||||
SOGetTargets,
|
||||
RSGetState,
|
||||
RSGetViewports,
|
||||
RSGetScissorRects,
|
||||
GetDeviceRemovedReason,
|
||||
SetExceptionMode,
|
||||
GetExceptionMode,
|
||||
GetPrivateData,
|
||||
SetPrivateData,
|
||||
SetPrivateDataInterface,
|
||||
ClearState,
|
||||
Flush,
|
||||
CreateBuffer,
|
||||
CreateTexture1D,
|
||||
CreateTexture2D,
|
||||
CreateTexture3D,
|
||||
CreateShaderResourceView,
|
||||
CreateRenderTargetView,
|
||||
CreateDepthStencilView,
|
||||
CreateInputLayout,
|
||||
CreateVertexShader,
|
||||
CreateGeometryShader,
|
||||
CreateGeometryShaderWithStreamOutput,
|
||||
CreatePixelShader,
|
||||
CreateBlendState,
|
||||
CreateDepthStencilState,
|
||||
CreateRasterizerState,
|
||||
CreateSamplerState,
|
||||
CreateQuery,
|
||||
CreatePredicate,
|
||||
CreateCounter,
|
||||
CheckFormatSupport,
|
||||
CheckMultisampleQualityLevels,
|
||||
CheckCounterInfo,
|
||||
CheckCounter,
|
||||
GetCreationFlags,
|
||||
OpenSharedResource,
|
||||
SetTextFilterSize,
|
||||
GetTextFilterSize,
|
||||
};
|
||||
|
||||
enum class IDirect3DDevice9VTable
|
||||
{
|
||||
// IUnknown
|
||||
QueryInterface,
|
||||
AddRef,
|
||||
Release,
|
||||
|
||||
// IDirect3DDevice9
|
||||
TestCooperativeLevel,
|
||||
GetAvailableTextureMem,
|
||||
EvictManagedResources,
|
||||
GetDirect3D,
|
||||
GetDeviceCaps,
|
||||
GetDisplayMode,
|
||||
GetCreationParameters,
|
||||
SetCursorProperties,
|
||||
SetCursorPosition,
|
||||
ShowCursor,
|
||||
CreateAdditionalSwapChain,
|
||||
GetSwapChain,
|
||||
GetNumberOfSwapChains,
|
||||
Reset,
|
||||
Present,
|
||||
GetBackBuffer,
|
||||
GetRasterStatus,
|
||||
SetDialogBoxMode,
|
||||
SetGammaRamp,
|
||||
GetGammaRamp,
|
||||
CreateTexture,
|
||||
CreateVolumeTexture,
|
||||
CreateCubeTexture,
|
||||
CreateVertexBuffer,
|
||||
CreateIndexBuffer,
|
||||
CreateRenderTarget,
|
||||
CreateDepthStencilSurface,
|
||||
UpdateSurface,
|
||||
UpdateTexture,
|
||||
GetRenderTargetData,
|
||||
GetFrontBufferData,
|
||||
StretchRect,
|
||||
ColorFill,
|
||||
CreateOffscreenPlainSurface,
|
||||
SetRenderTarget,
|
||||
GetRenderTarget,
|
||||
SetDepthStencilSurface,
|
||||
GetDepthStencilSurface,
|
||||
BeginScene,
|
||||
EndScene,
|
||||
Clear,
|
||||
SetTransform,
|
||||
GetTransform,
|
||||
MultiplyTransform,
|
||||
SetViewport,
|
||||
GetViewport,
|
||||
SetMaterial,
|
||||
GetMaterial,
|
||||
SetLight,
|
||||
GetLight,
|
||||
LightEnable,
|
||||
GetLightEnable,
|
||||
SetClipPlane,
|
||||
GetClipPlane,
|
||||
SetRenderState,
|
||||
GetRenderState,
|
||||
CreateStateBlock,
|
||||
BeginStateBlock,
|
||||
EndStateBlock,
|
||||
SetClipStatus,
|
||||
GetClipStatus,
|
||||
GetTexture,
|
||||
SetTexture,
|
||||
GetTextureStageState,
|
||||
SetTextureStageState,
|
||||
GetSamplerState,
|
||||
SetSamplerState,
|
||||
ValidateDevice,
|
||||
SetPaletteEntries,
|
||||
GetPaletteEntries,
|
||||
SetCurrentTexturePalette,
|
||||
GetCurrentTexturePalette,
|
||||
SetScissorRect,
|
||||
GetScissorRect,
|
||||
SetSoftwareVertexProcessing,
|
||||
GetSoftwareVertexProcessing,
|
||||
SetNPatchMode,
|
||||
GetNPatchMode,
|
||||
DrawPrimitive,
|
||||
DrawIndexedPrimitive,
|
||||
DrawPrimitiveUP,
|
||||
DrawIndexedPrimitiveUP,
|
||||
ProcessVertices,
|
||||
CreateVertexDeclaration,
|
||||
SetVertexDeclaration,
|
||||
GetVertexDeclaration,
|
||||
SetFVF,
|
||||
GetFVF,
|
||||
CreateVertexShader,
|
||||
SetVertexShader,
|
||||
GetVertexShader,
|
||||
SetVertexShaderConstantF,
|
||||
GetVertexShaderConstantF,
|
||||
SetVertexShaderConstantI,
|
||||
GetVertexShaderConstantI,
|
||||
SetVertexShaderConstantB,
|
||||
GetVertexShaderConstantB,
|
||||
SetStreamSource,
|
||||
GetStreamSource,
|
||||
SetStreamSourceFreq,
|
||||
GetStreamSourceFreq,
|
||||
SetIndices,
|
||||
GetIndices,
|
||||
CreatePixelShader,
|
||||
SetPixelShader,
|
||||
GetPixelShader,
|
||||
SetPixelShaderConstantF,
|
||||
GetPixelShaderConstantF,
|
||||
SetPixelShaderConstantI,
|
||||
GetPixelShaderConstantI,
|
||||
SetPixelShaderConstantB,
|
||||
GetPixelShaderConstantB,
|
||||
DrawRectPatch,
|
||||
DrawTriPatch,
|
||||
DeletePatch,
|
||||
CreateQuery,
|
||||
|
||||
// IDirect3DDevice9Ex
|
||||
SetConvolutionMonoKernel,
|
||||
ComposeRects,
|
||||
PresentEx,
|
||||
GetGPUThreadPriority,
|
||||
SetGPUThreadPriority,
|
||||
WaitForVBlank,
|
||||
CheckResourceResidency,
|
||||
SetMaximumFrameLatency,
|
||||
GetMaximumFrameLatency,
|
||||
CheckDeviceState,
|
||||
CreateRenderTargetEx,
|
||||
CreateOffscreenPlainSurfaceEx,
|
||||
CreateDepthStencilSurfaceEx,
|
||||
ResetEx,
|
||||
GetDisplayModeEx,
|
||||
};
|
|
@ -0,0 +1,178 @@
|
|||
#include "../dll/dll.h"
|
||||
#include "Hook_Manager.h"
|
||||
|
||||
#include "../detours/detours.h"
|
||||
|
||||
#include "DX12_Hook.h"
|
||||
#include "DX11_Hook.h"
|
||||
#include "DX10_Hook.h"
|
||||
#include "DX9_Hook.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
decltype(LoadLibraryA )* _LoadLibraryA = LoadLibraryA;
|
||||
decltype(LoadLibraryW )* _LoadLibraryW = LoadLibraryW;
|
||||
decltype(LoadLibraryExA )* _LoadLibraryExA = LoadLibraryExA;
|
||||
decltype(LoadLibraryExW )* _LoadLibraryExW = LoadLibraryExW;
|
||||
|
||||
void create_hookA(const char* libname)
|
||||
{
|
||||
if (!strcmp(libname, "d3d9.dll"))
|
||||
DX9_Hook::Create();
|
||||
else if (!strcmp(libname, "d3d10.dll"))
|
||||
DX10_Hook::Create();
|
||||
else if (!strcmp(libname, "d3d11.dll"))
|
||||
DX11_Hook::Create();
|
||||
else if (!strcmp(libname, "d3d12.dll"))
|
||||
DX12_Hook::Create();
|
||||
}
|
||||
|
||||
void create_hookW(const wchar_t *libname)
|
||||
{
|
||||
if (!wcscmp(libname, L"d3d9.dll"))
|
||||
DX9_Hook::Create();
|
||||
else if (!wcscmp(libname, L"d3d10.dll"))
|
||||
DX10_Hook::Create();
|
||||
else if (!wcscmp(libname, L"d3d11.dll"))
|
||||
DX11_Hook::Create();
|
||||
else if (!wcscmp(libname, L"d3d12.dll"))
|
||||
DX12_Hook::Create();
|
||||
}
|
||||
|
||||
HMODULE WINAPI mLoadLibraryA(LPCTSTR lpLibFileName)
|
||||
{
|
||||
auto res = _LoadLibraryA(lpLibFileName);
|
||||
create_hookA(lpLibFileName);
|
||||
return res;
|
||||
}
|
||||
|
||||
HMODULE WINAPI mLoadLibraryW(LPCWSTR lpLibFileName)
|
||||
{
|
||||
auto res = _LoadLibraryW(lpLibFileName);
|
||||
create_hookW(lpLibFileName);
|
||||
return res;
|
||||
}
|
||||
|
||||
HMODULE WINAPI mLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
|
||||
{
|
||||
auto res = _LoadLibraryA(lpLibFileName);
|
||||
create_hookA(lpLibFileName);
|
||||
return res;
|
||||
}
|
||||
|
||||
HMODULE WINAPI mLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
|
||||
{
|
||||
auto res = _LoadLibraryExW(lpLibFileName, hFile, dwFlags);
|
||||
create_hookW(lpLibFileName);
|
||||
return res;
|
||||
}
|
||||
|
||||
Hook_Manager::Hook_Manager():
|
||||
_isSet(false),
|
||||
_LoadLibraryHooked(false)
|
||||
{}
|
||||
|
||||
Hook_Manager::~Hook_Manager()
|
||||
{
|
||||
for (auto& i : _hooks)
|
||||
delete i;
|
||||
}
|
||||
|
||||
Hook_Manager& Hook_Manager::Inst()
|
||||
{
|
||||
static Hook_Manager hook;
|
||||
return hook;
|
||||
}
|
||||
|
||||
void Hook_Manager::HookRenderer(Steam_Overlay *ovlay)
|
||||
{
|
||||
overlay = ovlay;
|
||||
HookLoadLibrary();
|
||||
std::vector<std::string> const libraries = { "d3d12.dll", "d3d11.dll", "d3d10.dll", "d3d9.dll" };
|
||||
std::vector<std::string>::const_iterator it = libraries.begin();
|
||||
while (it != libraries.end())
|
||||
{
|
||||
it = std::find_if(it, libraries.end(), [](std::string const& name) {
|
||||
auto x = GetModuleHandle(name.c_str());
|
||||
if (x != 0 && x != INVALID_HANDLE_VALUE)
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (it == libraries.end())
|
||||
break;
|
||||
|
||||
if (*it == "d3d9.dll")
|
||||
DX9_Hook::Create();
|
||||
else if (*it == "d3d10.dll")
|
||||
DX10_Hook::Create();
|
||||
else if (*it == "d3d11.dll")
|
||||
DX11_Hook::Create();
|
||||
else if (*it == "d3d12.dll")
|
||||
DX12_Hook::Create();
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void Hook_Manager::UnHookLoadLibrary()
|
||||
{
|
||||
_LoadLibraryHooked = false;
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourDetach((PVOID*)& _LoadLibraryA, mLoadLibraryA);
|
||||
DetourDetach((PVOID*)& _LoadLibraryW, mLoadLibraryW);
|
||||
DetourDetach((PVOID*)& _LoadLibraryExA, mLoadLibraryExA);
|
||||
DetourDetach((PVOID*)& _LoadLibraryExW, mLoadLibraryExW);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
void Hook_Manager::HookLoadLibrary()
|
||||
{
|
||||
if (!_isSet && !_LoadLibraryHooked)
|
||||
{
|
||||
_LoadLibraryHooked = true;
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach((PVOID*)& _LoadLibraryA, mLoadLibraryA);
|
||||
DetourAttach((PVOID*)& _LoadLibraryW, mLoadLibraryW);
|
||||
DetourAttach((PVOID*)& _LoadLibraryExA, mLoadLibraryExA);
|
||||
DetourAttach((PVOID*)& _LoadLibraryExW, mLoadLibraryExW);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
}
|
||||
|
||||
void Hook_Manager::FoundHook(Base_Hook* hook)
|
||||
{
|
||||
if (!_isSet)
|
||||
{
|
||||
_isSet = true;
|
||||
|
||||
UnHookLoadLibrary();
|
||||
|
||||
// Remove all hooks that are unused
|
||||
_hooks.erase(std::remove_if(_hooks.begin(), _hooks.end(), [&hook](Base_Hook* it_hook) {
|
||||
if (hook != it_hook)
|
||||
{
|
||||
delete it_hook;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}), _hooks.end());
|
||||
}
|
||||
}
|
||||
|
||||
void Hook_Manager::ChangeGameWindow(HWND hWnd) const
|
||||
{
|
||||
overlay->HookReady(hWnd);
|
||||
}
|
||||
|
||||
void Hook_Manager::CallOverlayProc(int width, int height) const
|
||||
{
|
||||
overlay->OverlayProc(width, height);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef __INCLUDED_HOOK_BASE_H__
|
||||
#define __INCLUDED_HOOK_BASE_H__
|
||||
|
||||
#include <Windows.h>
|
||||
#include <vector>
|
||||
#include "Base_Hook.h"
|
||||
|
||||
class Hook_Manager
|
||||
{
|
||||
friend class Base_Hook;
|
||||
public:
|
||||
using overlayProc_t = void(*)(int,int);
|
||||
using hookReady_t = void(*)(void*);
|
||||
|
||||
protected:
|
||||
std::vector<Base_Hook*> _hooks;
|
||||
|
||||
WNDPROC _gameWndProc; // The game main windows proc
|
||||
HWND _gameHWnd; // The game main window
|
||||
bool _showOverlay; // Should we render the overlay
|
||||
bool _isSet; // Is the renderer hooked ?
|
||||
bool _LoadLibraryHooked; // Are the LoadLibrary functions hooked ?
|
||||
class Steam_Overlay* overlay;
|
||||
|
||||
Hook_Manager();
|
||||
virtual ~Hook_Manager();
|
||||
|
||||
void HookLoadLibrary();
|
||||
void UnHookLoadLibrary();
|
||||
|
||||
public:
|
||||
static Hook_Manager& Inst();
|
||||
|
||||
void HookRenderer(Steam_Overlay *overlay);
|
||||
|
||||
// Set the found hook and free all other hooks
|
||||
void FoundHook(Base_Hook *hook);
|
||||
|
||||
inline void AddHook(Base_Hook* hook) { _hooks.push_back(hook); }
|
||||
void ChangeGameWindow(HWND hWnd) const;
|
||||
void CallOverlayProc(int width, int height) const;
|
||||
Steam_Overlay* GetOverlay() const { return overlay; }
|
||||
};
|
||||
|
||||
|
||||
#endif//__INCLUDED_HOOK_BASE_H__
|
Loading…
Reference in New Issue