Author: jgardou
Date: Sat Jul 21 22:59:41 2012
New Revision: 56931
URL:
http://svn.reactos.org/svn/reactos?rev=56931&view=rev
Log:
[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!
Modified:
trunk/reactos/win32ss/user/ntuser/callback.c
trunk/reactos/win32ss/user/ntuser/message.c
trunk/reactos/win32ss/user/ntuser/msgqueue.h
trunk/reactos/win32ss/user/user32/windows/hook.c
Modified: trunk/reactos/win32ss/user/ntuser/callback.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/callba…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/callback.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/callback.c [iso-8859-1] Sat Jul 21 22:59:41 2012
@@ -13,6 +13,7 @@
#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserCallback);
+
/* CALLBACK MEMORY MANAGEMENT ************************************************/
typedef struct _INT_CALLBACK_HEADER
@@ -115,8 +116,8 @@
/* Calls ClientLoadLibrary in user32 */
HMODULE
-co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName,
- PUNICODE_STRING pstrInitFunc,
+co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName,
+ PUNICODE_STRING pstrInitFunc,
BOOL Unload,
BOOL ApiHook)
{
@@ -139,7 +140,7 @@
}
if(pstrInitFunc)
{
- pInitFuncBuffer = ArgumentLength;
+ pInitFuncBuffer = ArgumentLength;
ArgumentLength += pstrInitFunc->Length + sizeof(WCHAR);
}
@@ -443,6 +444,7 @@
PWND pWnd;
PMSG pMsg = NULL;
BOOL Hit = FALSE;
+ UINT lParamSize = 0;
ASSERT(Proc);
@@ -509,11 +511,21 @@
ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
break;
case WH_CALLWNDPROC:
+ {
+ CWPSTRUCT* pCWP = (CWPSTRUCT*) lParam;
ArgumentLength += sizeof(CWPSTRUCT);
- break;
+ lParamSize = lParamMemorySize(pCWP->message, pCWP->wParam,
pCWP->lParam);
+ ArgumentLength += lParamSize;
+ break;
+ }
case WH_CALLWNDPROCRET:
+ {
+ CWPRETSTRUCT* pCWPR = (CWPRETSTRUCT*) lParam;
ArgumentLength += sizeof(CWPRETSTRUCT);
- break;
+ lParamSize = lParamMemorySize(pCWPR->message, pCWPR->wParam,
pCWPR->lParam);
+ ArgumentLength += lParamSize;
+ break;
+ }
case WH_MSGFILTER:
case WH_SYSMSGFILTER:
case WH_GETMESSAGE:
@@ -583,12 +595,25 @@
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
break;
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));
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
+ if(lParamSize)
+ {
+ RtlCopyMemory(Extra + sizeof(CWPSTRUCT),
(PVOID)((CWPSTRUCT*)lParam)->lParam, lParamSize);
+ ((CWPSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
+ }
break;
case WH_CALLWNDPROCRET:
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPRETSTRUCT));
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
+ if(lParamSize)
+ {
+ RtlCopyMemory(Extra + sizeof(CWPRETSTRUCT),
(PVOID)((CWPRETSTRUCT*)lParam)->lParam, lParamSize);
+ ((CWPRETSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
+ }
break;
case WH_MSGFILTER:
case WH_SYSMSGFILTER:
Modified: trunk/reactos/win32ss/user/ntuser/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/messag…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] Sat Jul 21 22:59:41 2012
@@ -223,6 +223,13 @@
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
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL
NonPagedPoolNeeded)
{
@@ -2143,7 +2150,7 @@
}
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;
}
UserLeave();
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgque…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] Sat Jul 21 22:59:41 2012
@@ -296,4 +296,6 @@
BOOL ForceChange);
DWORD APIENTRY IntGetQueueStatus(DWORD);
+
+UINT lParamMemorySize(UINT Msg, WPARAM wParam, LPARAM lParam);
/* EOF */
Modified: trunk/reactos/win32ss/user/user32/windows/hook.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/window…
==============================================================================
--- trunk/reactos/win32ss/user/user32/windows/hook.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/windows/hook.c [iso-8859-1] Sat Jul 21 22:59:41
2012
@@ -216,7 +216,7 @@
ClientInfo = GetWin32ClientInfo();
if (!ClientInfo->phkCurrent) return 0;
-
+
pHook = DesktopPtrToUser(ClientInfo->phkCurrent);
if (!pHook->phkNext) return 0; // Nothing to do....
@@ -240,7 +240,7 @@
NtUserMessageCall( pCWP->hwnd,
pCWP->message,
pCWP->wParam,
- pCWP->lParam,
+ pCWP->lParam,
(ULONG_PTR)&lResult,
FNID_CALLWNDPROC,
phkNext->Ansi);
@@ -254,7 +254,7 @@
NtUserMessageCall( pCWPR->hwnd,
pCWPR->message,
pCWPR->wParam,
- pCWPR->lParam,
+ pCWPR->lParam,
(ULONG_PTR)&lResult,
FNID_CALLWNDPROCRET,
phkNext->Ansi);
@@ -427,8 +427,8 @@
return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, FALSE);
}
-HINSTANCE ClientLoadLibrary(PUNICODE_STRING pstrLibName,
- PUNICODE_STRING pstrInitFunc,
+HINSTANCE ClientLoadLibrary(PUNICODE_STRING pstrLibName,
+ PUNICODE_STRING pstrInitFunc,
BOOL Unload,
BOOL ApiHook)
{
@@ -440,7 +440,7 @@
TRACE("ClientLoadLibrary: pid: %d, strLibraryName: %S, "
"strInitFuncName: %S, Unload: %d, ApiHook:%d\n",
- GetCurrentProcessId(),
+ GetCurrentProcessId(),
pstrLibName->Buffer,
pstrInitFunc->Buffer,
Unload,
@@ -467,7 +467,7 @@
/* Initialize the user api hook */
ASSERT(pstrInitFunc->Buffer);
- /*Status = */ RtlUnicodeStringToAnsiString(&InitFuncName,
+ /*Status = */ RtlUnicodeStringToAnsiString(&InitFuncName,
pstrInitFunc,
TRUE);
@@ -539,7 +539,7 @@
}
/* Call the implementation of the callback */
- Result = ClientLoadLibrary(&Argument->strLibraryName,
+ Result = ClientLoadLibrary(&Argument->strLibraryName,
&Argument->strInitFuncName,
Argument->Unload,
Argument->ApiHook);
@@ -558,9 +558,9 @@
MSLLHOOKSTRUCT MouseLlData, *pMouseLlData;
MSG *pcMsg, *pMsg;
PMOUSEHOOKSTRUCT pMHook;
- CWPSTRUCT CWP, *pCWP;
- CWPRETSTRUCT CWPR, *pCWPR;
- PRECTL prl;
+ CWPSTRUCT *pCWP;
+ CWPRETSTRUCT *pCWPR;
+ PRECTL prl;
LPCBTACTIVATESTRUCT pcbtas;
WPARAM wParam = 0;
LPARAM lParam = 0;
@@ -631,7 +631,7 @@
switch(Common->Code)
{
case HCBT_CREATEWND:
- CbtCreatewndExtra->WndInsertAfter = CbtCreatewndw.hwndInsertAfter;
+ CbtCreatewndExtra->WndInsertAfter = CbtCreatewndw.hwndInsertAfter;
CbtCreatewndExtra->Cs.x = CbtCreatewndw.lpcs->x;
CbtCreatewndExtra->Cs.y = CbtCreatewndw.lpcs->y;
CbtCreatewndExtra->Cs.cx = CbtCreatewndw.lpcs->cx;
@@ -666,14 +666,34 @@
break;
case WH_CALLWNDPROC:
// ERR("WH_CALLWNDPROC: Code %d, wParam
%d\n",Common->Code,Common->wParam);
- pCWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam);
- RtlCopyMemory(&CWP, pCWP, sizeof(CWPSTRUCT));
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWP);
+ pCWP = HeapAlloc(GetProcessHeap(), 0, ArgumentLength -
sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
+ RtlCopyMemory(pCWP, (PCHAR) Common + Common->lParam, sizeof(CWPSTRUCT));
+ /* 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;
case WH_CALLWNDPROCRET:
- pCWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam);
- RtlCopyMemory(&CWPR, pCWPR, sizeof(CWPRETSTRUCT));
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWPR);
+ /* 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)))
+ {
+ 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;
case WH_MSGFILTER: /* All SEH support */
case WH_SYSMSGFILTER:
@@ -698,7 +718,7 @@
case WH_KEYBOARD:
case WH_SHELL:
Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
- break;
+ break;
case WH_FOREGROUNDIDLE: /* <-- SEH support */
_SEH2_TRY
{