- 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:
Giannis Adamopoulos 2010-04-29 07:48:43 +00:00
parent 3ec3baec08
commit 0ec839d544
4 changed files with 140 additions and 112 deletions

View file

@ -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);

View file

@ -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,

View file

@ -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.

View file

@ -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. */