From 44d583ee7dba0c58af385f0b7fc45c27d6c41b73 Mon Sep 17 00:00:00 2001 From: Nemirtingas Date: Tue, 27 Aug 2019 15:38:07 +0200 Subject: [PATCH] Added class Renderer_Detector. Hook_Manager now only manages hooks. Renderer_Detector is used to detect the game's renderer. There will be 2 version of it. 1 for windows and 1 for Linux. --- overlay_experimental/Base_Hook.cpp | 3 +- overlay_experimental/Base_Hook.h | 1 - overlay_experimental/DX10_Hook.cpp | 17 +- overlay_experimental/DX10_Hook.h | 4 +- overlay_experimental/DX11_Hook.cpp | 17 +- overlay_experimental/DX11_Hook.h | 4 +- overlay_experimental/DX12_Hook.cpp | 32 +- overlay_experimental/DX12_Hook.h | 6 +- overlay_experimental/DX9_Hook.cpp | 21 +- overlay_experimental/DX9_Hook.h | 4 +- overlay_experimental/Hook_Manager.cpp | 572 +----------------- overlay_experimental/Hook_Manager.h | 77 +-- overlay_experimental/OpenGL_Hook.cpp | 30 +- overlay_experimental/OpenGL_Hook.h | 5 +- overlay_experimental/Renderer_Detector.cpp | 670 +++++++++++++++++++++ overlay_experimental/Renderer_Detector.h | 68 +++ overlay_experimental/Windows_Hook.cpp | 73 +-- overlay_experimental/Windows_Hook.h | 12 +- overlay_experimental/steam_overlay.cpp | 8 +- 19 files changed, 865 insertions(+), 759 deletions(-) create mode 100644 overlay_experimental/Renderer_Detector.cpp create mode 100644 overlay_experimental/Renderer_Detector.h diff --git a/overlay_experimental/Base_Hook.cpp b/overlay_experimental/Base_Hook.cpp index 3c73584..6189f2a 100644 --- a/overlay_experimental/Base_Hook.cpp +++ b/overlay_experimental/Base_Hook.cpp @@ -12,8 +12,7 @@ #include Base_Hook::Base_Hook(): - _library(nullptr), - _hooked(false) + _library(nullptr) {} Base_Hook::~Base_Hook() diff --git a/overlay_experimental/Base_Hook.h b/overlay_experimental/Base_Hook.h index 55fbfae..28fdcdb 100644 --- a/overlay_experimental/Base_Hook.h +++ b/overlay_experimental/Base_Hook.h @@ -14,7 +14,6 @@ protected: std::vector> _hooked_funcs; void* _library; - bool _hooked; Base_Hook(const Base_Hook&) = delete; Base_Hook(Base_Hook&&) = delete; diff --git a/overlay_experimental/DX10_Hook.cpp b/overlay_experimental/DX10_Hook.cpp index fe0726a..f7895d3 100644 --- a/overlay_experimental/DX10_Hook.cpp +++ b/overlay_experimental/DX10_Hook.cpp @@ -1,6 +1,6 @@ #include "DX10_Hook.h" #include "Windows_Hook.h" -#include "Hook_Manager.h" +#include "Renderer_Detector.h" #include "../dll/dll.h" #ifndef NO_OVERLAY @@ -13,17 +13,16 @@ DX10_Hook* DX10_Hook::_inst = nullptr; bool DX10_Hook::start_hook() { bool res = true; - if (!_hooked) + if (!hooked) { - if (!Windows_Hook::Inst().start_hook()) + if (!Windows_Hook::Inst()->start_hook()) return false; PRINT_DEBUG("Hooked DirectX 10\n"); - _hooked = true; + hooked = true; - Hook_Manager::Inst().FoundRenderer(this); + Renderer_Detector::Inst().renderer_found(this); - UnhookAll(); BeginHook(); HookFuncs( std::make_pair(&(PVOID&)DX10_Hook::Present, &DX10_Hook::MyPresent), @@ -44,7 +43,7 @@ void DX10_Hook::resetRenderState() mainRenderTargetView->Release(); ImGui_ImplDX10_Shutdown(); - Windows_Hook::Inst().resetRenderState(); + Windows_Hook::Inst()->resetRenderState(); ImGui::DestroyContext(); initialized = false; @@ -80,7 +79,7 @@ void DX10_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain) } ImGui_ImplDX10_NewFrame(); - Windows_Hook::Inst().prepareForOverlay(desc.OutputWindow); + Windows_Hook::Inst()->prepareForOverlay(desc.OutputWindow); ImGui::NewFrame(); @@ -138,6 +137,7 @@ HRESULT STDMETHODCALLTYPE DX10_Hook::MyResizeBuffers(IDXGISwapChain* _this, UINT DX10_Hook::DX10_Hook(): initialized(false), + hooked(false), pDevice(nullptr), mainRenderTargetView(nullptr), Present(nullptr), @@ -169,7 +169,6 @@ DX10_Hook::~DX10_Hook() //ImGui_ImplDX10_Shutdown(); ImGui_ImplDX10_InvalidateDeviceObjects(); - Windows_Hook::Inst().resetRenderState(); ImGui::DestroyContext(); initialized = false; diff --git a/overlay_experimental/DX10_Hook.h b/overlay_experimental/DX10_Hook.h index 63bb974..972be00 100644 --- a/overlay_experimental/DX10_Hook.h +++ b/overlay_experimental/DX10_Hook.h @@ -16,13 +16,13 @@ private: static DX10_Hook* _inst; // Variables + bool hooked; bool initialized; ID3D10Device* pDevice; ID3D10RenderTargetView* mainRenderTargetView; // Functions DX10_Hook(); - virtual ~DX10_Hook(); void resetRenderState(); void prepareForOverlay(IDXGISwapChain *pSwapChain); @@ -44,6 +44,8 @@ private: //decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain; public: + virtual ~DX10_Hook(); + bool start_hook(); static DX10_Hook* Inst(); virtual const char* get_lib_name() const; diff --git a/overlay_experimental/DX11_Hook.cpp b/overlay_experimental/DX11_Hook.cpp index 81c4afa..ae728fe 100644 --- a/overlay_experimental/DX11_Hook.cpp +++ b/overlay_experimental/DX11_Hook.cpp @@ -1,6 +1,6 @@ #include "DX11_Hook.h" #include "Windows_Hook.h" -#include "Hook_Manager.h" +#include "Renderer_Detector.h" #include "../dll/dll.h" #ifndef NO_OVERLAY @@ -23,17 +23,16 @@ HRESULT GetDeviceAndCtxFromSwapchain(IDXGISwapChain* pSwapChain, ID3D11Device** bool DX11_Hook::start_hook() { bool res = true; - if (!_hooked) + if (!hooked) { - if (!Windows_Hook::Inst().start_hook()) + if (!Windows_Hook::Inst()->start_hook()) return false; PRINT_DEBUG("Hooked DirectX 11\n"); - _hooked = true; + hooked = true; - Hook_Manager::Inst().FoundRenderer(this); + Renderer_Detector::Inst().renderer_found(this); - UnhookAll(); BeginHook(); HookFuncs( std::make_pair(&(PVOID&)DX11_Hook::Present, &DX11_Hook::MyPresent), @@ -55,7 +54,7 @@ void DX11_Hook::resetRenderState() pContext->Release(); ImGui_ImplDX11_Shutdown(); - Windows_Hook::Inst().resetRenderState(); + Windows_Hook::Inst()->resetRenderState(); ImGui::DestroyContext(); initialized = false; @@ -92,7 +91,7 @@ void DX11_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain) } ImGui_ImplDX11_NewFrame(); - Windows_Hook::Inst().prepareForOverlay(desc.OutputWindow); + Windows_Hook::Inst()->prepareForOverlay(desc.OutputWindow); ImGui::NewFrame(); @@ -155,6 +154,7 @@ HRESULT STDMETHODCALLTYPE DX11_Hook::MyResizeBuffers(IDXGISwapChain* _this, UINT DX11_Hook::DX11_Hook(): initialized(false), + hooked(false), pContext(nullptr), mainRenderTargetView(nullptr), Present(nullptr), @@ -187,7 +187,6 @@ DX11_Hook::~DX11_Hook() //ImGui_ImplDX11_Shutdown(); ImGui_ImplDX11_InvalidateDeviceObjects(); - Windows_Hook::Inst().resetRenderState(); ImGui::DestroyContext(); initialized = false; diff --git a/overlay_experimental/DX11_Hook.h b/overlay_experimental/DX11_Hook.h index c0ceea3..a56bc66 100644 --- a/overlay_experimental/DX11_Hook.h +++ b/overlay_experimental/DX11_Hook.h @@ -16,13 +16,13 @@ private: static DX11_Hook* _inst; // Variables + bool hooked; bool initialized; ID3D11DeviceContext* pContext; ID3D11RenderTargetView* mainRenderTargetView; // Functions DX11_Hook(); - virtual ~DX11_Hook(); void resetRenderState(); void prepareForOverlay(IDXGISwapChain* pSwapChain); @@ -44,6 +44,8 @@ private: //decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain; public: + virtual ~DX11_Hook(); + bool start_hook(); static DX11_Hook* Inst(); virtual const char* get_lib_name() const; diff --git a/overlay_experimental/DX12_Hook.cpp b/overlay_experimental/DX12_Hook.cpp index 2665170..89f0ef6 100644 --- a/overlay_experimental/DX12_Hook.cpp +++ b/overlay_experimental/DX12_Hook.cpp @@ -1,6 +1,6 @@ #include "DX12_Hook.h" #include "Windows_Hook.h" -#include "Hook_Manager.h" +#include "Renderer_Detector.h" #include "../dll/dll.h" #ifndef NO_OVERLAY @@ -15,17 +15,16 @@ DX12_Hook* DX12_Hook::_inst = nullptr; bool DX12_Hook::start_hook() { bool res = true; - if (!_hooked) + if (!hooked) { - if (!Windows_Hook::Inst().start_hook()) + if (!Windows_Hook::Inst()->start_hook()) return false; PRINT_DEBUG("Hooked DirectX 12\n"); - _hooked = true; + hooked = true; - Hook_Manager::Inst().FoundRenderer(this); + Renderer_Detector::Inst().renderer_found(this); - UnhookAll(); BeginHook(); HookFuncs( std::make_pair(&(PVOID&)DX12_Hook::Present, &DX12_Hook::MyPresent), @@ -48,7 +47,7 @@ void DX12_Hook::resetRenderState() pSrvDescHeap->Release(); ImGui_ImplDX12_Shutdown(); - Windows_Hook::Inst().resetRenderState(); + Windows_Hook::Inst()->resetRenderState(); ImGui::DestroyContext(); initialized = false; @@ -147,7 +146,7 @@ void STDMETHODCALLTYPE DX12_Hook::MyExecuteCommandLists(ID3D12CommandQueue *_thi if (((ID3D12GraphicsCommandList*)ppCommandLists[i])->GetType() == D3D12_COMMAND_LIST_TYPE_DIRECT) { ImGui_ImplDX12_NewFrame(); - Windows_Hook::Inst().prepareForOverlay(me->sc_desc.OutputWindow); + Windows_Hook::Inst()->prepareForOverlay(me->sc_desc.OutputWindow); ImGui::NewFrame(); @@ -174,7 +173,14 @@ HRESULT STDMETHODCALLTYPE DX12_Hook::MyClose(ID3D12GraphicsCommandList* _this) } DX12_Hook::DX12_Hook(): - initialized(false) + initialized(false), + hooked(false), + pSrvDescHeap(nullptr), + Present(nullptr), + ResizeBuffers(nullptr), + ResizeTarget(nullptr), + ExecuteCommandLists(nullptr), + Close(nullptr) { _library = LoadLibrary(DLL_NAME); @@ -199,7 +205,6 @@ DX12_Hook::~DX12_Hook() { //ImGui_ImplDX12_Shutdown(); ImGui_ImplDX12_InvalidateDeviceObjects(); - Windows_Hook::Inst().resetRenderState(); ImGui::DestroyContext(); initialized = false; @@ -223,10 +228,15 @@ const char* DX12_Hook::get_lib_name() const return DLL_NAME; } -void DX12_Hook::loadFunctions(ID3D12CommandList* pCommandList, IDXGISwapChain *pSwapChain) +void DX12_Hook::loadFunctions(ID3D12CommandQueue* pCommandQueue, ID3D12GraphicsCommandList* pCommandList, IDXGISwapChain *pSwapChain) { void** vTable; + vTable = *reinterpret_cast(pCommandList); +#define LOAD_FUNC(X) (void*&)X = vTable[(int)ID3D12CommandQueueVTable::X] + LOAD_FUNC(ExecuteCommandLists); +#undef LOAD_FUNC + vTable = *reinterpret_cast(pCommandList); #define LOAD_FUNC(X) (void*&)X = vTable[(int)ID3D12GraphicsCommandListVTable::X] LOAD_FUNC(Close); diff --git a/overlay_experimental/DX12_Hook.h b/overlay_experimental/DX12_Hook.h index 4556c52..7bf7fa4 100644 --- a/overlay_experimental/DX12_Hook.h +++ b/overlay_experimental/DX12_Hook.h @@ -17,6 +17,7 @@ private: static DX12_Hook* _inst; // Variables + bool hooked; bool initialized; DXGI_SWAP_CHAIN_DESC sc_desc; @@ -24,7 +25,6 @@ private: // Functions DX12_Hook(); - virtual ~DX12_Hook(); void resetRenderState(); void prepareForOverlay(IDXGISwapChain* pSwapChain); @@ -48,11 +48,13 @@ private: //decltype(D3D12CreateDevice)* D3D12CreateDevice; public: + virtual ~DX12_Hook(); + bool start_hook(); static DX12_Hook* Inst(); virtual const char* get_lib_name() const; - void loadFunctions(ID3D12CommandList *pCommandList, IDXGISwapChain *pSwapChain); + void loadFunctions(ID3D12CommandQueue* pCommandQueue, ID3D12GraphicsCommandList* pCommandList, IDXGISwapChain* pSwapChain); }; #endif//NO_OVERLAY diff --git a/overlay_experimental/DX9_Hook.cpp b/overlay_experimental/DX9_Hook.cpp index e5a0113..f663b01 100644 --- a/overlay_experimental/DX9_Hook.cpp +++ b/overlay_experimental/DX9_Hook.cpp @@ -1,6 +1,6 @@ #include "DX9_Hook.h" #include "Windows_Hook.h" -#include "Hook_Manager.h" +#include "Renderer_Detector.h" #include "../dll/dll.h" #ifndef NO_OVERLAY @@ -14,17 +14,16 @@ DX9_Hook* DX9_Hook::_inst = nullptr; bool DX9_Hook::start_hook() { - if (!_hooked) + if (!hooked) { - if (!Windows_Hook::Inst().start_hook()) + if (!Windows_Hook::Inst()->start_hook()) return false; PRINT_DEBUG("Hooked DirectX 9\n"); - _hooked = true; - - Hook_Manager::Inst().FoundRenderer(this); + hooked = true; - UnhookAll(); + Renderer_Detector::Inst().renderer_found(this); + BeginHook(); HookFuncs( std::make_pair(&(PVOID&)Reset, &DX9_Hook::MyReset), @@ -50,7 +49,7 @@ void DX9_Hook::resetRenderState() { initialized = false; ImGui_ImplDX9_Shutdown(); - Windows_Hook::Inst().resetRenderState(); + Windows_Hook::Inst()->resetRenderState(); ImGui::DestroyContext(); } } @@ -68,7 +67,7 @@ void DX9_Hook::prepareForOverlay(IDirect3DDevice9 *pDevice) pDevice->GetCreationParameters(¶m); // Workaround to detect if we changed window. - if (param.hFocusWindow != Windows_Hook::Inst().GetGameHwnd()) + if (param.hFocusWindow != Windows_Hook::Inst()->GetGameHwnd()) resetRenderState(); if (!initialized) @@ -82,7 +81,7 @@ void DX9_Hook::prepareForOverlay(IDirect3DDevice9 *pDevice) } ImGui_ImplDX9_NewFrame(); - Windows_Hook::Inst().prepareForOverlay(param.hFocusWindow); + Windows_Hook::Inst()->prepareForOverlay(param.hFocusWindow); ImGui::NewFrame(); @@ -147,6 +146,7 @@ HRESULT STDMETHODCALLTYPE DX9_Hook::MyPresentEx(IDirect3DDevice9Ex* _this, CONST DX9_Hook::DX9_Hook(): initialized(false), + hooked(false), uses_present(false), EndScene(nullptr), Present(nullptr), @@ -177,7 +177,6 @@ DX9_Hook::~DX9_Hook() //ImGui_ImplDX9_Shutdown(); This makes some games hang when Releasing the D3D9 device (pDevice->Release()) // maybe because D3D is already shut down when we try to free the device? ImGui_ImplDX9_InvalidateDeviceObjects(); - Windows_Hook::Inst().resetRenderState(); ImGui::DestroyContext(); } diff --git a/overlay_experimental/DX9_Hook.h b/overlay_experimental/DX9_Hook.h index 6239f1b..28f35ab 100644 --- a/overlay_experimental/DX9_Hook.h +++ b/overlay_experimental/DX9_Hook.h @@ -16,12 +16,12 @@ private: static DX9_Hook* _inst; // Variables + bool hooked; bool initialized; bool uses_present; // Functions DX9_Hook(); - virtual ~DX9_Hook(); void resetRenderState(); void prepareForOverlay(IDirect3DDevice9* pDevice); @@ -45,6 +45,8 @@ private: //decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex; public: + virtual ~DX9_Hook(); + bool start_hook(); static DX9_Hook* Inst(); virtual const char* get_lib_name() const; diff --git a/overlay_experimental/Hook_Manager.cpp b/overlay_experimental/Hook_Manager.cpp index ca6523c..b1888e5 100644 --- a/overlay_experimental/Hook_Manager.cpp +++ b/overlay_experimental/Hook_Manager.cpp @@ -3,545 +3,7 @@ #ifndef NO_OVERLAY -#include "../detours/detours.h" - -#ifdef STEAM_WIN32 -#include "DX12_Hook.h" -#include "DX11_Hook.h" -#include "DX10_Hook.h" -#include "DX9_Hook.h" -#include "Windows_Hook.h" -#endif - -#include "OpenGL_Hook.h" - -#include - -constexpr int max_hook_retries = 500; - -#ifdef STEAM_WIN32 -static decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present = nullptr; -static decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present = nullptr; -static decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx = nullptr; -static decltype(wglMakeCurrent)* _wglMakeCurrent = nullptr; - -HRESULT STDMETHODCALLTYPE Hook_Manager::MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags) -{ - Hook_Manager& inst = Hook_Manager::Inst(); - if (!inst.stop_retry()) - { - IUnknown* pDevice = nullptr; - _this->GetDevice(__uuidof(ID3D10Device), (void**)&pDevice); - if (pDevice) - { - DX10_Hook* hook = DX10_Hook::Inst(); - if (hook->start_hook()) - inst.AddHook(hook); - } - else - { - _this->GetDevice(__uuidof(ID3D11Device), (void**)& pDevice); - if (pDevice) - { - DX11_Hook* hook = DX11_Hook::Inst(); - if (hook->start_hook()) - inst.AddHook(hook); - } - else - { - //_this->GetDevice(__uuidof(ID3D12Device), (void**)& pDevice); - //if (pDevice) - //{ - // DX12_Hook* hook = DX12_Hook::Inst(); - // if (hook->start_hook()) - // inst.AddHook(hook); - //} - } - } - if (pDevice) pDevice->Release(); - } - - return (_this->*_IDXGISwapChain_Present)(SyncInterval, Flags); -} - -HRESULT STDMETHODCALLTYPE Hook_Manager::MyPresent(IDirect3DDevice9* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) -{ - Hook_Manager& inst = Hook_Manager::Inst(); - if (!inst.stop_retry()) - { - DX9_Hook* hook = DX9_Hook::Inst(); - if (hook->start_hook()) - inst.AddHook(hook); - } - return (_this->*_IDirect3DDevice9_Present)(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); -} - -HRESULT STDMETHODCALLTYPE Hook_Manager::MyPresentEx(IDirect3DDevice9Ex* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) -{ - Hook_Manager& inst = Hook_Manager::Inst(); - if (!inst.stop_retry()) - { - DX9_Hook* hook = DX9_Hook::Inst(); - if (hook->start_hook()) - inst.AddHook(hook); - } - return (_this->*_IDirect3DDevice9Ex_PresentEx)(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags); -} - -BOOL WINAPI Hook_Manager::MywglMakeCurrent(HDC hDC, HGLRC hGLRC) -{ - Hook_Manager& inst = Hook_Manager::Inst(); - if (!inst.stop_retry()) - { - OpenGL_Hook* hook = OpenGL_Hook::Inst(); - if (hook->start_hook()) - inst.AddHook(hook); - } - return _wglMakeCurrent(hDC, hGLRC); -} - -void Hook_Manager::HookDXGIPresent(IDXGISwapChain *pSwapChain) -{ - if (!_dxgi_hooked) - { - _dxgi_hooked = true; - (void*&)_IDXGISwapChain_Present = (*reinterpret_cast(pSwapChain))[(int)IDXGISwapChainVTable::Present]; - - rendererdetect_hook->BeginHook(); - - rendererdetect_hook->HookFuncs( - std::pair((PVOID*)& _IDXGISwapChain_Present, &Hook_Manager::MyIDXGISwapChain_Present) - ); - - rendererdetect_hook->EndHook(); - } -} - -void Hook_Manager::HookDX9Present(IDirect3DDevice9* pDevice, bool ex) -{ - if (!_dx9_hooked) - { - _dx9_hooked = true; - (void*&)_IDirect3DDevice9_Present = (*reinterpret_cast(pDevice))[(int)IDirect3DDevice9VTable::Present]; - if (ex) - (void*&)_IDirect3DDevice9Ex_PresentEx = (*reinterpret_cast(pDevice))[(int)IDirect3DDevice9VTable::PresentEx]; - - rendererdetect_hook->BeginHook(); - - rendererdetect_hook->HookFuncs( - std::pair((PVOID*)& _IDirect3DDevice9_Present, &Hook_Manager::MyPresent) - ); - if (ex) - { - rendererdetect_hook->HookFuncs( - std::pair((PVOID*)& _IDirect3DDevice9Ex_PresentEx, &Hook_Manager::MyPresentEx) - ); - } - - rendererdetect_hook->EndHook(); - } -} - -void Hook_Manager::HookwglMakeCurrent(BOOL(WINAPI* wglMakeCurrent)(HDC, HGLRC)) -{ - if (!_ogl_hooked) - { - _ogl_hooked = true; - - _wglMakeCurrent = wglMakeCurrent; - - rendererdetect_hook->BeginHook(); - - rendererdetect_hook->HookFuncs( - std::pair((PVOID*)& _wglMakeCurrent, &Hook_Manager::MywglMakeCurrent) - ); - - rendererdetect_hook->EndHook(); - } -} - -void Hook_Manager::hook_dx9() -{ - if (!_dx9_hooked && !_renderer_found) - { - HWND hWnd = GetGameWindow(); - if (!hWnd) - return; - - IDirect3D9Ex* pD3D = nullptr; - IUnknown* pDevice = nullptr; - HMODULE library = GetModuleHandle(DX9_Hook::DLL_NAME); - decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = nullptr; - if (library != nullptr) - { - Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(library, "Direct3DCreate9Ex"); - D3DPRESENT_PARAMETERS params = {}; - params.BackBufferWidth = 1; - params.BackBufferHeight = 1; - params.hDeviceWindow = hWnd; - params.BackBufferCount = 1; - params.Windowed = TRUE; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - - if (Direct3DCreate9Ex != nullptr) - { - Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D); - pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, reinterpret_cast(&pDevice)); - } - else - { - decltype(Direct3DCreate9)* Direct3DCreate9 = (decltype(Direct3DCreate9))GetProcAddress(library, "Direct3DCreate9"); - if (Direct3DCreate9 != nullptr) - { - pD3D = reinterpret_cast(Direct3DCreate9(D3D_SDK_VERSION)); - pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, reinterpret_cast(&pDevice)); - } - } - } - - if (pDevice != nullptr) - { - PRINT_DEBUG("Hooked D3D9::Present to detect DX Version\n"); - auto h = DX9_Hook::Inst(); - h->loadFunctions(reinterpret_cast(pDevice), Direct3DCreate9Ex != nullptr); - _hooks.insert(h); - HookDX9Present(reinterpret_cast(pDevice), Direct3DCreate9Ex != nullptr); - } - else - { - PRINT_DEBUG("Failed to hook D3D9::Present to detect DX Version\n"); - } - - if (pDevice) pDevice->Release(); - if (pD3D) pD3D->Release(); - } -} - -void Hook_Manager::hook_dx10() -{ - if (!_dxgi_hooked && !_renderer_found) - { - HWND hWnd = GetGameWindow(); - if (!hWnd) - return; - - IDXGISwapChain* pSwapChain = nullptr; - ID3D10Device* pDevice = nullptr; - HMODULE library = GetModuleHandle(DX10_Hook::DLL_NAME); - if (library != nullptr) - { - decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain = - (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(library, "D3D10CreateDeviceAndSwapChain"); - if (D3D10CreateDeviceAndSwapChain != nullptr) - { - DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; - - SwapChainDesc.BufferCount = 1; - SwapChainDesc.BufferDesc.Width = 1; - SwapChainDesc.BufferDesc.Height = 1; - SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; - SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; - SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - SwapChainDesc.OutputWindow = hWnd; - SwapChainDesc.SampleDesc.Count = 1; - SwapChainDesc.SampleDesc.Quality = 0; - SwapChainDesc.Windowed = TRUE; - - D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_NULL, NULL, 0, D3D10_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDevice); - } - } - if (pSwapChain != nullptr) - { - PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); - auto h = DX10_Hook::Inst(); - h->loadFunctions(pSwapChain); - _hooks.insert(h); - HookDXGIPresent(pSwapChain); - } - else - { - PRINT_DEBUG("Failed to Hook IDXGISwapChain::Present to detect DX Version\n"); - } - if (pDevice)pDevice->Release(); - if (pSwapChain)pSwapChain->Release(); - } -} - -void Hook_Manager::hook_dx11() -{ - if (!_dxgi_hooked && !_renderer_found) - { - HWND hWnd = GetGameWindow(); - if (!hWnd) - return; - - IDXGISwapChain* pSwapChain = nullptr; - ID3D11Device* pDevice = nullptr; - HMODULE library = GetModuleHandle(DX11_Hook::DLL_NAME); - if (library != nullptr) - { - decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain = - (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(library, "D3D11CreateDeviceAndSwapChain"); - if (D3D11CreateDeviceAndSwapChain != nullptr) - { - DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; - - SwapChainDesc.BufferCount = 1; - SwapChainDesc.BufferDesc.Width = 1; - SwapChainDesc.BufferDesc.Height = 1; - SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; - SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; - SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - SwapChainDesc.OutputWindow = hWnd; - SwapChainDesc.SampleDesc.Count = 1; - SwapChainDesc.SampleDesc.Quality = 0; - SwapChainDesc.Windowed = TRUE; - - D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, NULL, D3D11_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDevice, NULL, NULL); - } - } - if (pSwapChain != nullptr) - { - PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); - auto h = DX11_Hook::Inst(); - h->loadFunctions(pSwapChain); - _hooks.insert(h); - HookDXGIPresent(pSwapChain); - } - else - { - PRINT_DEBUG("Failed to Hook IDXGISwapChain::Present to detect DX Version\n"); - } - - if (pDevice) pDevice->Release(); - if (pSwapChain) pSwapChain->Release(); - } -} - -void Hook_Manager::hook_dx12() -{ - if (!_dxgi_hooked && !_renderer_found) - { - HWND hWnd = GetGameWindow(); - if (!hWnd) - return; - - IDXGIFactory4* pDXGIFactory = nullptr; - IDXGISwapChain1* pSwapChain = nullptr; - ID3D12CommandQueue* pCommandQueue = nullptr; - ID3D12Device* pDevice = nullptr; - ID3D12CommandAllocator* pCommandAllocator = nullptr; - ID3D12CommandList* pCommandList = nullptr; - - HMODULE library = GetModuleHandle(DX12_Hook::DLL_NAME); - if (library != nullptr) - { - decltype(D3D12CreateDevice)* D3D12CreateDevice = - (decltype(D3D12CreateDevice))GetProcAddress(library, "D3D12CreateDevice"); - - if (D3D12CreateDevice != nullptr) - { - D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&pDevice)); - - if (pDevice != nullptr) - { - DXGI_SWAP_CHAIN_DESC1 SwapChainDesc = {}; - SwapChainDesc.BufferCount = 2; - SwapChainDesc.Width = 1; - SwapChainDesc.Height = 1; - SwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - SwapChainDesc.Stereo = FALSE; - SwapChainDesc.SampleDesc = { 1, 0 }; - SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - SwapChainDesc.Scaling = DXGI_SCALING_NONE; - SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; - - D3D12_COMMAND_QUEUE_DESC queueDesc = {}; - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - pDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&pCommandQueue)); - - if (pCommandQueue != nullptr) - { - HMODULE dxgi = GetModuleHandle("dxgi.dll"); - if (dxgi != nullptr) - { - decltype(CreateDXGIFactory1)* CreateDXGIFactory1 = (decltype(CreateDXGIFactory1))GetProcAddress(dxgi, "CreateDXGIFactory1"); - if (CreateDXGIFactory1 != nullptr) - { - CreateDXGIFactory1(IID_PPV_ARGS(&pDXGIFactory)); - if (pDXGIFactory != nullptr) - { - pDXGIFactory->CreateSwapChainForHwnd(pCommandQueue, hWnd, &SwapChainDesc, NULL, NULL, &pSwapChain); - - pDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&pCommandAllocator)); - if (pCommandAllocator != nullptr) - { - pDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, pCommandAllocator, NULL, IID_PPV_ARGS(&pCommandList)); - } - } - } - } - } - }//if (pDevice != nullptr) - }//if (D3D12CreateDevice != nullptr) - }//if (library != nullptr) - if (pSwapChain != nullptr && pCommandList != nullptr) - { - PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); - - auto h = DX12_Hook::Inst(); - h->loadFunctions(pCommandList, pSwapChain); - _hooks.insert(h); - HookDXGIPresent(pSwapChain); - } - else - { - PRINT_DEBUG("Failed to Hook IDXGISwapChain::Present to detect DX Version\n"); - } - - if (pCommandList) pCommandList->Release(); - if (pCommandAllocator) pCommandAllocator->Release(); - if (pSwapChain) pSwapChain->Release(); - if (pDXGIFactory) pDXGIFactory->Release(); - if (pCommandQueue) pCommandQueue->Release(); - if (pDevice) pDevice->Release(); - } -} - -void Hook_Manager::hook_opengl() -{ - if (!_ogl_hooked && !_renderer_found) - { - HMODULE library = GetModuleHandle(OpenGL_Hook::DLL_NAME); - decltype(wglMakeCurrent)* wglMakeCurrent = nullptr; - if (library != nullptr) - { - wglMakeCurrent = (decltype(wglMakeCurrent))GetProcAddress(library, "wglMakeCurrent"); - } - if (wglMakeCurrent != nullptr) - { - PRINT_DEBUG("Hooked wglMakeCurrent to detect OpenGL\n"); - HookwglMakeCurrent(wglMakeCurrent); - } - else - { - PRINT_DEBUG("Failed to Hook wglMakeCurrent to detect OpenGL\n"); - } - } -} - -void Hook_Manager::create_hook(const char* libname) -{ - if (!_stricmp(libname, "d3d9.dll")) - Hook_Manager::Inst().hook_dx9(); - else if (!_stricmp(libname, "d3d10.dll")) - Hook_Manager::Inst().hook_dx10(); - else if (!_stricmp(libname, "d3d11.dll")) - Hook_Manager::Inst().hook_dx11(); - else if (!_stricmp(libname, "d3d12.dll")) - Hook_Manager::Inst().hook_dx12(); - else if (!_stricmp(libname, "opengl32.dll")) - Hook_Manager::Inst().hook_opengl(); -} - -//void Hook_Manager::create_hookW(const wchar_t *libname) -//{ -// if (!_wcsicmp(libname, L"d3d9.dll")) -// Hook_Manager::Inst().hook_dx9(); -// else if (!_wcsicmp(libname, L"d3d10.dll")) -// Hook_Manager::Inst().hook_dx10(); -// else if (!_wcsicmp(libname, L"d3d11.dll")) -// Hook_Manager::Inst().hook_dx11(); -// else if (!_wcsicmp(libname, L"d3d12.dll")) -// Hook_Manager::Inst().hook_dx12(); -// else if (!_wcsicmp(libname, L"opengl32.dll")) -// Hook_Manager::Inst().hook_opengl(); -//} -// -//HMODULE WINAPI Hook_Manager::MyLoadLibraryA(LPCTSTR lpLibFileName) -//{ -// auto res = _LoadLibraryA(lpLibFileName); -// Hook_Manager::Inst().create_hookA(lpLibFileName); -// return res; -//} -// -//HMODULE WINAPI Hook_Manager::MyLoadLibraryW(LPCWSTR lpLibFileName) -//{ -// auto res = _LoadLibraryW(lpLibFileName); -// Hook_Manager::Inst().create_hookW(lpLibFileName); -// return res; -//} -// -//HMODULE WINAPI Hook_Manager::MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -//{ -// auto res = _LoadLibraryA(lpLibFileName); -// Hook_Manager::Inst().create_hookA(lpLibFileName); -// return res; -//} -// -//HMODULE WINAPI Hook_Manager::MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -//{ -// auto res = _LoadLibraryExW(lpLibFileName, hFile, dwFlags); -// Hook_Manager::Inst().create_hookW(lpLibFileName); -// return res; -//} - -bool Hook_Manager::stop_retry() -{ - // Retry or not - bool stop = ++_hook_retries >= max_hook_retries; - - if (stop) - FoundRenderer(nullptr); - - return stop; -} - -void Hook_Manager::find_renderer(Hook_Manager* _this) -{ - _this->rendererdetect_hook = new Base_Hook(); - _this->AddHook(_this->rendererdetect_hook); - - std::vector const libraries = { "opengl32.dll", "d3d12.dll", "d3d11.dll", "d3d10.dll", "d3d9.dll" }; - - while (!_this->_renderer_found && !_this->stop_retry()) - { - std::vector::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 != NULL) - return true; - return false; - }); - - if (it == libraries.end()) - break; - - _this->create_hook(it->c_str()); - ++it; - } - - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } -} - -#endif - -Hook_Manager::Hook_Manager(): - _hook_retries(0), -#ifdef STEAM_WIN32 - _loadlibrary_hooked(false), - _dxgi_hooked(false), - _dx9_hooked(false), -#endif - _renderer_found(false), - _ogl_hooked(false) +Hook_Manager::Hook_Manager() {} Hook_Manager::~Hook_Manager() @@ -556,36 +18,18 @@ Hook_Manager& Hook_Manager::Inst() return hook; } -void Hook_Manager::HookRenderer() +void Hook_Manager::AddHook(Base_Hook* hook) { -#ifdef STEAM_WIN32 - _hook_thread = new std::thread(&Hook_Manager::find_renderer, this); -#endif + _hooks.insert(hook); } -void Hook_Manager::FoundRenderer(Base_Hook* hook) +void Hook_Manager::RemoveHook(Base_Hook* hook) { - if (!_renderer_found) + auto it = _hooks.find(hook); + if (it != _hooks.end()) { - _renderer_found = true; - game_renderer = hook; - - if (hook == nullptr) - PRINT_DEBUG("We found a renderer but couldn't hook it, aborting overlay hook.\n"); - else - PRINT_DEBUG("Hooked renderer in %d tries\n", _hook_retries); - - _hook_thread->join(); - delete _hook_thread; - _hook_thread = nullptr; - - // Remove all hooks that are unused - std::set::iterator item; - while ((item = std::find_if(_hooks.begin(), _hooks.end(), [hook](Base_Hook* item) {return item != hook; })) != _hooks.end()) - { - delete *item; - _hooks.erase(item); - } + delete hook; + _hooks.erase(it); } } diff --git a/overlay_experimental/Hook_Manager.h b/overlay_experimental/Hook_Manager.h index 0722cbf..8d84170 100644 --- a/overlay_experimental/Hook_Manager.h +++ b/overlay_experimental/Hook_Manager.h @@ -6,15 +6,6 @@ #ifndef NO_OVERLAY #include -#include - -#if defined(_WIN32) || defined(WIN32) -#include - -struct IDXGISwapChain; -struct IDirect3DDevice9; -struct IDirect3DDevice9Ex; -#endif /* * @@ -22,9 +13,6 @@ struct IDirect3DDevice9Ex; class Hook_Manager { friend class Base_Hook; -public: - using overlayProc_t = void(*)(int,int); - using hookReady_t = void(*)(void*); protected: // TODO: If needed, create a second vector with only the renderers hook @@ -32,75 +20,14 @@ protected: // If you do that, you should consider moving the renderer hooks to its own class and keep this one generic ? std::set _hooks; - std::thread *_hook_thread; - unsigned int _hook_retries; - bool _renderer_found; // Is the renderer hooked ? - bool _ogl_hooked; // wglMakeCurrent is hooked ? (opengl) - Base_Hook* rendererdetect_hook; - Base_Hook* game_renderer; - class Steam_Overlay* overlay; - Hook_Manager(); virtual ~Hook_Manager(); - - // Setup opengl device - void hook_opengl(); - - bool stop_retry(); - //void HookLoadLibrary(); - -#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) - bool _loadlibrary_hooked; // Are the LoadLibrary functions hooked ? - bool _dx9_hooked; // DX9 Present and PresentEx Hooked ? - bool _dxgi_hooked; // DXGI Present is hooked ? (DX10, DX11, DX12) - - // DXGIPresent will be used to detect if DX10, DX11 or DX12 should be used for overlay - void HookDXGIPresent(IDXGISwapChain* pSwapChain); - // DX9 Present and PresentEx will be used to detect if DX9 should be used for overlay - void HookDX9Present(IDirect3DDevice9* pDevice, bool ex); - // wglMakeCurrent will be used to detect if OpenGL3 should be used for overlay - void HookwglMakeCurrent(BOOL (WINAPI *wglMakeCurrent)(HDC, HGLRC)); - // Setup DX9 Device and get vtable - void hook_dx9(); - // Setup DX10 Device and get vtable - void hook_dx10(); - // Setup DX11 Device and get vtable - void hook_dx11(); - // Setup DX12 Device and get vtable - void hook_dx12(); - - void create_hook(const char* libname); - //void create_hookW(const wchar_t* libname); - - static void find_renderer(Hook_Manager* _this); - - //static HMODULE WINAPI MyLoadLibraryA(LPCTSTR lpLibFileName); - //static HMODULE WINAPI MyLoadLibraryW(LPCWSTR lpLibFileName); - //static HMODULE WINAPI MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); - //static HMODULE WINAPI MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); - // If this is called, then DX10, DX11 or DX12 will be used to render overlay - static HRESULT STDMETHODCALLTYPE MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags); - // If any of theses is called, then DX9 will be used to render overlay - 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); - // If this is called, then OpenGL 3 will be used to render overlay - static BOOL WINAPI MywglMakeCurrent(HDC hDC, HGLRC hGLRC); - -#elif defined(__linux__) - -#endif public: static Hook_Manager& Inst(); - void HookRenderer(); - - // Set the found hook and free all other hooks - void FoundRenderer(Base_Hook *hook); - - inline void AddHook(Base_Hook* hook) { _hooks.insert(hook); } - - inline Base_Hook* get_renderer() const { return game_renderer; } + void AddHook(Base_Hook* hook); + void RemoveHook(Base_Hook* hook); }; #endif//NO_OVERLAY diff --git a/overlay_experimental/OpenGL_Hook.cpp b/overlay_experimental/OpenGL_Hook.cpp index 0b77924..9dfbfc0 100644 --- a/overlay_experimental/OpenGL_Hook.cpp +++ b/overlay_experimental/OpenGL_Hook.cpp @@ -1,6 +1,6 @@ #include "OpenGL_Hook.h" #include "Windows_Hook.h" -#include "Hook_Manager.h" +#include "Renderer_Detector.h" #include "../dll/dll.h" #ifndef NO_OVERLAY @@ -17,9 +17,9 @@ OpenGL_Hook* OpenGL_Hook::_inst = nullptr; bool OpenGL_Hook::start_hook() { bool res = true; - if (!_hooked) + if (!hooked) { - if (!Windows_Hook::Inst().start_hook()) + if (!Windows_Hook::Inst()->start_hook()) return false; GLenum err = glewInit(); @@ -28,10 +28,8 @@ bool OpenGL_Hook::start_hook() { PRINT_DEBUG("Hooked OpenGL\n"); - _hooked = true; - Hook_Manager::Inst().FoundRenderer(this); - - wglSwapBuffers = (decltype(wglSwapBuffers))GetProcAddress(reinterpret_cast(_library), "wglSwapBuffers"); + hooked = true; + Renderer_Detector::Inst().renderer_found(this); UnhookAll(); BeginHook(); @@ -58,7 +56,7 @@ void OpenGL_Hook::resetRenderState() if (initialized) { ImGui_ImplOpenGL3_Shutdown(); - Windows_Hook::Inst().resetRenderState(); + Windows_Hook::Inst()->resetRenderState(); ImGui::DestroyContext(); initialized = false; @@ -73,7 +71,7 @@ void OpenGL_Hook::prepareForOverlay(HDC hDC) GetClientRect(hWnd, &rect); - if (hWnd != Windows_Hook::Inst().GetGameHwnd()) + if (hWnd != Windows_Hook::Inst()->GetGameHwnd()) resetRenderState(); if (!initialized) @@ -87,7 +85,7 @@ void OpenGL_Hook::prepareForOverlay(HDC hDC) initialized = true; } ImGui_ImplOpenGL3_NewFrame(); - Windows_Hook::Inst().prepareForOverlay(hWnd); + Windows_Hook::Inst()->prepareForOverlay(hWnd); ImGui::NewFrame(); @@ -118,6 +116,7 @@ BOOL WINAPI OpenGL_Hook::MywglSwapBuffers(HDC hDC) OpenGL_Hook::OpenGL_Hook(): initialized(false), + hooked(false), wglSwapBuffers(nullptr) { _library = LoadLibrary(DLL_NAME); @@ -137,7 +136,11 @@ OpenGL_Hook::~OpenGL_Hook() { PRINT_DEBUG("OpenGL Hook removed\n"); - resetRenderState(); + if (initialized) + { + ImGui_ImplOpenGL3_Shutdown(); + ImGui::DestroyContext(); + } FreeLibrary(reinterpret_cast(_library)); @@ -157,4 +160,9 @@ const char* OpenGL_Hook::get_lib_name() const return DLL_NAME; } +void OpenGL_Hook::loadFunctions(wglSwapBuffers_t pfnwglSwapBuffers) +{ + wglSwapBuffers = pfnwglSwapBuffers; +} + #endif//NO_OVERLAY \ No newline at end of file diff --git a/overlay_experimental/OpenGL_Hook.h b/overlay_experimental/OpenGL_Hook.h index a0bdb2c..bf45754 100644 --- a/overlay_experimental/OpenGL_Hook.h +++ b/overlay_experimental/OpenGL_Hook.h @@ -16,11 +16,11 @@ private: static OpenGL_Hook* _inst; // Variables + bool hooked; bool initialized; // Functions OpenGL_Hook(); - virtual ~OpenGL_Hook(); void resetRenderState(); void prepareForOverlay(HDC hDC); @@ -36,9 +36,12 @@ private: //wglMakeCurrent_t wglMakeCurrent; public: + virtual ~OpenGL_Hook(); + bool start_hook(); static OpenGL_Hook* Inst(); virtual const char* get_lib_name() const; + void loadFunctions(wglSwapBuffers_t pfnwglSwapBuffers); }; #endif//NO_OVERLAY diff --git a/overlay_experimental/Renderer_Detector.cpp b/overlay_experimental/Renderer_Detector.cpp new file mode 100644 index 0000000..90495f4 --- /dev/null +++ b/overlay_experimental/Renderer_Detector.cpp @@ -0,0 +1,670 @@ +#include "Renderer_Detector.h" + +#include "../detours/detours.h" +#include "Hook_Manager.h" + +#ifdef STEAM_WIN32 +#include "DX12_Hook.h" +#include "DX11_Hook.h" +#include "DX10_Hook.h" +#include "DX9_Hook.h" +#include "OpenGL_Hook.h" +#include "Windows_Hook.h" +#endif + +#include + +constexpr int max_hook_retries = 500; + +#ifdef STEAM_WIN32 +static decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present = nullptr; +static decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present = nullptr; +static decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx = nullptr; +static decltype(wglMakeCurrent)* _wglMakeCurrent = nullptr; + +static constexpr auto windowClassName = "___overlay_window_class___"; + +void Renderer_Detector::create_hwnd() +{ + if (dummy_hWnd == nullptr) + { + HINSTANCE hInst = GetModuleHandle(nullptr); + if (atom == 0) + { + // Register a window class for creating our render window with. + WNDCLASSEX windowClass = {}; + + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = DefWindowProc; + windowClass.cbClsExtra = 0; + windowClass.cbWndExtra = 0; + windowClass.hInstance = hInst; + windowClass.hIcon = NULL; + windowClass.hCursor = ::LoadCursor(NULL, IDC_ARROW); + windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + windowClass.lpszMenuName = NULL; + windowClass.lpszClassName = windowClassName; + windowClass.hIconSm = NULL; + + atom = ::RegisterClassEx(&windowClass); + } + + if (atom > 0) + { + dummy_hWnd = ::CreateWindowEx( + NULL, + windowClassName, + "", + WS_OVERLAPPEDWINDOW, + 0, + 0, + 1, + 1, + NULL, + NULL, + hInst, + nullptr + ); + + assert(dummy_hWnd && "Failed to create window"); + } + } + +} + +void Renderer_Detector::destroy_hwnd() +{ + if (dummy_hWnd != nullptr) + { + DestroyWindow(dummy_hWnd); + UnregisterClass(windowClassName, GetModuleHandle(nullptr)); + } +} + +HRESULT STDMETHODCALLTYPE Renderer_Detector::MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags) +{ + Renderer_Detector& inst = Renderer_Detector::Inst(); + Hook_Manager& hm = Hook_Manager::Inst(); + if (!inst.stop_retry()) + { + IUnknown* pDevice = nullptr; + _this->GetDevice(IID_PPV_ARGS(reinterpret_cast(&pDevice))); + if (pDevice) + { + DX10_Hook::Inst()->start_hook(); + } + else + { + _this->GetDevice(IID_PPV_ARGS(reinterpret_cast(&pDevice))); + if (pDevice) + { + DX11_Hook::Inst()->start_hook(); + } + else + { + _this->GetDevice(IID_PPV_ARGS(reinterpret_cast(&pDevice))); + if (pDevice) + { + DX12_Hook::Inst()->start_hook(); + } + } + } + if (pDevice) pDevice->Release(); + } + + return (_this->*_IDXGISwapChain_Present)(SyncInterval, Flags); +} + +HRESULT STDMETHODCALLTYPE Renderer_Detector::MyPresent(IDirect3DDevice9* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) +{ + Renderer_Detector& inst = Renderer_Detector::Inst(); + Hook_Manager& hm = Hook_Manager::Inst(); + if (!inst.stop_retry()) + { + DX9_Hook::Inst()->start_hook(); + } + return (_this->*_IDirect3DDevice9_Present)(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); +} + +HRESULT STDMETHODCALLTYPE Renderer_Detector::MyPresentEx(IDirect3DDevice9Ex* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) +{ + Renderer_Detector& inst = Renderer_Detector::Inst(); + Hook_Manager& hm = Hook_Manager::Inst(); + if (!inst.stop_retry()) + { + DX9_Hook::Inst()->start_hook(); + } + return (_this->*_IDirect3DDevice9Ex_PresentEx)(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags); +} + +BOOL WINAPI Renderer_Detector::MywglMakeCurrent(HDC hDC, HGLRC hGLRC) +{ + Renderer_Detector& inst = Renderer_Detector::Inst(); + Hook_Manager& hm = Hook_Manager::Inst(); + if (!inst.stop_retry()) + { + OpenGL_Hook::Inst()->start_hook(); + } + return _wglMakeCurrent(hDC, hGLRC); +} + +void Renderer_Detector::HookDXGIPresent(IDXGISwapChain* pSwapChain) +{ + if (!_dxgi_hooked) + { + _dxgi_hooked = true; + (void*&)_IDXGISwapChain_Present = (*reinterpret_cast(pSwapChain))[(int)IDXGISwapChainVTable::Present]; + + rendererdetect_hook->BeginHook(); + + rendererdetect_hook->HookFuncs( + std::pair((PVOID*)& _IDXGISwapChain_Present, &Renderer_Detector::MyIDXGISwapChain_Present) + ); + + rendererdetect_hook->EndHook(); + } +} + +void Renderer_Detector::HookDX9Present(IDirect3DDevice9* pDevice, bool ex) +{ + (void*&)_IDirect3DDevice9_Present = (*reinterpret_cast(pDevice))[(int)IDirect3DDevice9VTable::Present]; + if (ex) + (void*&)_IDirect3DDevice9Ex_PresentEx = (*reinterpret_cast(pDevice))[(int)IDirect3DDevice9VTable::PresentEx]; + + rendererdetect_hook->BeginHook(); + + rendererdetect_hook->HookFuncs( + std::pair((PVOID*)& _IDirect3DDevice9_Present, &Renderer_Detector::MyPresent) + ); + if (ex) + { + rendererdetect_hook->HookFuncs( + std::pair((PVOID*)& _IDirect3DDevice9Ex_PresentEx, &Renderer_Detector::MyPresentEx) + ); + } + + rendererdetect_hook->EndHook(); +} + +void Renderer_Detector::HookwglMakeCurrent(decltype(wglMakeCurrent)* wglMakeCurrent) +{ + _wglMakeCurrent = wglMakeCurrent; + + rendererdetect_hook->BeginHook(); + + rendererdetect_hook->HookFuncs( + std::pair((PVOID*)& _wglMakeCurrent, &Renderer_Detector::MywglMakeCurrent) + ); + + rendererdetect_hook->EndHook(); +} + +void Renderer_Detector::hook_dx9() +{ + if (!_dx9_hooked && !_renderer_found) + { + create_hwnd(); + if (dummy_hWnd == nullptr) + return; + + IDirect3D9Ex* pD3D = nullptr; + IUnknown* pDevice = nullptr; + HMODULE library = GetModuleHandle(DX9_Hook::DLL_NAME); + decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = nullptr; + if (library != nullptr) + { + Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(library, "Direct3DCreate9Ex"); + D3DPRESENT_PARAMETERS params = {}; + params.BackBufferWidth = 1; + params.BackBufferHeight = 1; + params.hDeviceWindow = dummy_hWnd; + params.BackBufferCount = 1; + params.Windowed = TRUE; + params.SwapEffect = D3DSWAPEFFECT_DISCARD; + + if (Direct3DCreate9Ex != nullptr) + { + Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D); + pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, reinterpret_cast(&pDevice)); + } + else + { + decltype(Direct3DCreate9)* Direct3DCreate9 = (decltype(Direct3DCreate9))GetProcAddress(library, "Direct3DCreate9"); + if (Direct3DCreate9 != nullptr) + { + pD3D = reinterpret_cast(Direct3DCreate9(D3D_SDK_VERSION)); + pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, reinterpret_cast(&pDevice)); + } + } + } + + if (pDevice != nullptr) + { + PRINT_DEBUG("Hooked D3D9::Present to detect DX Version\n"); + + _dx9_hooked = true; + auto h = DX9_Hook::Inst(); + h->loadFunctions(reinterpret_cast(pDevice), Direct3DCreate9Ex != nullptr); + Hook_Manager::Inst().AddHook(h); + HookDX9Present(reinterpret_cast(pDevice), Direct3DCreate9Ex != nullptr); + } + else + { + PRINT_DEBUG("Failed to hook D3D9::Present to detect DX Version\n"); + } + + if (pDevice) pDevice->Release(); + if (pD3D) pD3D->Release(); + } +} + +void Renderer_Detector::hook_dx10() +{ + if (!_dxgi_hooked && !_renderer_found) + { + create_hwnd(); + if (dummy_hWnd == nullptr) + return; + + IDXGISwapChain* pSwapChain = nullptr; + ID3D10Device* pDevice = nullptr; + HMODULE library = GetModuleHandle(DX10_Hook::DLL_NAME); + if (library != nullptr) + { + decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain = + (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(library, "D3D10CreateDeviceAndSwapChain"); + if (D3D10CreateDeviceAndSwapChain != nullptr) + { + DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; + + SwapChainDesc.BufferCount = 1; + SwapChainDesc.BufferDesc.Width = 1; + SwapChainDesc.BufferDesc.Height = 1; + SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; + SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + SwapChainDesc.OutputWindow = dummy_hWnd; + SwapChainDesc.SampleDesc.Count = 1; + SwapChainDesc.SampleDesc.Quality = 0; + SwapChainDesc.Windowed = TRUE; + + D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_NULL, NULL, 0, D3D10_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDevice); + } + } + if (pSwapChain != nullptr) + { + PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); + + _dx10_hooked = true; + auto h = DX10_Hook::Inst(); + h->loadFunctions(pSwapChain); + Hook_Manager::Inst().AddHook(h); + HookDXGIPresent(pSwapChain); + } + else + { + PRINT_DEBUG("Failed to Hook IDXGISwapChain::Present to detect DX Version\n"); + } + if (pDevice)pDevice->Release(); + if (pSwapChain)pSwapChain->Release(); + } +} + +void Renderer_Detector::hook_dx11() +{ + if (!_dxgi_hooked && !_renderer_found) + { + create_hwnd(); + if (dummy_hWnd == nullptr) + return; + + IDXGISwapChain* pSwapChain = nullptr; + ID3D11Device* pDevice = nullptr; + HMODULE library = GetModuleHandle(DX11_Hook::DLL_NAME); + if (library != nullptr) + { + decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain = + (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(library, "D3D11CreateDeviceAndSwapChain"); + if (D3D11CreateDeviceAndSwapChain != nullptr) + { + DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; + + SwapChainDesc.BufferCount = 1; + SwapChainDesc.BufferDesc.Width = 1; + SwapChainDesc.BufferDesc.Height = 1; + SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; + SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + SwapChainDesc.OutputWindow = dummy_hWnd; + SwapChainDesc.SampleDesc.Count = 1; + SwapChainDesc.SampleDesc.Quality = 0; + SwapChainDesc.Windowed = TRUE; + + D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, NULL, D3D11_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDevice, NULL, NULL); + } + } + if (pSwapChain != nullptr) + { + PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); + + _dx11_hooked = true; + auto h = DX11_Hook::Inst(); + h->loadFunctions(pSwapChain); + Hook_Manager::Inst().AddHook(h); + HookDXGIPresent(pSwapChain); + } + else + { + PRINT_DEBUG("Failed to Hook IDXGISwapChain::Present to detect DX Version\n"); + } + + if (pDevice) pDevice->Release(); + if (pSwapChain) pSwapChain->Release(); + } +} + +void Renderer_Detector::hook_dx12() +{ + if (!_dxgi_hooked && !_renderer_found) + { + create_hwnd(); + if (dummy_hWnd == nullptr) + return; + + IDXGIFactory4* pDXGIFactory = nullptr; + IDXGISwapChain1* pSwapChain = nullptr; + ID3D12CommandQueue* pCommandQueue = nullptr; + ID3D12Device* pDevice = nullptr; + ID3D12CommandAllocator* pCommandAllocator = nullptr; + ID3D12GraphicsCommandList* pCommandList = nullptr; + + HMODULE library = GetModuleHandle(DX12_Hook::DLL_NAME); + if (library != nullptr) + { + decltype(D3D12CreateDevice)* D3D12CreateDevice = + (decltype(D3D12CreateDevice))GetProcAddress(library, "D3D12CreateDevice"); + + if (D3D12CreateDevice != nullptr) + { + D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&pDevice)); + + if (pDevice != nullptr) + { + DXGI_SWAP_CHAIN_DESC1 SwapChainDesc = {}; + SwapChainDesc.BufferCount = 2; + SwapChainDesc.Width = 1; + SwapChainDesc.Height = 1; + SwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + SwapChainDesc.Stereo = FALSE; + SwapChainDesc.SampleDesc = { 1, 0 }; + SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + SwapChainDesc.Scaling = DXGI_SCALING_NONE; + SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + pDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&pCommandQueue)); + + if (pCommandQueue != nullptr) + { + HMODULE dxgi = GetModuleHandle("dxgi.dll"); + if (dxgi != nullptr) + { + decltype(CreateDXGIFactory1)* CreateDXGIFactory1 = (decltype(CreateDXGIFactory1))GetProcAddress(dxgi, "CreateDXGIFactory1"); + if (CreateDXGIFactory1 != nullptr) + { + CreateDXGIFactory1(IID_PPV_ARGS(&pDXGIFactory)); + if (pDXGIFactory != nullptr) + { + pDXGIFactory->CreateSwapChainForHwnd(pCommandQueue, dummy_hWnd, &SwapChainDesc, NULL, NULL, &pSwapChain); + + pDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&pCommandAllocator)); + if (pCommandAllocator != nullptr) + { + pDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, pCommandAllocator, NULL, IID_PPV_ARGS(&pCommandList)); + } + } + } + } + } + }//if (pDevice != nullptr) + }//if (D3D12CreateDevice != nullptr) + }//if (library != nullptr) + if (pSwapChain != nullptr && pCommandList != nullptr) + { + PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); + + _dx12_hooked = true; + auto h = DX12_Hook::Inst(); + h->loadFunctions(pCommandQueue, pCommandList, pSwapChain); + Hook_Manager::Inst().AddHook(h); + HookDXGIPresent(pSwapChain); + } + else + { + PRINT_DEBUG("Failed to Hook IDXGISwapChain::Present to detect DX Version\n"); + } + + if (pCommandList) pCommandList->Release(); + if (pCommandAllocator) pCommandAllocator->Release(); + if (pSwapChain) pSwapChain->Release(); + if (pDXGIFactory) pDXGIFactory->Release(); + if (pCommandQueue) pCommandQueue->Release(); + if (pDevice) pDevice->Release(); + } +} + +void Renderer_Detector::hook_opengl() +{ + if (!_ogl_hooked && !_renderer_found) + { + HMODULE library = GetModuleHandle(OpenGL_Hook::DLL_NAME); + decltype(wglMakeCurrent)* wglMakeCurrent = nullptr; + OpenGL_Hook::wglSwapBuffers_t wglSwapBuffers = nullptr; + if (library != nullptr) + { + wglMakeCurrent = (decltype(wglMakeCurrent))GetProcAddress(library, "wglMakeCurrent"); + wglSwapBuffers = (decltype(wglSwapBuffers))GetProcAddress(library, "wglSwapBuffers"); + } + if (wglMakeCurrent != nullptr && wglSwapBuffers != nullptr) + { + PRINT_DEBUG("Hooked wglMakeCurrent to detect OpenGL\n"); + + _ogl_hooked = true; + auto h = OpenGL_Hook::Inst(); + h->loadFunctions(wglSwapBuffers); + Hook_Manager::Inst().AddHook(h); + HookwglMakeCurrent(wglMakeCurrent); + } + else + { + PRINT_DEBUG("Failed to Hook wglMakeCurrent to detect OpenGL\n"); + } + } +} + +void Renderer_Detector::create_hook(const char* libname) +{ + if (!_stricmp(libname, "d3d9.dll")) + hook_dx9(); + else if (!_stricmp(libname, "d3d10.dll")) + hook_dx10(); + else if (!_stricmp(libname, "d3d11.dll")) + hook_dx11(); + else if (!_stricmp(libname, "d3d12.dll")) + hook_dx12(); + else if (!_stricmp(libname, "opengl32.dll")) + hook_opengl(); +} + +bool Renderer_Detector::stop_retry() +{ + // Retry or not + bool stop = ++_hook_retries >= max_hook_retries; + + if (stop) + renderer_found(nullptr); + + return stop; +} + +void Renderer_Detector::find_renderer_proc(Renderer_Detector* _this) +{ + _this->rendererdetect_hook = new Base_Hook(); + Hook_Manager& hm = Hook_Manager::Inst(); + hm.AddHook(_this->rendererdetect_hook); + + std::vector const libraries = { "opengl32.dll", "d3d12.dll", "d3d11.dll", "d3d10.dll", "d3d9.dll" }; + + while (!_this->_renderer_found && !_this->stop_retry()) + { + std::vector::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 != NULL) + return true; + return false; + }); + + if (it == libraries.end()) + break; + + _this->create_hook(it->c_str()); + ++it; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } +} + +#endif + +void Renderer_Detector::find_renderer() +{ + if (_hook_thread == nullptr) + { +#ifdef STEAM_WIN32 + _hook_thread = new std::thread(&Renderer_Detector::find_renderer_proc, this); +#endif + } +} + +void Renderer_Detector::renderer_found(Base_Hook* hook) +{ + Hook_Manager& hm = Hook_Manager::Inst(); + + _renderer_found = true; + game_renderer = hook; + + if (hook == nullptr) + PRINT_DEBUG("We found a renderer but couldn't hook it, aborting overlay hook.\n"); + else + PRINT_DEBUG("Hooked renderer in %d/%d tries\n", _hook_retries, max_hook_retries); + + _hook_thread->join(); + delete _hook_thread; + _hook_thread = nullptr; + + hm.RemoveHook(rendererdetect_hook); + destroy_hwnd(); + +#ifdef STEAM_WIN32 + if (hook == nullptr) // Couldn't hook renderer + { + hm.RemoveHook(Windows_Hook::Inst()); + } + else + { + hm.AddHook(Windows_Hook::Inst()); + } + if (_ogl_hooked) + { + auto h = OpenGL_Hook::Inst(); + if (h != hook) + { + _ogl_hooked = false; + hm.RemoveHook(h); + } + } + if (_dx9_hooked) + { + auto h = DX9_Hook::Inst(); + if (h != hook) + { + _dx9_hooked = false; + hm.RemoveHook(h); + } + } + if (_dx10_hooked) + { + auto h = DX10_Hook::Inst(); + if (h != hook) + { + _dx10_hooked = false; + hm.RemoveHook(h); + } + } + if (_dx11_hooked) + { + auto h = DX11_Hook::Inst(); + if (h != hook) + { + _dx11_hooked = false; + hm.RemoveHook(h); + } + } + if (_dx12_hooked) + { + auto h = DX12_Hook::Inst(); + if (h != hook) + { + _dx12_hooked = false; + hm.RemoveHook(h); + } + } +#endif +} + +Renderer_Detector& Renderer_Detector::Inst() +{ + static Renderer_Detector inst; + return inst; +} + +Base_Hook* Renderer_Detector::get_renderer() const +{ + return game_renderer; +} + +Renderer_Detector::Renderer_Detector(): + _hook_thread(nullptr), + _hook_retries(0), + _renderer_found(false), + _dx9_hooked(false), + _dx10_hooked(false), + _dx11_hooked(false), + _dx12_hooked(false), + _dxgi_hooked(false), + _ogl_hooked(false), + rendererdetect_hook(nullptr), + game_renderer(nullptr), + atom(0), + dummy_hWnd(nullptr) +{} + +Renderer_Detector::~Renderer_Detector() +{ + if (_hook_thread != nullptr) + { + _hook_retries = max_hook_retries; + _hook_thread->join(); + delete _hook_thread; + } +} \ No newline at end of file diff --git a/overlay_experimental/Renderer_Detector.h b/overlay_experimental/Renderer_Detector.h new file mode 100644 index 0000000..8f72d3c --- /dev/null +++ b/overlay_experimental/Renderer_Detector.h @@ -0,0 +1,68 @@ +#ifndef __INCLUDED_RENDERER_DETECTOR_H__ +#define __INCLUDED_RENDERER_DETECTOR_H__ + +#include "Base_Hook.h" +#ifndef NO_OVERLAY + +#if defined(_WIN32) || defined(WIN32) +#include + +struct IDXGISwapChain; +struct IDirect3DDevice9; +struct IDirect3DDevice9Ex; +#endif + +class Renderer_Detector +{ +private: + // Variables + std::thread* _hook_thread; + unsigned int _hook_retries; + bool _renderer_found; // Is the renderer hooked ? + bool _dx9_hooked; + bool _dx10_hooked; + bool _dx11_hooked; + bool _dx12_hooked; + bool _dxgi_hooked; + bool _ogl_hooked; // wglMakeCurrent is hooked ? (opengl) + Base_Hook* rendererdetect_hook; + Base_Hook* game_renderer; + + ATOM atom; + HWND dummy_hWnd; + + // Functions + Renderer_Detector(); + ~Renderer_Detector(); + + static HRESULT STDMETHODCALLTYPE MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags); + 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); + static BOOL WINAPI MywglMakeCurrent(HDC hDC, HGLRC hGLRC); + + void HookDXGIPresent(IDXGISwapChain* pSwapChain); + void HookDX9Present(IDirect3DDevice9* pDevice, bool ex); + void HookwglMakeCurrent(decltype(wglMakeCurrent)* wglMakeCurrent); + + void hook_dx9(); + void hook_dx10(); + void hook_dx11(); + void hook_dx12(); + void hook_opengl(); + + void create_hwnd(); + void destroy_hwnd(); + void create_hook(const char* libname); + bool stop_retry(); + + static void find_renderer_proc(Renderer_Detector* _this); + +public: + void find_renderer(); + void renderer_found(Base_Hook* hook); + Base_Hook* get_renderer() const; + static Renderer_Detector& Inst(); +}; + +#endif//NO_OVERLAY +#endif//__INCLUDED_RENDERER_DETECTOR_H__ \ No newline at end of file diff --git a/overlay_experimental/Windows_Hook.cpp b/overlay_experimental/Windows_Hook.cpp index 83f5c31..4ccff4a 100644 --- a/overlay_experimental/Windows_Hook.cpp +++ b/overlay_experimental/Windows_Hook.cpp @@ -1,62 +1,26 @@ #include "Windows_Hook.h" +#include "Renderer_Detector.h" +#include "../dll/dll.h" + +#ifndef NO_OVERLAY #include #include extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -#include "../dll/dll.h" - -#include - -struct enum_wnd_param -{ - //HMODULE hModules[512]; - //DWORD num_mods; - DWORD pid; - HWND window; -}; - -static BOOL __stdcall EnumWindowsProc(HWND hWnd, enum_wnd_param* param) -{ - DWORD pid; - GetWindowThreadProcessId(hWnd, &pid); - if (pid == param->pid && GetWindow(hWnd, GW_OWNER) == nullptr && IsWindowVisible(hWnd)) - { - param->window = hWnd; - return FALSE; - } - - return TRUE; -} - -HWND GetGameWindow() -{ - enum_wnd_param param; - param.window = nullptr; - - param.pid = GetCurrentProcessId(); - EnumWindows(reinterpret_cast(EnumWindowsProc), reinterpret_cast(¶m)); - - if (param.window != nullptr) { - PRINT_DEBUG("Failed to get game window HWND\n"); - } - else { - char wnd_name[1024]; - GetWindowText(param.window, wnd_name, 1023); - PRINT_DEBUG("Found window %s\n", wnd_name); - } - return param.window; -} +Windows_Hook* Windows_Hook::_inst = nullptr; bool Windows_Hook::start_hook() { bool res = true; - if (!_hooked) + if (!hooked) { GetRawInputBuffer = ::GetRawInputBuffer; GetRawInputData = ::GetRawInputData; + PRINT_DEBUG("Hooked Windows\n"); + BeginHook(); HookFuncs( std::make_pair(&(PVOID&)GetRawInputBuffer, &Windows_Hook::MyGetRawInputBuffer), @@ -64,7 +28,7 @@ bool Windows_Hook::start_hook() ); EndHook(); - _hooked = true; + hooked = true; } return res; } @@ -159,13 +123,13 @@ LRESULT CALLBACK Windows_Hook::HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, } // Call the overlay window procedure - return CallWindowProc(Windows_Hook::Inst()._game_wndproc, hWnd, uMsg, wParam, lParam); + return CallWindowProc(Windows_Hook::Inst()->_game_wndproc, hWnd, uMsg, wParam, lParam); } UINT WINAPI Windows_Hook::MyGetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader) { if (!get_steam_client()->steam_overlay->ShowOverlay()) - return Windows_Hook::Inst().GetRawInputBuffer(pData, pcbSize, cbSizeHeader); + return Windows_Hook::Inst()->GetRawInputBuffer(pData, pcbSize, cbSizeHeader); return -1; } @@ -173,7 +137,7 @@ UINT WINAPI Windows_Hook::MyGetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UI UINT WINAPI Windows_Hook::MyGetRawInputData(HRAWINPUT hRawInput, UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader) { if (!get_steam_client()->steam_overlay->ShowOverlay()) - return Windows_Hook::Inst().GetRawInputData(hRawInput, uiCommand, pData, pcbSize, cbSizeHeader); + return Windows_Hook::Inst()->GetRawInputData(hRawInput, uiCommand, pData, pcbSize, cbSizeHeader); return -1; } @@ -181,6 +145,7 @@ UINT WINAPI Windows_Hook::MyGetRawInputData(HRAWINPUT hRawInput, UINT uiCommand, Windows_Hook::Windows_Hook() : initialized(false), + hooked(false), _game_hwnd(nullptr), _game_wndproc(nullptr), GetRawInputBuffer(nullptr), @@ -196,15 +161,21 @@ Windows_Hook::~Windows_Hook() resetRenderState(); //FreeLibrary(reinterpret_cast(_library)); + + _inst = nullptr; } -Windows_Hook& Windows_Hook::Inst() +Windows_Hook* Windows_Hook::Inst() { - static Windows_Hook _inst; + if (_inst == nullptr) + _inst = new Windows_Hook; + return _inst; } const char* Windows_Hook::get_lib_name() const { return DLL_NAME; -} \ No newline at end of file +} + +#endif//NO_OVERLAY \ No newline at end of file diff --git a/overlay_experimental/Windows_Hook.h b/overlay_experimental/Windows_Hook.h index e4c03d3..24e3156 100644 --- a/overlay_experimental/Windows_Hook.h +++ b/overlay_experimental/Windows_Hook.h @@ -14,14 +14,16 @@ public: static constexpr const char* DLL_NAME = "user32.dll"; private: + static Windows_Hook* _inst; + // Variables + bool hooked; bool initialized; HWND _game_hwnd; WNDPROC _game_wndproc; // Functions Windows_Hook(); - virtual ~Windows_Hook(); // Hook to Windows window messages decltype(GetRawInputBuffer)* GetRawInputBuffer; @@ -32,18 +34,18 @@ private: static UINT WINAPI MyGetRawInputData(HRAWINPUT hRawInput, UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader); public: - bool start_hook(); + virtual ~Windows_Hook(); + void resetRenderState(); void prepareForOverlay(HWND); HWND GetGameHwnd() const; WNDPROC GetGameWndProc() const; - static Windows_Hook& Inst(); + bool start_hook(); + static Windows_Hook* Inst(); virtual const char* get_lib_name() const; }; -HWND GetGameWindow(); - #endif//NO_OVERLAY #endif//__INCLUDED_WINDOWS_HOOK_H__ \ No newline at end of file diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index ab8b3e5..4f833ec 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -10,7 +10,7 @@ #include "../dll/dll.h" -#include "Hook_Manager.h" +#include "Renderer_Detector.h" #include "Windows_Hook.h" // Look here for info on how to hook on linux @@ -80,7 +80,7 @@ void Steam_Overlay::SetupOverlay() if (!setup_overlay_called) { setup_overlay_called = true; - Hook_Manager::Inst().HookRenderer(); + Renderer_Detector::Inst().find_renderer(); } } @@ -128,7 +128,7 @@ void Steam_Overlay::ShowOverlay(bool state) show_overlay = state; if (show_overlay) { - HWND game_hwnd = Windows_Hook::Inst().GetGameHwnd(); + HWND game_hwnd = Windows_Hook::Inst()->GetGameHwnd(); RECT cliRect, wndRect, clipRect; GetClipCursor(&old_clip); @@ -408,7 +408,7 @@ void Steam_Overlay::OverlayProc( int width, int height ) settings->get_local_steam_id().ConvertToUint64(), settings->get_local_game_id().AppID()); ImGui::SameLine(); - Base_Hook *hook = Hook_Manager::Inst().get_renderer(); + Base_Hook* hook = Renderer_Detector::Inst().get_renderer(); ImGui::LabelText("##label", "Renderer: %s", (hook == nullptr ? "Unknown" : hook->get_lib_name())); ImGui::Spacing();