https://git.reactos.org/?p=reactos.git;a=commitdiff;h=915a5764a98be6f8a0347…
commit 915a5764a98be6f8a03471d68a55e4b1a5899f66
Author: jimtabor <james.tabor(a)reactos.org>
AuthorDate: Sat Mar 28 14:18:14 2020 -0500
Commit: jimtabor <james.tabor(a)reactos.org>
CommitDate: Sat Mar 28 14:18:14 2020 -0500
[Win32SS] Form Sanity to Hook Callbacks
Fix WH_CALLWNDPROC/RET data to user hook calls. See CORE-13019 and CORE-13907.
---
win32ss/include/callback.h | 15 ++++++++++
win32ss/user/ntuser/callback.c | 60 +++++++++++++++++++++++---------------
win32ss/user/user32/windows/hook.c | 30 ++++++++++---------
3 files changed, 69 insertions(+), 36 deletions(-)
diff --git a/win32ss/include/callback.h b/win32ss/include/callback.h
index 5b6f49ce3a2..7eef1d6c278 100644
--- a/win32ss/include/callback.h
+++ b/win32ss/include/callback.h
@@ -61,6 +61,7 @@ typedef struct _HOOKPROC_CALLBACK_ARGUMENTS
ULONG_PTR offPfn;
BOOLEAN Ansi;
LRESULT Result;
+ UINT lParamSize;
WCHAR ModuleName[512];
} HOOKPROC_CALLBACK_ARGUMENTS, *PHOOKPROC_CALLBACK_ARGUMENTS;
@@ -72,6 +73,20 @@ typedef struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
/* WCHAR szClass[] */
} HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS, *PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS;
+typedef struct tagCWP_Struct
+{
+ HOOKPROC_CALLBACK_ARGUMENTS hpca;
+ CWPSTRUCT cwps;
+ PBYTE Extra[4];
+} CWP_Struct, *PCWP_Struct;
+
+typedef struct tagCWPR_Struct
+{
+ HOOKPROC_CALLBACK_ARGUMENTS hpca;
+ CWPRETSTRUCT cwprs;
+ PBYTE Extra[4];
+} CWPR_Struct, *PCWPR_Struct;
+
typedef struct _EVENTPROC_CALLBACK_ARGUMENTS
{
HWINEVENTHOOK hook;
diff --git a/win32ss/user/ntuser/callback.c b/win32ss/user/ntuser/callback.c
index 42d50002d33..1497d72a892 100644
--- a/win32ss/user/ntuser/callback.c
+++ b/win32ss/user/ntuser/callback.c
@@ -509,6 +509,8 @@ co_IntLoadDefaultCursors(VOID)
return TRUE;
}
+static INT iTheId = -2; // Set it out of range.
+
LRESULT APIENTRY
co_IntCallHookProc(INT HookId,
INT Code,
@@ -535,6 +537,8 @@ co_IntCallHookProc(INT HookId,
PMSG pMsg = NULL;
BOOL Hit = FALSE;
UINT lParamSize = 0;
+ CWPSTRUCT* pCWP = NULL;
+ CWPRETSTRUCT* pCWPR = NULL;
ASSERT(Proc);
/* Do not allow the desktop thread to do callback to user mode */
@@ -593,27 +597,27 @@ co_IntCallHookProc(INT HookId,
goto Fault_Exit;
}
break;
- case WH_KEYBOARD_LL:
+ case WH_KEYBOARD_LL:
ArgumentLength += sizeof(KBDLLHOOKSTRUCT);
break;
- case WH_MOUSE_LL:
+ case WH_MOUSE_LL:
ArgumentLength += sizeof(MSLLHOOKSTRUCT);
break;
- case WH_MOUSE:
+ case WH_MOUSE:
ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
break;
case WH_CALLWNDPROC:
{
- CWPSTRUCT* pCWP = (CWPSTRUCT*) lParam;
- ArgumentLength += sizeof(CWPSTRUCT);
+ pCWP = (CWPSTRUCT*) lParam;
+ ArgumentLength = sizeof(CWP_Struct);
lParamSize = lParamMemorySize(pCWP->message, pCWP->wParam,
pCWP->lParam);
ArgumentLength += lParamSize;
break;
}
case WH_CALLWNDPROCRET:
{
- CWPRETSTRUCT* pCWPR = (CWPRETSTRUCT*) lParam;
- ArgumentLength += sizeof(CWPRETSTRUCT);
+ pCWPR = (CWPRETSTRUCT*) lParam;
+ ArgumentLength = sizeof(CWPR_Struct);
lParamSize = lParamMemorySize(pCWPR->message, pCWPR->wParam,
pCWPR->lParam);
ArgumentLength += lParamSize;
break;
@@ -647,6 +651,7 @@ co_IntCallHookProc(INT HookId,
Common->Mod = Mod;
Common->offPfn = offPfn;
Common->Ansi = Ansi;
+ Common->lParamSize = lParamSize;
RtlZeroMemory(&Common->ModuleName, sizeof(Common->ModuleName));
if (ModuleName->Buffer && ModuleName->Length)
{
@@ -697,25 +702,27 @@ co_IntCallHookProc(INT HookId,
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
break;
case WH_CALLWNDPROC:
+ {
+ PCWP_Struct pcwps = (PCWP_Struct)Common;
+ RtlCopyMemory( &pcwps->cwps, pCWP, sizeof(CWPSTRUCT));
/* For CALLWNDPROC and CALLWNDPROCRET, we must be wary of the fact that
* lParam could be a pointer to a buffer. This buffer must be exported
* to user space too */
- RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPSTRUCT));
- Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
- if(lParamSize)
+ if ( lParamSize )
{
- RtlCopyMemory(Extra + sizeof(CWPSTRUCT),
(PVOID)((CWPSTRUCT*)lParam)->lParam, lParamSize);
- ((CWPSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
+ RtlCopyMemory( &pcwps->Extra, (PVOID)pCWP->lParam, lParamSize );
}
+ }
break;
case WH_CALLWNDPROCRET:
- RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPRETSTRUCT));
- Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
- if(lParamSize)
+ {
+ PCWPR_Struct pcwprs = (PCWPR_Struct)Common;
+ RtlCopyMemory( &pcwprs->cwprs, pCWPR, sizeof(CWPRETSTRUCT));
+ if ( lParamSize )
{
- RtlCopyMemory(Extra + sizeof(CWPRETSTRUCT),
(PVOID)((CWPRETSTRUCT*)lParam)->lParam, lParamSize);
- ((CWPRETSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
+ RtlCopyMemory( &pcwprs->Extra, (PVOID)pCWPR->lParam, lParamSize
);
}
+ }
break;
case WH_MSGFILTER:
case WH_SYSMSGFILTER:
@@ -745,7 +752,11 @@ co_IntCallHookProc(INT HookId,
if (!NT_SUCCESS(Status))
{
- ERR("Failure to make Callback! Status 0x%x\n",Status);
+ if ( iTheId != HookId ) // Hook ID can change.
+ {
+ ERR("Failure to make Callback %d! Status 0x%x\n",HookId,Status);
+ iTheId = HookId;
+ }
goto Fault_Exit;
}
@@ -1216,12 +1227,13 @@ APIENTRY
co_UserCBClientPrinterThunk( PVOID pkt, INT InSize, PVOID pvOutData, INT OutSize )
{
NTSTATUS Status;
+ PVOID ResultPointer;
- Status = KeUserModeCallback(USER32_CALLBACK_UMPD,
- pkt,
- InSize,
- pvOutData,
- (PULONG)&OutSize);
+ Status = KeUserModeCallback( USER32_CALLBACK_UMPD,
+ pkt,
+ InSize,
+ &ResultPointer,
+ (PULONG)&OutSize );
if (!NT_SUCCESS(Status))
@@ -1230,6 +1242,8 @@ co_UserCBClientPrinterThunk( PVOID pkt, INT InSize, PVOID pvOutData,
INT OutSize
return 1;
}
+ if (OutSize) RtlMoveMemory( pvOutData, ResultPointer, OutSize );
+
return 0;
}
diff --git a/win32ss/user/user32/windows/hook.c b/win32ss/user/user32/windows/hook.c
index e0cb8e4a041..f525bf1cc5a 100644
--- a/win32ss/user/user32/windows/hook.c
+++ b/win32ss/user/user32/windows/hook.c
@@ -699,35 +699,39 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
_SEH2_END;
break;
case WH_CALLWNDPROC:
-// ERR("WH_CALLWNDPROC: Code %d, wParam
%d\n",Common->Code,Common->wParam);
- pCWP = HeapAlloc(GetProcessHeap(), 0, ArgumentLength -
sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
- RtlCopyMemory(pCWP, (PCHAR) Common + Common->lParam, sizeof(CWPSTRUCT));
+ {
+ PCWP_Struct pcwps = (PCWP_Struct)Common;
+ CWPSTRUCT *pCWPT = &pcwps->cwps;
+ pCWP = HeapAlloc(GetProcessHeap(), 0, Common->lParamSize + sizeof(CWPSTRUCT));
+ RtlCopyMemory(pCWP, pCWPT, sizeof(CWPSTRUCT));
+// ERR("WH_CALLWNDPROC: Code %d, wParam %d msg
%d\n",Common->Code,Common->wParam,pCWP->message);
/* If more memory is reserved, then lParam is a pointer.
* Size of the buffer is stocked in the lParam member, and its content
* is at the end of the argument buffer */
- if(ArgumentLength > (sizeof(CWPSTRUCT) + sizeof(HOOKPROC_CALLBACK_ARGUMENTS)))
+ if ( Common->lParamSize )
{
- RtlCopyMemory((PCHAR)pCWP + sizeof(CWPSTRUCT),
- (PCHAR)Common + Common->lParam + sizeof(CWPSTRUCT),
- pCWP->lParam);
pCWP->lParam = (LPARAM)((PCHAR)pCWP + sizeof(CWPSTRUCT));
+ RtlCopyMemory( (PCHAR)pCWP + sizeof(CWPSTRUCT), &pcwps->Extra,
Common->lParamSize );
}
Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
HeapFree(GetProcessHeap(), 0, pCWP);
+ }
break;
case WH_CALLWNDPROCRET:
/* Almost the same as WH_CALLWNDPROC */
- pCWPR = HeapAlloc(GetProcessHeap(), 0, ArgumentLength -
sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
- RtlCopyMemory(pCWPR, (PCHAR) Common + Common->lParam, sizeof(CWPRETSTRUCT));
- if(ArgumentLength > (sizeof(CWPRETSTRUCT) +
sizeof(HOOKPROC_CALLBACK_ARGUMENTS)))
+ {
+ PCWPR_Struct pcwprs = (PCWPR_Struct)Common;
+ CWPRETSTRUCT *pCWPRT = &pcwprs->cwprs;
+ pCWPR = HeapAlloc(GetProcessHeap(), 0, Common->lParamSize +
sizeof(CWPRETSTRUCT));
+ RtlCopyMemory(pCWPR, pCWPRT, sizeof(CWPSTRUCT));
+ if ( Common->lParamSize )
{
- RtlCopyMemory((PCHAR)pCWPR + sizeof(CWPRETSTRUCT),
- (PCHAR)Common + Common->lParam + sizeof(CWPRETSTRUCT),
- pCWPR->lParam);
pCWPR->lParam = (LPARAM)((PCHAR)pCWPR + sizeof(CWPRETSTRUCT));
+ RtlCopyMemory( (PCHAR)pCWPR + sizeof(CWPRETSTRUCT), &pcwprs->Extra,
Common->lParamSize );
}
Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
HeapFree(GetProcessHeap(), 0, pCWPR);
+ }
break;
case WH_MSGFILTER: /* All SEH support */
case WH_SYSMSGFILTER: