Added patch to invalidate key state cache globally after calling LL hooks.

This commit is contained in:
Sebastian Lackner 2015-03-15 05:49:45 +01:00
parent 0c660b9e3a
commit d57ae8c150
5 changed files with 138 additions and 1 deletions

View File

@ -38,7 +38,7 @@ Wine. All those differences are also documented on the
Included bug fixes and improvements
===================================
**Bugfixes and features included in the next upcoming release [8]:**
**Bugfixes and features included in the next upcoming release [9]:**
* Add stub for PowerCreateRequest
* Fix caps lock state issues with multiple processes ([Wine Bug #35907](https://bugs.winehq.org/show_bug.cgi?id=35907))
@ -47,6 +47,7 @@ Included bug fixes and improvements
* Fix wrong version of ID3DXEffect interface for d3dx9_25
* GetMessage should remove already seen messages with higher priority ([Wine Bug #28884](https://bugs.winehq.org/show_bug.cgi?id=28884))
* Implement locking and synchronization of key states ([Wine Bug #31899](https://bugs.winehq.org/show_bug.cgi?id=31899))
* Invalidate key state cache globally after calling LL hooks ([Wine Bug #29871](https://bugs.winehq.org/show_bug.cgi?id=29871))
* Python PIP needs better NtQueryInformationJobObject stub

1
debian/changelog vendored
View File

@ -11,6 +11,7 @@ wine-staging (1.7.39) UNRELEASED; urgency=low
* Added patch to modify GetMessage to return already seen messages with higher priority.
* Added patch to silence repeated 'Unhandled blend factor 0' FIXME messages.
* Added patch for stub of PowerCreateRequest.
* Added patch to invalidate key state cache globally after calling LL hooks.
* Removed patch to avoid hardcoded values for sizeof(GUID) (accepted upstream).
* Removed patches for SLGetWindowsInformationDWORD (accepted upstream).
-- Sebastian Lackner <sebastian@fds-team.de> Mon, 09 Mar 2015 16:52:35 +0100

View File

@ -192,6 +192,7 @@ patch_enable_all ()
enable_user32_GetRawInputDeviceList="$1"
enable_user32_GetSystemMetrics="$1"
enable_user32_GetTipText="$1"
enable_user32_Key_State="$1"
enable_user32_Mouse_Message_Hwnd="$1"
enable_user32_Painting="$1"
enable_user32_ScrollWindowEx="$1"
@ -625,6 +626,9 @@ patch_enable ()
user32-GetTipText)
enable_user32_GetTipText="$2"
;;
user32-Key_State)
enable_user32_Key_State="$2"
;;
user32-Mouse_Message_Hwnd)
enable_user32_Mouse_Message_Hwnd="$2"
;;
@ -3939,6 +3943,21 @@ if test "$enable_user32_GetTipText" -eq 1; then
) >> "$patchlist"
fi
# Patchset user32-Key_State
# |
# | This patchset fixes the following Wine bugs:
# | * [#29871] Invalidate key state cache globally after calling LL hooks
# |
# | Modified files:
# | * dlls/user32/hook.c, dlls/user32/input.c, dlls/user32/message.c, dlls/user32/user_private.h
# |
if test "$enable_user32_Key_State" -eq 1; then
patch_apply user32-Key_State/0001-user32-After-calling-LL-hooks-the-key-state-cache-ha.patch
(
echo '+ { "Sebastian Lackner", "user32: After calling LL hooks the key state cache has to be invalidated globally.", 1 },';
) >> "$patchlist"
fi
# Patchset user32-Mouse_Message_Hwnd
# |
# | This patchset fixes the following Wine bugs:

View File

@ -0,0 +1,115 @@
From 96c4389fb6f0799c218394dce61e204c5a03dc8f Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 14 Jul 2014 05:06:40 +0200
Subject: user32: After calling LL hooks the key state cache has to be
invalidated globally.
---
dlls/user32/hook.c | 2 +-
dlls/user32/input.c | 8 ++++++--
dlls/user32/message.c | 7 ++++++-
dlls/user32/user_private.h | 3 +++
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index 2f6b42c..0c6a059 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -437,7 +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)
- get_user_thread_info()->key_state_time = 0; /* force refreshing the key state cache */
+ interlocked_xchg_add(&global_key_state_epoch, 1); /* force refreshing the key state cache */
return ret;
}
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 1f05f34..5671285 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_epoch = 0;
/***********************************************************************
* get_key_state
@@ -369,6 +370,7 @@ static void check_for_events( UINT flags )
SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
{
struct user_thread_info *thread_info = get_user_thread_info();
+ INT epoch = global_key_state_epoch;
SHORT ret;
if (key < 0 || key >= 256) return 0;
@@ -379,7 +381,8 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
{
if (thread_info->key_state &&
!(thread_info->key_state[key] & 0xc0) &&
- GetTickCount() - thread_info->key_state_time < 50)
+ GetTickCount() - thread_info->key_state_time < 50 &&
+ thread_info->key_state_epoch == epoch)
return 0;
if (!thread_info->key_state) thread_info->key_state = HeapAlloc( GetProcessHeap(), 0, 256 );
@@ -394,7 +397,8 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
{
if (reply->state & 0x40) ret |= 0x0001;
if (reply->state & 0x80) ret |= 0x8000;
- thread_info->key_state_time = GetTickCount();
+ thread_info->key_state_time = GetTickCount();
+ thread_info->key_state_epoch = epoch;
}
}
SERVER_END_REQ;
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index eac4e4d..d59e342 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3294,6 +3294,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
struct send_message_info info;
int prev_x, prev_y, new_x, new_y;
NTSTATUS ret;
+ INT epoch = global_key_state_epoch;
BOOL wait;
info.type = MSG_HARDWARE;
@@ -3341,7 +3342,11 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
if (!ret)
{
- if (thread_info->key_state) thread_info->key_state_time = GetTickCount();
+ if (thread_info->key_state)
+ {
+ thread_info->key_state_time = GetTickCount();
+ thread_info->key_state_epoch = epoch;
+ }
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 adf3f7d..7afe48b 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -184,6 +184,7 @@ struct user_thread_info
DWORD GetMessagePosVal; /* Value for GetMessagePos */
ULONG_PTR GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */
UINT active_hooks; /* Bitmap of active hooks */
+ INT key_state_epoch; /* Counter to invalidate the key state */
UINT key_state_time; /* Time of last key state refresh */
BYTE *key_state; /* Cache of global key state */
HWND top_window; /* Desktop window */
@@ -193,6 +194,8 @@ struct user_thread_info
ULONG pad[6]; /* Available for more data */
};
+extern INT global_key_state_epoch DECLSPEC_HIDDEN;
+
struct hook_extra_info
{
HHOOK handle;
--
2.3.2

View File

@ -0,0 +1 @@
Fixes: [29871] Invalidate key state cache globally after calling LL hooks