From 4f11e10d3d38cce0f863c8bb4f5acfd71d792e77 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 22 Jul 2008 04:54:53 +0000 Subject: [PATCH] - Rewrite HOOKs, Implement CallNextHookEx and fix prototype for NtUserCallNextHookEx. Move hook structure to ntuser.h for user verifying. - Tested with FF, Seamonkey, Abiword, and the rest of our applications. svn path=/trunk/; revision=34653 --- reactos/dll/win32/user32/windows/hook.c | 67 ++- reactos/include/reactos/win32k/ntuser.h | 22 +- .../subsystems/win32/win32k/include/hook.h | 8 +- .../subsystems/win32/win32k/include/window.h | 2 +- .../subsystems/win32/win32k/ntuser/callback.c | 17 + .../subsystems/win32/win32k/ntuser/defwnd.c | 6 +- reactos/subsystems/win32/win32k/ntuser/hook.c | 384 ++++++++++++++++-- .../subsystems/win32/win32k/ntuser/message.c | 21 +- 8 files changed, 480 insertions(+), 47 deletions(-) diff --git a/reactos/dll/win32/user32/windows/hook.c b/reactos/dll/win32/user32/windows/hook.c index 7529aa86ff9..ae1fb21aa9d 100644 --- a/reactos/dll/win32/user32/windows/hook.c +++ b/reactos/dll/win32/user32/windows/hook.c @@ -193,9 +193,66 @@ CallNextHookEx( WPARAM wParam, LPARAM lParam) { - return NtUserCallNextHookEx(Hook, Code, wParam, lParam); + PW32CLIENTINFO ClientInfo; + PHOOK pHook; + DWORD Flags, Save; + LRESULT lResult = 0; + + GetConnected(); + + ClientInfo = GetWin32ClientInfo(); + + pHook = ValidateHandle(Hook, VALIDATE_TYPE_HOOK); + + if (!pHook) return 0; + + ClientInfo->phkCurrent = (PHOOK)pHook->Self; // Pass this over to the kernel. + + if (pHook->HookId == WH_CALLWNDPROC || pHook->HookId == WH_CALLWNDPROCRET) + { + Save = ClientInfo->dwHookData; + Flags = ClientInfo->CI_flags & CI_CURTHPRHOOK; +// wParam: If the message was sent by the current thread/process, it is +// nonzero; otherwise, it is zero. + if (wParam) ClientInfo->CI_flags |= CI_CURTHPRHOOK; + else ClientInfo->CI_flags &= ~CI_CURTHPRHOOK; + + if (pHook->HookId == WH_CALLWNDPROC) + { + PCWPSTRUCT pCWP = (PCWPSTRUCT)lParam; + + lResult = NtUserMessageCall( pCWP->hwnd, + pCWP->message, + pCWP->wParam, + pCWP->lParam, + 0, + FNID_CALLWNDPROC, + pHook->Ansi); + } + else + { + PCWPRETSTRUCT pCWPR = (PCWPRETSTRUCT)lParam; + + ClientInfo->dwHookData = pCWPR->lResult; + + lResult = NtUserMessageCall( pCWPR->hwnd, + pCWPR->message, + pCWPR->wParam, + pCWPR->lParam, + 0, + FNID_CALLWNDPROCRET, + pHook->Ansi); + } + ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK); + ClientInfo->dwHookData = Save; + } + else + lResult = NtUserCallNextHookEx(Code, wParam, lParam, pHook->Ansi); + + return lResult; } + /* * @unimplemented */ @@ -366,6 +423,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) LPARAM lParam; PKBDLLHOOKSTRUCT KeyboardLlData; PMSLLHOOKSTRUCT MouseLlData; + PMSG Msg; Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments; @@ -446,6 +504,13 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData); break; + case WH_MSGFILTER: + case WH_SYSMSGFILTER: + case WH_GETMESSAGE: + Msg = (PMSG)((PCHAR) Common + Common->lParam); + FIXME("UHOOK Memory: %x: %x\n",Common, Msg); + Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) Msg); + break; default: return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED); } diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index eb8110799e5..a7b029df6c4 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -317,6 +317,20 @@ typedef struct _W32THREADINFO } W32THREADINFO, *PW32THREADINFO; /* Window Client Information structure */ +struct _ETHREAD; + + +typedef struct tagHOOK +{ + LIST_ENTRY Chain; /* Hook chain entry */ + HHOOK Self; /* user handle for this hook */ + struct _ETHREAD* Thread; /* Thread owning the hook */ + int HookId; /* Hook table index */ + HOOKPROC Proc; /* Hook function */ + BOOLEAN Ansi; /* Is it an Ansi hook? */ + ULONG Flags; /* Some internal flags */ + UNICODE_STRING ModuleName; /* Module name for global hooks */ +} HOOK, *PHOOK; typedef struct _CALLBACKWND { @@ -324,6 +338,8 @@ typedef struct _CALLBACKWND PVOID pvWnd; } CALLBACKWND, *PCALLBACKWND; +#define CI_CURTHPRHOOK 0x00000010 + typedef struct _W32CLIENTINFO { ULONG CI_flags; @@ -334,7 +350,7 @@ typedef struct _W32CLIENTINFO DWORD dwTIFlags; PVOID pDeskInfo; ULONG_PTR ulClientDelta; - PVOID phkCurrent; + PHOOK phkCurrent; ULONG fsHooks; HWND hWND; // Will be replaced with CALLBACKWND. PVOID pvWND; // " " @@ -848,10 +864,10 @@ NtUserCallMsgFilter( LRESULT NTAPI NtUserCallNextHookEx( - HHOOK Hook, int Code, WPARAM wParam, - LPARAM lParam); + LPARAM lParam, + BOOL Ansi); DWORD NTAPI diff --git a/reactos/subsystems/win32/win32k/include/hook.h b/reactos/subsystems/win32/win32k/include/hook.h index 2eb0aca6cf9..65b0e679df7 100644 --- a/reactos/subsystems/win32/win32k/include/hook.h +++ b/reactos/subsystems/win32/win32k/include/hook.h @@ -2,7 +2,7 @@ #define _WIN32K_HOOK_H #define HOOK_THREAD_REFERENCED (0x1) - +#if 0 typedef struct tagHOOK { LIST_ENTRY Chain; /* Hook chain entry */ @@ -14,8 +14,11 @@ typedef struct tagHOOK ULONG Flags; /* Some internal flags */ UNICODE_STRING ModuleName; /* Module name for global hooks */ } HOOK, *PHOOK; - +#endif #define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1) +#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK) +#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1)) +#define ISITHOOKED(HookId) (PsGetCurrentThreadWin32Thread()->Hooks & HOOKID_TO_FLAG(HookId)) typedef struct tagHOOKTABLE { @@ -46,6 +49,7 @@ LRESULT FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM l LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, LONG, LONG); VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread); PHOOK FASTCALL IntGetHookObject(HHOOK); +LRESULT FASTCALL UserCallNextHookEx( int HookId, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi); #endif /* _WIN32K_HOOK_H */ diff --git a/reactos/subsystems/win32/win32k/include/window.h b/reactos/subsystems/win32/win32k/include/window.h index 97594c8cb80..3358d31c48f 100644 --- a/reactos/subsystems/win32/win32k/include/window.h +++ b/reactos/subsystems/win32/win32k/include/window.h @@ -165,7 +165,7 @@ BOOL FASTCALL IntShowOwnedPopups( PWINDOW_OBJECT owner, BOOL fShow ); LRESULT FASTCALL -IntDefWindowProc( PWINDOW_OBJECT Window, UINT Msg, WPARAM wParam, LPARAM lParam); +IntDefWindowProc( PWINDOW_OBJECT Window, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi); #endif /* _WIN32K_WINDOW_H */ diff --git a/reactos/subsystems/win32/win32k/ntuser/callback.c b/reactos/subsystems/win32/win32k/ntuser/callback.c index 335d909075a..b57fffd3283 100644 --- a/reactos/subsystems/win32/win32k/ntuser/callback.c +++ b/reactos/subsystems/win32/win32k/ntuser/callback.c @@ -379,6 +379,13 @@ co_IntCallHookProc(INT HookId, case WH_MOUSE_LL: ArgumentLength += sizeof(MSLLHOOKSTRUCT); break; + case WH_MSGFILTER: + case WH_SYSMSGFILTER: + case WH_GETMESSAGE: + ArgumentLength += sizeof(MSG); + break; +// case WH_SHELL: +// break; default: DPRINT1("Trying to call unsupported window hook %d\n", HookId); return 0; @@ -437,6 +444,16 @@ co_IntCallHookProc(INT HookId, RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSLLHOOKSTRUCT)); Common->lParam = (LPARAM) (Extra - (PCHAR) Common); break; + case WH_MSGFILTER: + case WH_SYSMSGFILTER: + case WH_GETMESSAGE: + RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSG)); + Common->lParam = (LPARAM) (Extra - (PCHAR) Common); + DPRINT1("KHOOK Memory: %x\n",Common); + break; +// case WH_SHELL: +// Extra = lParam; +// break; } ResultPointer = NULL; diff --git a/reactos/subsystems/win32/win32k/ntuser/defwnd.c b/reactos/subsystems/win32/win32k/ntuser/defwnd.c index d23f1288552..d59d9106212 100644 --- a/reactos/subsystems/win32/win32k/ntuser/defwnd.c +++ b/reactos/subsystems/win32/win32k/ntuser/defwnd.c @@ -4,8 +4,7 @@ * PURPOSE: Misc User funcs * FILE: subsystem/win32/win32k/ntuser/defwnd.c * PROGRAMER: - * REVISION HISTORY: - * 2003/05/22 Created + * */ #include @@ -22,7 +21,8 @@ IntDefWindowProc( PWINDOW_OBJECT Window, UINT Msg, WPARAM wParam, - LPARAM lParam) + LPARAM lParam, + BOOL Ansi) { PWINDOW Wnd; diff --git a/reactos/subsystems/win32/win32k/ntuser/hook.c b/reactos/subsystems/win32/win32k/ntuser/hook.c index 06d2fbce24f..bc890d79c32 100644 --- a/reactos/subsystems/win32/win32k/ntuser/hook.c +++ b/reactos/subsystems/win32/win32k/ntuser/hook.c @@ -15,9 +15,6 @@ #define NDEBUG #include -#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK) -#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1)) - static PHOOKTABLE GlobalHooks; @@ -107,11 +104,14 @@ IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinSt Hook->Thread = Thread; Hook->HookId = HookId; - W32Thread = ((PW32THREAD)Thread->Tcb.Win32Thread); - ASSERT(W32Thread != NULL); - W32Thread->Hooks |= HOOKID_TO_FLAG(HookId); - if (W32Thread->ThreadInfo != NULL) - W32Thread->ThreadInfo->Hooks = W32Thread->Hooks; + if (Thread) + { + W32Thread = ((PW32THREAD)Thread->Tcb.Win32Thread); + ASSERT(W32Thread != NULL); + W32Thread->Hooks |= HOOKID_TO_FLAG(HookId); + if (W32Thread->ThreadInfo != NULL) + W32Thread->ThreadInfo->Hooks = W32Thread->Hooks; + } RtlInitUnicodeString(&Hook->ModuleName, NULL); @@ -318,7 +318,7 @@ co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam) return IntCallLowLevelHook(HookId, Code, wParam, lParam, Hook); } - if (Hook->Thread != PsGetCurrentThread()) + if ((Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL)) { DPRINT1("Calling hooks in other threads not implemented yet"); return 0; @@ -394,22 +394,350 @@ HOOK_DestroyThreadHooks(PETHREAD Thread) break; } } - - ObDereferenceObject(WinStaObj); } } +LRESULT +FASTCALL +IntCallDebugHook( + int Code, + WPARAM wParam, + LPARAM lParam) +{ + UNIMPLEMENTED + return 0; +} + +LRESULT +FASTCALL +UserCallNextHookEx( + int HookId, + int Code, + WPARAM wParam, + LPARAM lParam, + BOOL Ansi) +{ + LRESULT lResult = 0; + BOOL BadChk = FALSE; + +// Handle this one first. + if ((HookId == WH_MOUSE) || (HookId == WH_CBT && Code == HCBT_CLICKSKIPPED)) + { + MOUSEHOOKSTRUCTEX Mouse; + if (lParam) + { + _SEH_TRY + { + ProbeForRead((PVOID)lParam, + sizeof(MOUSEHOOKSTRUCTEX), + 1); + RtlCopyMemory( &Mouse, + (PVOID)lParam, + sizeof(MOUSEHOOKSTRUCTEX)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK WH_MOUSE read from lParam ERROR!\n"); + } + } + if (!BadChk) + { + lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Mouse); + } + return lResult; + } + + switch(HookId) + { + case WH_MOUSE_LL: + { + MSLLHOOKSTRUCT Mouse; + if (lParam) + { + _SEH_TRY + { + ProbeForRead((PVOID)lParam, + sizeof(MSLLHOOKSTRUCT), + 1); + RtlCopyMemory( &Mouse, + (PVOID)lParam, + sizeof(MSLLHOOKSTRUCT)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK WH_MOUSE_LL read from lParam ERROR!\n"); + } + } + if (!BadChk) + { + lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Mouse); + } + break; + } + + case WH_KEYBOARD_LL: + { + KBDLLHOOKSTRUCT Keyboard; + if (lParam) + { + _SEH_TRY + { + ProbeForRead((PVOID)lParam, + sizeof(KBDLLHOOKSTRUCT), + 1); + RtlCopyMemory( &Keyboard, + (PVOID)lParam, + sizeof(KBDLLHOOKSTRUCT)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK WH_KEYBORD_LL read from lParam ERROR!\n"); + } + } + if (!BadChk) + { + lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Keyboard); + } + break; + } + + + case WH_MSGFILTER: + case WH_SYSMSGFILTER: + case WH_GETMESSAGE: + { + MSG Msg; + if (lParam) + { + _SEH_TRY + { + ProbeForRead((PVOID)lParam, + sizeof(MSG), + 1); + RtlCopyMemory( &Msg, + (PVOID)lParam, + sizeof(MSG)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK WH_XMESSAGEX read from lParam ERROR!\n"); + } + } + if (!BadChk) + { + lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Msg); + if (lParam && (HookId == WH_GETMESSAGE)) + { + _SEH_TRY + { + ProbeForWrite((PVOID)lParam, + sizeof(MSG), + 1); + RtlCopyMemory((PVOID)lParam, + &Msg, + sizeof(MSG)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK WH_GETMESSAGE write to lParam ERROR!\n"); + } + } + } + break; + } + + case WH_CBT: + switch (Code) + { + case HCBT_CREATEWND: + lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); + break; + + case HCBT_MOVESIZE: + { + RECT rt; + + if (lParam) + { + _SEH_TRY + { + ProbeForRead((PVOID)lParam, + sizeof(RECT), + 1); + RtlCopyMemory( &rt, + (PVOID)lParam, + sizeof(RECT)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK HCBT_MOVESIZE read from lParam ERROR!\n"); + } + } + if (!BadChk) + { + lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&rt); + } + break; + } + + case HCBT_ACTIVATE: + { + CBTACTIVATESTRUCT CbAs; + + if (lParam) + { + _SEH_TRY + { + ProbeForRead((PVOID)lParam, + sizeof(CBTACTIVATESTRUCT), + 1); + RtlCopyMemory( &CbAs, + (PVOID)lParam, + sizeof(CBTACTIVATESTRUCT)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK HCBT_ACTIVATE read from lParam ERROR!\n"); + } + } + if (!BadChk) + { + lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&CbAs); + } + break; + } + /* + The rest just use default. + */ + default: + lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); + break; + } + break; + + + case WH_JOURNALPLAYBACK: + case WH_JOURNALRECORD: + { + EVENTMSG EventMsg; + if (lParam) + { + _SEH_TRY + { + ProbeForRead((PVOID)lParam, + sizeof(EVENTMSG), + 1); + RtlCopyMemory( &EventMsg, + (PVOID)lParam, + sizeof(EVENTMSG)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK WH_JOURNAL read from lParam ERROR!\n"); + } + } + if (!BadChk) + { + lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)(lParam ? &EventMsg : NULL)); + if (lParam) + { + _SEH_TRY + { + ProbeForWrite((PVOID)lParam, + sizeof(EVENTMSG), + 1); + RtlCopyMemory((PVOID)lParam, + &EventMsg, + sizeof(EVENTMSG)); + } + _SEH_HANDLE + { + BadChk = TRUE; + } + _SEH_END; + if (BadChk) + { + DPRINT1("HOOK WH_JOURNAL write to lParam ERROR!\n"); + } + } + } + break; + } + + case WH_DEBUG: + lResult = IntCallDebugHook( Code, wParam, lParam); + break; +/* + Default the rest like, WH_FOREGROUNDIDLE, WH_KEYBOARD and WH_SHELL. + */ + case WH_FOREGROUNDIDLE: + case WH_KEYBOARD: + case WH_SHELL: + lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); + break; + + default: + DPRINT1("Unsupported HOOK Id -> %d\n",HookId); + break; + } + return lResult; +} + LRESULT STDCALL NtUserCallNextHookEx( - HHOOK Hook, int Code, WPARAM wParam, - LPARAM lParam) + LPARAM lParam, + BOOL Ansi) { + HHOOK Hook; PHOOK HookObj, NextObj; + PW32CLIENTINFO ClientInfo; PWINSTATION_OBJECT WinStaObj; NTSTATUS Status; + LRESULT lResult; + INT HookId; DECLARE_RETURN(LRESULT); DPRINT("Enter NtUserCallNextHookEx\n"); @@ -420,22 +748,17 @@ NtUserCallNextHookEx( 0, &WinStaObj); - if (! NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { SetLastNtError(Status); - RETURN( FALSE); + RETURN( 0); } - //Status = UserReferenceObjectByHandle(gHandleTable, Hook, - // otHookProc, (PVOID *) &HookObj); ObDereferenceObject(WinStaObj); - // if (! NT_SUCCESS(Status)) - // { - // DPRINT1("Invalid handle passed to NtUserCallNextHookEx\n"); - // SetLastNtError(Status); - // RETURN( 0); - // } + ClientInfo = GetWin32ClientInfo(); + + Hook = (HHOOK)ClientInfo->phkCurrent; if (!(HookObj = IntGetHookObject(Hook))) { @@ -444,6 +767,9 @@ NtUserCallNextHookEx( ASSERT(Hook == HookObj->Self); + HookId = HookObj->HookId; + Ansi = HookObj->Ansi; + if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread())) { DPRINT1("Thread mismatch\n"); @@ -451,15 +777,15 @@ NtUserCallNextHookEx( SetLastWin32Error(ERROR_INVALID_HANDLE); RETURN( 0); } - + NextObj = IntGetNextHook(HookObj); UserDereferenceObject(HookObj); if (NULL != NextObj) { - DPRINT1("Calling next hook not implemented\n"); - UNIMPLEMENTED - SetLastWin32Error(ERROR_NOT_SUPPORTED); - RETURN( 0); + lResult = UserCallNextHookEx( HookId, Code, wParam, lParam, Ansi); + + if (lResult == 0) RETURN( 0); + RETURN( (LRESULT)NextObj); } RETURN( 0); @@ -570,7 +896,7 @@ NtUserSetWindowsHookEx( /* We only (partially) support local WH_CBT hooks and * WH_KEYBOARD_LL/WH_MOUSE_LL hooks for now */ if ((WH_CBT != HookId || Global) - && WH_KEYBOARD_LL != HookId && WH_MOUSE_LL != HookId) // && WH_GETMESSAGE != HookId) + && WH_KEYBOARD_LL != HookId && WH_MOUSE_LL != HookId && WH_GETMESSAGE != 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 3a6a8fd0461..deefa47cc28 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -694,7 +694,7 @@ CheckMessages: { ThreadQueue->QuitPosted = FALSE; } - return TRUE; + goto MsgExit; } /* Now check for normal messages. */ @@ -741,7 +741,7 @@ CheckMessages: if (IntGetPaintMessage(hWnd, MsgFilterMin, MsgFilterMax, PsGetCurrentThreadWin32Thread(), &Msg->Msg, RemoveMessages)) { Msg->FreeLParam = FALSE; - return TRUE; + goto MsgExit; } /* Check for WM_(SYS)TIMER messages */ @@ -802,7 +802,7 @@ MessageFound: // UserDereferenceObject(MsgWindow); // } - return TRUE; + goto MsgExit; } if((Msg->Msg.hwnd && Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST) && @@ -813,7 +813,14 @@ MessageFound: /* eat the message, search again */ goto CheckMessages; } - +MsgExit: + // The WH_GETMESSAGE hook enables an application to monitor messages about to + // be returned by the GetMessage or PeekMessage function. + if(ISITHOOKED(WH_GETMESSAGE)) + { + DPRINT1("Peek WH_GETMESSAGE -> %x\n",&Msg); + co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg); + } return TRUE; } @@ -856,12 +863,10 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo, } Present = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg); - // The WH_GETMESSAGE hook enables an application to monitor messages about to - // be returned by the GetMessage or PeekMessage function. - co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg); if (Present) { + Info.Msg = Msg.Msg; /* See if this message type is present in the table */ MsgMemoryEntry = FindMsgMemory(Info.Msg.message); @@ -1862,7 +1867,7 @@ NtUserMessageCall( switch(dwType) { case FNID_DEFWINDOWPROC: - lResult = IntDefWindowProc(Window, Msg, wParam, lParam); + lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi); break; } UserDerefObjectCo(Window);