From 274bd6b2ab5f72cf978ad67740badc5c1e6257ab Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 29 Jul 2008 00:35:05 +0000 Subject: [PATCH] - Added more hook points, WH_FOREGROUNDIDLE and WH_KEYBOARD. - Fixed WH_CALLWNDPROC/RET, now the posted test program works as it should. - Tested with Opera 9.51, FF, Seamonkey, Abiword, Miranda, Mirc and the rest of our applications. svn path=/trunk/; revision=34922 --- reactos/dll/win32/user32/windows/hook.c | 2 + .../subsystems/win32/win32k/ntuser/callback.c | 8 +- reactos/subsystems/win32/win32k/ntuser/hook.c | 51 +++++++---- .../subsystems/win32/win32k/ntuser/message.c | 91 +++++++++++-------- 4 files changed, 93 insertions(+), 59 deletions(-) diff --git a/reactos/dll/win32/user32/windows/hook.c b/reactos/dll/win32/user32/windows/hook.c index 1bba40d9161..7e4d39b1569 100644 --- a/reactos/dll/win32/user32/windows/hook.c +++ b/reactos/dll/win32/user32/windows/hook.c @@ -524,7 +524,9 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) // FIXME("UHOOK Memory: %x: %x\n",Common, Msg); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) Msg); break; + case WH_FOREGROUNDIDLE: case WH_KEYBOARD: + case WH_SHELL: Result = Common->Proc(Common->Code, Common->wParam, Common->lParam); break; default: diff --git a/reactos/subsystems/win32/win32k/ntuser/callback.c b/reactos/subsystems/win32/win32k/ntuser/callback.c index d0513dbe419..6fdad2e714f 100644 --- a/reactos/subsystems/win32/win32k/ntuser/callback.c +++ b/reactos/subsystems/win32/win32k/ntuser/callback.c @@ -393,8 +393,9 @@ co_IntCallHookProc(INT HookId, case WH_GETMESSAGE: ArgumentLength += sizeof(MSG); break; + case WH_FOREGROUNDIDLE: case WH_KEYBOARD: -// case WH_SHELL: + case WH_SHELL: break; default: DPRINT1("Trying to call unsupported window hook %d\n", HookId); @@ -473,10 +474,9 @@ co_IntCallHookProc(INT HookId, Common->lParam = (LPARAM) (Extra - (PCHAR) Common); // DPRINT1("KHOOK Memory: %x\n",Common); break; + case WH_FOREGROUNDIDLE: case WH_KEYBOARD: - break; -// case WH_SHELL: -// Extra = lParam; + case WH_SHELL: break; } diff --git a/reactos/subsystems/win32/win32k/ntuser/hook.c b/reactos/subsystems/win32/win32k/ntuser/hook.c index c14c2b5d036..5b508fff483 100644 --- a/reactos/subsystems/win32/win32k/ntuser/hook.c +++ b/reactos/subsystems/win32/win32k/ntuser/hook.c @@ -267,15 +267,22 @@ IntReleaseHookChain(PHOOKTABLE Table, int HookId, PWINSTATION_OBJECT WinStaObj) } static LRESULT FASTCALL -IntCallLowLevelHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam, PHOOK Hook) +IntCallLowLevelHook(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam) { NTSTATUS Status; ULONG_PTR uResult; /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage(((PW32THREAD)Hook->Thread->Tcb.Win32Thread)->MessageQueue, (HWND) Code, HookId, - wParam, lParam, 5000, TRUE, TRUE, &uResult); + Status = co_MsqSendMessage(((PW32THREAD)Hook->Thread->Tcb.Win32Thread)->MessageQueue, + (HWND) Code, + Hook->HookId, + wParam, + lParam, + 5000, + TRUE, + TRUE, + &uResult); return NT_SUCCESS(Status) ? uResult : 0; } @@ -317,17 +324,10 @@ co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam) } } - if (Hook->Thread != PsGetCurrentThread() - && (WH_KEYBOARD_LL == HookId || WH_MOUSE_LL == HookId)) - { - DPRINT("Calling hook in owning thread\n"); - return IntCallLowLevelHook(HookId, Code, wParam, lParam, Hook); - } - if ((Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL)) { - DPRINT1("Calling hooks in other threads not implemented yet"); - return 0; + // Post it in message queue. + return IntCallLowLevelHook(Hook, Code, wParam, lParam); } Table->Counts[HOOKID_TO_INDEX(HookId)]++; @@ -340,8 +340,13 @@ co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam) SaveHook = ClientInfo->phkCurrent; ClientInfo->phkCurrent = Hook; // Load the call. - Result = co_IntCallHookProc(HookId, Code, wParam, lParam, Hook->Proc, - Hook->Ansi, &Hook->ModuleName); + Result = co_IntCallHookProc( HookId, + Code, + wParam, + lParam, + Hook->Proc, + Hook->Ansi, + &Hook->ModuleName); ClientInfo->phkCurrent = SaveHook; @@ -413,9 +418,19 @@ static LRESULT FASTCALL co_HOOK_CallHookNext(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam) { + if ((Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL)) + { + DPRINT1("CALLING HOOK from another Thread. %d\n",Hook->HookId); + return IntCallLowLevelHook(Hook, Code, wParam, lParam); + } DPRINT("CALLING HOOK %d\n",Hook->HookId); - return co_IntCallHookProc(Hook->HookId, Code, wParam, lParam, Hook->Proc, - Hook->Ansi, &Hook->ModuleName); + return co_IntCallHookProc(Hook->HookId, + Code, + wParam, + lParam, + Hook->Proc, + Hook->Ansi, + &Hook->ModuleName); } @@ -1030,9 +1045,7 @@ NtUserSetWindowsHookEx( if (Global || WH_DEBUG == HookId || WH_JOURNALPLAYBACK == HookId || - WH_JOURNALRECORD == HookId || - WH_FOREGROUNDIDLE == HookId || - WH_SHELL == HookId) + WH_JOURNALRECORD == HookId) { #if 0 /* Removed to get winEmbed working again */ UNIMPLEMENTED diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index 70ae5fd93f4..ac1a77cca50 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -295,6 +295,53 @@ UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam) return STATUS_INVALID_PARAMETER; } +static +VOID +FASTCALL +IntCallWndProc +( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + BOOL SameThread = FALSE; + + if (Window->ti == PsGetCurrentThreadWin32Thread()->ThreadInfo) + SameThread = TRUE; + + if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) || + (SameThread && ISITHOOKED(WH_CALLWNDPROC)) ) + { + CWPSTRUCT CWP; + CWP.hwnd = hWnd; + CWP.message = Msg; + CWP.wParam = wParam; + CWP.lParam = lParam; + co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP ); + } +} +static +VOID +FASTCALL +IntCallWndProcRet +( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult) +{ + BOOL SameThread = FALSE; + + if (Window->ti == PsGetCurrentThreadWin32Thread()->ThreadInfo) + SameThread = TRUE; + + if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) || + (SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) ) + { + CWPRETSTRUCT CWPR; + CWPR.hwnd = hWnd; + CWPR.message = Msg; + CWPR.wParam = wParam; + CWPR.lParam = lParam; + CWPR.lResult = *uResult; + co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR ); + } +} + + BOOL STDCALL NtUserCallMsgFilter( @@ -1429,7 +1476,6 @@ co_IntSendMessageTimeoutSingle(HWND hWnd, PW32THREAD Win32Thread; DECLARE_RETURN(LRESULT); USER_REFERENCE_ENTRY Ref; - BOOL SameThread = FALSE; if (!(Window = UserGetWindowObject(hWnd))) { @@ -1440,20 +1486,8 @@ co_IntSendMessageTimeoutSingle(HWND hWnd, Win32Thread = PsGetCurrentThreadWin32Thread(); - if (Window->ti == Win32Thread->ThreadInfo) - SameThread = TRUE; + IntCallWndProc( Window, hWnd, Msg, wParam, lParam); - if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) || - (SameThread && ISITHOOKED(WH_CALLWNDPROC)) ) - { - CWPSTRUCT CWP; - CWP.hwnd = hWnd; - CWP.message = Msg; - CWP.wParam = wParam; - CWP.lParam = lParam; - co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP ); - } - if (NULL != Win32Thread && Window->MessageQueue == Win32Thread->MessageQueue) { @@ -1488,17 +1522,7 @@ co_IntSendMessageTimeoutSingle(HWND hWnd, *uResult = Result; } - if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) || - (SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) ) - { - CWPRETSTRUCT CWPR; - CWPR.hwnd = hWnd; - CWPR.message = Msg; - CWPR.wParam = wParam; - CWPR.lParam = lParam; - CWPR.lResult = Result; - co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR ); - } + IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam))) { @@ -1538,17 +1562,7 @@ co_IntSendMessageTimeoutSingle(HWND hWnd, (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) && !MsqIsHung(Window->MessageQueue)); - if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) || - (SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) ) - { - CWPRETSTRUCT CWPR; - CWPR.hwnd = hWnd; - CWPR.message = Msg; - CWPR.wParam = wParam; - CWPR.lParam = lParam; - CWPR.lResult = *uResult; - co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR ); - } + IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); if (STATUS_TIMEOUT == Status) { @@ -1703,6 +1717,8 @@ co_IntDoSendMessage(HWND hWnd, Info.Ansi = ! Window->Wnd->Unicode; } + IntCallWndProc( Window, hWnd, Msg, wParam, lParam); + if (Window->Wnd->IsSystem) { Info.Proc = (!Info.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra); @@ -1712,6 +1728,9 @@ co_IntDoSendMessage(HWND hWnd, Info.Ansi = !Window->Wnd->Unicode; Info.Proc = Window->Wnd->WndProc; } + + IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result); + } else {