mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:42:57 +00:00
[WIN32SS/USER]
- Handle transferring buffer to user mode in WH_CALLWNDPROC(RET) hooks if lParam is a pointer. This fixes the gallium3d opengl ICD, so newest VMWare opengl Driver should now work. Please TEST! svn path=/trunk/; revision=56931
This commit is contained in:
parent
5cc65e64c7
commit
4be2c40f92
4 changed files with 77 additions and 23 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include <win32k.h>
|
#include <win32k.h>
|
||||||
DBG_DEFAULT_CHANNEL(UserCallback);
|
DBG_DEFAULT_CHANNEL(UserCallback);
|
||||||
|
|
||||||
|
|
||||||
/* CALLBACK MEMORY MANAGEMENT ************************************************/
|
/* CALLBACK MEMORY MANAGEMENT ************************************************/
|
||||||
|
|
||||||
typedef struct _INT_CALLBACK_HEADER
|
typedef struct _INT_CALLBACK_HEADER
|
||||||
|
@ -115,8 +116,8 @@ IntRestoreTebWndCallback (HWND hWnd, PWND pWnd, PVOID pActCtx)
|
||||||
|
|
||||||
/* Calls ClientLoadLibrary in user32 */
|
/* Calls ClientLoadLibrary in user32 */
|
||||||
HMODULE
|
HMODULE
|
||||||
co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName,
|
co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName,
|
||||||
PUNICODE_STRING pstrInitFunc,
|
PUNICODE_STRING pstrInitFunc,
|
||||||
BOOL Unload,
|
BOOL Unload,
|
||||||
BOOL ApiHook)
|
BOOL ApiHook)
|
||||||
{
|
{
|
||||||
|
@ -139,7 +140,7 @@ co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName,
|
||||||
}
|
}
|
||||||
if(pstrInitFunc)
|
if(pstrInitFunc)
|
||||||
{
|
{
|
||||||
pInitFuncBuffer = ArgumentLength;
|
pInitFuncBuffer = ArgumentLength;
|
||||||
ArgumentLength += pstrInitFunc->Length + sizeof(WCHAR);
|
ArgumentLength += pstrInitFunc->Length + sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,6 +444,7 @@ co_IntCallHookProc(INT HookId,
|
||||||
PWND pWnd;
|
PWND pWnd;
|
||||||
PMSG pMsg = NULL;
|
PMSG pMsg = NULL;
|
||||||
BOOL Hit = FALSE;
|
BOOL Hit = FALSE;
|
||||||
|
UINT lParamSize = 0;
|
||||||
|
|
||||||
ASSERT(Proc);
|
ASSERT(Proc);
|
||||||
|
|
||||||
|
@ -509,11 +511,21 @@ co_IntCallHookProc(INT HookId,
|
||||||
ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
|
ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROC:
|
case WH_CALLWNDPROC:
|
||||||
|
{
|
||||||
|
CWPSTRUCT* pCWP = (CWPSTRUCT*) lParam;
|
||||||
ArgumentLength += sizeof(CWPSTRUCT);
|
ArgumentLength += sizeof(CWPSTRUCT);
|
||||||
|
lParamSize = lParamMemorySize(pCWP->message, pCWP->wParam, pCWP->lParam);
|
||||||
|
ArgumentLength += lParamSize;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case WH_CALLWNDPROCRET:
|
case WH_CALLWNDPROCRET:
|
||||||
|
{
|
||||||
|
CWPRETSTRUCT* pCWPR = (CWPRETSTRUCT*) lParam;
|
||||||
ArgumentLength += sizeof(CWPRETSTRUCT);
|
ArgumentLength += sizeof(CWPRETSTRUCT);
|
||||||
|
lParamSize = lParamMemorySize(pCWPR->message, pCWPR->wParam, pCWPR->lParam);
|
||||||
|
ArgumentLength += lParamSize;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case WH_MSGFILTER:
|
case WH_MSGFILTER:
|
||||||
case WH_SYSMSGFILTER:
|
case WH_SYSMSGFILTER:
|
||||||
case WH_GETMESSAGE:
|
case WH_GETMESSAGE:
|
||||||
|
@ -583,12 +595,25 @@ co_IntCallHookProc(INT HookId,
|
||||||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROC:
|
case WH_CALLWNDPROC:
|
||||||
|
/* 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));
|
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPSTRUCT));
|
||||||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
||||||
|
if(lParamSize)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(Extra + sizeof(CWPSTRUCT), (PVOID)((CWPSTRUCT*)lParam)->lParam, lParamSize);
|
||||||
|
((CWPSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROCRET:
|
case WH_CALLWNDPROCRET:
|
||||||
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPRETSTRUCT));
|
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPRETSTRUCT));
|
||||||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
||||||
|
if(lParamSize)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(Extra + sizeof(CWPRETSTRUCT), (PVOID)((CWPRETSTRUCT*)lParam)->lParam, lParamSize);
|
||||||
|
((CWPRETSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WH_MSGFILTER:
|
case WH_MSGFILTER:
|
||||||
case WH_SYSMSGFILTER:
|
case WH_SYSMSGFILTER:
|
||||||
|
|
|
@ -223,6 +223,13 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
|
||||||
return Size;
|
return Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT lParamMemorySize(UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
PMSGMEMORY MsgMemory = FindMsgMemory(Msg);
|
||||||
|
if(MsgMemory == NULL) return 0;
|
||||||
|
return MsgMemorySize(MsgMemory, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolNeeded)
|
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolNeeded)
|
||||||
{
|
{
|
||||||
|
@ -2143,7 +2150,7 @@ NtUserTranslateMessage(LPMSG lpMsg, UINT flags)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("No Window for Translate. hwnd 0x%p Msg %d\n",SafeMsg.hwnd,SafeMsg.message);
|
ERR("No Window for Translate. hwnd 0x%p Msg %d\n",SafeMsg.hwnd,SafeMsg.message);
|
||||||
Ret = FALSE;
|
Ret = FALSE;
|
||||||
}
|
}
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
|
|
@ -296,4 +296,6 @@ UserSetCursor(PCURICON_OBJECT NewCursor,
|
||||||
BOOL ForceChange);
|
BOOL ForceChange);
|
||||||
|
|
||||||
DWORD APIENTRY IntGetQueueStatus(DWORD);
|
DWORD APIENTRY IntGetQueueStatus(DWORD);
|
||||||
|
|
||||||
|
UINT lParamMemorySize(UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -216,7 +216,7 @@ CallNextHookEx(
|
||||||
ClientInfo = GetWin32ClientInfo();
|
ClientInfo = GetWin32ClientInfo();
|
||||||
|
|
||||||
if (!ClientInfo->phkCurrent) return 0;
|
if (!ClientInfo->phkCurrent) return 0;
|
||||||
|
|
||||||
pHook = DesktopPtrToUser(ClientInfo->phkCurrent);
|
pHook = DesktopPtrToUser(ClientInfo->phkCurrent);
|
||||||
|
|
||||||
if (!pHook->phkNext) return 0; // Nothing to do....
|
if (!pHook->phkNext) return 0; // Nothing to do....
|
||||||
|
@ -240,7 +240,7 @@ CallNextHookEx(
|
||||||
NtUserMessageCall( pCWP->hwnd,
|
NtUserMessageCall( pCWP->hwnd,
|
||||||
pCWP->message,
|
pCWP->message,
|
||||||
pCWP->wParam,
|
pCWP->wParam,
|
||||||
pCWP->lParam,
|
pCWP->lParam,
|
||||||
(ULONG_PTR)&lResult,
|
(ULONG_PTR)&lResult,
|
||||||
FNID_CALLWNDPROC,
|
FNID_CALLWNDPROC,
|
||||||
phkNext->Ansi);
|
phkNext->Ansi);
|
||||||
|
@ -254,7 +254,7 @@ CallNextHookEx(
|
||||||
NtUserMessageCall( pCWPR->hwnd,
|
NtUserMessageCall( pCWPR->hwnd,
|
||||||
pCWPR->message,
|
pCWPR->message,
|
||||||
pCWPR->wParam,
|
pCWPR->wParam,
|
||||||
pCWPR->lParam,
|
pCWPR->lParam,
|
||||||
(ULONG_PTR)&lResult,
|
(ULONG_PTR)&lResult,
|
||||||
FNID_CALLWNDPROCRET,
|
FNID_CALLWNDPROCRET,
|
||||||
phkNext->Ansi);
|
phkNext->Ansi);
|
||||||
|
@ -427,8 +427,8 @@ SetWindowsHookExW(
|
||||||
return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, FALSE);
|
return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
HINSTANCE ClientLoadLibrary(PUNICODE_STRING pstrLibName,
|
HINSTANCE ClientLoadLibrary(PUNICODE_STRING pstrLibName,
|
||||||
PUNICODE_STRING pstrInitFunc,
|
PUNICODE_STRING pstrInitFunc,
|
||||||
BOOL Unload,
|
BOOL Unload,
|
||||||
BOOL ApiHook)
|
BOOL ApiHook)
|
||||||
{
|
{
|
||||||
|
@ -440,7 +440,7 @@ HINSTANCE ClientLoadLibrary(PUNICODE_STRING pstrLibName,
|
||||||
|
|
||||||
TRACE("ClientLoadLibrary: pid: %d, strLibraryName: %S, "
|
TRACE("ClientLoadLibrary: pid: %d, strLibraryName: %S, "
|
||||||
"strInitFuncName: %S, Unload: %d, ApiHook:%d\n",
|
"strInitFuncName: %S, Unload: %d, ApiHook:%d\n",
|
||||||
GetCurrentProcessId(),
|
GetCurrentProcessId(),
|
||||||
pstrLibName->Buffer,
|
pstrLibName->Buffer,
|
||||||
pstrInitFunc->Buffer,
|
pstrInitFunc->Buffer,
|
||||||
Unload,
|
Unload,
|
||||||
|
@ -467,7 +467,7 @@ HINSTANCE ClientLoadLibrary(PUNICODE_STRING pstrLibName,
|
||||||
/* Initialize the user api hook */
|
/* Initialize the user api hook */
|
||||||
ASSERT(pstrInitFunc->Buffer);
|
ASSERT(pstrInitFunc->Buffer);
|
||||||
|
|
||||||
/*Status = */ RtlUnicodeStringToAnsiString(&InitFuncName,
|
/*Status = */ RtlUnicodeStringToAnsiString(&InitFuncName,
|
||||||
pstrInitFunc,
|
pstrInitFunc,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
|
@ -539,7 +539,7 @@ User32CallClientLoadLibraryFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the implementation of the callback */
|
/* Call the implementation of the callback */
|
||||||
Result = ClientLoadLibrary(&Argument->strLibraryName,
|
Result = ClientLoadLibrary(&Argument->strLibraryName,
|
||||||
&Argument->strInitFuncName,
|
&Argument->strInitFuncName,
|
||||||
Argument->Unload,
|
Argument->Unload,
|
||||||
Argument->ApiHook);
|
Argument->ApiHook);
|
||||||
|
@ -558,9 +558,9 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
MSLLHOOKSTRUCT MouseLlData, *pMouseLlData;
|
MSLLHOOKSTRUCT MouseLlData, *pMouseLlData;
|
||||||
MSG *pcMsg, *pMsg;
|
MSG *pcMsg, *pMsg;
|
||||||
PMOUSEHOOKSTRUCT pMHook;
|
PMOUSEHOOKSTRUCT pMHook;
|
||||||
CWPSTRUCT CWP, *pCWP;
|
CWPSTRUCT *pCWP;
|
||||||
CWPRETSTRUCT CWPR, *pCWPR;
|
CWPRETSTRUCT *pCWPR;
|
||||||
PRECTL prl;
|
PRECTL prl;
|
||||||
LPCBTACTIVATESTRUCT pcbtas;
|
LPCBTACTIVATESTRUCT pcbtas;
|
||||||
WPARAM wParam = 0;
|
WPARAM wParam = 0;
|
||||||
LPARAM lParam = 0;
|
LPARAM lParam = 0;
|
||||||
|
@ -631,7 +631,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
switch(Common->Code)
|
switch(Common->Code)
|
||||||
{
|
{
|
||||||
case HCBT_CREATEWND:
|
case HCBT_CREATEWND:
|
||||||
CbtCreatewndExtra->WndInsertAfter = CbtCreatewndw.hwndInsertAfter;
|
CbtCreatewndExtra->WndInsertAfter = CbtCreatewndw.hwndInsertAfter;
|
||||||
CbtCreatewndExtra->Cs.x = CbtCreatewndw.lpcs->x;
|
CbtCreatewndExtra->Cs.x = CbtCreatewndw.lpcs->x;
|
||||||
CbtCreatewndExtra->Cs.y = CbtCreatewndw.lpcs->y;
|
CbtCreatewndExtra->Cs.y = CbtCreatewndw.lpcs->y;
|
||||||
CbtCreatewndExtra->Cs.cx = CbtCreatewndw.lpcs->cx;
|
CbtCreatewndExtra->Cs.cx = CbtCreatewndw.lpcs->cx;
|
||||||
|
@ -666,14 +666,34 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROC:
|
case WH_CALLWNDPROC:
|
||||||
// ERR("WH_CALLWNDPROC: Code %d, wParam %d\n",Common->Code,Common->wParam);
|
// ERR("WH_CALLWNDPROC: Code %d, wParam %d\n",Common->Code,Common->wParam);
|
||||||
pCWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam);
|
pCWP = HeapAlloc(GetProcessHeap(), 0, ArgumentLength - sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
|
||||||
RtlCopyMemory(&CWP, pCWP, sizeof(CWPSTRUCT));
|
RtlCopyMemory(pCWP, (PCHAR) Common + Common->lParam, sizeof(CWPSTRUCT));
|
||||||
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWP);
|
/* 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)))
|
||||||
|
{
|
||||||
|
RtlCopyMemory((PCHAR)pCWP + sizeof(CWPSTRUCT),
|
||||||
|
(PCHAR)Common + Common->lParam + sizeof(CWPSTRUCT),
|
||||||
|
pCWP->lParam);
|
||||||
|
pCWP->lParam = (LPARAM)((PCHAR)pCWP + sizeof(CWPSTRUCT));
|
||||||
|
}
|
||||||
|
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
|
||||||
|
HeapFree(GetProcessHeap(), 0, pCWP);
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROCRET:
|
case WH_CALLWNDPROCRET:
|
||||||
pCWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam);
|
/* Almost the same as WH_CALLWNDPROC */
|
||||||
RtlCopyMemory(&CWPR, pCWPR, sizeof(CWPRETSTRUCT));
|
pCWPR = HeapAlloc(GetProcessHeap(), 0, ArgumentLength - sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
|
||||||
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWPR);
|
RtlCopyMemory(pCWPR, (PCHAR) Common + Common->lParam, sizeof(CWPRETSTRUCT));
|
||||||
|
if(ArgumentLength > (sizeof(CWPRETSTRUCT) + sizeof(HOOKPROC_CALLBACK_ARGUMENTS)))
|
||||||
|
{
|
||||||
|
RtlCopyMemory((PCHAR)pCWPR + sizeof(CWPRETSTRUCT),
|
||||||
|
(PCHAR)Common + Common->lParam + sizeof(CWPRETSTRUCT),
|
||||||
|
pCWPR->lParam);
|
||||||
|
pCWPR->lParam = (LPARAM)((PCHAR)pCWPR + sizeof(CWPRETSTRUCT));
|
||||||
|
}
|
||||||
|
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
|
||||||
|
HeapFree(GetProcessHeap(), 0, pCWPR);
|
||||||
break;
|
break;
|
||||||
case WH_MSGFILTER: /* All SEH support */
|
case WH_MSGFILTER: /* All SEH support */
|
||||||
case WH_SYSMSGFILTER:
|
case WH_SYSMSGFILTER:
|
||||||
|
@ -698,7 +718,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
case WH_KEYBOARD:
|
case WH_KEYBOARD:
|
||||||
case WH_SHELL:
|
case WH_SHELL:
|
||||||
Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
|
Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
|
||||||
break;
|
break;
|
||||||
case WH_FOREGROUNDIDLE: /* <-- SEH support */
|
case WH_FOREGROUNDIDLE: /* <-- SEH support */
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue