graphics-hook: Use Detours for function hooking
Helped D3D12 path recover from window mode changes, so we assume it should be more stable across the board for all API hooks.
This commit is contained in:
parent
492f4c05e1
commit
452ee646e1
@ -2,7 +2,8 @@
|
||||
|
||||
#include "../d3d8-api/d3d8.h"
|
||||
#include "graphics-hook.h"
|
||||
#include "../funchook.h"
|
||||
|
||||
#include <detours.h>
|
||||
|
||||
typedef HRESULT(STDMETHODCALLTYPE *reset_t)(IDirect3DDevice8 *,
|
||||
D3DPRESENT_PARAMETERS *);
|
||||
@ -10,8 +11,8 @@ typedef HRESULT(STDMETHODCALLTYPE *present_t)(IDirect3DDevice8 *, CONST RECT *,
|
||||
CONST RECT *, HWND,
|
||||
CONST RGNDATA *);
|
||||
|
||||
static struct func_hook present;
|
||||
static struct func_hook reset;
|
||||
reset_t RealReset = NULL;
|
||||
present_t RealPresent = NULL;
|
||||
|
||||
struct d3d8_data {
|
||||
HMODULE d3d8;
|
||||
@ -250,17 +251,10 @@ static void d3d8_capture(IDirect3DDevice8 *device,
|
||||
static HRESULT STDMETHODCALLTYPE hook_reset(IDirect3DDevice8 *device,
|
||||
D3DPRESENT_PARAMETERS *parameters)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (capture_active())
|
||||
d3d8_free();
|
||||
|
||||
unhook(&reset);
|
||||
reset_t call = (reset_t)reset.call_addr;
|
||||
hr = call(device, parameters);
|
||||
rehook(&reset);
|
||||
|
||||
return hr;
|
||||
return RealReset(device, parameters);
|
||||
}
|
||||
|
||||
static bool hooked_reset = false;
|
||||
@ -269,11 +263,19 @@ static void setup_reset_hooks(IDirect3DDevice8 *device)
|
||||
{
|
||||
uintptr_t *vtable = *(uintptr_t **)device;
|
||||
|
||||
hook_init(&reset, (void *)vtable[14], (void *)hook_reset,
|
||||
"IDirect3DDevice8::Reset");
|
||||
rehook(&reset);
|
||||
DetourTransactionBegin();
|
||||
|
||||
hooked_reset = true;
|
||||
RealReset = (reset_t)vtable[14];
|
||||
DetourAttach((PVOID *)&RealReset, hook_reset);
|
||||
|
||||
const LONG error = DetourTransactionCommit();
|
||||
const bool success = error == NO_ERROR;
|
||||
if (success) {
|
||||
hlog("Hooked IDirect3DDevice8::Reset");
|
||||
hooked_reset = true;
|
||||
} else {
|
||||
RealReset = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice8 *device,
|
||||
@ -283,7 +285,6 @@ static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice8 *device,
|
||||
CONST RGNDATA *dirty_region)
|
||||
{
|
||||
IDirect3DSurface8 *backbuffer;
|
||||
HRESULT hr;
|
||||
|
||||
if (!hooked_reset)
|
||||
setup_reset_hooks(device);
|
||||
@ -294,12 +295,8 @@ static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice8 *device,
|
||||
backbuffer->Release();
|
||||
}
|
||||
|
||||
unhook(&present);
|
||||
present_t call = (present_t)present.call_addr;
|
||||
hr = call(device, src_rect, dst_rect, override_window, dirty_region);
|
||||
rehook(&present);
|
||||
|
||||
return hr;
|
||||
return RealPresent(device, src_rect, dst_rect, override_window,
|
||||
dirty_region);
|
||||
}
|
||||
|
||||
typedef IDirect3D8 *(WINAPI *d3d8create_t)(UINT);
|
||||
@ -388,11 +385,20 @@ bool hook_d3d8(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
hook_init(&present, present_addr, (void *)hook_present,
|
||||
"IDirect3DDevice8::Present");
|
||||
DetourTransactionBegin();
|
||||
|
||||
rehook(&present);
|
||||
RealPresent = (present_t)present_addr;
|
||||
DetourAttach((PVOID *)&RealPresent, hook_present);
|
||||
|
||||
hlog("Hooked D3D8");
|
||||
return true;
|
||||
const LONG error = DetourTransactionCommit();
|
||||
const bool success = error == NO_ERROR;
|
||||
if (success) {
|
||||
hlog("Hooked IDirect3DDevice8::Present");
|
||||
hlog("Hooked D3D8");
|
||||
} else {
|
||||
RealPresent = nullptr;
|
||||
hlog("Failed to attach Detours hook: %ld", error);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -3,13 +3,14 @@
|
||||
#include <dxgi.h>
|
||||
|
||||
#include "graphics-hook.h"
|
||||
#include "../funchook.h"
|
||||
#include "d3d9-patches.hpp"
|
||||
|
||||
#include <detours.h>
|
||||
|
||||
typedef HRESULT(STDMETHODCALLTYPE *present_t)(IDirect3DDevice9 *, CONST RECT *,
|
||||
CONST RECT *, HWND,
|
||||
CONST RGNDATA *);
|
||||
typedef HRESULT(STDMETHODCALLTYPE *present_ex_t)(IDirect3DDevice9 *,
|
||||
typedef HRESULT(STDMETHODCALLTYPE *present_ex_t)(IDirect3DDevice9Ex *,
|
||||
CONST RECT *, CONST RECT *,
|
||||
HWND, CONST RGNDATA *, DWORD);
|
||||
typedef HRESULT(STDMETHODCALLTYPE *present_swap_t)(IDirect3DSwapChain9 *,
|
||||
@ -24,11 +25,11 @@ typedef HRESULT(STDMETHODCALLTYPE *reset_ex_t)(IDirect3DDevice9 *,
|
||||
|
||||
typedef HRESULT(WINAPI *createfactory1_t)(REFIID, void **);
|
||||
|
||||
static struct func_hook present;
|
||||
static struct func_hook present_ex;
|
||||
static struct func_hook present_swap;
|
||||
static struct func_hook reset;
|
||||
static struct func_hook reset_ex;
|
||||
present_t RealPresent = NULL;
|
||||
present_ex_t RealPresentEx = NULL;
|
||||
present_swap_t RealPresentSwap = NULL;
|
||||
reset_t RealReset = NULL;
|
||||
reset_ex_t RealResetEx = NULL;
|
||||
|
||||
struct d3d9_data {
|
||||
HMODULE d3d9;
|
||||
@ -641,17 +642,14 @@ static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice9 *device,
|
||||
CONST RGNDATA *dirty_region)
|
||||
{
|
||||
IDirect3DSurface9 *backbuffer = nullptr;
|
||||
HRESULT hr;
|
||||
|
||||
if (!hooked_reset)
|
||||
setup_reset_hooks(device);
|
||||
|
||||
present_begin(device, backbuffer);
|
||||
|
||||
unhook(&present);
|
||||
present_t call = (present_t)present.call_addr;
|
||||
hr = call(device, src_rect, dst_rect, override_window, dirty_region);
|
||||
rehook(&present);
|
||||
const HRESULT hr = RealPresent(device, src_rect, dst_rect,
|
||||
override_window, dirty_region);
|
||||
|
||||
present_end(device, backbuffer);
|
||||
|
||||
@ -659,22 +657,18 @@ static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice9 *device,
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE hook_present_ex(
|
||||
IDirect3DDevice9 *device, CONST RECT *src_rect, CONST RECT *dst_rect,
|
||||
IDirect3DDevice9Ex *device, CONST RECT *src_rect, CONST RECT *dst_rect,
|
||||
HWND override_window, CONST RGNDATA *dirty_region, DWORD flags)
|
||||
{
|
||||
IDirect3DSurface9 *backbuffer = nullptr;
|
||||
HRESULT hr;
|
||||
|
||||
if (!hooked_reset)
|
||||
setup_reset_hooks(device);
|
||||
|
||||
present_begin(device, backbuffer);
|
||||
|
||||
unhook(&present_ex);
|
||||
present_ex_t call = (present_ex_t)present_ex.call_addr;
|
||||
hr = call(device, src_rect, dst_rect, override_window, dirty_region,
|
||||
flags);
|
||||
rehook(&present_ex);
|
||||
const HRESULT hr = RealPresentEx(device, src_rect, dst_rect,
|
||||
override_window, dirty_region, flags);
|
||||
|
||||
present_end(device, backbuffer);
|
||||
|
||||
@ -687,12 +681,11 @@ static HRESULT STDMETHODCALLTYPE hook_present_swap(
|
||||
{
|
||||
IDirect3DSurface9 *backbuffer = nullptr;
|
||||
IDirect3DDevice9 *device = nullptr;
|
||||
HRESULT hr;
|
||||
|
||||
if (!present_recurse) {
|
||||
hr = swap->GetDevice(&device);
|
||||
if (SUCCEEDED(hr)) {
|
||||
device->Release();
|
||||
IDirect3DDevice9 *temp;
|
||||
if (SUCCEEDED(swap->GetDevice(&temp))) {
|
||||
device = temp;
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,14 +696,13 @@ static HRESULT STDMETHODCALLTYPE hook_present_swap(
|
||||
present_begin(device, backbuffer);
|
||||
}
|
||||
|
||||
unhook(&present_swap);
|
||||
present_swap_t call = (present_swap_t)present_swap.call_addr;
|
||||
hr = call(swap, src_rect, dst_rect, override_window, dirty_region,
|
||||
flags);
|
||||
rehook(&present_swap);
|
||||
const HRESULT hr = RealPresentSwap(
|
||||
swap, src_rect, dst_rect, override_window, dirty_region, flags);
|
||||
|
||||
if (device)
|
||||
if (device) {
|
||||
present_end(device, backbuffer);
|
||||
device->Release();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
@ -718,34 +710,20 @@ static HRESULT STDMETHODCALLTYPE hook_present_swap(
|
||||
static HRESULT STDMETHODCALLTYPE hook_reset(IDirect3DDevice9 *device,
|
||||
D3DPRESENT_PARAMETERS *params)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (capture_active())
|
||||
d3d9_free();
|
||||
|
||||
unhook(&reset);
|
||||
reset_t call = (reset_t)reset.call_addr;
|
||||
hr = call(device, params);
|
||||
rehook(&reset);
|
||||
|
||||
return hr;
|
||||
return RealReset(device, params);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE hook_reset_ex(IDirect3DDevice9 *device,
|
||||
D3DPRESENT_PARAMETERS *params,
|
||||
D3DDISPLAYMODEEX *dmex)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (capture_active())
|
||||
d3d9_free();
|
||||
|
||||
unhook(&reset_ex);
|
||||
reset_ex_t call = (reset_ex_t)reset_ex.call_addr;
|
||||
hr = call(device, params, dmex);
|
||||
rehook(&reset_ex);
|
||||
|
||||
return hr;
|
||||
return RealResetEx(device, params, dmex);
|
||||
}
|
||||
|
||||
static void setup_reset_hooks(IDirect3DDevice9 *device)
|
||||
@ -754,21 +732,30 @@ static void setup_reset_hooks(IDirect3DDevice9 *device)
|
||||
uintptr_t *vtable = *(uintptr_t **)device;
|
||||
HRESULT hr;
|
||||
|
||||
hook_init(&reset, (void *)vtable[16], (void *)hook_reset,
|
||||
"IDirect3DDevice9::Reset");
|
||||
rehook(&reset);
|
||||
DetourTransactionBegin();
|
||||
|
||||
hr = device->QueryInterface(__uuidof(IDirect3DDevice9Ex),
|
||||
(void **)&d3d9ex);
|
||||
RealReset = (reset_t)vtable[16];
|
||||
DetourAttach((PVOID *)&RealReset, hook_reset);
|
||||
|
||||
hr = device->QueryInterface(IID_PPV_ARGS(&d3d9ex));
|
||||
if (SUCCEEDED(hr)) {
|
||||
hook_init(&reset_ex, (void *)vtable[132], (void *)hook_reset_ex,
|
||||
"IDirect3DDevice9Ex::ResetEx");
|
||||
rehook(&reset_ex);
|
||||
RealResetEx = (reset_ex_t)vtable[132];
|
||||
DetourAttach((PVOID *)&RealResetEx, hook_reset_ex);
|
||||
|
||||
d3d9ex->Release();
|
||||
}
|
||||
|
||||
hooked_reset = true;
|
||||
const LONG error = DetourTransactionCommit();
|
||||
const bool success = error == NO_ERROR;
|
||||
if (success) {
|
||||
hlog("Hooked IDirect3DDevice9::Reset");
|
||||
if (RealResetEx)
|
||||
hlog("Hooked IDirect3DDevice9Ex::ResetEx");
|
||||
hooked_reset = true;
|
||||
} else {
|
||||
RealReset = nullptr;
|
||||
RealResetEx = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
typedef HRESULT(WINAPI *d3d9create_ex_t)(UINT, IDirect3D9Ex **);
|
||||
@ -878,23 +865,37 @@ bool hook_d3d9(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
DetourTransactionBegin();
|
||||
|
||||
if (present_swap_addr) {
|
||||
hook_init(&present_swap, present_swap_addr,
|
||||
(void *)hook_present_swap,
|
||||
"IDirect3DSwapChain9::Present");
|
||||
rehook(&present_swap);
|
||||
RealPresentSwap = (present_swap_t)present_swap_addr;
|
||||
DetourAttach((PVOID *)&RealPresentSwap, hook_present_swap);
|
||||
}
|
||||
if (present_ex_addr) {
|
||||
hook_init(&present_ex, present_ex_addr, (void *)hook_present_ex,
|
||||
"IDirect3DDevice9Ex::PresentEx");
|
||||
rehook(&present_ex);
|
||||
RealPresentEx = (present_ex_t)present_ex_addr;
|
||||
DetourAttach((PVOID *)&RealPresentEx, hook_present_ex);
|
||||
}
|
||||
if (present_addr) {
|
||||
hook_init(&present, present_addr, (void *)hook_present,
|
||||
"IDirect3DDevice9::Present");
|
||||
rehook(&present);
|
||||
RealPresent = (present_t)present_addr;
|
||||
DetourAttach((PVOID *)&RealPresent, hook_present);
|
||||
}
|
||||
|
||||
hlog("Hooked D3D9");
|
||||
return true;
|
||||
const LONG error = DetourTransactionCommit();
|
||||
const bool success = error == NO_ERROR;
|
||||
if (success) {
|
||||
if (RealPresentSwap)
|
||||
hlog("Hooked IDirect3DSwapChain9::Present");
|
||||
if (RealPresentEx)
|
||||
hlog("Hooked IDirect3DDevice9Ex::PresentEx");
|
||||
if (RealPresent)
|
||||
hlog("Hooked IDirect3DDevice9::Present");
|
||||
hlog("Hooked D3D9");
|
||||
} else {
|
||||
RealPresentSwap = nullptr;
|
||||
RealPresentEx = nullptr;
|
||||
RealPresent = nullptr;
|
||||
hlog("Failed to attach Detours hook: %ld", error);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -5,7 +5,8 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "graphics-hook.h"
|
||||
#include "../funchook.h"
|
||||
|
||||
#include <detours.h>
|
||||
|
||||
#if COMPILE_D3D12_HOOK
|
||||
#include <d3d12.h>
|
||||
@ -19,10 +20,10 @@ typedef HRESULT(STDMETHODCALLTYPE *present_t)(IDXGISwapChain *, UINT, UINT);
|
||||
typedef HRESULT(STDMETHODCALLTYPE *present1_t)(IDXGISwapChain1 *, UINT, UINT,
|
||||
const DXGI_PRESENT_PARAMETERS *);
|
||||
|
||||
static struct func_hook release;
|
||||
static struct func_hook resize_buffers;
|
||||
static struct func_hook present;
|
||||
static struct func_hook present1;
|
||||
release_t RealRelease = nullptr;
|
||||
resize_buffers_t RealResizeBuffers = nullptr;
|
||||
present_t RealPresent = nullptr;
|
||||
present1_t RealPresent1 = nullptr;
|
||||
|
||||
thread_local bool dxgi_presenting = false;
|
||||
struct ID3D12CommandQueue *dxgi_possible_swap_queues[8]{};
|
||||
@ -112,10 +113,7 @@ static bool setup_dxgi(IDXGISwapChain *swap)
|
||||
|
||||
static ULONG STDMETHODCALLTYPE hook_release(IUnknown *unknown)
|
||||
{
|
||||
unhook(&release);
|
||||
release_t call = (release_t)release.call_addr;
|
||||
ULONG refs = call(unknown);
|
||||
rehook(&release);
|
||||
const ULONG refs = RealRelease(unknown);
|
||||
|
||||
hlog_verbose("Release callback: Refs=%lu", refs);
|
||||
if (unknown == data.swap && refs == 0) {
|
||||
@ -155,11 +153,8 @@ static HRESULT STDMETHODCALLTYPE hook_resize_buffers(IDXGISwapChain *swap,
|
||||
data.free();
|
||||
data.free = nullptr;
|
||||
|
||||
unhook(&resize_buffers);
|
||||
resize_buffers_t call = (resize_buffers_t)resize_buffers.call_addr;
|
||||
const HRESULT hr =
|
||||
call(swap, buffer_count, width, height, format, flags);
|
||||
rehook(&resize_buffers);
|
||||
const HRESULT hr = RealResizeBuffers(swap, buffer_count, width, height,
|
||||
format, flags);
|
||||
|
||||
resize_buffers_called = true;
|
||||
|
||||
@ -229,10 +224,7 @@ static HRESULT STDMETHODCALLTYPE hook_present(IDXGISwapChain *swap,
|
||||
}
|
||||
|
||||
dxgi_presenting = true;
|
||||
unhook(&present);
|
||||
present_t call = (present_t)present.call_addr;
|
||||
const HRESULT hr = call(swap, sync_interval, flags);
|
||||
rehook(&present);
|
||||
const HRESULT hr = RealPresent(swap, sync_interval, flags);
|
||||
dxgi_presenting = false;
|
||||
dxgi_present_attempted = true;
|
||||
|
||||
@ -291,10 +283,7 @@ hook_present1(IDXGISwapChain1 *swap, UINT sync_interval, UINT flags,
|
||||
}
|
||||
|
||||
dxgi_presenting = true;
|
||||
unhook(&present1);
|
||||
present1_t call = (present1_t)present1.call_addr;
|
||||
const HRESULT hr = call(swap, sync_interval, flags, params);
|
||||
rehook(&present1);
|
||||
const HRESULT hr = RealPresent1(swap, sync_interval, flags, params);
|
||||
dxgi_presenting = false;
|
||||
dxgi_present_attempted = true;
|
||||
|
||||
@ -337,30 +326,41 @@ bool hook_dxgi(void)
|
||||
release_addr = get_offset_addr(
|
||||
dxgi_module, global_hook_info->offsets.dxgi2.release);
|
||||
|
||||
hook_init(&present, present_addr, (void *)hook_present,
|
||||
"IDXGISwapChain::Present");
|
||||
hlog("Hooked IDXGISwapChain::Present");
|
||||
hook_init(&resize_buffers, resize_addr, (void *)hook_resize_buffers,
|
||||
"IDXGISwapChain::ResizeBuffers");
|
||||
hlog("Hooked IDXGISwapChain::ResizeBuffers");
|
||||
DetourTransactionBegin();
|
||||
|
||||
RealPresent = (present_t)present_addr;
|
||||
DetourAttach(&(PVOID &)RealPresent, hook_present);
|
||||
|
||||
RealResizeBuffers = (resize_buffers_t)resize_addr;
|
||||
DetourAttach(&(PVOID &)RealResizeBuffers, hook_resize_buffers);
|
||||
|
||||
if (present1_addr) {
|
||||
hook_init(&present1, present1_addr, (void *)hook_present1,
|
||||
"IDXGISwapChain1::Present1");
|
||||
hlog("Hooked IDXGISwapChain::Present1");
|
||||
RealPresent1 = (present1_t)present1_addr;
|
||||
DetourAttach(&(PVOID &)RealPresent1, hook_present1);
|
||||
}
|
||||
|
||||
if (release_addr) {
|
||||
hook_init(&release, release_addr, (void *)hook_release,
|
||||
"IDXGISwapChain::Release");
|
||||
hlog("Hooked IDXGISwapChain::Release");
|
||||
RealRelease = (release_t)release_addr;
|
||||
DetourAttach(&(PVOID &)RealRelease, hook_release);
|
||||
}
|
||||
|
||||
rehook(&resize_buffers);
|
||||
rehook(&present);
|
||||
if (present1_addr)
|
||||
rehook(&present1);
|
||||
if (release_addr)
|
||||
rehook(&release);
|
||||
const LONG error = DetourTransactionCommit();
|
||||
const bool success = error == NO_ERROR;
|
||||
if (success) {
|
||||
hlog("Hooked IDXGISwapChain::Present");
|
||||
hlog("Hooked IDXGISwapChain::ResizeBuffers");
|
||||
if (RealPresent1)
|
||||
hlog("Hooked IDXGISwapChain1::Present1");
|
||||
if (RealRelease)
|
||||
hlog("Hooked IDXGISwapChain::Release");
|
||||
hlog("Hooked DXGI");
|
||||
} else {
|
||||
RealPresent = nullptr;
|
||||
RealResizeBuffers = nullptr;
|
||||
RealPresent1 = nullptr;
|
||||
RealRelease = nullptr;
|
||||
hlog("Failed to attach Detours hook: %ld", error);
|
||||
}
|
||||
|
||||
hlog("Hooked DXGI");
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
@ -11,7 +11,8 @@
|
||||
|
||||
#include "gl-decs.h"
|
||||
#include "graphics-hook.h"
|
||||
#include "../funchook.h"
|
||||
|
||||
#include <detours.h>
|
||||
|
||||
#define DUMMY_WINDOW_CLASS_NAME L"graphics_hook_gl_dummy_window"
|
||||
|
||||
@ -24,10 +25,15 @@ static const GUID GUID_IDXGIResource =
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
static struct func_hook swap_buffers;
|
||||
static struct func_hook wgl_swap_layer_buffers;
|
||||
static struct func_hook wgl_swap_buffers;
|
||||
static struct func_hook wgl_delete_context;
|
||||
typedef BOOL(WINAPI *PFN_SwapBuffers)(HDC);
|
||||
typedef BOOL(WINAPI *PFN_WglSwapLayerBuffers)(HDC, UINT);
|
||||
typedef BOOL(WINAPI *PFN_WglSwapBuffers)(HDC);
|
||||
typedef BOOL(WINAPI *PFN_WglDeleteContext)(HGLRC);
|
||||
|
||||
PFN_SwapBuffers RealSwapBuffers = NULL;
|
||||
PFN_WglSwapLayerBuffers RealWglSwapLayerBuffers = NULL;
|
||||
PFN_WglSwapBuffers RealWglSwapBuffers = NULL;
|
||||
PFN_WglDeleteContext RealWglDeleteContext = NULL;
|
||||
|
||||
static bool darkest_dungeon_fix = false;
|
||||
static bool functions_initialized = false;
|
||||
@ -780,14 +786,9 @@ static inline void gl_swap_end(HDC hdc)
|
||||
|
||||
static BOOL WINAPI hook_swap_buffers(HDC hdc)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
gl_swap_begin(hdc);
|
||||
|
||||
unhook(&swap_buffers);
|
||||
BOOL(WINAPI * call)(HDC) = swap_buffers.call_addr;
|
||||
ret = call(hdc);
|
||||
rehook(&swap_buffers);
|
||||
const BOOL ret = RealSwapBuffers(hdc);
|
||||
|
||||
gl_swap_end(hdc);
|
||||
|
||||
@ -796,14 +797,9 @@ static BOOL WINAPI hook_swap_buffers(HDC hdc)
|
||||
|
||||
static BOOL WINAPI hook_wgl_swap_buffers(HDC hdc)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
gl_swap_begin(hdc);
|
||||
|
||||
unhook(&wgl_swap_buffers);
|
||||
BOOL(WINAPI * call)(HDC) = wgl_swap_buffers.call_addr;
|
||||
ret = call(hdc);
|
||||
rehook(&wgl_swap_buffers);
|
||||
const BOOL ret = RealWglSwapBuffers(hdc);
|
||||
|
||||
gl_swap_end(hdc);
|
||||
|
||||
@ -812,14 +808,9 @@ static BOOL WINAPI hook_wgl_swap_buffers(HDC hdc)
|
||||
|
||||
static BOOL WINAPI hook_wgl_swap_layer_buffers(HDC hdc, UINT planes)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
gl_swap_begin(hdc);
|
||||
|
||||
unhook(&wgl_swap_layer_buffers);
|
||||
BOOL(WINAPI * call)(HDC, UINT) = wgl_swap_layer_buffers.call_addr;
|
||||
ret = call(hdc, planes);
|
||||
rehook(&wgl_swap_layer_buffers);
|
||||
const BOOL ret = RealWglSwapLayerBuffers(hdc, planes);
|
||||
|
||||
gl_swap_end(hdc);
|
||||
|
||||
@ -828,8 +819,6 @@ static BOOL WINAPI hook_wgl_swap_layer_buffers(HDC hdc, UINT planes)
|
||||
|
||||
static BOOL WINAPI hook_wgl_delete_context(HGLRC hrc)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (capture_active() && functions_initialized) {
|
||||
HDC last_hdc = jimglGetCurrentDC();
|
||||
HGLRC last_hrc = jimglGetCurrentContext();
|
||||
@ -839,12 +828,7 @@ static BOOL WINAPI hook_wgl_delete_context(HGLRC hrc)
|
||||
jimglMakeCurrent(last_hdc, last_hrc);
|
||||
}
|
||||
|
||||
unhook(&wgl_delete_context);
|
||||
BOOL(WINAPI * call)(HGLRC) = wgl_delete_context.call_addr;
|
||||
ret = call(hrc);
|
||||
rehook(&wgl_delete_context);
|
||||
|
||||
return ret;
|
||||
return RealWglDeleteContext(hrc);
|
||||
}
|
||||
|
||||
static bool gl_register_window(void)
|
||||
@ -892,24 +876,44 @@ bool hook_gl(void)
|
||||
wgl_slb_proc = base_get_proc("wglSwapLayerBuffers");
|
||||
wgl_sb_proc = base_get_proc("wglSwapBuffers");
|
||||
|
||||
hook_init(&swap_buffers, SwapBuffers, hook_swap_buffers, "SwapBuffers");
|
||||
DetourTransactionBegin();
|
||||
|
||||
RealSwapBuffers = SwapBuffers;
|
||||
DetourAttach((PVOID *)&RealSwapBuffers, hook_swap_buffers);
|
||||
if (wgl_dc_proc) {
|
||||
hook_init(&wgl_delete_context, wgl_dc_proc,
|
||||
hook_wgl_delete_context, "wglDeleteContext");
|
||||
rehook(&wgl_delete_context);
|
||||
RealWglDeleteContext = (PFN_WglDeleteContext)wgl_dc_proc;
|
||||
DetourAttach((PVOID *)&RealWglDeleteContext,
|
||||
hook_wgl_delete_context);
|
||||
}
|
||||
if (wgl_slb_proc) {
|
||||
hook_init(&wgl_swap_layer_buffers, wgl_slb_proc,
|
||||
hook_wgl_swap_layer_buffers, "wglSwapLayerBuffers");
|
||||
rehook(&wgl_swap_layer_buffers);
|
||||
RealWglSwapLayerBuffers = (PFN_WglSwapLayerBuffers)wgl_slb_proc;
|
||||
DetourAttach((PVOID *)&RealWglSwapLayerBuffers,
|
||||
hook_wgl_swap_layer_buffers);
|
||||
}
|
||||
if (wgl_sb_proc) {
|
||||
hook_init(&wgl_swap_buffers, wgl_sb_proc, hook_wgl_swap_buffers,
|
||||
"wglSwapBuffers");
|
||||
rehook(&wgl_swap_buffers);
|
||||
RealWglSwapBuffers = (PFN_WglSwapBuffers)wgl_sb_proc;
|
||||
DetourAttach((PVOID *)&RealWglSwapBuffers,
|
||||
hook_wgl_swap_buffers);
|
||||
}
|
||||
|
||||
rehook(&swap_buffers);
|
||||
const LONG error = DetourTransactionCommit();
|
||||
const bool success = error == NO_ERROR;
|
||||
if (success) {
|
||||
hlog("Hooked SwapBuffers");
|
||||
if (RealWglDeleteContext)
|
||||
hlog("Hooked wglDeleteContext");
|
||||
if (RealWglSwapLayerBuffers)
|
||||
hlog("Hooked wglSwapLayerBuffers");
|
||||
if (RealWglSwapBuffers)
|
||||
hlog("Hooked wglSwapBuffers");
|
||||
hlog("Hooked GL");
|
||||
} else {
|
||||
RealSwapBuffers = NULL;
|
||||
RealWglDeleteContext = NULL;
|
||||
RealWglSwapLayerBuffers = NULL;
|
||||
RealWglSwapBuffers = NULL;
|
||||
hlog("Failed to attach Detours hook: %ld", error);
|
||||
}
|
||||
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user