[Win32SS]

- Improvements to the message system. Fix hook write backs. Reduced memory when calling back from server side. Disabled post or send, leaving it in place just for a while, to test. See CORE-7447.

svn path=/trunk/; revision=61251
This commit is contained in:
James Tabor 2013-12-09 01:55:48 +00:00
parent 43e1c8ae59
commit 5a02327fd0
7 changed files with 121 additions and 60 deletions

View file

@ -54,6 +54,7 @@ typedef struct _HOOKPROC_CALLBACK_ARGUMENTS
INT Mod;
ULONG_PTR offPfn;
BOOLEAN Ansi;
LRESULT Result;
WCHAR ModuleName[512];
} HOOKPROC_CALLBACK_ARGUMENTS, *PHOOKPROC_CALLBACK_ARGUMENTS;

View file

@ -290,7 +290,7 @@ co_IntCallWindowProc(WNDPROC Proc,
/* Do not allow the desktop thread to do callback to user mode */
ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread);
if (0 < lParamBufferSize)
if (lParamBufferSize != -1)
{
ArgumentLength = sizeof(WINDOWPROC_CALLBACK_ARGUMENTS) + lParamBufferSize;
Arguments = IntCbAllocateMemory(ArgumentLength);
@ -334,7 +334,7 @@ co_IntCallWindowProc(WNDPROC Proc,
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ERR("Failed to copy result from user mode Message %d!\n", Message);
ERR("Failed to copy result from user mode, Message %d lParam size %d!\n", Message, lParamBufferSize);
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
@ -346,7 +346,7 @@ co_IntCallWindowProc(WNDPROC Proc,
if (!NT_SUCCESS(Status))
{
ERR("Call to user mode failed!\n");
if (0 < lParamBufferSize)
if (lParamBufferSize != -1)
{
IntCbFreeMemory(Arguments);
}
@ -354,11 +354,48 @@ co_IntCallWindowProc(WNDPROC Proc,
}
Result = Arguments->Result;
if (0 < lParamBufferSize)
if (lParamBufferSize != -1)
{
RtlMoveMemory((PVOID) lParam,
(PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
lParamBufferSize);
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
// Is this message being processed from inside kernel space?
BOOL InSendMessage = (pti->pcti->CTI_flags & CTI_INSENDMESSAGE);
TRACE("Copy lParam Message %d lParam %d!\n", Message, lParam);
switch (Message)
{
default:
TRACE("Don't copy lParam, Message %d Size %d lParam %d!\n", Message, lParamBufferSize, lParam);
break;
// Write back to user/kernel space. Also see g_MsgMemory.
case WM_CREATE:
case WM_GETMINMAXINFO:
case WM_GETTEXT:
case WM_NCCALCSIZE:
case WM_NCCREATE:
case WM_STYLECHANGING:
case WM_WINDOWPOSCHANGING:
TRACE("Copy lParam, Message %d Size %d lParam %d!\n", Message, lParamBufferSize, lParam);
if (InSendMessage)
// Copy into kernel space.
RtlMoveMemory((PVOID) lParam,
(PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
lParamBufferSize);
else
{
_SEH2_TRY
{ // Copy into user space.
RtlMoveMemory((PVOID) lParam,
(PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
lParamBufferSize);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ERR("Failed to copy lParam to user space, Message %d!\n", Message);
}
_SEH2_END;
}
break;
}
IntCbFreeMemory(Arguments);
}
@ -398,7 +435,7 @@ co_IntLoadSysMenuTemplate()
{
Result = 0;
}
_SEH2_END
_SEH2_END;
}
UserEnterCo();
@ -658,7 +695,7 @@ co_IntCallHookProc(INT HookId,
}
ResultPointer = NULL;
ResultLength = sizeof(LRESULT);
ResultLength = ArgumentLength;
UserLeaveCo();
@ -674,9 +711,9 @@ co_IntCallHookProc(INT HookId,
{
_SEH2_TRY
{
ProbeForRead(ResultPointer, sizeof(LRESULT), 1);
/* Simulate old behaviour: copy into our local buffer */
Result = *(LRESULT*)ResultPointer;
RtlMoveMemory(Argument, ResultPointer, ArgumentLength);
Result = Common->Result;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -687,7 +724,7 @@ co_IntCallHookProc(INT HookId,
}
else
{
ERR("ERROR: Hook ResultPointer 0x%p ResultLength %u\n",ResultPointer,ResultLength);
ERR("ERROR: Hook %d Code %d ResultPointer 0x%p ResultLength %u\n",HookId,Code,ResultPointer,ResultLength);
}
if (!NT_SUCCESS(Status))
@ -1000,10 +1037,8 @@ co_IntSetWndIcons(VOID)
PVOID Argument, ResultPointer;
PSETWNDICONS_CALLBACK_ARGUMENTS Common;
ArgumentLength = ResultLength = 0;
Argument = ResultPointer = NULL;
ArgumentLength = sizeof(SETWNDICONS_CALLBACK_ARGUMENTS);
ResultPointer = NULL;
ResultLength = ArgumentLength = sizeof(SETWNDICONS_CALLBACK_ARGUMENTS);
Argument = IntCbAllocateMemory(ArgumentLength);
if (NULL == Argument)
@ -1025,6 +1060,7 @@ co_IntSetWndIcons(VOID)
UserEnterCo();
/* FIXME: Need to setup Registry System Cursor & Icons via Callbacks at init time! */
RtlMoveMemory(Common, ResultPointer, ArgumentLength);
gpsi->hIconSmWindows = Common->hIconSmWindows;
gpsi->hIconWindows = Common->hIconWindows;

View file

@ -870,10 +870,14 @@ VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
for (; *cursor; cursor++)
{
TRACE("Sending notify\n");
co_IntPostOrSendMessage(*cursor,
UserPostMessage(*cursor,
gpsi->uiShellMsg,
Message,
(Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );
/* co_IntPostOrSendMessage(*cursor,
gpsi->uiShellMsg,
Message,
(Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );
(Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );*/
}
ExFreePoolWithTag(HwndList, USERTAG_WINDOWLIST);

View file

@ -112,7 +112,8 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
/* Send palette messages */
if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
//co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
co_IntSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
{
UserSendNotifyMessage( HWND_BROADCAST,
WM_PALETTEISCHANGING,
@ -276,12 +277,14 @@ IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
{
if (pWndPrev)
{
co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
//co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
}
if (ThreadQueue->spwndFocus == pWnd)
{
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
//co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
}
}
else
@ -289,7 +292,8 @@ IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
if (pWndPrev)
{
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
//co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
}
}
}
@ -958,7 +962,8 @@ co_UserSetCapture(HWND hWnd)
{
if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
//co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
co_IntSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
}

View file

@ -128,7 +128,7 @@ static MSGMEMORY g_MsgMemory[] =
{ WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
{ WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
{ WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
{ WM_SETTINGCHANGE, MMS_SIZE_LPARAMSZ, MMS_FLAG_READWRITE },
{ WM_SETTINGCHANGE, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
{ WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
{ WM_COPYGLOBALDATA, MMS_SIZE_WPARAM, MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
@ -447,7 +447,7 @@ CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEnt
Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
if (! NT_SUCCESS(Status))
{
ERR("Failed to copy message to kernel: invalid usermode buffer\n");
ERR("Failed to copy message to kernel: invalid usermode lParam buffer\n");
ExFreePoolWithTag(KernelMem, TAG_MSG);
return Status;
}
@ -492,7 +492,7 @@ CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
if (! NT_SUCCESS(Status))
{
ERR("Failed to copy message from kernel: invalid usermode buffer\n");
ERR("Failed to copy message from kernel: invalid usermode lParam buffer\n");
ExFreePool((PVOID) KernelModeMsg->lParam);
return Status;
}
@ -685,7 +685,7 @@ IntDispatchMessage(PMSG pMsg)
WM_TIMER,
pMsg->wParam,
(LPARAM)Time,
0);
-1);
}
return retval;
}
@ -739,7 +739,7 @@ IntDispatchMessage(PMSG pMsg)
pMsg->message,
pMsg->wParam,
pMsg->lParam,
0);
-1);
if (pMsg->message == WM_PAINT)
{
@ -1100,12 +1100,13 @@ IntSendTo(PWND Window, PTHREADINFO ptiCur, UINT Msg)
{
if ( ptiCur )
{
if ( Window->head.pti->MessageQueue == ptiCur->MessageQueue )
if (!Window ||
Window->head.pti->MessageQueue == ptiCur->MessageQueue )
{
return NULL;
}
}
return Window->head.pti;
return Window ? Window->head.pti : NULL;
}
BOOL FASTCALL
@ -1359,7 +1360,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
RETURN( TRUE);
}
if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(ptiSendTo/*Window->head.pti*/))
if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(ptiSendTo))
{
// FIXME: Set window hung and add to a list.
/* FIXME: Set a LastError? */
@ -1375,7 +1376,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
do
{
Status = co_MsqSendMessage( ptiSendTo, //Window->head.pti,
Status = co_MsqSendMessage( ptiSendTo,
hWnd,
Msg,
wParam,
@ -1387,7 +1388,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
!MsqIsHung(ptiSendTo/*Window->head.pti*/)); // FIXME: Set window hung and add to a list.
!MsqIsHung(ptiSendTo)); // FIXME: Set window hung and add to a list.
if (STATUS_TIMEOUT == Status)
{
@ -1650,7 +1651,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->Result = 0;
Message->lResult = 0;
Message->QS_Flags = 0;
Message->ptiReceiver = ptiSendTo; //Window->head.pti;
Message->ptiReceiver = ptiSendTo;
Message->ptiSender = NULL; // mjmartin, you are right! This is null.
Message->ptiCallBackSender = Win32Thread;
Message->DispatchingListEntry.Flink = NULL;
@ -1661,10 +1662,10 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->QS_Flags = QS_SENDMESSAGE;
if (Msg & 0x80000000) // Higher priority event message!
InsertHeadList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry);
InsertHeadList(&ptiSendTo->SentMessagesListHead, &Message->ListEntry);
else
InsertTailList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry);
MsqWakeQueue(ptiSendTo/*Window->head.pti*/, QS_SENDMESSAGE, TRUE);
InsertTailList(&ptiSendTo->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(ptiSendTo, QS_SENDMESSAGE, TRUE);
RETURN(TRUE);
@ -1718,20 +1719,19 @@ co_IntPostOrSendMessage( HWND hWnd,
return (LRESULT)Result;
}
LRESULT FASTCALL
static LRESULT FASTCALL
co_IntDoSendMessage( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
PDOSENDMESSAGE dsm)
{
//PTHREADINFO pti;
LRESULT Result = TRUE;
NTSTATUS Status;
PWND Window = NULL;
MSG UserModeMsg;
MSG KernelModeMsg;
MSG UserModeMsg, KernelModeMsg;
PMSGMEMORY MsgMemoryEntry;
PTHREADINFO ptiSendTo;
if (hWnd != HWND_BROADCAST && hWnd != HWND_TOPMOST)
{
@ -1748,20 +1748,30 @@ co_IntDoSendMessage( HWND hWnd,
ERR("co_IntDoSendMessage Window Exiting!\n");
}
/* See if the current thread can handle the message */
//pti = PsGetCurrentThreadWin32Thread();
/* See if the current thread can handle this message */
ptiSendTo = IntSendTo(Window, gptiCurrent, Msg);
UserModeMsg.hwnd = hWnd;
UserModeMsg.message = Msg;
UserModeMsg.wParam = wParam;
UserModeMsg.lParam = lParam;
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
// If broadcasting or sending to another thread, save the users data.
if (!Window || ptiSendTo )
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return (dsm ? 0 : -1);
UserModeMsg.hwnd = hWnd;
UserModeMsg.message = Msg;
UserModeMsg.wParam = wParam;
UserModeMsg.lParam = lParam;
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (!NT_SUCCESS(Status))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return (dsm ? 0 : -1);
}
}
else
{
KernelModeMsg.hwnd = hWnd;
KernelModeMsg.message = Msg;
KernelModeMsg.wParam = wParam;
KernelModeMsg.lParam = lParam;
}
if (!dsm)
@ -1782,11 +1792,14 @@ co_IntDoSendMessage( HWND hWnd,
&dsm->Result );
}
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
if (! NT_SUCCESS(Status))
if (!Window || ptiSendTo )
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return(dsm ? 0 : -1);
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
if (!NT_SUCCESS(Status))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return(dsm ? 0 : -1);
}
}
return (LRESULT)Result;

View file

@ -417,6 +417,6 @@ User32CallSetWndIconsFromKernel(PVOID Arguments, ULONG ArgumentLength)
}
Common->hIconSmWindows = hIconSmWindows;
Common->hIconWindows = hIconWindows;
ERR("hIconSmWindows %p hIconWindows %p \n",hIconSmWindows,hIconWindows);
return ZwCallbackReturn(Arguments, ArgumentLength, STATUS_SUCCESS);
}

View file

@ -595,7 +595,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
}
if (mod)
{
TRACE("Loading Hook Module.\n");
TRACE("Loading Hook Module. %S\n",Common->ModuleName);
Proc = (HOOKPROC)((char *)mod + Common->offPfn);
}
}
@ -764,6 +764,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
break;
default:
if (Loaded) FreeLibrary(mod);
ERR("WH_ not supported = %d\n", Common->HookId);
return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
}
if (Hit)
@ -772,7 +773,8 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
Status = STATUS_UNSUCCESSFUL;
}
if (Loaded) FreeLibrary(mod);
return ZwCallbackReturn(&Result, sizeof(LRESULT), Status);
Common->Result = Result;
return ZwCallbackReturn(Arguments, ArgumentLength, Status);
}
NTSTATUS WINAPI