From d3be42ab96cf8925bb2abd5c26b8ffa67c8b910c Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 7 Apr 2015 02:53:06 +0200 Subject: [PATCH] user32: Invalidate key state cache globally after running LL hooks. --- dlls/user32/hook.c | 5 +---- dlls/user32/input.c | 9 ++++++++- dlls/user32/message.c | 7 ++++++- dlls/user32/user_private.h | 3 +++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index f19949c2865..281b88e70e5 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -437,10 +437,7 @@ static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARA } if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL) - { - struct user_key_state_info *key_state_info = get_user_thread_info()->key_state; - if (key_state_info) key_state_info->time = 0; /* force refreshing the key state cache */ - } + interlocked_xchg_add( &global_key_state_counter, 1 ); /* force refreshing the key state cache */ return ret; } diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 6ea2c2ff4e6..57594a787da 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -52,6 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DECLARE_DEBUG_CHANNEL(keyboard); +INT global_key_state_counter = 0; /*********************************************************************** * get_key_state @@ -369,6 +370,7 @@ static void check_for_events( UINT flags ) SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key ) { struct user_key_state_info *key_state_info = get_user_thread_info()->key_state; + INT counter = global_key_state_counter; SHORT ret; if (key < 0 || key >= 256) return 0; @@ -379,6 +381,7 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key ) { if (key_state_info && !(key_state_info->state[key] & 0xc0) && + key_state_info->counter == counter && GetTickCount() - key_state_info->time < 50) { /* use cached value */ @@ -401,7 +404,11 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key ) { if (reply->state & 0x40) ret |= 0x0001; if (reply->state & 0x80) ret |= 0x8000; - if (key_state_info) key_state_info->time = GetTickCount(); + if (key_state_info) + { + key_state_info->time = GetTickCount(); + key_state_info->counter = counter; + } } } SERVER_END_REQ; diff --git a/dlls/user32/message.c b/dlls/user32/message.c index fbc11daf0c1..2b544de84d6 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -3293,6 +3293,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) struct user_key_state_info *key_state_info = get_user_thread_info()->key_state; struct send_message_info info; int prev_x, prev_y, new_x, new_y; + INT counter = global_key_state_counter; NTSTATUS ret; BOOL wait; @@ -3342,7 +3343,11 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) if (!ret) { - if (key_state_info) key_state_info->time = GetTickCount(); + if (key_state_info) + { + key_state_info->time = GetTickCount(); + key_state_info->counter = counter; + } if ((flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y)) USER_Driver->pSetCursorPos( new_x, new_y ); } diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 9e3a373940a..445fd40ae7d 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -192,9 +192,12 @@ struct user_thread_info C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo) ); +extern INT global_key_state_counter DECLSPEC_HIDDEN; + struct user_key_state_info { UINT time; /* Time of last key state refresh */ + INT counter; /* Counter to invalidate the key state */ BYTE state[256]; /* State for each key */ };