diff --git a/reactos/subsystems/win32/win32k/include/hook.h b/reactos/subsystems/win32/win32k/include/hook.h index 65b0e679df7..221372b615b 100644 --- a/reactos/subsystems/win32/win32k/include/hook.h +++ b/reactos/subsystems/win32/win32k/include/hook.h @@ -49,7 +49,8 @@ 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); +PHOOK FASTCALL IntGetNextHook(PHOOK Hook); +LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi); #endif /* _WIN32K_HOOK_H */ diff --git a/reactos/subsystems/win32/win32k/ntuser/defwnd.c b/reactos/subsystems/win32/win32k/ntuser/defwnd.c index 5344fc94c90..7ca86ff9cc4 100644 --- a/reactos/subsystems/win32/win32k/ntuser/defwnd.c +++ b/reactos/subsystems/win32/win32k/ntuser/defwnd.c @@ -19,14 +19,14 @@ IntDefWinHandleSysCommand( PWINDOW_OBJECT Window, WPARAM wParam, LPARAM lParam , if (!ISITHOOKED(WH_CBT)) return 0; - if (!UserCallNextHookEx(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam, Ansi)) +// if (!UserCallNextHookEx(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam, Ansi)) return 0; switch (wParam & 0xfff0) { case SC_MOVE: case SC_SIZE: - return UserCallNextHookEx(WH_CBT, HCBT_MOVESIZE, (WPARAM)Window->hSelf, lParam, Ansi); + // return UserCallNextHookEx(WH_CBT, HCBT_MOVESIZE, (WPARAM)Window->hSelf, lParam, Ansi); break; } return 1; diff --git a/reactos/subsystems/win32/win32k/ntuser/hook.c b/reactos/subsystems/win32/win32k/ntuser/hook.c index a667ba56014..16e464055ad 100644 --- a/reactos/subsystems/win32/win32k/ntuser/hook.c +++ b/reactos/subsystems/win32/win32k/ntuser/hook.c @@ -161,7 +161,8 @@ IntGetFirstValidHook(PHOOKTABLE Table, int HookId) } /* find the next hook in the chain, skipping the deleted ones */ -static PHOOK FASTCALL +PHOOK +FASTCALL IntGetNextHook(PHOOK Hook) { PHOOKTABLE Table = IntGetTable(Hook); @@ -279,11 +280,16 @@ IntCallLowLevelHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam, PHOOK Ho return NT_SUCCESS(Status) ? uResult : 0; } -LRESULT FASTCALL +/* + Called from inside kernel space. + */ +LRESULT +FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam) { - PHOOK Hook; + PHOOK Hook, SaveHook; PW32THREAD Win32Thread; + PW32CLIENTINFO ClientInfo; PHOOKTABLE Table; LRESULT Result; PWINSTATION_OBJECT WinStaObj; @@ -330,9 +336,15 @@ co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam) GlobalHooks->Counts[HOOKID_TO_INDEX(HookId)]++; } + ClientInfo = GetWin32ClientInfo(); + SaveHook = ClientInfo->phkCurrent; + ClientInfo->phkCurrent = Hook; // Load the call. + Result = co_IntCallHookProc(HookId, Code, wParam, lParam, Hook->Proc, Hook->Ansi, &Hook->ModuleName); + ClientInfo->phkCurrent = SaveHook; + Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, KernelMode, 0, @@ -397,9 +409,19 @@ HOOK_DestroyThreadHooks(PETHREAD Thread) } } +static LRESULT +FASTCALL +co_HOOK_CallHookNext(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam) +{ + return co_IntCallHookProc(Hook->HookId, Code, wParam, lParam, Hook->Proc, + Hook->Ansi, &Hook->ModuleName); +} + + LRESULT FASTCALL IntCallDebugHook( + PHOOK Hook, int Code, WPARAM wParam, LPARAM lParam) @@ -514,15 +536,18 @@ IntCallDebugHook( } if (HooklParam) Debug.lParam = (LPARAM)HooklParam; - lResult = co_HOOK_CallHooks(WH_DEBUG, Code, wParam, (LPARAM)&Debug); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Debug); if (HooklParam) ExFreePool(HooklParam); return lResult; } +/* + Called from user space via CallNextHook. + */ LRESULT FASTCALL UserCallNextHookEx( - int HookId, + PHOOK Hook, int Code, WPARAM wParam, LPARAM lParam, @@ -532,7 +557,8 @@ UserCallNextHookEx( BOOL BadChk = FALSE; // Handle this one first. - if ((HookId == WH_MOUSE) || (HookId == WH_CBT && Code == HCBT_CLICKSKIPPED)) + if ((Hook->HookId == WH_MOUSE) || + (Hook->HookId == WH_CBT && Code == HCBT_CLICKSKIPPED)) { MOUSEHOOKSTRUCTEX Mouse; if (lParam) @@ -558,12 +584,12 @@ UserCallNextHookEx( } if (!BadChk) { - lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Mouse); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Mouse); } return lResult; } - switch(HookId) + switch(Hook->HookId) { case WH_MOUSE_LL: { @@ -591,7 +617,7 @@ UserCallNextHookEx( } if (!BadChk) { - lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Mouse); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Mouse); } break; } @@ -622,7 +648,7 @@ UserCallNextHookEx( } if (!BadChk) { - lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Keyboard); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Keyboard); } break; } @@ -655,8 +681,8 @@ UserCallNextHookEx( } if (!BadChk) { - lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Msg); - if (lParam && (HookId == WH_GETMESSAGE)) + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Msg); + if (lParam && (Hook->HookId == WH_GETMESSAGE)) { _SEH_TRY { @@ -685,7 +711,7 @@ UserCallNextHookEx( switch (Code) { case HCBT_CREATEWND: // Use Ansi. - lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam); break; case HCBT_MOVESIZE: @@ -715,7 +741,7 @@ UserCallNextHookEx( } if (!BadChk) { - lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&rt); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&rt); } break; } @@ -747,7 +773,7 @@ UserCallNextHookEx( } if (!BadChk) { - lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&CbAs); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&CbAs); } break; } @@ -755,7 +781,7 @@ UserCallNextHookEx( The rest just use default. */ default: - lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam); break; } break; @@ -787,7 +813,7 @@ UserCallNextHookEx( } if (!BadChk) { - lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)(lParam ? &EventMsg : NULL)); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)(lParam ? &EventMsg : NULL)); if (lParam) { _SEH_TRY @@ -814,7 +840,7 @@ UserCallNextHookEx( } case WH_DEBUG: - lResult = IntCallDebugHook( Code, wParam, lParam); + lResult = IntCallDebugHook(Hook, Code, wParam, lParam); break; /* Default the rest like, WH_FOREGROUNDIDLE, WH_KEYBOARD and WH_SHELL. @@ -822,11 +848,11 @@ UserCallNextHookEx( case WH_FOREGROUNDIDLE: case WH_KEYBOARD: case WH_SHELL: - lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); + lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam); break; default: - DPRINT1("Unsupported HOOK Id -> %d\n",HookId); + DPRINT1("Unsupported HOOK Id -> %d\n",Hook->HookId); break; } return lResult; @@ -844,8 +870,6 @@ NtUserCallNextHookEx( PW32CLIENTINFO ClientInfo; PWINSTATION_OBJECT WinStaObj; NTSTATUS Status; - LRESULT lResult; - INT HookId; DECLARE_RETURN(LRESULT); DPRINT("Enter NtUserCallNextHookEx\n"); @@ -855,7 +879,6 @@ NtUserCallNextHookEx( KernelMode, 0, &WinStaObj); - if (!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -866,9 +889,14 @@ NtUserCallNextHookEx( ClientInfo = GetWin32ClientInfo(); - HookObj = ClientInfo->phkCurrent; // Use this one set from SetWindowHook. + if (!ClientInfo) RETURN( 0); + + HookObj = ClientInfo->phkCurrent; + + if (!HookObj) RETURN( 0); + + UserReferenceObject(HookObj); - HookId = HookObj->HookId; Ansi = HookObj->Ansi; if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread())) @@ -880,19 +908,11 @@ NtUserCallNextHookEx( } NextObj = IntGetNextHook(HookObj); + ClientInfo->phkCurrent = NextObj; // Preset next hook from list. + UserCallNextHookEx( HookObj, Code, wParam, lParam, Ansi); UserDereferenceObject(HookObj); - if (NULL != NextObj) - { - lResult = UserCallNextHookEx( HookId, Code, wParam, lParam, Ansi); - ClientInfo->phkCurrent = NextObj; - - if (lResult == 0) RETURN( 0); - RETURN( (LRESULT)NextObj); - } - ClientInfo->phkCurrent = NextObj; - - RETURN( 0); + RETURN( (LRESULT)NextObj); CLEANUP: DPRINT("Leave NtUserCallNextHookEx, ret=%i\n",_ret_); @@ -1109,8 +1129,8 @@ NtUserSetWindowsHookEx( Hook->Ansi = Ansi; Handle = Hook->Self; -// Set the client threads next hook based on the hooks type. - ClientInfo->phkCurrent = IntGetNextHook( Hook); +// Clear the client threads next hook. + ClientInfo->phkCurrent = 0; UserDereferenceObject(Hook); ObDereferenceObject(WinStaObj); diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index 79a7402276a..43126c3dc00 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -2087,33 +2087,62 @@ NtUserMessageCall( break; case FNID_SENDMESSAGECALLBACK: break; + // CallNextHook bypass. case FNID_CALLWNDPROC: - { - CWPSTRUCT CWP; - PW32CLIENTINFO ClientInfo = GetWin32ClientInfo(); - CWP.hwnd = hWnd; - CWP.message = Msg; - CWP.wParam = wParam; - CWP.lParam = lParam; - lResult = co_HOOK_CallHooks( WH_CALLWNDPROC, - HC_ACTION, - ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0), - (LPARAM)&CWP ); - } - break; case FNID_CALLWNDPROCRET: { - CWPRETSTRUCT CWPR; PW32CLIENTINFO ClientInfo = GetWin32ClientInfo(); - CWPR.hwnd = hWnd; - CWPR.message = Msg; - CWPR.wParam = wParam; - CWPR.lParam = lParam; - CWPR.lResult = ClientInfo->dwHookData; - lResult = co_HOOK_CallHooks( WH_CALLWNDPROCRET, - HC_ACTION, - ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0), - (LPARAM)&CWPR ); + PHOOK NextObj, Hook = ClientInfo->phkCurrent; + + if (!ClientInfo || !Hook) break; + + UserReferenceObject(Hook); + + if (Hook->Thread && (Hook->Thread != PsGetCurrentThread())) + { + UserDereferenceObject(Hook); + break; + } + + NextObj = IntGetNextHook(Hook); + ClientInfo->phkCurrent = NextObj; + + if ( Hook->HookId == WH_CALLWNDPROC) + { + CWPSTRUCT CWP; + CWP.hwnd = hWnd; + CWP.message = Msg; + CWP.wParam = wParam; + CWP.lParam = lParam; + DPRINT1("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj ); + + lResult = co_IntCallHookProc( Hook->HookId, + HC_ACTION, + ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0), + (LPARAM)&CWP, + Hook->Proc, + Hook->Ansi, + &Hook->ModuleName); + } + else + { + CWPRETSTRUCT CWPR; + CWPR.hwnd = hWnd; + CWPR.message = Msg; + CWPR.wParam = wParam; + CWPR.lParam = lParam; + CWPR.lResult = ClientInfo->dwHookData; + + lResult = co_IntCallHookProc( Hook->HookId, + HC_ACTION, + ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0), + (LPARAM)&CWPR, + Hook->Proc, + Hook->Ansi, + &Hook->ModuleName); + } + UserDereferenceObject(Hook); + lResult = (LRESULT) NextObj; } break; }