mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 07:52:56 +00:00
[win32k]
- Do not do callbacks to user mode while holding a lock - Fix when WH_MOUSE_LL and WH_JOURNALRECORD are called See issue #4926 for more details. svn path=/trunk/; revision=47058
This commit is contained in:
parent
3ec3baec08
commit
0ec839d544
4 changed files with 140 additions and 112 deletions
|
@ -248,6 +248,16 @@ VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers,
|
||||||
(message) == WM_NCRBUTTON##code || \
|
(message) == WM_NCRBUTTON##code || \
|
||||||
(message) == WM_NCXBUTTON##code )
|
(message) == WM_NCXBUTTON##code )
|
||||||
|
|
||||||
|
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
|
||||||
|
#define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
|
||||||
|
|
||||||
|
#define IS_MOUSE_MESSAGE(message) \
|
||||||
|
((message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST) || \
|
||||||
|
(message >= WM_MOUSEFIRST && message <= WM_MOUSELAST))
|
||||||
|
|
||||||
|
#define IS_KBD_MESSAGE(message) \
|
||||||
|
(message == WM_KEYDOWN || message == WM_KEYUP)
|
||||||
|
|
||||||
HANDLE FASTCALL
|
HANDLE FASTCALL
|
||||||
IntMsqSetWakeMask(DWORD WakeMask);
|
IntMsqSetWakeMask(DWORD WakeMask);
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,16 @@ MouseThreadMain(PVOID StartContext)
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
MOUSE_ATTRIBUTES MouseAttr;
|
MOUSE_ATTRIBUTES MouseAttr;
|
||||||
|
|
||||||
|
Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Win32K: Failed making keyboard thread a win32 thread.\n");
|
||||||
|
return; //(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
|
||||||
|
LOW_REALTIME_PRIORITY + 3);
|
||||||
|
|
||||||
InitializeObjectAttributes(&MouseObjectAttributes,
|
InitializeObjectAttributes(&MouseObjectAttributes,
|
||||||
&MouseDeviceName,
|
&MouseDeviceName,
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -645,6 +645,74 @@ co_IntTranslateMouseMessage(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL ProcessMouseMessage(MSG* Msg, USHORT HitTest, UINT RemoveMsg)
|
||||||
|
{
|
||||||
|
MOUSEHOOKSTRUCT MHook;
|
||||||
|
EVENTMSG Event;
|
||||||
|
|
||||||
|
Event.message = Msg->message;
|
||||||
|
Event.time = Msg->time;
|
||||||
|
Event.hwnd = Msg->hwnd;
|
||||||
|
Event.paramL = Msg->pt.x;
|
||||||
|
Event.paramH = Msg->pt.y;
|
||||||
|
co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
|
||||||
|
|
||||||
|
|
||||||
|
MHook.pt = Msg->pt;
|
||||||
|
MHook.hwnd = Msg->hwnd;
|
||||||
|
MHook.wHitTestCode = HitTest;
|
||||||
|
MHook.dwExtraInfo = 0;
|
||||||
|
if (co_HOOK_CallHooks( WH_MOUSE,
|
||||||
|
RemoveMsg ? HC_ACTION : HC_NOREMOVE,
|
||||||
|
Msg->message,
|
||||||
|
(LPARAM)&MHook ))
|
||||||
|
{
|
||||||
|
if (ISITHOOKED(WH_CBT))
|
||||||
|
{
|
||||||
|
MHook.pt = Msg->pt;
|
||||||
|
MHook.hwnd = Msg->hwnd;
|
||||||
|
MHook.wHitTestCode = HitTest;
|
||||||
|
MHook.dwExtraInfo = 0;
|
||||||
|
co_HOOK_CallHooks( WH_CBT,
|
||||||
|
HCBT_CLICKSKIPPED,
|
||||||
|
Msg->message,
|
||||||
|
(LPARAM)&MHook);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ProcessKeyboardMessage(MSG* Msg, UINT RemoveMsg)
|
||||||
|
{
|
||||||
|
EVENTMSG Event;
|
||||||
|
|
||||||
|
Event.message = Msg->message;
|
||||||
|
Event.hwnd = Msg->hwnd;
|
||||||
|
Event.time = Msg->time;
|
||||||
|
Event.paramL = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
|
||||||
|
Event.paramH = Msg->lParam & 0x7FFF;
|
||||||
|
if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
|
||||||
|
co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
|
||||||
|
|
||||||
|
if (co_HOOK_CallHooks( WH_KEYBOARD,
|
||||||
|
RemoveMsg ? HC_ACTION : HC_NOREMOVE,
|
||||||
|
LOWORD(Msg->wParam),
|
||||||
|
Msg->lParam))
|
||||||
|
{
|
||||||
|
if (ISITHOOKED(WH_CBT))
|
||||||
|
{
|
||||||
|
/* skip this message */
|
||||||
|
co_HOOK_CallHooks( WH_CBT,
|
||||||
|
HCBT_KEYSKIPPED,
|
||||||
|
LOWORD(Msg->wParam),
|
||||||
|
Msg->lParam );
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Internal version of PeekMessage() doing all the work
|
* Internal version of PeekMessage() doing all the work
|
||||||
*/
|
*/
|
||||||
|
@ -662,7 +730,6 @@ co_IntPeekMessage( PUSER_MESSAGE Msg,
|
||||||
BOOL Present, RemoveMessages;
|
BOOL Present, RemoveMessages;
|
||||||
USER_REFERENCE_ENTRY Ref;
|
USER_REFERENCE_ENTRY Ref;
|
||||||
USHORT HitTest;
|
USHORT HitTest;
|
||||||
MOUSEHOOKSTRUCT MHook;
|
|
||||||
|
|
||||||
/* The queues and order in which they are checked are documented in the MSDN
|
/* The queues and order in which they are checked are documented in the MSDN
|
||||||
article on GetMessage() */
|
article on GetMessage() */
|
||||||
|
@ -867,52 +934,20 @@ MessageFound:
|
||||||
}
|
}
|
||||||
|
|
||||||
MsgExit:
|
MsgExit:
|
||||||
if ( ISITHOOKED(WH_MOUSE) &&
|
if ( ISITHOOKED(WH_MOUSE) && IS_MOUSE_MESSAGE(Msg->Msg.message))
|
||||||
Msg->Msg.message >= WM_MOUSEFIRST &&
|
|
||||||
Msg->Msg.message <= WM_MOUSELAST )
|
|
||||||
{
|
{
|
||||||
MHook.pt = Msg->Msg.pt;
|
if(!ProcessMouseMessage(&Msg->Msg, HitTest, RemoveMsg))
|
||||||
MHook.hwnd = Msg->Msg.hwnd;
|
{
|
||||||
MHook.wHitTestCode = HitTest;
|
return FALSE;
|
||||||
MHook.dwExtraInfo = 0;
|
}
|
||||||
if (co_HOOK_CallHooks( WH_MOUSE,
|
}
|
||||||
RemoveMsg ? HC_ACTION : HC_NOREMOVE,
|
|
||||||
Msg->Msg.message,
|
|
||||||
(LPARAM)&MHook ))
|
|
||||||
{
|
|
||||||
if (ISITHOOKED(WH_CBT))
|
|
||||||
{
|
|
||||||
MHook.pt = Msg->Msg.pt;
|
|
||||||
MHook.hwnd = Msg->Msg.hwnd;
|
|
||||||
MHook.wHitTestCode = HitTest;
|
|
||||||
MHook.dwExtraInfo = 0;
|
|
||||||
co_HOOK_CallHooks( WH_CBT,
|
|
||||||
HCBT_CLICKSKIPPED,
|
|
||||||
Msg->Msg.message,
|
|
||||||
(LPARAM)&MHook);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ISITHOOKED(WH_KEYBOARD) &&
|
if ( ISITHOOKED(WH_KEYBOARD) && IS_KBD_MESSAGE(Msg->Msg.message))
|
||||||
(Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) )
|
|
||||||
{
|
{
|
||||||
if (co_HOOK_CallHooks( WH_KEYBOARD,
|
if(!ProcessKeyboardMessage(&Msg->Msg, RemoveMsg))
|
||||||
RemoveMsg ? HC_ACTION : HC_NOREMOVE,
|
{
|
||||||
LOWORD(Msg->Msg.wParam),
|
return FALSE;
|
||||||
Msg->Msg.lParam))
|
}
|
||||||
{
|
|
||||||
if (ISITHOOKED(WH_CBT))
|
|
||||||
{
|
|
||||||
/* skip this message */
|
|
||||||
co_HOOK_CallHooks( WH_CBT,
|
|
||||||
HCBT_KEYSKIPPED,
|
|
||||||
LOWORD(Msg->Msg.wParam),
|
|
||||||
Msg->Msg.lParam );
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// The WH_GETMESSAGE hook enables an application to monitor messages about to
|
// The WH_GETMESSAGE hook enables an application to monitor messages about to
|
||||||
// be returned by the GetMessage or PeekMessage function.
|
// be returned by the GetMessage or PeekMessage function.
|
||||||
|
|
|
@ -174,8 +174,41 @@ MsqInsertSystemMessage(MSG* Msg)
|
||||||
LARGE_INTEGER LargeTickCount;
|
LARGE_INTEGER LargeTickCount;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
ULONG Prev;
|
ULONG Prev;
|
||||||
EVENTMSG Event;
|
MSLLHOOKSTRUCT MouseHookData;
|
||||||
|
|
||||||
|
KeQueryTickCount(&LargeTickCount);
|
||||||
|
Msg->time = MsqCalculateMessageTime(&LargeTickCount);
|
||||||
|
|
||||||
|
MouseHookData.pt.x = LOWORD(Msg->lParam);
|
||||||
|
MouseHookData.pt.y = HIWORD(Msg->lParam);
|
||||||
|
switch(Msg->message)
|
||||||
|
{
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam));
|
||||||
|
break;
|
||||||
|
case WM_XBUTTONDOWN:
|
||||||
|
case WM_XBUTTONUP:
|
||||||
|
case WM_XBUTTONDBLCLK:
|
||||||
|
case WM_NCXBUTTONDOWN:
|
||||||
|
case WM_NCXBUTTONUP:
|
||||||
|
case WM_NCXBUTTONDBLCLK:
|
||||||
|
MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg->wParam));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MouseHookData.mouseData = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MouseHookData.flags = 0;
|
||||||
|
MouseHookData.time = Msg->time;
|
||||||
|
MouseHookData.dwExtraInfo = 0;
|
||||||
|
if( co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we got WM_MOUSEMOVE and there are already messages in the
|
||||||
|
* system message queue, check if the last message is mouse move
|
||||||
|
* and if it is then just overwrite it.
|
||||||
|
*/
|
||||||
IntLockSystemMessageQueue(OldIrql);
|
IntLockSystemMessageQueue(OldIrql);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -189,22 +222,6 @@ MsqInsertSystemMessage(MSG* Msg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeQueryTickCount(&LargeTickCount);
|
|
||||||
Msg->time = MsqCalculateMessageTime(&LargeTickCount);
|
|
||||||
|
|
||||||
Event.message = Msg->message;
|
|
||||||
Event.time = Msg->time;
|
|
||||||
Event.hwnd = Msg->hwnd;
|
|
||||||
Event.paramL = Msg->pt.x;
|
|
||||||
Event.paramH = Msg->pt.y;
|
|
||||||
co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we got WM_MOUSEMOVE and there are already messages in the
|
|
||||||
* system message queue, check if the last message is mouse move
|
|
||||||
* and if it is then just overwrite it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (Msg->message == WM_MOUSEMOVE && SystemMessageQueueCount)
|
if (Msg->message == WM_MOUSEMOVE && SystemMessageQueueCount)
|
||||||
{
|
{
|
||||||
if (SystemMessageQueueTail == 0)
|
if (SystemMessageQueueTail == 0)
|
||||||
|
@ -623,7 +640,6 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Windo
|
||||||
{
|
{
|
||||||
PUSER_MESSAGE UserMsg;
|
PUSER_MESSAGE UserMsg;
|
||||||
MSG Msg;
|
MSG Msg;
|
||||||
BOOL ProcessMessage;
|
|
||||||
|
|
||||||
ASSERT(SystemMessageQueueHead < SYSTEM_MESSAGE_QUEUE_SIZE);
|
ASSERT(SystemMessageQueueHead < SYSTEM_MESSAGE_QUEUE_SIZE);
|
||||||
Msg = SystemMessageQueue[SystemMessageQueueHead];
|
Msg = SystemMessageQueue[SystemMessageQueueHead];
|
||||||
|
@ -631,48 +647,14 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Windo
|
||||||
(SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
|
(SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
|
||||||
SystemMessageQueueCount--;
|
SystemMessageQueueCount--;
|
||||||
IntUnLockSystemMessageQueue(OldIrql);
|
IntUnLockSystemMessageQueue(OldIrql);
|
||||||
if (WM_MOUSEFIRST <= Msg.message && Msg.message <= WM_MOUSELAST)
|
|
||||||
{
|
|
||||||
MSLLHOOKSTRUCT MouseHookData;
|
|
||||||
|
|
||||||
MouseHookData.pt.x = LOWORD(Msg.lParam);
|
UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
|
||||||
MouseHookData.pt.y = HIWORD(Msg.lParam);
|
/* What to do if out of memory? For now we just panic a bit in debug */
|
||||||
switch(Msg.message)
|
ASSERT(UserMsg);
|
||||||
{
|
UserMsg->FreeLParam = FALSE;
|
||||||
case WM_MOUSEWHEEL:
|
UserMsg->Msg = Msg;
|
||||||
MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg.wParam));
|
InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
|
||||||
break;
|
|
||||||
case WM_XBUTTONDOWN:
|
|
||||||
case WM_XBUTTONUP:
|
|
||||||
case WM_XBUTTONDBLCLK:
|
|
||||||
case WM_NCXBUTTONDOWN:
|
|
||||||
case WM_NCXBUTTONUP:
|
|
||||||
case WM_NCXBUTTONDBLCLK:
|
|
||||||
MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg.wParam));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MouseHookData.mouseData = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MouseHookData.flags = 0;
|
|
||||||
MouseHookData.time = Msg.time;
|
|
||||||
MouseHookData.dwExtraInfo = 0;
|
|
||||||
ProcessMessage = (0 == co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION,
|
|
||||||
Msg.message, (LPARAM) &MouseHookData));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ProcessMessage = TRUE;
|
|
||||||
}
|
|
||||||
if (ProcessMessage)
|
|
||||||
{
|
|
||||||
UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
|
|
||||||
/* What to do if out of memory? For now we just panic a bit in debug */
|
|
||||||
ASSERT(UserMsg);
|
|
||||||
UserMsg->FreeLParam = FALSE;
|
|
||||||
UserMsg->Msg = Msg;
|
|
||||||
InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
|
|
||||||
}
|
|
||||||
IntLockSystemMessageQueue(OldIrql);
|
IntLockSystemMessageQueue(OldIrql);
|
||||||
}
|
}
|
||||||
HardwareMessageQueueStamp++;
|
HardwareMessageQueueStamp++;
|
||||||
|
@ -767,7 +749,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
MSG Msg;
|
MSG Msg;
|
||||||
LARGE_INTEGER LargeTickCount;
|
LARGE_INTEGER LargeTickCount;
|
||||||
KBDLLHOOKSTRUCT KbdHookData;
|
KBDLLHOOKSTRUCT KbdHookData;
|
||||||
EVENTMSG Event;
|
|
||||||
BOOLEAN Entered = FALSE;
|
BOOLEAN Entered = FALSE;
|
||||||
|
|
||||||
DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
|
DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
|
||||||
|
@ -795,14 +776,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
KeQueryTickCount(&LargeTickCount);
|
KeQueryTickCount(&LargeTickCount);
|
||||||
Msg.time = MsqCalculateMessageTime(&LargeTickCount);
|
Msg.time = MsqCalculateMessageTime(&LargeTickCount);
|
||||||
|
|
||||||
Event.message = Msg.message;
|
|
||||||
Event.hwnd = Msg.hwnd;
|
|
||||||
Event.time = Msg.time;
|
|
||||||
Event.paramL = (Msg.wParam & 0xFF) | (HIWORD(Msg.lParam) << 8);
|
|
||||||
Event.paramH = Msg.lParam & 0x7FFF;
|
|
||||||
if (HIWORD(Msg.lParam) & 0x0100) Event.paramH |= 0x8000;
|
|
||||||
co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
|
|
||||||
|
|
||||||
/* We can't get the Msg.pt point here since we don't know thread
|
/* We can't get the Msg.pt point here since we don't know thread
|
||||||
(and thus the window station) the message will end up in yet. */
|
(and thus the window station) the message will end up in yet. */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue