@ -5,78 +5,368 @@
# include "../detours/detours.h"
# ifdef STEAM_WIN32
# include "DX12_Hook.h"
# include "DX11_Hook.h"
# include "DX10_Hook.h"
# include "DX9_Hook.h"
# endif
# include "OpenGL_Hook.h"
# include <algorithm>
# ifdef STEAM_WIN32
decltype ( LoadLibraryA ) * _LoadLibraryA = LoadLibraryA ;
decltype ( LoadLibraryW ) * _LoadLibraryW = LoadLibraryW ;
decltype ( LoadLibraryExA ) * _LoadLibraryExA = LoadLibraryExA ;
decltype ( LoadLibraryExW ) * _LoadLibraryExW = LoadLibraryExW ;
void create_hookA ( const char * libname )
decltype ( & IDXGISwapChain : : Present ) _IDXGISwapChain_Present ;
decltype ( & IDirect3DDevice9 : : Present ) _IDirect3DDevice9_Present ;
decltype ( & IDirect3DDevice9Ex : : PresentEx ) _IDirect3DDevice9Ex_PresentEx ;
decltype ( wglMakeCurrent ) * _wglMakeCurrent ;
HRESULT STDMETHODCALLTYPE Hook_Manager : : MyIDXGISwapChain_Present ( IDXGISwapChain * _this , UINT SyncInterval , UINT Flags )
{
IUnknown * pDevice ;
_this - > GetDevice ( __uuidof ( ID3D10Device ) , ( void * * ) & pDevice ) ;
if ( pDevice )
{
Hook_Manager : : Inst ( ) . UnHookAllRendererDetector ( ) ;
DX10_Hook : : Create ( ) ;
}
else
{
_this - > GetDevice ( __uuidof ( ID3D11Device ) , ( void * * ) & pDevice ) ;
if ( pDevice )
{
Hook_Manager : : Inst ( ) . UnHookAllRendererDetector ( ) ;
DX11_Hook : : Create ( ) ;
}
else
{
_this - > GetDevice ( __uuidof ( ID3D12Device ) , ( void * * ) & pDevice ) ;
if ( pDevice )
{
Hook_Manager : : Inst ( ) . UnHookAllRendererDetector ( ) ;
DX12_Hook : : Create ( ) ;
}
}
}
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 ( ) . UnHookAllRendererDetector ( ) ;
DX9_Hook : : Create ( ) ;
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 ( ) . UnHookAllRendererDetector ( ) ;
DX9_Hook : : Create ( ) ;
return ( _this - > * _IDirect3DDevice9Ex_PresentEx ) ( pSourceRect , pDestRect , hDestWindowOverride , pDirtyRegion , dwFlags ) ;
}
BOOL WINAPI Hook_Manager : : MywglMakeCurrent ( HDC hDC , HGLRC hGLRC )
{
Hook_Manager : : Inst ( ) . UnHookAllRendererDetector ( ) ;
OpenGL_Hook : : Create ( ) ;
return _wglMakeCurrent ( hDC , hGLRC ) ; ;
}
void Hook_Manager : : HookDXGIPresent ( )
{
if ( ! _dxgi_hooked )
{
rendererdetect_hook - > BeginHook ( ) ;
rendererdetect_hook - > HookFuncs (
std : : pair < void * * , void * > ( ( PVOID * ) & _IDXGISwapChain_Present , & Hook_Manager : : MyIDXGISwapChain_Present )
) ;
rendererdetect_hook - > EndHook ( ) ;
}
}
void Hook_Manager : : HookDX9Present ( )
{
if ( ! _dx9_hooked )
{
rendererdetect_hook - > BeginHook ( ) ;
rendererdetect_hook - > HookFuncs (
std : : pair < void * * , void * > ( ( PVOID * ) & _IDirect3DDevice9_Present , & Hook_Manager : : MyPresent ) ,
std : : pair < void * * , void * > ( ( PVOID * ) & _IDirect3DDevice9Ex_PresentEx , & Hook_Manager : : MyPresentEx )
) ;
rendererdetect_hook - > EndHook ( ) ;
}
}
void Hook_Manager : : HookwglMakeCurrent ( )
{
if ( ! _ogl_hooked )
{
rendererdetect_hook - > BeginHook ( ) ;
rendererdetect_hook - > HookFuncs (
std : : pair < void * * , void * > ( ( PVOID * ) & _wglMakeCurrent , & Hook_Manager : : MywglMakeCurrent )
) ;
rendererdetect_hook - > EndHook ( ) ;
}
}
void Hook_Manager : : hook_dx9 ( )
{
if ( ! _dx9_hooked & & ! _renderer_found )
{
IDirect3D9Ex * pD3D ;
IDirect3DDevice9Ex * pDeviceEx ;
decltype ( Direct3DCreate9Ex ) * Direct3DCreate9Ex = ( decltype ( Direct3DCreate9Ex ) ) GetProcAddress ( GetModuleHandle ( DX9_Hook : : DLL_NAME ) , " Direct3DCreate9Ex " ) ;
Direct3DCreate9Ex ( D3D_SDK_VERSION , & pD3D ) ;
D3DPRESENT_PARAMETERS params = { } ;
params . BackBufferWidth = 1 ;
params . BackBufferHeight = 1 ;
params . hDeviceWindow = GetForegroundWindow ( ) ;
pD3D - > CreateDeviceEx ( D3DADAPTER_DEFAULT , D3DDEVTYPE_NULLREF , NULL , D3DCREATE_HARDWARE_VERTEXPROCESSING , & params , NULL , & pDeviceEx ) ;
if ( pDeviceEx )
{
PRINT_DEBUG ( " Hooked D3D9::Present to detect DX Version \n " ) ;
( void * & ) _IDirect3DDevice9_Present = ( * reinterpret_cast < void * * * > ( pDeviceEx ) ) [ ( int ) IDirect3DDevice9VTable : : Present ] ;
( void * & ) _IDirect3DDevice9Ex_PresentEx = ( * reinterpret_cast < void * * * > ( pDeviceEx ) ) [ ( int ) IDirect3DDevice9VTable : : PresentEx ] ;
HookDX9Present ( ) ;
}
else
{
PRINT_DEBUG ( " Failed to hook D3D9::Present to detect DX Version \n " ) ;
}
if ( pDeviceEx ) pDeviceEx - > Release ( ) ;
if ( pD3D ) pD3D - > Release ( ) ;
}
}
void Hook_Manager : : hook_dx10 ( )
{
if ( ! _dxgi_hooked & & ! _renderer_found )
{
IDXGISwapChain * pSwapChain ;
ID3D10Device * pDevice ;
DXGI_SWAP_CHAIN_DESC SwapChainDesc = { } ;
decltype ( D3D10CreateDeviceAndSwapChain ) * D3D10CreateDeviceAndSwapChain =
( decltype ( D3D10CreateDeviceAndSwapChain ) ) GetProcAddress ( GetModuleHandle ( DX10_Hook : : DLL_NAME ) , " D3D10CreateDeviceAndSwapChain " ) ;
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 = GetForegroundWindow ( ) ;
SwapChainDesc . SampleDesc . Count = 1 ;
SwapChainDesc . SampleDesc . Quality = 0 ;
SwapChainDesc . Windowed = TRUE ;
D3D10CreateDeviceAndSwapChain ( NULL , D3D10_DRIVER_TYPE_HARDWARE , NULL , 0 , D3D10_SDK_VERSION , & SwapChainDesc , & pSwapChain , & pDevice ) ;
if ( pDevice ! = nullptr & & pSwapChain ! = nullptr )
{
PRINT_DEBUG ( " Hooked IDXGISwapChain::Present to detect DX Version \n " ) ;
( void * & ) _IDXGISwapChain_Present = ( * reinterpret_cast < void * * * > ( pSwapChain ) ) [ ( int ) IDXGISwapChainVTable : : Present ] ;
HookDXGIPresent ( ) ;
}
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 )
{
IDXGISwapChain * pSwapChain ;
ID3D11Device * pDevice ;
DXGI_SWAP_CHAIN_DESC SwapChainDesc = { } ;
decltype ( D3D11CreateDeviceAndSwapChain ) * D3D11CreateDeviceAndSwapChain =
( decltype ( D3D11CreateDeviceAndSwapChain ) ) GetProcAddress ( GetModuleHandle ( DX11_Hook : : DLL_NAME ) , " D3D11CreateDeviceAndSwapChain " ) ;
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 = GetForegroundWindow ( ) ;
SwapChainDesc . SampleDesc . Count = 1 ;
SwapChainDesc . SampleDesc . Quality = 0 ;
SwapChainDesc . Windowed = TRUE ;
D3D11CreateDeviceAndSwapChain ( NULL , D3D_DRIVER_TYPE_HARDWARE , NULL , 0 , NULL , NULL , D3D11_SDK_VERSION , & SwapChainDesc , & pSwapChain , & pDevice , NULL , NULL ) ;
if ( pDevice ! = nullptr & & pSwapChain ! = nullptr )
{
PRINT_DEBUG ( " Hooked IDXGISwapChain::Present to detect DX Version \n " ) ;
( void * & ) _IDXGISwapChain_Present = ( * reinterpret_cast < void * * * > ( pSwapChain ) ) [ ( int ) IDXGISwapChainVTable : : Present ] ;
HookDXGIPresent ( ) ;
}
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 )
{
DX12_Hook : : Create ( ) ;
}
}
void Hook_Manager : : hook_opengl ( )
{
if ( ! _ogl_hooked & & ! _renderer_found )
{
_wglMakeCurrent = ( decltype ( _wglMakeCurrent ) ) GetProcAddress ( GetModuleHandle ( OpenGL_Hook : : DLL_NAME ) , " wglMakeCurrent " ) ;
HookwglMakeCurrent ( ) ;
}
}
void Hook_Manager : : create_hookA ( const char * libname )
{
if ( ! _stricmp ( libname , " d3d9.dll " ) )
DX9_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_dx9 ( ) ;
else if ( ! _stricmp ( libname , " d3d10.dll " ) )
DX10_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_dx10 ( ) ;
else if ( ! _stricmp ( libname , " d3d11.dll " ) )
DX11_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_dx11 ( ) ;
else if ( ! _stricmp ( libname , " d3d12.dll " ) )
DX12_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_dx12 ( ) ;
else if ( ! _stricmp ( libname , " opengl32.dll " ) )
OpenGL_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_opengl ( ) ;
}
void create_hookW ( const wchar_t * libname )
void Hook_Manager: : create_hookW( const wchar_t * libname )
{
if ( ! _wcsicmp ( libname , L " d3d9.dll " ) )
DX9_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_dx9 ( ) ;
else if ( ! _wcsicmp ( libname , L " d3d10.dll " ) )
DX10_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_dx10 ( ) ;
else if ( ! _wcsicmp ( libname , L " d3d11.dll " ) )
DX11_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_dx11 ( ) ;
else if ( ! _wcsicmp ( libname , L " d3d12.dll " ) )
DX12_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_dx12 ( ) ;
else if ( ! _wcsicmp ( libname , L " opengl32.dll " ) )
OpenGL_Hook : : Create ( ) ;
Hook_Manager: : Inst ( ) . hook_opengl ( ) ;
}
HMODULE WINAPI mLoadLibraryA ( LPCTSTR lpLibFileName )
HMODULE WINAPI Hook_Manager: : My LoadLibraryA( LPCTSTR lpLibFileName )
{
auto res = _LoadLibraryA ( lpLibFileName ) ;
create_hookA ( lpLibFileName ) ;
Hook_Manager: : Inst ( ) . create_hookA( lpLibFileName ) ;
return res ;
}
HMODULE WINAPI mLoadLibraryW ( LPCWSTR lpLibFileName )
HMODULE WINAPI Hook_Manager: : My LoadLibraryW( LPCWSTR lpLibFileName )
{
auto res = _LoadLibraryW ( lpLibFileName ) ;
create_hookW ( lpLibFileName ) ;
Hook_Manager: : Inst ( ) . create_hookW( lpLibFileName ) ;
return res ;
}
HMODULE WINAPI mLoadLibraryExA ( LPCTSTR lpLibFileName , HANDLE hFile , DWORD dwFlags )
HMODULE WINAPI Hook_Manager: : My LoadLibraryExA( LPCTSTR lpLibFileName , HANDLE hFile , DWORD dwFlags )
{
auto res = _LoadLibraryA ( lpLibFileName ) ;
create_hookA ( lpLibFileName ) ;
Hook_Manager: : Inst ( ) . create_hookA( lpLibFileName ) ;
return res ;
}
HMODULE WINAPI mLoadLibraryExW ( LPCWSTR lpLibFileName , HANDLE hFile , DWORD dwFlags )
HMODULE WINAPI Hook_Manager: : My LoadLibraryExW( LPCWSTR lpLibFileName , HANDLE hFile , DWORD dwFlags )
{
auto res = _LoadLibraryExW ( lpLibFileName , hFile , dwFlags ) ;
create_hookW ( lpLibFileName ) ;
Hook_Manager: : Inst ( ) . create_hookW( lpLibFileName ) ;
return res ;
}
void Hook_Manager : : HookLoadLibrary ( )
{
if ( ! _renderer_found & & ! _loadlibrary_hooked )
{
_loadlibrary_hooked = true ;
rendererdetect_hook = new Base_Hook ( ) ;
AddHook ( rendererdetect_hook ) ;
rendererdetect_hook - > BeginHook ( ) ;
rendererdetect_hook - > HookFuncs (
std : : pair < void * * , void * > ( ( PVOID * ) & _LoadLibraryA , & Hook_Manager : : MyLoadLibraryA ) ,
std : : pair < void * * , void * > ( ( PVOID * ) & _LoadLibraryW , & Hook_Manager : : MyLoadLibraryW ) ,
std : : pair < void * * , void * > ( ( PVOID * ) & _LoadLibraryExA , & Hook_Manager : : MyLoadLibraryExA ) ,
std : : pair < void * * , void * > ( ( PVOID * ) & _LoadLibraryExW , & Hook_Manager : : MyLoadLibraryExW )
) ;
rendererdetect_hook - > EndHook ( ) ;
}
}
void Hook_Manager : : ChangeGameWindow ( HWND hWnd ) const
{
overlay - > HookReady ( hWnd ) ;
}
void Hook_Manager : : CallOverlayProc ( int width , int height ) const
{
overlay - > OverlayProc ( width , height ) ;
}
# endif
void Hook_Manager : : UnHookAllRendererDetector ( )
{
auto it = std : : find ( _hooks . begin ( ) , _hooks . end ( ) , rendererdetect_hook ) ;
if ( it ! = _hooks . end ( ) )
{
_hooks . erase ( it ) ;
delete rendererdetect_hook ;
rendererdetect_hook = nullptr ;
}
_ogl_hooked = false ;
# ifdef STEAM_WIN32
_dxgi_hooked = _dx9_hooked = false ;
# endif
}
Hook_Manager : : Hook_Manager ( ) :
_isSet ( false ) ,
_LoadLibraryHooked ( false )
# ifdef STEAM_WIN32
_game_hwnd ( nullptr ) ,
_game_wndproc ( nullptr ) ,
_loadlibrary_hooked ( false ) ,
_dxgi_hooked ( false ) ,
_dx9_hooked ( false ) ,
# endif
_renderer_found ( false ) ,
_ogl_hooked ( false )
{ }
Hook_Manager : : ~ Hook_Manager ( )
@ -94,6 +384,7 @@ Hook_Manager& Hook_Manager::Inst()
void Hook_Manager : : HookRenderer ( Steam_Overlay * ovlay )
{
overlay = ovlay ;
# ifdef STEAM_WIN32
HookLoadLibrary ( ) ;
std : : vector < std : : string > const libraries = { " opengl32.dll " , " d3d12.dll " , " d3d11.dll " , " d3d10.dll " , " d3d9.dll " } ;
std : : vector < std : : string > : : const_iterator it = libraries . begin ( ) ;
@ -112,47 +403,14 @@ void Hook_Manager::HookRenderer(Steam_Overlay *ovlay)
create_hookA ( it - > c_str ( ) ) ;
+ + it ;
}
# endif
}
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 )
void Hook_Manager : : FoundRenderer ( Base_Hook * hook )
{
if ( ! _ isSet )
if ( ! _renderer_found )
{
_isSet = true ;
UnHookLoadLibrary ( ) ;
_renderer_found = true ;
// Remove all hooks that are unused
_hooks . erase ( std : : remove_if ( _hooks . begin ( ) , _hooks . end ( ) , [ & hook ] ( Base_Hook * it_hook ) {
@ -163,17 +421,9 @@ void Hook_Manager::FoundHook(Base_Hook* hook)
}
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 ) ;
_loadlibrary_hooked = false ;
}
}
# endif //NO_OVERLAY