mirror of
https://gitlab.com/Mr_Goldberg/goldberg_emulator.git
synced 2024-11-23 20:38:07 +01:00
Added hook retry.
Handed hook detection to a thread that can then retry. With that, don't need to wait for loadLibrary. Will remove all those commented functions in another version.
This commit is contained in:
parent
5893b69d1f
commit
c99628a88a
2 changed files with 85 additions and 94 deletions
|
@ -17,23 +17,18 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef STEAM_WIN32
|
#ifdef STEAM_WIN32
|
||||||
decltype(LoadLibraryA )* _LoadLibraryA = LoadLibraryA;
|
static decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present;
|
||||||
decltype(LoadLibraryW )* _LoadLibraryW = LoadLibraryW;
|
static decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present;
|
||||||
decltype(LoadLibraryExA )* _LoadLibraryExA = LoadLibraryExA;
|
static decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx;
|
||||||
decltype(LoadLibraryExW )* _LoadLibraryExW = LoadLibraryExW;
|
static decltype(wglMakeCurrent)* _wglMakeCurrent;
|
||||||
|
|
||||||
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)
|
HRESULT STDMETHODCALLTYPE Hook_Manager::MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags)
|
||||||
{
|
{
|
||||||
Hook_Manager& inst = Hook_Manager::Inst();
|
Hook_Manager& inst = Hook_Manager::Inst();
|
||||||
if (!inst.stop_retry())
|
if (!inst.stop_retry())
|
||||||
{
|
{
|
||||||
IUnknown* pDevice;
|
IUnknown* pDevice = nullptr;
|
||||||
_this->GetDevice(__uuidof(ID3D10Device), (void**)& pDevice);
|
_this->GetDevice(__uuidof(ID3D10Device), (void**)&pDevice);
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
{
|
{
|
||||||
DX10_Hook* hook = DX10_Hook::Inst();
|
DX10_Hook* hook = DX10_Hook::Inst();
|
||||||
|
@ -324,7 +319,7 @@ void Hook_Manager::hook_opengl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hook_Manager::create_hookA(const char* libname)
|
void Hook_Manager::create_hook(const char* libname)
|
||||||
{
|
{
|
||||||
if (!_stricmp(libname, "d3d9.dll"))
|
if (!_stricmp(libname, "d3d9.dll"))
|
||||||
Hook_Manager::Inst().hook_dx9();
|
Hook_Manager::Inst().hook_dx9();
|
||||||
|
@ -338,47 +333,47 @@ void Hook_Manager::create_hookA(const char* libname)
|
||||||
Hook_Manager::Inst().hook_opengl();
|
Hook_Manager::Inst().hook_opengl();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hook_Manager::create_hookW(const wchar_t *libname)
|
//void Hook_Manager::create_hookW(const wchar_t *libname)
|
||||||
{
|
//{
|
||||||
if (!_wcsicmp(libname, L"d3d9.dll"))
|
// if (!_wcsicmp(libname, L"d3d9.dll"))
|
||||||
Hook_Manager::Inst().hook_dx9();
|
// Hook_Manager::Inst().hook_dx9();
|
||||||
else if (!_wcsicmp(libname, L"d3d10.dll"))
|
// else if (!_wcsicmp(libname, L"d3d10.dll"))
|
||||||
Hook_Manager::Inst().hook_dx10();
|
// Hook_Manager::Inst().hook_dx10();
|
||||||
else if (!_wcsicmp(libname, L"d3d11.dll"))
|
// else if (!_wcsicmp(libname, L"d3d11.dll"))
|
||||||
Hook_Manager::Inst().hook_dx11();
|
// Hook_Manager::Inst().hook_dx11();
|
||||||
else if (!_wcsicmp(libname, L"d3d12.dll"))
|
// else if (!_wcsicmp(libname, L"d3d12.dll"))
|
||||||
Hook_Manager::Inst().hook_dx12();
|
// Hook_Manager::Inst().hook_dx12();
|
||||||
else if (!_wcsicmp(libname, L"opengl32.dll"))
|
// else if (!_wcsicmp(libname, L"opengl32.dll"))
|
||||||
Hook_Manager::Inst().hook_opengl();
|
// Hook_Manager::Inst().hook_opengl();
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
HMODULE WINAPI Hook_Manager::MyLoadLibraryA(LPCTSTR lpLibFileName)
|
//HMODULE WINAPI Hook_Manager::MyLoadLibraryA(LPCTSTR lpLibFileName)
|
||||||
{
|
//{
|
||||||
auto res = _LoadLibraryA(lpLibFileName);
|
// auto res = _LoadLibraryA(lpLibFileName);
|
||||||
Hook_Manager::Inst().create_hookA(lpLibFileName);
|
// Hook_Manager::Inst().create_hookA(lpLibFileName);
|
||||||
return res;
|
// return res;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
HMODULE WINAPI Hook_Manager::MyLoadLibraryW(LPCWSTR lpLibFileName)
|
//HMODULE WINAPI Hook_Manager::MyLoadLibraryW(LPCWSTR lpLibFileName)
|
||||||
{
|
//{
|
||||||
auto res = _LoadLibraryW(lpLibFileName);
|
// auto res = _LoadLibraryW(lpLibFileName);
|
||||||
Hook_Manager::Inst().create_hookW(lpLibFileName);
|
// Hook_Manager::Inst().create_hookW(lpLibFileName);
|
||||||
return res;
|
// return res;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
HMODULE WINAPI Hook_Manager::MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
|
//HMODULE WINAPI Hook_Manager::MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
|
||||||
{
|
//{
|
||||||
auto res = _LoadLibraryA(lpLibFileName);
|
// auto res = _LoadLibraryA(lpLibFileName);
|
||||||
Hook_Manager::Inst().create_hookA(lpLibFileName);
|
// Hook_Manager::Inst().create_hookA(lpLibFileName);
|
||||||
return res;
|
// return res;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
HMODULE WINAPI Hook_Manager::MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
|
//HMODULE WINAPI Hook_Manager::MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
|
||||||
{
|
//{
|
||||||
auto res = _LoadLibraryExW(lpLibFileName, hFile, dwFlags);
|
// auto res = _LoadLibraryExW(lpLibFileName, hFile, dwFlags);
|
||||||
Hook_Manager::Inst().create_hookW(lpLibFileName);
|
// Hook_Manager::Inst().create_hookW(lpLibFileName);
|
||||||
return res;
|
// return res;
|
||||||
}
|
//}
|
||||||
|
|
||||||
bool Hook_Manager::stop_retry()
|
bool Hook_Manager::stop_retry()
|
||||||
{
|
{
|
||||||
|
@ -394,25 +389,33 @@ bool Hook_Manager::stop_retry()
|
||||||
return stop;
|
return stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hook_Manager::HookLoadLibrary()
|
void Hook_Manager::find_renderer(Hook_Manager* _this)
|
||||||
{
|
{
|
||||||
if (!_renderer_found && !_loadlibrary_hooked)
|
_this->rendererdetect_hook = new Base_Hook();
|
||||||
|
_this->AddHook(_this->rendererdetect_hook);
|
||||||
|
|
||||||
|
std::vector<std::string> const libraries = { "opengl32.dll", "d3d12.dll", "d3d11.dll", "d3d10.dll", "d3d9.dll" };
|
||||||
|
|
||||||
|
while (!_this->_renderer_found && !_this->stop_retry())
|
||||||
{
|
{
|
||||||
_loadlibrary_hooked = true;
|
std::vector<std::string>::const_iterator it = libraries.begin();
|
||||||
|
while (it != libraries.end())
|
||||||
|
{
|
||||||
|
it = std::find_if(it, libraries.end(), [](std::string const& name) {
|
||||||
|
auto x = GetModuleHandle(name.c_str());
|
||||||
|
if (x != NULL)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
rendererdetect_hook = new Base_Hook();
|
if (it == libraries.end())
|
||||||
AddHook(rendererdetect_hook);
|
break;
|
||||||
|
|
||||||
rendererdetect_hook->BeginHook();
|
_this->create_hook(it->c_str());
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
rendererdetect_hook->HookFuncs(
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,24 +447,7 @@ Hook_Manager& Hook_Manager::Inst()
|
||||||
void Hook_Manager::HookRenderer()
|
void Hook_Manager::HookRenderer()
|
||||||
{
|
{
|
||||||
#ifdef STEAM_WIN32
|
#ifdef STEAM_WIN32
|
||||||
HookLoadLibrary();
|
_hook_thread = new std::thread(&Hook_Manager::find_renderer, this);
|
||||||
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();
|
|
||||||
while (it != libraries.end())
|
|
||||||
{
|
|
||||||
it = std::find_if(it, libraries.end(), [](std::string const& name) {
|
|
||||||
auto x = GetModuleHandle(name.c_str());
|
|
||||||
if (x != 0 && x != INVALID_HANDLE_VALUE)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (it == libraries.end())
|
|
||||||
break;
|
|
||||||
|
|
||||||
create_hookA(it->c_str());
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,6 +457,9 @@ void Hook_Manager::FoundRenderer(Base_Hook* hook)
|
||||||
{
|
{
|
||||||
_renderer_found = true;
|
_renderer_found = true;
|
||||||
|
|
||||||
|
_hook_thread->join();
|
||||||
|
delete _hook_thread;
|
||||||
|
|
||||||
// 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) {
|
_hooks.erase(std::remove_if(_hooks.begin(), _hooks.end(), [&hook](Base_Hook* it_hook) {
|
||||||
if (hook != it_hook)
|
if (hook != it_hook)
|
||||||
|
@ -480,8 +469,6 @@ void Hook_Manager::FoundRenderer(Base_Hook* hook)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}), _hooks.end());
|
}), _hooks.end());
|
||||||
|
|
||||||
_loadlibrary_hooked = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#ifndef NO_OVERLAY
|
#ifndef NO_OVERLAY
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(WIN32)
|
#if defined(_WIN32) || defined(WIN32)
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -31,6 +32,7 @@ protected:
|
||||||
// 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::vector<Base_Hook*> _hooks;
|
||||||
|
|
||||||
|
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)
|
||||||
|
@ -44,7 +46,7 @@ protected:
|
||||||
void hook_opengl();
|
void hook_opengl();
|
||||||
|
|
||||||
bool stop_retry();
|
bool stop_retry();
|
||||||
void HookLoadLibrary();
|
//void HookLoadLibrary();
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
|
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
|
||||||
bool _loadlibrary_hooked; // Are the LoadLibrary functions hooked ?
|
bool _loadlibrary_hooked; // Are the LoadLibrary functions hooked ?
|
||||||
|
@ -66,13 +68,15 @@ protected:
|
||||||
// Setup DX12 Device and get vtable
|
// Setup DX12 Device and get vtable
|
||||||
void hook_dx12();
|
void hook_dx12();
|
||||||
|
|
||||||
void create_hookA(const char* libname);
|
void create_hook(const char* libname);
|
||||||
void create_hookW(const wchar_t* libname);
|
//void create_hookW(const wchar_t* libname);
|
||||||
|
|
||||||
static HMODULE WINAPI MyLoadLibraryA(LPCTSTR lpLibFileName);
|
static void find_renderer(Hook_Manager* _this);
|
||||||
static HMODULE WINAPI MyLoadLibraryW(LPCWSTR lpLibFileName);
|
|
||||||
static HMODULE WINAPI MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
|
//static HMODULE WINAPI MyLoadLibraryA(LPCTSTR lpLibFileName);
|
||||||
static HMODULE WINAPI MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
|
//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
|
// 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);
|
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
|
// If any of theses is called, then DX9 will be used to render overlay
|
||||||
|
|
Loading…
Reference in a new issue