From 38a6785ff8e7ba1d36c21f4129c2ae770c9a4855 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 10 Jun 2024 22:00:38 +0200 Subject: [PATCH] #323 remove dinput hooks when dlls is being unloaded --- src/directinput.c | 88 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/src/directinput.c b/src/directinput.c index 6dd5e5e..13d06b8 100644 --- a/src/directinput.c +++ b/src/directinput.c @@ -19,10 +19,15 @@ DIRECTINPUTCREATEEXPROC real_DirectInputCreateEx; DIRECTINPUT8CREATEPROC real_DirectInput8Create; static DICREATEDEVICEPROC real_di_CreateDevice; +static PROC* di_CreateDevice_vtbl_addr; static DICREATEDEVICEEXPROC real_di_CreateDeviceEx; +static PROC* di_CreateDeviceEx_vtbl_addr; static DIDSETCOOPERATIVELEVELPROC real_did_SetCooperativeLevel; +static PROC* did_SetCooperativeLevel_vtbl_addr; static DIDGETDEVICEDATAPROC real_did_GetDeviceData; +static PROC* did_GetDeviceData_vtbl_addr; static DIDGETDEVICESTATEPROC real_did_GetDeviceState; +static PROC* did_GetDeviceState_vtbl_addr; static LPDIRECTINPUTDEVICEA g_mouse_device; static PROC hook_func(PROC* org_func, PROC new_func) @@ -121,17 +126,20 @@ static HRESULT WINAPI fake_di_CreateDevice( if (!real_did_SetCooperativeLevel) { + did_SetCooperativeLevel_vtbl_addr = (PROC*)&(*lplpDIDevice)->lpVtbl->SetCooperativeLevel; + real_did_SetCooperativeLevel = - (DIDSETCOOPERATIVELEVELPROC)hook_func( - (PROC*)&(*lplpDIDevice)->lpVtbl->SetCooperativeLevel, (PROC)fake_did_SetCooperativeLevel); + (DIDSETCOOPERATIVELEVELPROC)hook_func(did_SetCooperativeLevel_vtbl_addr, (PROC)fake_did_SetCooperativeLevel); + + did_GetDeviceData_vtbl_addr = (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceData; real_did_GetDeviceData = - (DIDGETDEVICEDATAPROC)hook_func( - (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceData, (PROC)fake_did_GetDeviceData); + (DIDGETDEVICEDATAPROC)hook_func(did_GetDeviceData_vtbl_addr, (PROC)fake_did_GetDeviceData); + + did_GetDeviceState_vtbl_addr = (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceState; real_did_GetDeviceState = - (DIDGETDEVICESTATEPROC)hook_func( - (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceState, (PROC)fake_did_GetDeviceState); + (DIDGETDEVICESTATEPROC)hook_func(did_GetDeviceState_vtbl_addr, (PROC)fake_did_GetDeviceState); } } @@ -158,17 +166,20 @@ static HRESULT WINAPI fake_di_CreateDeviceEx( if (!real_did_SetCooperativeLevel) { + did_SetCooperativeLevel_vtbl_addr = (PROC*)&(*lplpDIDevice)->lpVtbl->SetCooperativeLevel; + real_did_SetCooperativeLevel = - (DIDSETCOOPERATIVELEVELPROC)hook_func( - (PROC*)&(*lplpDIDevice)->lpVtbl->SetCooperativeLevel, (PROC)fake_did_SetCooperativeLevel); + (DIDSETCOOPERATIVELEVELPROC)hook_func(did_SetCooperativeLevel_vtbl_addr, (PROC)fake_did_SetCooperativeLevel); + + did_GetDeviceData_vtbl_addr = (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceData; real_did_GetDeviceData = - (DIDGETDEVICEDATAPROC)hook_func( - (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceData, (PROC)fake_did_GetDeviceData); + (DIDGETDEVICEDATAPROC)hook_func(did_GetDeviceData_vtbl_addr, (PROC)fake_did_GetDeviceData); + + did_GetDeviceState_vtbl_addr = (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceState; real_did_GetDeviceState = - (DIDGETDEVICESTATEPROC)hook_func( - (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceState, (PROC)fake_did_GetDeviceState); + (DIDGETDEVICESTATEPROC)hook_func(did_GetDeviceState_vtbl_addr, (PROC)fake_did_GetDeviceState); } } @@ -186,7 +197,7 @@ HRESULT WINAPI fake_DirectInputCreateA( if (!real_DirectInputCreateA) { real_DirectInputCreateA = - (DIRECTINPUTCREATEAPROC)real_GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA"); + (DIRECTINPUTCREATEAPROC)real_GetProcAddress(real_LoadLibraryA("dinput.dll"), "DirectInputCreateA"); if (real_DirectInputCreateA == fake_DirectInputCreateA) { @@ -204,8 +215,10 @@ HRESULT WINAPI fake_DirectInputCreateA( if (SUCCEEDED(result) && !real_di_CreateDevice && !g_config.no_dinput_hook) { + di_CreateDevice_vtbl_addr = (PROC*)&(*lplpDirectInput)->lpVtbl->CreateDevice; + real_di_CreateDevice = - (DICREATEDEVICEPROC)hook_func((PROC*)&(*lplpDirectInput)->lpVtbl->CreateDevice, (PROC)fake_di_CreateDevice); + (DICREATEDEVICEPROC)hook_func(di_CreateDevice_vtbl_addr, (PROC)fake_di_CreateDevice); } return result; @@ -222,7 +235,7 @@ HRESULT WINAPI fake_DirectInputCreateW( if (!real_DirectInputCreateW) { real_DirectInputCreateW = - (DIRECTINPUTCREATEWPROC)real_GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateW"); + (DIRECTINPUTCREATEWPROC)real_GetProcAddress(real_LoadLibraryA("dinput.dll"), "DirectInputCreateW"); if (real_DirectInputCreateW == fake_DirectInputCreateW) { @@ -240,8 +253,10 @@ HRESULT WINAPI fake_DirectInputCreateW( if (SUCCEEDED(result) && !real_di_CreateDevice && !g_config.no_dinput_hook) { + di_CreateDevice_vtbl_addr = (PROC*)&(*lplpDirectInput)->lpVtbl->CreateDevice; + real_di_CreateDevice = - (DICREATEDEVICEPROC)hook_func((PROC*)&(*lplpDirectInput)->lpVtbl->CreateDevice, (PROC)fake_di_CreateDevice); + (DICREATEDEVICEPROC)hook_func(di_CreateDevice_vtbl_addr, (PROC)fake_di_CreateDevice); } return result; @@ -259,7 +274,7 @@ HRESULT WINAPI fake_DirectInputCreateEx( if (!real_DirectInputCreateEx) { real_DirectInputCreateEx = - (DIRECTINPUTCREATEEXPROC)real_GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateEx"); + (DIRECTINPUTCREATEEXPROC)real_GetProcAddress(real_LoadLibraryA("dinput.dll"), "DirectInputCreateEx"); if (real_DirectInputCreateEx == fake_DirectInputCreateEx) { @@ -277,8 +292,10 @@ HRESULT WINAPI fake_DirectInputCreateEx( if (SUCCEEDED(result) && !real_di_CreateDevice && !g_config.no_dinput_hook) { + di_CreateDevice_vtbl_addr = (PROC*)&(*ppvOut)->lpVtbl->CreateDevice; + real_di_CreateDevice = - (DICREATEDEVICEPROC)hook_func((PROC*)&(*ppvOut)->lpVtbl->CreateDevice, (PROC)fake_di_CreateDevice); + (DICREATEDEVICEPROC)hook_func(di_CreateDevice_vtbl_addr, (PROC)fake_di_CreateDevice); } if (SUCCEEDED(result) && @@ -287,8 +304,10 @@ HRESULT WINAPI fake_DirectInputCreateEx( (IsEqualGUID(&IID_IDirectInput7A, riidltf) || IsEqualGUID(&IID_IDirectInput7W, riidltf)) && !g_config.no_dinput_hook) { + di_CreateDeviceEx_vtbl_addr = (PROC*)&(*ppvOut)->lpVtbl->CreateDeviceEx; + real_di_CreateDeviceEx = - (DICREATEDEVICEEXPROC)hook_func((PROC*)&(*ppvOut)->lpVtbl->CreateDeviceEx, (PROC)fake_di_CreateDeviceEx); + (DICREATEDEVICEEXPROC)hook_func(di_CreateDeviceEx_vtbl_addr, (PROC)fake_di_CreateDeviceEx); } return result; @@ -306,7 +325,7 @@ HRESULT WINAPI fake_DirectInput8Create( if (!real_DirectInput8Create) { real_DirectInput8Create = - (DIRECTINPUT8CREATEPROC)real_GetProcAddress(GetModuleHandle("dinput8.dll"), "DirectInput8Create"); + (DIRECTINPUT8CREATEPROC)real_GetProcAddress(real_LoadLibraryA("dinput8.dll"), "DirectInput8Create"); if (real_DirectInput8Create == fake_DirectInput8Create) { @@ -324,8 +343,10 @@ HRESULT WINAPI fake_DirectInput8Create( if (SUCCEEDED(result) && !real_di_CreateDevice && !g_config.no_dinput_hook) { + di_CreateDevice_vtbl_addr = (PROC*)&(*ppvOut)->lpVtbl->CreateDevice; + real_di_CreateDevice = - (DICREATEDEVICEPROC)hook_func((PROC*)&(*ppvOut)->lpVtbl->CreateDevice, (PROC)fake_di_CreateDevice); + (DICREATEDEVICEPROC)hook_func(di_CreateDevice_vtbl_addr, (PROC)fake_di_CreateDevice); } return result; @@ -383,6 +404,31 @@ void dinput_hook_init() void dinput_hook_exit() { + if (di_CreateDevice_vtbl_addr && *di_CreateDevice_vtbl_addr == (PROC)fake_di_CreateDevice) + { + hook_func(di_CreateDevice_vtbl_addr, (PROC)real_di_CreateDevice); + } + + if (di_CreateDeviceEx_vtbl_addr && *di_CreateDeviceEx_vtbl_addr == (PROC)fake_di_CreateDeviceEx) + { + hook_func(di_CreateDeviceEx_vtbl_addr, (PROC)real_di_CreateDeviceEx); + } + + if (did_SetCooperativeLevel_vtbl_addr && *did_SetCooperativeLevel_vtbl_addr == (PROC)fake_did_SetCooperativeLevel) + { + hook_func(did_SetCooperativeLevel_vtbl_addr, (PROC)real_did_SetCooperativeLevel); + } + + if (did_GetDeviceData_vtbl_addr && *did_GetDeviceData_vtbl_addr == (PROC)fake_did_GetDeviceData) + { + hook_func(did_GetDeviceData_vtbl_addr, (PROC)real_did_GetDeviceData); + } + + if (did_GetDeviceState_vtbl_addr && *did_GetDeviceState_vtbl_addr == (PROC)fake_did_GetDeviceState) + { + hook_func(did_GetDeviceState_vtbl_addr, (PROC)real_did_GetDeviceState); + } + #ifdef _MSC_VER if (g_dinput_hook_active) {