From 5b42135defc5a84716bb2d56197dc3fb22def8fc Mon Sep 17 00:00:00 2001 From: Kaldaien Date: Mon, 17 Feb 2025 20:55:33 -0500 Subject: [PATCH] Fixed (low-level) keyboard/mouse hook function table issues in 32-bit games Prevent games from using low-level keyboard hooks to block Alt+Tab --- CHANGELOG.txt | 7 ++- include/SpecialK/DLL_VERSION.H | 2 +- src/input/winhook_input.cpp | 81 +++++++++++++++++----------------- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 782436036..2754a66c0 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,9 @@ -25.2.17 +25.2.18 +======= + + Fixed (low-level) keyboard/mouse hook function table issues in 32-bit games + + Prevent games from using low-level keyboard hooks to block Alt+Tab + +25.2.17 ======= + Fixed cursor issues in Kingdom Come Deliverance 2 once and for all. diff --git a/include/SpecialK/DLL_VERSION.H b/include/SpecialK/DLL_VERSION.H index e3f5d76b7..468714b27 100644 --- a/include/SpecialK/DLL_VERSION.H +++ b/include/SpecialK/DLL_VERSION.H @@ -2,7 +2,7 @@ #define SK_YEAR 25 #define SK_MONTH 2 -#define SK_DATE 17 +#define SK_DATE 18 #define SK_REV_N 0 #define SK_REV 0 diff --git a/src/input/winhook_input.cpp b/src/input/winhook_input.cpp index 039f40ec3..479971bad 100644 --- a/src/input/winhook_input.cpp +++ b/src/input/winhook_input.cpp @@ -214,8 +214,8 @@ SK_Proxy_MouseProc ( DWORD dwTid = GetCurrentThreadId (); - auto local_hook_fn = __hooks.mouse [dwTid|(WH_MOUSE<<31)].first; - auto global_hook_fn = __hooks.mouse [0ULL |(WH_MOUSE<<31)].first; + auto local_hook_fn = __hooks.mouse [(DWORD64)dwTid|((DWORD64)WH_MOUSE<<31ULL)].first; + auto global_hook_fn = __hooks.mouse [ 0ULL |((DWORD64)WH_MOUSE<<31ULL)].first; SK_ReleaseAssert (!(local_hook_fn && global_hook_fn)); @@ -349,8 +349,8 @@ SK_Proxy_LLMouseProc ( DWORD dwTid = GetCurrentThreadId (); - auto local_hook_fn = __hooks.mouse [dwTid|(WH_MOUSE_LL<<31)].first; - auto global_hook_fn = __hooks.mouse [0 |(WH_MOUSE_LL<<31)].first; + auto local_hook_fn = __hooks.mouse [(DWORD64)dwTid|((DWORD64)WH_MOUSE_LL<<31ULL)].first; + auto global_hook_fn = __hooks.mouse [0 |((DWORD64)WH_MOUSE_LL<<31ULL)].first; SK_ReleaseAssert (!(local_hook_fn && global_hook_fn)); @@ -425,8 +425,8 @@ SK_Proxy_KeyboardProc ( SK_WinHook_Backend->markRead (sk_input_dev_type::Keyboard); - auto local_hook_fn = __hooks.keyboard [dwTid|(WH_KEYBOARD<<31)].first; - auto global_hook_fn = __hooks.keyboard [0 |(WH_KEYBOARD<<31)].first; + auto local_hook_fn = __hooks.keyboard [(DWORD64)dwTid|((DWORD64)WH_KEYBOARD<<31ULL)].first; + auto global_hook_fn = __hooks.keyboard [(DWORD64)0 |((DWORD64)WH_KEYBOARD<<31ULL)].first; SK_ReleaseAssert (!(local_hook_fn && global_hook_fn)); @@ -553,8 +553,8 @@ SK_Proxy_LLKeyboardProc ( SK_WinHook_Backend->markRead (sk_input_dev_type::Keyboard); - auto local_hook_fn = __hooks.keyboard [dwTid|(WH_KEYBOARD_LL<<31)].first; - auto global_hook_fn = __hooks.keyboard [0ULL |(WH_KEYBOARD_LL<<31)].first; + auto local_hook_fn = __hooks.keyboard [(DWORD64)dwTid|((DWORD64)WH_KEYBOARD_LL<<31ULL)].first; + auto global_hook_fn = __hooks.keyboard [ 0ULL |((DWORD64)WH_KEYBOARD_LL<<31ULL)].first; SK_ReleaseAssert (!(local_hook_fn && global_hook_fn)); @@ -563,28 +563,27 @@ SK_Proxy_LLKeyboardProc ( hide |= config.input.keyboard.disabled_to_game == 1; - // Fix common keys that may be stuck in combination with Alt, Windows Key, etc. - // the game shouldn't have seen those keys, but the hook they are using doesn't - // hide them... - if ((hide || !game_window.active) && (wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU || wParam == VK_TAB)) + if (hook_fn != nullptr && !hide) { - if (hook_fn != nullptr && config.input.keyboard.disabled_to_game != 1) - { - lParam &= ~(1UL<<31UL); - lParam &= ~(1UL<<30UL); - lParam &= ~(1UL<<29UL); - + LRESULT result = hook_fn (nCode, wParam, lParam); - return - CallNextHookEx ( - nullptr, nCode, - wParam, lParamOrig ); + if (result == 0) + return result; + + KBDLLHOOKSTRUCT* kbd = (KBDLLHOOKSTRUCT*)lParam; + + if (kbd != nullptr) + { + // Disallow the game from blocking these keys... + if (kbd->vkCode != VK_MENU && kbd->vkCode != VK_LMENU && kbd->vkCode != VK_RMENU && + kbd->vkCode != VK_TAB && kbd->vkCode != VK_LWIN && kbd->vkCode != VK_RWIN && + kbd->vkCode != VK_CONTROL && kbd->vkCode != VK_LCONTROL && kbd->vkCode != VK_RCONTROL) + { + return result; + } } } - - if ( hook_fn != nullptr && !hide) - return hook_fn (nCode, wParam, lParam); } return @@ -658,10 +657,10 @@ SetWindowsHookExW_Detour ( bool install = false; - if ( !__hooks.keyboard.count (dwThreadId|(idHook<<31)) || - __hooks.keyboard [dwThreadId|(idHook<<31)].first == nullptr) - { __hooks.keyboard [dwThreadId|(idHook<<31)].first = lpfn; - hook =&__hooks.keyboard [dwThreadId|(idHook<<31)].second; + if ( !__hooks.keyboard.count ((DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)) || + __hooks.keyboard [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].first == nullptr) + { __hooks.keyboard [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].first = lpfn; + hook =&__hooks.keyboard [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].second; install = true; } @@ -702,10 +701,10 @@ SetWindowsHookExW_Detour ( bool install = false; - if ( !__hooks.mouse.count (dwThreadId|(idHook<<31)) || - __hooks.mouse [dwThreadId|(idHook<<31)].first == nullptr) - { __hooks.mouse [dwThreadId|(idHook<<31)].first = lpfn; - hook =&__hooks.mouse [dwThreadId|(idHook<<31)].second; + if ( !__hooks.mouse.count ((DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)) || + __hooks.mouse [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].first == nullptr) + { __hooks.mouse [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].first = lpfn; + hook =&__hooks.mouse [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].second; install = true; } @@ -781,10 +780,10 @@ SetWindowsHookExA_Detour ( bool install = false; - if ( !__hooks.keyboard.count (dwThreadId|(idHook<<31)) || - __hooks.keyboard [dwThreadId|(idHook<<31)].first == nullptr) - { __hooks.keyboard [dwThreadId|(idHook<<31)].first = lpfn; - hook =&__hooks.keyboard [dwThreadId|(idHook<<31)].second; + if ( !__hooks.keyboard.count ((DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)) || + __hooks.keyboard [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].first == nullptr) + { __hooks.keyboard [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].first = lpfn; + hook =&__hooks.keyboard [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].second; install = true; } @@ -825,10 +824,10 @@ SetWindowsHookExA_Detour ( bool install = false; - if ( !__hooks.mouse.count (dwThreadId|(idHook<<31)) || - __hooks.mouse [dwThreadId|(idHook<<31)].first == nullptr) - { __hooks.mouse [dwThreadId|(idHook<<31)].first = lpfn; - hook =&__hooks.mouse [dwThreadId|(idHook<<31)].second; + if ( !__hooks.mouse.count ((DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)) || + __hooks.mouse [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].first == nullptr) + { __hooks.mouse [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].first = lpfn; + hook =&__hooks.mouse [(DWORD64)dwThreadId|((DWORD64)idHook<<31ULL)].second; install = true; }