From e928cd52fd0a76ca6572fa0131deef1b2f6ea2aa Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 24 Jul 2008 11:38:08 +0000 Subject: [PATCH] - 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 --- reactos/dll/win32/user32/windows/hook.c | 5 + reactos/dll/win32/user32/windows/message.c | 9 -- reactos/include/reactos/win32k/ntuser.h | 9 +- .../subsystems/win32/win32k/ntuser/callback.c | 7 + .../subsystems/win32/win32k/ntuser/message.c | 132 +++++++++++++++++- .../subsystems/win32/win32k/ntuser/msgqueue.c | 46 +++++- 6 files changed, 188 insertions(+), 20 deletions(-) diff --git a/reactos/dll/win32/user32/windows/hook.c b/reactos/dll/win32/user32/windows/hook.c index d54eb5a2f53..694057a97b1 100644 --- a/reactos/dll/win32/user32/windows/hook.c +++ b/reactos/dll/win32/user32/windows/hook.c @@ -422,6 +422,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) PKBDLLHOOKSTRUCT KeyboardLlData; PMSLLHOOKSTRUCT MouseLlData; PMSG Msg; + PMOUSEHOOKSTRUCT MHook; Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments; @@ -502,6 +503,10 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData); 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_SYSMSGFILTER: case WH_GETMESSAGE: diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index 56db32c198f..7d27a8eea94 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -2560,15 +2560,6 @@ IsDialogMessageA( HWND hwndDlg, LPMSG pmsg ) return IsDialogMessageW( hwndDlg, &msg ); } -typedef struct _BROADCASTPARM -{ - DWORD flags; - DWORD recipients; - HDESK hDesk; - HWND hWnd; - LUID luid; -} BROADCASTPARM, *PBROADCASTPARM; - LONG STDCALL IntBroadcastSystemMessage( diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index a7b029df6c4..0cc48479d64 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -392,7 +392,14 @@ typedef struct _PROPERTY ATOM Atom; } PROPERTY, *PPROPERTY; - +typedef struct _BROADCASTPARM +{ + DWORD flags; + DWORD recipients; + HDESK hDesk; + HWND hWnd; + LUID luid; +} BROADCASTPARM, *PBROADCASTPARM; PW32THREADINFO GetW32ThreadInfo(VOID); PW32PROCESSINFO GetW32ProcessInfo(VOID); diff --git a/reactos/subsystems/win32/win32k/ntuser/callback.c b/reactos/subsystems/win32/win32k/ntuser/callback.c index 362bc406f83..83452c50ed7 100644 --- a/reactos/subsystems/win32/win32k/ntuser/callback.c +++ b/reactos/subsystems/win32/win32k/ntuser/callback.c @@ -379,6 +379,9 @@ co_IntCallHookProc(INT HookId, case WH_MOUSE_LL: ArgumentLength += sizeof(MSLLHOOKSTRUCT); break; + case WH_MOUSE: + ArgumentLength += sizeof(MOUSEHOOKSTRUCT); + break; case WH_MSGFILTER: case WH_SYSMSGFILTER: case WH_GETMESSAGE: @@ -444,6 +447,10 @@ co_IntCallHookProc(INT HookId, RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSLLHOOKSTRUCT)); Common->lParam = (LPARAM) (Extra - (PCHAR) Common); break; + case WH_MOUSE: + RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT)); + Common->lParam = (LPARAM) (Extra - (PCHAR) Common); + break; case WH_MSGFILTER: case WH_SYSMSGFILTER: case WH_GETMESSAGE: diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index ddaeb443c35..327f6164b49 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -658,6 +658,7 @@ 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() */ @@ -814,9 +815,51 @@ MessageFound: goto CheckMessages; } 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 // be returned by the GetMessage or PeekMessage function. - if(ISITHOOKED(WH_GETMESSAGE)) + if (ISITHOOKED(WH_GETMESSAGE)) { //DPRINT1("Peek WH_GETMESSAGE -> %x\n",&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); - if (Present) { @@ -1506,8 +1548,7 @@ co_IntPostOrSendMessage(HWND hWnd, } 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; } } @@ -1863,14 +1904,93 @@ NtUserMessageCall( { return 0; } - UserRefObjectCo(Window, &Ref); switch(dwType) { case FNID_DEFWINDOWPROC: + UserRefObjectCo(Window, &Ref); 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; } - UserDerefObjectCo(Window); UserLeave(); return lResult; } diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index fae5d732608..fadc4f067c5 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -70,7 +70,22 @@ static PAGED_LOOKASIDE_LIST TimerLookasideList; static VOID FASTCALL IdlePing(VOID) { + HWND hWnd; + PWINDOW_OBJECT Window; 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) KePulseEvent( W32d->InputIdleEvent, EVENT_INCREMENT, TRUE); } @@ -159,6 +174,7 @@ MsqInsertSystemMessage(MSG* Msg) LARGE_INTEGER LargeTickCount; KIRQL OldIrql; ULONG Prev; + EVENTMSG Event; IntLockSystemMessageQueue(OldIrql); @@ -176,6 +192,13 @@ MsqInsertSystemMessage(MSG* Msg) 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 @@ -713,20 +736,36 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) MSG Msg; LARGE_INTEGER LargeTickCount; KBDLLHOOKSTRUCT KbdHookData; - - // Condition may arise when calling MsqPostMessage and waiting for an event. - if (!UserIsEntered()) UserEnterExclusive(); // Fixme: Not sure ATM if this thread is locked. + EVENTMSG Event; DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n", 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; + + if (FocusMessageQueue && (FocusMessageQueue->FocusWindow != (HWND)0)) + Msg.hwnd = FocusMessageQueue->FocusWindow; + Msg.message = uMsg; Msg.wParam = wParam; Msg.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. */ @@ -744,7 +783,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) return; } - FocusMessageQueue = IntGetFocusMessageQueue(); if (FocusMessageQueue == NULL) { DPRINT("No focus message queue\n");