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/callbac... ============================================================================== --- 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/message... ============================================================================== --- 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/msgqueu... ============================================================================== --- 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/windows... ============================================================================== --- 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 {