Now passing to hooks device object.
Added Base_Hook::get_lib_name to track what renderer is hooked for overlay. Objects used to detect renderer type are now also used to hook the rendering functions. So we don't have to build another device. Updated VTables for DX12.merge-requests/28/head
parent
cd8c5fc2ea
commit
dd530e80b1
|
@ -45,6 +45,11 @@ void Base_Hook::UnhookAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* Base_Hook::get_lib_name() const
|
||||||
|
{
|
||||||
|
return "<no_name>";
|
||||||
|
}
|
||||||
|
|
||||||
void Base_Hook::HookFunc(std::pair<void**, void*> hook)
|
void Base_Hook::HookFunc(std::pair<void**, void*> hook)
|
||||||
{
|
{
|
||||||
if( DetourAttach(hook.first, hook.second) == 0 )
|
if( DetourAttach(hook.first, hook.second) == 0 )
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
void EndHook();
|
void EndHook();
|
||||||
void UnhookAll();
|
void UnhookAll();
|
||||||
|
|
||||||
|
virtual const char* get_lib_name() const;
|
||||||
void HookFunc(std::pair<void**, void*> hook);
|
void HookFunc(std::pair<void**, void*> hook);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -18,37 +18,10 @@ bool DX10_Hook::start_hook()
|
||||||
if (!Windows_Hook::Inst().start_hook())
|
if (!Windows_Hook::Inst().start_hook())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
HWND hWnd = GetGameWindow();
|
|
||||||
if (!hWnd)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
IDXGISwapChain* pSwapChain;
|
|
||||||
ID3D10Device* pDevice;
|
|
||||||
DXGI_SWAP_CHAIN_DESC SwapChainDesc = {};
|
|
||||||
decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain =
|
|
||||||
(decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(reinterpret_cast<HMODULE>(_library), "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 = 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 (pDevice != nullptr && pSwapChain != nullptr)
|
|
||||||
{
|
|
||||||
PRINT_DEBUG("Hooked DirectX 10\n");
|
PRINT_DEBUG("Hooked DirectX 10\n");
|
||||||
|
|
||||||
_hooked = true;
|
_hooked = true;
|
||||||
Hook_Manager::Inst().FoundRenderer(this);
|
|
||||||
|
|
||||||
loadFunctions(pDevice, pSwapChain);
|
Hook_Manager::Inst().FoundRenderer(this);
|
||||||
|
|
||||||
UnhookAll();
|
UnhookAll();
|
||||||
BeginHook();
|
BeginHook();
|
||||||
|
@ -61,14 +34,6 @@ bool DX10_Hook::start_hook()
|
||||||
|
|
||||||
get_steam_client()->steam_overlay->HookReady();
|
get_steam_client()->steam_overlay->HookReady();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
PRINT_DEBUG("Failed to hook DirectX 10\n");
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
if(pDevice)pDevice->Release();
|
|
||||||
if(pSwapChain)pSwapChain->Release();
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +185,11 @@ DX10_Hook* DX10_Hook::Inst()
|
||||||
return _inst;
|
return _inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* DX10_Hook::get_lib_name() const
|
||||||
|
{
|
||||||
|
return DLL_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
void DX10_Hook::loadFunctions(ID3D10Device *pDevice, IDXGISwapChain *pSwapChain)
|
void DX10_Hook::loadFunctions(ID3D10Device *pDevice, IDXGISwapChain *pSwapChain)
|
||||||
{
|
{
|
||||||
void** vTable = *reinterpret_cast<void***>(pDevice);
|
void** vTable = *reinterpret_cast<void***>(pDevice);
|
||||||
|
|
|
@ -46,6 +46,7 @@ private:
|
||||||
public:
|
public:
|
||||||
bool start_hook();
|
bool start_hook();
|
||||||
static DX10_Hook* Inst();
|
static DX10_Hook* Inst();
|
||||||
|
virtual const char* get_lib_name() const;
|
||||||
|
|
||||||
void loadFunctions(ID3D10Device *pDevice, IDXGISwapChain *pSwapChain);
|
void loadFunctions(ID3D10Device *pDevice, IDXGISwapChain *pSwapChain);
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,37 +28,10 @@ bool DX11_Hook::start_hook()
|
||||||
if (!Windows_Hook::Inst().start_hook())
|
if (!Windows_Hook::Inst().start_hook())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
HWND hWnd = GetGameWindow();
|
|
||||||
if (!hWnd)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
IDXGISwapChain* pSwapChain;
|
|
||||||
ID3D11Device* pDevice;
|
|
||||||
DXGI_SWAP_CHAIN_DESC SwapChainDesc = {};
|
|
||||||
decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain =
|
|
||||||
(decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(reinterpret_cast<HMODULE>(_library), "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 = 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 (pDevice != nullptr && pSwapChain != nullptr)
|
|
||||||
{
|
|
||||||
PRINT_DEBUG("Hooked DirectX 11\n");
|
PRINT_DEBUG("Hooked DirectX 11\n");
|
||||||
|
|
||||||
_hooked = true;
|
_hooked = true;
|
||||||
Hook_Manager::Inst().FoundRenderer(this);
|
|
||||||
|
|
||||||
loadFunctions(pDevice, pSwapChain);
|
Hook_Manager::Inst().FoundRenderer(this);
|
||||||
|
|
||||||
UnhookAll();
|
UnhookAll();
|
||||||
BeginHook();
|
BeginHook();
|
||||||
|
@ -71,15 +44,6 @@ bool DX11_Hook::start_hook()
|
||||||
|
|
||||||
get_steam_client()->steam_overlay->HookReady();
|
get_steam_client()->steam_overlay->HookReady();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
PRINT_DEBUG("Failed to hook DirectX 11\n");
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pDevice) pDevice->Release();
|
|
||||||
if(pSwapChain) pSwapChain->Release();
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +203,11 @@ DX11_Hook* DX11_Hook::Inst()
|
||||||
return _inst;
|
return _inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* DX11_Hook::get_lib_name() const
|
||||||
|
{
|
||||||
|
return DLL_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
void DX11_Hook::loadFunctions(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
|
void DX11_Hook::loadFunctions(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
|
||||||
{
|
{
|
||||||
void** vTable = *reinterpret_cast<void***>(pDevice);
|
void** vTable = *reinterpret_cast<void***>(pDevice);
|
||||||
|
|
|
@ -46,6 +46,7 @@ private:
|
||||||
public:
|
public:
|
||||||
bool start_hook();
|
bool start_hook();
|
||||||
static DX11_Hook* Inst();
|
static DX11_Hook* Inst();
|
||||||
|
virtual const char* get_lib_name() const;
|
||||||
|
|
||||||
void loadFunctions(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain);
|
void loadFunctions(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain);
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,60 +14,34 @@ DX9_Hook* DX9_Hook::_inst = nullptr;
|
||||||
|
|
||||||
bool DX9_Hook::start_hook()
|
bool DX9_Hook::start_hook()
|
||||||
{
|
{
|
||||||
bool res = true;
|
|
||||||
if (!_hooked)
|
if (!_hooked)
|
||||||
{
|
{
|
||||||
if (!Windows_Hook::Inst().start_hook())
|
if (!Windows_Hook::Inst().start_hook())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
HWND hWnd = GetGameWindow();
|
|
||||||
if (!hWnd)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
IDirect3D9Ex* pD3D;
|
|
||||||
IDirect3DDevice9Ex* pDeviceEx;
|
|
||||||
decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(reinterpret_cast<HMODULE>(_library), "Direct3DCreate9Ex");
|
|
||||||
|
|
||||||
Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D);
|
|
||||||
|
|
||||||
D3DPRESENT_PARAMETERS params = {};
|
|
||||||
params.BackBufferWidth = 1;
|
|
||||||
params.BackBufferHeight = 1;
|
|
||||||
params.hDeviceWindow = hWnd;
|
|
||||||
|
|
||||||
pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, &pDeviceEx);
|
|
||||||
|
|
||||||
if (pDeviceEx != nullptr)
|
|
||||||
{
|
|
||||||
PRINT_DEBUG("Hooked DirectX 9\n");
|
PRINT_DEBUG("Hooked DirectX 9\n");
|
||||||
|
|
||||||
_hooked = true;
|
_hooked = true;
|
||||||
Hook_Manager::Inst().FoundRenderer(this);
|
|
||||||
|
|
||||||
loadFunctions(pDeviceEx);
|
Hook_Manager::Inst().FoundRenderer(this);
|
||||||
|
|
||||||
UnhookAll();
|
UnhookAll();
|
||||||
BeginHook();
|
BeginHook();
|
||||||
HookFuncs(
|
HookFuncs(
|
||||||
std::make_pair<void**, void*>(&(PVOID&)Reset, &DX9_Hook::MyReset),
|
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&)Present, &DX9_Hook::MyPresent)
|
||||||
|
);
|
||||||
|
if (PresentEx != nullptr)
|
||||||
|
{
|
||||||
|
HookFuncs(
|
||||||
std::make_pair<void**, void*>(&(PVOID&)PresentEx, &DX9_Hook::MyPresentEx)
|
std::make_pair<void**, void*>(&(PVOID&)PresentEx, &DX9_Hook::MyPresentEx)
|
||||||
//std::make_pair<void**, void*>(&(PVOID&)EndScene, &DX9_Hook::MyEndScene)
|
//std::make_pair<void**, void*>(&(PVOID&)EndScene, &DX9_Hook::MyEndScene)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
EndHook();
|
EndHook();
|
||||||
|
|
||||||
get_steam_client()->steam_overlay->HookReady();
|
get_steam_client()->steam_overlay->HookReady();
|
||||||
}
|
}
|
||||||
else
|
return true;
|
||||||
{
|
|
||||||
PRINT_DEBUG("Failed to DirectX 9\n");
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pDeviceEx)pDeviceEx->Release();
|
|
||||||
if(pD3D)pD3D->Release();
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DX9_Hook::resetRenderState()
|
void DX9_Hook::resetRenderState()
|
||||||
|
@ -220,14 +194,20 @@ DX9_Hook* DX9_Hook::Inst()
|
||||||
return _inst;
|
return _inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DX9_Hook::loadFunctions(IDirect3DDevice9Ex* pDeviceEx)
|
const char* DX9_Hook::get_lib_name() const
|
||||||
{
|
{
|
||||||
void** vTable = *reinterpret_cast<void***>(pDeviceEx);
|
return DLL_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DX9_Hook::loadFunctions(IDirect3DDevice9* pDevice, bool ex)
|
||||||
|
{
|
||||||
|
void** vTable = *reinterpret_cast<void***>(pDevice);
|
||||||
|
|
||||||
#define LOAD_FUNC(X) (void*&)X = vTable[(int)IDirect3DDevice9VTable::X]
|
#define LOAD_FUNC(X) (void*&)X = vTable[(int)IDirect3DDevice9VTable::X]
|
||||||
LOAD_FUNC(Reset);
|
LOAD_FUNC(Reset);
|
||||||
LOAD_FUNC(EndScene);
|
LOAD_FUNC(EndScene);
|
||||||
LOAD_FUNC(Present);
|
LOAD_FUNC(Present);
|
||||||
|
if (ex)
|
||||||
LOAD_FUNC(PresentEx);
|
LOAD_FUNC(PresentEx);
|
||||||
#undef LOAD_FUNC
|
#undef LOAD_FUNC
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,9 @@ private:
|
||||||
public:
|
public:
|
||||||
bool start_hook();
|
bool start_hook();
|
||||||
static DX9_Hook* Inst();
|
static DX9_Hook* Inst();
|
||||||
|
virtual const char* get_lib_name() const;
|
||||||
|
|
||||||
void loadFunctions(IDirect3DDevice9Ex *pDeviceEx);
|
void loadFunctions(IDirect3DDevice9 *pDevice, bool ex);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif//NO_OVERLAY
|
#endif//NO_OVERLAY
|
||||||
|
|
|
@ -44,6 +44,111 @@ enum class IDXGISwapChainVTable
|
||||||
GetRotation,
|
GetRotation,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ID3D12CommandQueueVTable
|
||||||
|
{
|
||||||
|
// IUnknown
|
||||||
|
QueryInterface,
|
||||||
|
AddRef,
|
||||||
|
Release,
|
||||||
|
|
||||||
|
// ID3D12Object
|
||||||
|
GetPrivateData,
|
||||||
|
SetPrivateData,
|
||||||
|
SetPrivateDataInterface,
|
||||||
|
SetName,
|
||||||
|
|
||||||
|
// ID3D12DeviceChild
|
||||||
|
GetDevice,
|
||||||
|
|
||||||
|
// ID3D12Pageable
|
||||||
|
|
||||||
|
// ID3D12CommandQueue
|
||||||
|
UpdateTileMappings,
|
||||||
|
CopyTileMappings,
|
||||||
|
ExecuteCommandLists,
|
||||||
|
SetMarker,
|
||||||
|
BeginEvent,
|
||||||
|
EndEvent,
|
||||||
|
Signal,
|
||||||
|
Wait,
|
||||||
|
GetTimestampFrequency,
|
||||||
|
GetClockCalibration,
|
||||||
|
GetDesc,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ID3D12GraphicsCommandListVTable
|
||||||
|
{
|
||||||
|
// IUnknown
|
||||||
|
QueryInterface,
|
||||||
|
AddRef,
|
||||||
|
Release,
|
||||||
|
|
||||||
|
// ID3D12Object
|
||||||
|
GetPrivateData,
|
||||||
|
SetPrivateData,
|
||||||
|
SetPrivateDataInterface,
|
||||||
|
SetName,
|
||||||
|
|
||||||
|
// ID3D12DeviceChild
|
||||||
|
GetDevice,
|
||||||
|
|
||||||
|
// ID3D12CommandList
|
||||||
|
GetType,
|
||||||
|
|
||||||
|
// ID3D12GraphicsCommandList
|
||||||
|
Close,
|
||||||
|
Reset,
|
||||||
|
ClearState,
|
||||||
|
DrawInstanced,
|
||||||
|
DrawIndexedInstanced,
|
||||||
|
Dispatch,
|
||||||
|
CopyBufferRegion,
|
||||||
|
CopyTextureRegion,
|
||||||
|
CopyResource,
|
||||||
|
CopyTiles,
|
||||||
|
ResolveSubresource,
|
||||||
|
IASetPrimitiveTopology,
|
||||||
|
RSSetViewports,
|
||||||
|
RSSetScissorRects,
|
||||||
|
OMSetBlendFactor,
|
||||||
|
OMSetStencilRef,
|
||||||
|
SetPipelineState,
|
||||||
|
ResourceBarrier,
|
||||||
|
ExecuteBundle,
|
||||||
|
SetDescriptorHeaps,
|
||||||
|
SetComputeRootSignature,
|
||||||
|
SetGraphicsRootSignature,
|
||||||
|
SetComputeRootDescriptorTable,
|
||||||
|
SetGraphicsRootDescriptorTable,
|
||||||
|
SetComputeRoot32BitConstant,
|
||||||
|
SetGraphicsRoot32BitConstant,
|
||||||
|
SetComputeRoot32BitConstants,
|
||||||
|
SetGraphicsRoot32BitConstants,
|
||||||
|
SetComputeRootConstantBufferView,
|
||||||
|
SetGraphicsRootConstantBufferView,
|
||||||
|
SetComputeRootShaderResourceView,
|
||||||
|
SetGraphicsRootShaderResourceView,
|
||||||
|
SetComputeRootUnorderedAccessView,
|
||||||
|
SetGraphicsRootUnorderedAccessView,
|
||||||
|
IASetIndexBuffer,
|
||||||
|
IASetVertexBuffers,
|
||||||
|
SOSetTargets,
|
||||||
|
OMSetRenderTargets,
|
||||||
|
ClearDepthStencilView,
|
||||||
|
ClearRenderTargetView,
|
||||||
|
ClearUnorderedAccessViewUint,
|
||||||
|
ClearUnorderedAccessViewFloat,
|
||||||
|
DiscardResource,
|
||||||
|
BeginQuery,
|
||||||
|
EndQuery,
|
||||||
|
ResolveQueryData,
|
||||||
|
SetPredication,
|
||||||
|
SetMarker,
|
||||||
|
BeginEvent,
|
||||||
|
EndEvent,
|
||||||
|
ExecuteIndirect,
|
||||||
|
};
|
||||||
|
|
||||||
enum class ID3D11DeviceVTable
|
enum class ID3D11DeviceVTable
|
||||||
{
|
{
|
||||||
// IUnknown
|
// IUnknown
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
constexpr int max_hook_retries = 500;
|
constexpr int max_hook_retries = 500;
|
||||||
|
|
||||||
#ifdef STEAM_WIN32
|
#ifdef STEAM_WIN32
|
||||||
static decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present;
|
static decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present = nullptr;
|
||||||
static decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present;
|
static decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present = nullptr;
|
||||||
static decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx;
|
static decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx = nullptr;
|
||||||
static decltype(wglMakeCurrent)* _wglMakeCurrent;
|
static decltype(wglMakeCurrent)* _wglMakeCurrent = nullptr;
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE Hook_Manager::MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags)
|
HRESULT STDMETHODCALLTYPE Hook_Manager::MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags)
|
||||||
{
|
{
|
||||||
|
@ -100,11 +100,13 @@ BOOL WINAPI Hook_Manager::MywglMakeCurrent(HDC hDC, HGLRC hGLRC)
|
||||||
return _wglMakeCurrent(hDC, hGLRC);
|
return _wglMakeCurrent(hDC, hGLRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hook_Manager::HookDXGIPresent()
|
void Hook_Manager::HookDXGIPresent(IDXGISwapChain *pSwapChain)
|
||||||
{
|
{
|
||||||
if (!_dxgi_hooked)
|
if (!_dxgi_hooked)
|
||||||
{
|
{
|
||||||
_dxgi_hooked = true;
|
_dxgi_hooked = true;
|
||||||
|
(void*&)_IDXGISwapChain_Present = (*reinterpret_cast<void***>(pSwapChain))[(int)IDXGISwapChainVTable::Present];
|
||||||
|
|
||||||
rendererdetect_hook->BeginHook();
|
rendererdetect_hook->BeginHook();
|
||||||
|
|
||||||
rendererdetect_hook->HookFuncs(
|
rendererdetect_hook->HookFuncs(
|
||||||
|
@ -115,17 +117,26 @@ void Hook_Manager::HookDXGIPresent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hook_Manager::HookDX9Present()
|
void Hook_Manager::HookDX9Present(IDirect3DDevice9* pDevice, bool ex)
|
||||||
{
|
{
|
||||||
if (!_dx9_hooked)
|
if (!_dx9_hooked)
|
||||||
{
|
{
|
||||||
_dx9_hooked = true;
|
_dx9_hooked = true;
|
||||||
|
(void*&)_IDirect3DDevice9_Present = (*reinterpret_cast<void***>(pDevice))[(int)IDirect3DDevice9VTable::Present];
|
||||||
|
if (ex)
|
||||||
|
(void*&)_IDirect3DDevice9Ex_PresentEx = (*reinterpret_cast<void***>(pDevice))[(int)IDirect3DDevice9VTable::PresentEx];
|
||||||
|
|
||||||
rendererdetect_hook->BeginHook();
|
rendererdetect_hook->BeginHook();
|
||||||
|
|
||||||
rendererdetect_hook->HookFuncs(
|
rendererdetect_hook->HookFuncs(
|
||||||
std::pair<void**, void*>((PVOID*)& _IDirect3DDevice9_Present, &Hook_Manager::MyPresent),
|
std::pair<void**, void*>((PVOID*)& _IDirect3DDevice9_Present, &Hook_Manager::MyPresent)
|
||||||
|
);
|
||||||
|
if (ex)
|
||||||
|
{
|
||||||
|
rendererdetect_hook->HookFuncs(
|
||||||
std::pair<void**, void*>((PVOID*)& _IDirect3DDevice9Ex_PresentEx, &Hook_Manager::MyPresentEx)
|
std::pair<void**, void*>((PVOID*)& _IDirect3DDevice9Ex_PresentEx, &Hook_Manager::MyPresentEx)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
rendererdetect_hook->EndHook();
|
rendererdetect_hook->EndHook();
|
||||||
}
|
}
|
||||||
|
@ -154,33 +165,48 @@ void Hook_Manager::hook_dx9()
|
||||||
if (!hWnd)
|
if (!hWnd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IDirect3D9Ex* pD3D;
|
IDirect3D9Ex* pD3D = nullptr;
|
||||||
IDirect3DDevice9Ex* pDeviceEx;
|
IUnknown* pDevice = nullptr;
|
||||||
decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(GetModuleHandle(DX9_Hook::DLL_NAME), "Direct3DCreate9Ex");
|
|
||||||
|
|
||||||
Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D);
|
|
||||||
|
|
||||||
D3DPRESENT_PARAMETERS params = {};
|
D3DPRESENT_PARAMETERS params = {};
|
||||||
params.BackBufferWidth = 1;
|
params.BackBufferWidth = 1;
|
||||||
params.BackBufferHeight = 1;
|
params.BackBufferHeight = 1;
|
||||||
params.hDeviceWindow = hWnd;
|
params.hDeviceWindow = hWnd;
|
||||||
|
params.BackBufferCount = 1;
|
||||||
|
params.Windowed = TRUE;
|
||||||
|
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||||
|
|
||||||
pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, &pDeviceEx);
|
decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(GetModuleHandle(DX9_Hook::DLL_NAME), "Direct3DCreate9Ex");
|
||||||
|
if (Direct3DCreate9Ex != nullptr)
|
||||||
|
{
|
||||||
|
Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D);
|
||||||
|
pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, reinterpret_cast<IDirect3DDevice9Ex**>(&pDevice));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
decltype(Direct3DCreate9)* Direct3DCreate9 = (decltype(Direct3DCreate9))GetProcAddress(GetModuleHandle(DX9_Hook::DLL_NAME), "Direct3DCreate9");
|
||||||
|
if (Direct3DCreate9)
|
||||||
|
{
|
||||||
|
pD3D = reinterpret_cast<IDirect3D9Ex*>(Direct3DCreate9(D3D_SDK_VERSION));
|
||||||
|
pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, reinterpret_cast<IDirect3DDevice9 * *>(&pDevice));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pDeviceEx)
|
if (pDevice != nullptr)
|
||||||
{
|
{
|
||||||
PRINT_DEBUG("Hooked D3D9::Present to detect DX Version\n");
|
PRINT_DEBUG("Hooked D3D9::Present to detect DX Version\n");
|
||||||
(void*&)_IDirect3DDevice9_Present = (*reinterpret_cast<void***>(pDeviceEx))[(int)IDirect3DDevice9VTable::Present];
|
auto h = DX9_Hook::Inst();
|
||||||
(void*&)_IDirect3DDevice9Ex_PresentEx = (*reinterpret_cast<void***>(pDeviceEx))[(int)IDirect3DDevice9VTable::PresentEx];
|
h->loadFunctions(reinterpret_cast<IDirect3DDevice9*>(pDevice), Direct3DCreate9Ex != nullptr);
|
||||||
HookDX9Present();
|
_hooks.insert(h);
|
||||||
|
HookDX9Present(reinterpret_cast<IDirect3DDevice9*>(pDevice), Direct3DCreate9Ex != nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PRINT_DEBUG("Failed to hook D3D9::Present to detect DX Version\n");
|
PRINT_DEBUG("Failed to hook D3D9::Present to detect DX Version\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDeviceEx)pDeviceEx->Release();
|
if (pDevice) pDevice->Release();
|
||||||
if (pD3D)pD3D->Release();
|
if (pD3D) pD3D->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,8 +240,10 @@ void Hook_Manager::hook_dx10()
|
||||||
if (pDevice != nullptr && pSwapChain != nullptr)
|
if (pDevice != nullptr && pSwapChain != nullptr)
|
||||||
{
|
{
|
||||||
PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n");
|
PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n");
|
||||||
(void*&)_IDXGISwapChain_Present = (*reinterpret_cast<void***>(pSwapChain))[(int)IDXGISwapChainVTable::Present];
|
auto h = DX10_Hook::Inst();
|
||||||
HookDXGIPresent();
|
h->loadFunctions(pDevice, pSwapChain);
|
||||||
|
_hooks.insert(h);
|
||||||
|
HookDXGIPresent(pSwapChain);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -256,8 +284,10 @@ void Hook_Manager::hook_dx11()
|
||||||
if (pDevice != nullptr && pSwapChain != nullptr)
|
if (pDevice != nullptr && pSwapChain != nullptr)
|
||||||
{
|
{
|
||||||
PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n");
|
PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n");
|
||||||
(void*&)_IDXGISwapChain_Present = (*reinterpret_cast<void***>(pSwapChain))[(int)IDXGISwapChainVTable::Present];
|
auto h = DX11_Hook::Inst();
|
||||||
HookDXGIPresent();
|
h->loadFunctions(pDevice, pSwapChain);
|
||||||
|
_hooks.insert(h);
|
||||||
|
HookDXGIPresent(pSwapChain);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -282,6 +312,7 @@ void Hook_Manager::hook_dx12()
|
||||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||||
ID3D12CommandQueue* pCommandQueue = nullptr;
|
ID3D12CommandQueue* pCommandQueue = nullptr;
|
||||||
ID3D12Device* pDevice = nullptr;
|
ID3D12Device* pDevice = nullptr;
|
||||||
|
|
||||||
decltype(D3D12CreateDevice)* D3D12CreateDevice =
|
decltype(D3D12CreateDevice)* D3D12CreateDevice =
|
||||||
(decltype(D3D12CreateDevice))GetProcAddress(GetModuleHandle(DX12_Hook::DLL_NAME), "D3D12CreateDevice");
|
(decltype(D3D12CreateDevice))GetProcAddress(GetModuleHandle(DX12_Hook::DLL_NAME), "D3D12CreateDevice");
|
||||||
|
|
||||||
|
@ -290,14 +321,14 @@ void Hook_Manager::hook_dx12()
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
{
|
{
|
||||||
DXGI_SWAP_CHAIN_DESC1 SwapChainDesc = {};
|
DXGI_SWAP_CHAIN_DESC1 SwapChainDesc = {};
|
||||||
SwapChainDesc.Width = 0;
|
SwapChainDesc.BufferCount = 2;
|
||||||
SwapChainDesc.Height = 0;
|
SwapChainDesc.Width = 1;
|
||||||
|
SwapChainDesc.Height = 1;
|
||||||
SwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
SwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
SwapChainDesc.Stereo = FALSE;
|
SwapChainDesc.Stereo = FALSE;
|
||||||
SwapChainDesc.SampleDesc = { 1, 0 };
|
SwapChainDesc.SampleDesc = { 1, 0 };
|
||||||
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
SwapChainDesc.BufferCount = 3;
|
SwapChainDesc.Scaling = DXGI_SCALING_NONE;
|
||||||
SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
|
||||||
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||||
|
|
||||||
|
@ -312,8 +343,11 @@ void Hook_Manager::hook_dx12()
|
||||||
if (pSwapChain != nullptr)
|
if (pSwapChain != nullptr)
|
||||||
{
|
{
|
||||||
PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n");
|
PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n");
|
||||||
(void*&)_IDXGISwapChain_Present = (*reinterpret_cast<void***>(pSwapChain))[(int)IDXGISwapChainVTable::Present];
|
|
||||||
HookDXGIPresent();
|
auto h = DX12_Hook::Inst();
|
||||||
|
h->loadFunctions(pDevice, pCommandQueue, pSwapChain);
|
||||||
|
_hooks.insert(h);
|
||||||
|
HookDXGIPresent(pSwapChain);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -472,6 +506,7 @@ void Hook_Manager::FoundRenderer(Base_Hook* hook)
|
||||||
if (!_renderer_found)
|
if (!_renderer_found)
|
||||||
{
|
{
|
||||||
_renderer_found = true;
|
_renderer_found = true;
|
||||||
|
game_renderer = hook;
|
||||||
|
|
||||||
if (hook == nullptr)
|
if (hook == nullptr)
|
||||||
PRINT_DEBUG("We found a renderer but couldn't hook it, aborting overlay hook.\n");
|
PRINT_DEBUG("We found a renderer but couldn't hook it, aborting overlay hook.\n");
|
||||||
|
@ -480,16 +515,15 @@ void Hook_Manager::FoundRenderer(Base_Hook* hook)
|
||||||
|
|
||||||
_hook_thread->join();
|
_hook_thread->join();
|
||||||
delete _hook_thread;
|
delete _hook_thread;
|
||||||
|
_hook_thread = nullptr;
|
||||||
|
|
||||||
// Remove all hooks that are unused
|
// Remove all hooks that are unused
|
||||||
_hooks.erase(std::remove_if(_hooks.begin(), _hooks.end(), [&hook](Base_Hook* it_hook) {
|
std::set<Base_Hook*>::iterator item;
|
||||||
if (hook != it_hook)
|
while ((item = std::find_if(_hooks.begin(), _hooks.end(), [hook](Base_Hook* item) {return item != hook; })) != _hooks.end())
|
||||||
{
|
{
|
||||||
delete it_hook;
|
delete *item;
|
||||||
return true;
|
_hooks.erase(item);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}), _hooks.end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#ifndef NO_OVERLAY
|
#ifndef NO_OVERLAY
|
||||||
|
|
||||||
#include <vector>
|
#include <set>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(WIN32)
|
#if defined(_WIN32) || defined(WIN32)
|
||||||
|
@ -30,13 +30,14 @@ protected:
|
||||||
// TODO: If needed, create a second vector with only the renderers hook
|
// TODO: If needed, create a second vector with only the renderers hook
|
||||||
// Cause actually, a call to FoundRenderer will unhook everything registered except the renderer hook
|
// Cause actually, a call to FoundRenderer will unhook everything registered except the renderer hook
|
||||||
// If you do that, you should consider moving the renderer hooks to its own class and keep this one generic ?
|
// If you do that, you should consider moving the renderer hooks to its own class and keep this one generic ?
|
||||||
std::vector<Base_Hook*> _hooks;
|
std::set<Base_Hook*> _hooks;
|
||||||
|
|
||||||
std::thread *_hook_thread;
|
std::thread *_hook_thread;
|
||||||
unsigned int _hook_retries;
|
unsigned int _hook_retries;
|
||||||
bool _renderer_found; // Is the renderer hooked ?
|
bool _renderer_found; // Is the renderer hooked ?
|
||||||
bool _ogl_hooked; // wglMakeCurrent is hooked ? (opengl)
|
bool _ogl_hooked; // wglMakeCurrent is hooked ? (opengl)
|
||||||
Base_Hook* rendererdetect_hook;
|
Base_Hook* rendererdetect_hook;
|
||||||
|
Base_Hook* game_renderer;
|
||||||
class Steam_Overlay* overlay;
|
class Steam_Overlay* overlay;
|
||||||
|
|
||||||
Hook_Manager();
|
Hook_Manager();
|
||||||
|
@ -54,9 +55,9 @@ protected:
|
||||||
bool _dxgi_hooked; // DXGI Present is hooked ? (DX10, DX11, DX12)
|
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
|
// DXGIPresent will be used to detect if DX10, DX11 or DX12 should be used for overlay
|
||||||
void HookDXGIPresent();
|
void HookDXGIPresent(IDXGISwapChain* pSwapChain);
|
||||||
// DX9 Present and PresentEx will be used to detect if DX9 should be used for overlay
|
// DX9 Present and PresentEx will be used to detect if DX9 should be used for overlay
|
||||||
void HookDX9Present();
|
void HookDX9Present(IDirect3DDevice9* pDevice, bool ex);
|
||||||
// wglMakeCurrent will be used to detect if OpenGL3 should be used for overlay
|
// wglMakeCurrent will be used to detect if OpenGL3 should be used for overlay
|
||||||
void HookwglMakeCurrent();
|
void HookwglMakeCurrent();
|
||||||
// Setup DX9 Device and get vtable
|
// Setup DX9 Device and get vtable
|
||||||
|
@ -97,7 +98,9 @@ public:
|
||||||
// Set the found hook and free all other hooks
|
// Set the found hook and free all other hooks
|
||||||
void FoundRenderer(Base_Hook *hook);
|
void FoundRenderer(Base_Hook *hook);
|
||||||
|
|
||||||
inline void AddHook(Base_Hook* hook) { _hooks.push_back(hook); }
|
inline void AddHook(Base_Hook* hook) { _hooks.insert(hook); }
|
||||||
|
|
||||||
|
inline Base_Hook* get_renderer() const { return game_renderer; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif//NO_OVERLAY
|
#endif//NO_OVERLAY
|
||||||
|
|
|
@ -152,4 +152,9 @@ OpenGL_Hook* OpenGL_Hook::Inst()
|
||||||
return _inst;
|
return _inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* OpenGL_Hook::get_lib_name() const
|
||||||
|
{
|
||||||
|
return DLL_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
#endif//NO_OVERLAY
|
#endif//NO_OVERLAY
|
|
@ -38,6 +38,7 @@ private:
|
||||||
public:
|
public:
|
||||||
bool start_hook();
|
bool start_hook();
|
||||||
static OpenGL_Hook* Inst();
|
static OpenGL_Hook* Inst();
|
||||||
|
virtual const char* get_lib_name() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif//NO_OVERLAY
|
#endif//NO_OVERLAY
|
||||||
|
|
|
@ -189,3 +189,8 @@ Windows_Hook& Windows_Hook::Inst()
|
||||||
static Windows_Hook _inst;
|
static Windows_Hook _inst;
|
||||||
return _inst;
|
return _inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* Windows_Hook::get_lib_name() const
|
||||||
|
{
|
||||||
|
return DLL_NAME;
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ public:
|
||||||
WNDPROC GetGameWndProc() const;
|
WNDPROC GetGameWndProc() const;
|
||||||
|
|
||||||
static Windows_Hook& Inst();
|
static Windows_Hook& Inst();
|
||||||
|
virtual const char* get_lib_name() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
HWND GetGameWindow();
|
HWND GetGameWindow();
|
||||||
|
|
|
@ -30,12 +30,13 @@ void Steam_Overlay::steam_overlay_callback(void* object, Common_Message* msg)
|
||||||
_this->Callback(msg);
|
_this->Callback(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Steam_Overlay::Steam_Overlay(Settings* settings, SteamCallResults* callback_results, SteamCallBacks* callbacks, RunEveryRunCB* run_every_runcb, Networking *network) :
|
Steam_Overlay::Steam_Overlay(Settings* settings, SteamCallResults* callback_results, SteamCallBacks* callbacks, RunEveryRunCB* run_every_runcb, Networking* network) :
|
||||||
settings(settings),
|
settings(settings),
|
||||||
callback_results(callback_results),
|
callback_results(callback_results),
|
||||||
callbacks(callbacks),
|
callbacks(callbacks),
|
||||||
run_every_runcb(run_every_runcb),
|
run_every_runcb(run_every_runcb),
|
||||||
network(network),
|
network(network),
|
||||||
|
setup_overlay_called(false),
|
||||||
show_overlay(false),
|
show_overlay(false),
|
||||||
is_ready(false),
|
is_ready(false),
|
||||||
notif_position(ENotificationPosition::k_EPositionBottomLeft),
|
notif_position(ENotificationPosition::k_EPositionBottomLeft),
|
||||||
|
@ -75,7 +76,12 @@ void Steam_Overlay::SetNotificationInset(int nHorizontalInset, int nVerticalInse
|
||||||
|
|
||||||
void Steam_Overlay::SetupOverlay()
|
void Steam_Overlay::SetupOverlay()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||||
|
if (!setup_overlay_called)
|
||||||
|
{
|
||||||
|
setup_overlay_called = true;
|
||||||
Hook_Manager::Inst().HookRenderer();
|
Hook_Manager::Inst().HookRenderer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Steam_Overlay::HookReady()
|
void Steam_Overlay::HookReady()
|
||||||
|
@ -390,6 +396,9 @@ void Steam_Overlay::OverlayProc( int width, int height )
|
||||||
settings->get_local_name(),
|
settings->get_local_name(),
|
||||||
settings->get_local_steam_id().ConvertToUint64(),
|
settings->get_local_steam_id().ConvertToUint64(),
|
||||||
settings->get_local_game_id().AppID());
|
settings->get_local_game_id().AppID());
|
||||||
|
ImGui::SameLine();
|
||||||
|
Base_Hook *hook = Hook_Manager::Inst().get_renderer();
|
||||||
|
ImGui::LabelText("##label", "Renderer: %s", (hook == nullptr ? "Unknown" : hook->get_lib_name()));
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ class Steam_Overlay
|
||||||
// friend id, show client window (to chat and accept invite maybe)
|
// friend id, show client window (to chat and accept invite maybe)
|
||||||
std::map<Friend, friend_window_state, Friend_Less> friends;
|
std::map<Friend, friend_window_state, Friend_Less> friends;
|
||||||
|
|
||||||
|
bool setup_overlay_called;
|
||||||
bool is_ready;
|
bool is_ready;
|
||||||
bool show_overlay;
|
bool show_overlay;
|
||||||
ENotificationPosition notif_position;
|
ENotificationPosition notif_position;
|
||||||
|
|
Loading…
Reference in New Issue