- Added more hook points. Setup WH_MOUSE with callbacks, seems to be preloaded. Started BroadcastSystemMessage.

- Tested with Opera 9.51, FF, Seamonkey, Abiword, Miranda and the rest of our applications.

svn path=/trunk/; revision=34736
This commit is contained in:
James Tabor 2008-07-24 11:38:08 +00:00
parent face282d9f
commit e928cd52fd
6 changed files with 188 additions and 20 deletions

View file

@ -422,6 +422,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
PKBDLLHOOKSTRUCT KeyboardLlData; PKBDLLHOOKSTRUCT KeyboardLlData;
PMSLLHOOKSTRUCT MouseLlData; PMSLLHOOKSTRUCT MouseLlData;
PMSG Msg; PMSG Msg;
PMOUSEHOOKSTRUCT MHook;
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments; Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
@ -502,6 +503,10 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData);
break; break;
case WH_MOUSE:
MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MHook);
break;
case WH_MSGFILTER: case WH_MSGFILTER:
case WH_SYSMSGFILTER: case WH_SYSMSGFILTER:
case WH_GETMESSAGE: case WH_GETMESSAGE:

View file

@ -2560,15 +2560,6 @@ IsDialogMessageA( HWND hwndDlg, LPMSG pmsg )
return IsDialogMessageW( hwndDlg, &msg ); return IsDialogMessageW( hwndDlg, &msg );
} }
typedef struct _BROADCASTPARM
{
DWORD flags;
DWORD recipients;
HDESK hDesk;
HWND hWnd;
LUID luid;
} BROADCASTPARM, *PBROADCASTPARM;
LONG LONG
STDCALL STDCALL
IntBroadcastSystemMessage( IntBroadcastSystemMessage(

View file

@ -392,7 +392,14 @@ typedef struct _PROPERTY
ATOM Atom; ATOM Atom;
} PROPERTY, *PPROPERTY; } PROPERTY, *PPROPERTY;
typedef struct _BROADCASTPARM
{
DWORD flags;
DWORD recipients;
HDESK hDesk;
HWND hWnd;
LUID luid;
} BROADCASTPARM, *PBROADCASTPARM;
PW32THREADINFO GetW32ThreadInfo(VOID); PW32THREADINFO GetW32ThreadInfo(VOID);
PW32PROCESSINFO GetW32ProcessInfo(VOID); PW32PROCESSINFO GetW32ProcessInfo(VOID);

View file

@ -379,6 +379,9 @@ co_IntCallHookProc(INT HookId,
case WH_MOUSE_LL: case WH_MOUSE_LL:
ArgumentLength += sizeof(MSLLHOOKSTRUCT); ArgumentLength += sizeof(MSLLHOOKSTRUCT);
break; break;
case WH_MOUSE:
ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
break;
case WH_MSGFILTER: case WH_MSGFILTER:
case WH_SYSMSGFILTER: case WH_SYSMSGFILTER:
case WH_GETMESSAGE: case WH_GETMESSAGE:
@ -444,6 +447,10 @@ co_IntCallHookProc(INT HookId,
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSLLHOOKSTRUCT)); RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSLLHOOKSTRUCT));
Common->lParam = (LPARAM) (Extra - (PCHAR) Common); Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
break; break;
case WH_MOUSE:
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT));
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
break;
case WH_MSGFILTER: case WH_MSGFILTER:
case WH_SYSMSGFILTER: case WH_SYSMSGFILTER:
case WH_GETMESSAGE: case WH_GETMESSAGE:

View file

@ -658,6 +658,7 @@ 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() */
@ -814,9 +815,51 @@ MessageFound:
goto CheckMessages; goto CheckMessages;
} }
MsgExit: MsgExit:
if ( ISITHOOKED(WH_MOUSE) &&
Msg->Msg.message >= WM_MOUSEFIRST &&
Msg->Msg.message <= WM_MOUSELAST )
{
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 ( ISITHOOKED(WH_KEYBOARD) &&
(Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) )
{
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;
}
}
// 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.
if(ISITHOOKED(WH_GETMESSAGE)) if (ISITHOOKED(WH_GETMESSAGE))
{ {
//DPRINT1("Peek WH_GETMESSAGE -> %x\n",&Msg); //DPRINT1("Peek WH_GETMESSAGE -> %x\n",&Msg);
co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg); co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
@ -863,7 +906,6 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
} }
Present = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg); Present = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
if (Present) if (Present)
{ {
@ -1506,8 +1548,7 @@ co_IntPostOrSendMessage(HWND hWnd,
} }
else else
{ {
if(!co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result)) if(!co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result)) {
{
Result = 0; Result = 0;
} }
} }
@ -1863,14 +1904,93 @@ NtUserMessageCall(
{ {
return 0; return 0;
} }
UserRefObjectCo(Window, &Ref);
switch(dwType) switch(dwType)
{ {
case FNID_DEFWINDOWPROC: case FNID_DEFWINDOWPROC:
UserRefObjectCo(Window, &Ref);
lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi); lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
UserDerefObjectCo(Window);
break;
case FNID_BROADCASTSYSTEMMESSAGE:
{
PBROADCASTPARM parm;
BOOL BadChk = FALSE;
DWORD_PTR RetVal = 0;
lResult = -1;
if (ResultInfo)
{
_SEH_TRY
{
ProbeForWrite((PVOID)ResultInfo,
sizeof(BROADCASTPARM),
1);
parm = (PBROADCASTPARM)ResultInfo;
}
_SEH_HANDLE
{
BadChk = TRUE;
}
_SEH_END;
if (BadChk) break;
}
else
break;
if ( parm->recipients & BSM_ALLDESKTOPS ||
parm->recipients == BSM_ALLCOMPONENTS )
{
}
else if (parm->recipients & BSM_APPLICATIONS)
{
if (parm->flags & BSF_QUERY)
{
if (parm->flags & BSF_FORCEIFHUNG || parm->flags & BSF_NOHANG)
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
wParam,
lParam,
SMTO_ABORTIFHUNG,
2000,
&RetVal);
}
else if (parm->flags & BSF_NOTIMEOUTIFNOTHUNG)
{
#define SMTO_NOTIMEOUTIFNOTHUNG 0x0008
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
wParam,
lParam,
SMTO_NOTIMEOUTIFNOTHUNG,
2000,
&RetVal);
}
else
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
wParam,
lParam,
SMTO_NORMAL,
2000,
&RetVal);
}
}
else if (parm->flags & BSF_POSTMESSAGE)
{
lResult = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
}
else if ( parm->flags & BSF_SENDNOTIFYMESSAGE)
{
lResult = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
}
}
}
break;
case FNID_SENDMESSAGECALLBACK:
break; break;
} }
UserDerefObjectCo(Window);
UserLeave(); UserLeave();
return lResult; return lResult;
} }

View file

@ -70,7 +70,22 @@ static PAGED_LOOKASIDE_LIST TimerLookasideList;
static VOID FASTCALL static VOID FASTCALL
IdlePing(VOID) IdlePing(VOID)
{ {
HWND hWnd;
PWINDOW_OBJECT Window;
PW32PROCESS W32d = PsGetCurrentProcessWin32Process(); PW32PROCESS W32d = PsGetCurrentProcessWin32Process();
hWnd = UserGetForegroundWindow();
Window = UserGetWindowObject(hWnd);
if (Window && Window->Wnd && (Window->Wnd->ti == GetW32ThreadInfo()))
{
if (ISITHOOKED(WH_FOREGROUNDIDLE))
{
co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
}
}
if (W32d && W32d->InputIdleEvent) if (W32d && W32d->InputIdleEvent)
KePulseEvent( W32d->InputIdleEvent, EVENT_INCREMENT, TRUE); KePulseEvent( W32d->InputIdleEvent, EVENT_INCREMENT, TRUE);
} }
@ -159,6 +174,7 @@ MsqInsertSystemMessage(MSG* Msg)
LARGE_INTEGER LargeTickCount; LARGE_INTEGER LargeTickCount;
KIRQL OldIrql; KIRQL OldIrql;
ULONG Prev; ULONG Prev;
EVENTMSG Event;
IntLockSystemMessageQueue(OldIrql); IntLockSystemMessageQueue(OldIrql);
@ -176,6 +192,13 @@ MsqInsertSystemMessage(MSG* Msg)
KeQueryTickCount(&LargeTickCount); KeQueryTickCount(&LargeTickCount);
Msg->time = MsqCalculateMessageTime(&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 * If we got WM_MOUSEMOVE and there are already messages in the
* system message queue, check if the last message is mouse move * system message queue, check if the last message is mouse move
@ -713,20 +736,36 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
MSG Msg; MSG Msg;
LARGE_INTEGER LargeTickCount; LARGE_INTEGER LargeTickCount;
KBDLLHOOKSTRUCT KbdHookData; KBDLLHOOKSTRUCT KbdHookData;
EVENTMSG Event;
// Condition may arise when calling MsqPostMessage and waiting for an event.
if (!UserIsEntered()) UserEnterExclusive(); // Fixme: Not sure ATM if this thread is locked.
DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n", DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
uMsg, wParam, lParam); uMsg, wParam, lParam);
// Condition may arise when calling MsqPostMessage and waiting for an event.
if (!UserIsEntered()) UserEnterExclusive(); // Fixme: Not sure ATM if this thread is locked.
FocusMessageQueue = IntGetFocusMessageQueue();
Msg.hwnd = 0; Msg.hwnd = 0;
if (FocusMessageQueue && (FocusMessageQueue->FocusWindow != (HWND)0))
Msg.hwnd = FocusMessageQueue->FocusWindow;
Msg.message = uMsg; Msg.message = uMsg;
Msg.wParam = wParam; Msg.wParam = wParam;
Msg.lParam = lParam; Msg.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. */
@ -744,7 +783,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
return; return;
} }
FocusMessageQueue = IntGetFocusMessageQueue();
if (FocusMessageQueue == NULL) if (FocusMessageQueue == NULL)
{ {
DPRINT("No focus message queue\n"); DPRINT("No focus message queue\n");