mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +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
|
@ -248,6 +248,16 @@ VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers,
|
|||
(message) == WM_NCRBUTTON##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
|
||||
IntMsqSetWakeMask(DWORD WakeMask);
|
||||
|
||||
|
|
|
@ -204,6 +204,16 @@ MouseThreadMain(PVOID StartContext)
|
|||
NTSTATUS Status;
|
||||
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,
|
||||
&MouseDeviceName,
|
||||
0,
|
||||
|
|
|
@ -645,6 +645,74 @@ co_IntTranslateMouseMessage(
|
|||
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
|
||||
*/
|
||||
|
@ -662,7 +730,6 @@ co_IntPeekMessage( PUSER_MESSAGE Msg,
|
|||
BOOL Present, RemoveMessages;
|
||||
USER_REFERENCE_ENTRY Ref;
|
||||
USHORT HitTest;
|
||||
MOUSEHOOKSTRUCT MHook;
|
||||
|
||||
/* The queues and order in which they are checked are documented in the MSDN
|
||||
article on GetMessage() */
|
||||
|
@ -867,52 +934,20 @@ MessageFound:
|
|||
}
|
||||
|
||||
MsgExit:
|
||||
if ( ISITHOOKED(WH_MOUSE) &&
|
||||
Msg->Msg.message >= WM_MOUSEFIRST &&
|
||||
Msg->Msg.message <= WM_MOUSELAST )
|
||||
if ( ISITHOOKED(WH_MOUSE) && IS_MOUSE_MESSAGE(Msg->Msg.message))
|
||||
{
|
||||
MHook.pt = Msg->Msg.pt;
|
||||
MHook.hwnd = Msg->Msg.hwnd;
|
||||
MHook.wHitTestCode = HitTest;
|
||||
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(!ProcessMouseMessage(&Msg->Msg, HitTest, RemoveMsg))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ISITHOOKED(WH_KEYBOARD) &&
|
||||
(Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) )
|
||||
if ( ISITHOOKED(WH_KEYBOARD) && IS_KBD_MESSAGE(Msg->Msg.message))
|
||||
{
|
||||
if (co_HOOK_CallHooks( WH_KEYBOARD,
|
||||
RemoveMsg ? HC_ACTION : HC_NOREMOVE,
|
||||
LOWORD(Msg->Msg.wParam),
|
||||
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;
|
||||
}
|
||||
if(!ProcessKeyboardMessage(&Msg->Msg, RemoveMsg))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// The WH_GETMESSAGE hook enables an application to monitor messages about to
|
||||
// be returned by the GetMessage or PeekMessage function.
|
||||
|
|
|
@ -174,8 +174,41 @@ MsqInsertSystemMessage(MSG* Msg)
|
|||
LARGE_INTEGER LargeTickCount;
|
||||
KIRQL OldIrql;
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -189,22 +222,6 @@ MsqInsertSystemMessage(MSG* Msg)
|
|||
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 (SystemMessageQueueTail == 0)
|
||||
|
@ -623,7 +640,6 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Windo
|
|||
{
|
||||
PUSER_MESSAGE UserMsg;
|
||||
MSG Msg;
|
||||
BOOL ProcessMessage;
|
||||
|
||||
ASSERT(SystemMessageQueueHead < SYSTEM_MESSAGE_QUEUE_SIZE);
|
||||
Msg = SystemMessageQueue[SystemMessageQueueHead];
|
||||
|
@ -631,48 +647,14 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Windo
|
|||
(SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
|
||||
SystemMessageQueueCount--;
|
||||
IntUnLockSystemMessageQueue(OldIrql);
|
||||
if (WM_MOUSEFIRST <= Msg.message && Msg.message <= WM_MOUSELAST)
|
||||
{
|
||||
MSLLHOOKSTRUCT MouseHookData;
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
HardwareMessageQueueStamp++;
|
||||
|
@ -767,7 +749,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
MSG Msg;
|
||||
LARGE_INTEGER LargeTickCount;
|
||||
KBDLLHOOKSTRUCT KbdHookData;
|
||||
EVENTMSG Event;
|
||||
BOOLEAN Entered = FALSE;
|
||||
|
||||
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);
|
||||
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
|
||||
(and thus the window station) the message will end up in yet. */
|
||||
|
||||
|
|
Loading…
Reference in a new issue