*/
#include <win32k.h>
+
+#include <dde.h>
+
DBG_DEFAULT_CHANNEL(UserMsg);
#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
{ 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_READ },
{ WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
{ WM_COPYGLOBALDATA, MMS_SIZE_WPARAM, MMS_FLAG_READ },
- { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
+ { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
{ WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
+ { WM_SIZING, sizeof(RECT), MMS_FLAG_READWRITE },
+ { WM_MOVING, sizeof(RECT), MMS_FLAG_READWRITE },
};
static PMSGMEMORY FASTCALL
}
else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
{
- Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
+ // WM_SETTEXT and WM_SETTINGCHANGE can be null!
+ if (!lParam)
+ {
+ TRACE("lParam is NULL!\n");
+ Size = 0;
+ }
+ else
+ Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
}
else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
{
MsgMemoryEntry = FindMsgMemory(Msg);
- if ((!MsgMemoryEntry) || (MsgMemoryEntry->Size < 0))
+ if (!MsgMemoryEntry)
{
/* Keep previous behavior */
return STATUS_SUCCESS;
PMSGMEMORY MsgMemoryEntry;
MsgMemoryEntry = FindMsgMemory(Msg);
ASSERT(MsgMemoryEntry);
- if (MsgMemoryEntry->Size < 0)
- {
- /* Keep previous behavior */
- return STATUS_INVALID_PARAMETER;
- }
if (MsgMemoryEntry->Flags == MMS_FLAG_READWRITE)
{
/* Copy data if required */
if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
{
+ TRACE("Copy Message %d from usermode buffer\n", KernelModeMsg->message);
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;
}
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;
}
IdlePing(VOID)
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
- PUSER_MESSAGE_QUEUE ForegroundQueue;
- PTHREADINFO pti, ptiForeground = NULL;
-
- ForegroundQueue = IntGetFocusMessageQueue();
-
- if (ForegroundQueue)
- ptiForeground = ForegroundQueue->ptiOwner;
+ PTHREADINFO pti;
pti = PsGetCurrentThreadWin32Thread();
{
pti->pClientInfo->cSpins = 0; // Reset spins.
- if ( pti->pDeskInfo && pti == ptiForeground )
+ if ( pti->pDeskInfo && pti == gptiForeground )
{
if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ||
pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) )
}
}
- TRACE("IdlePing ppi 0x%x\n",ppi);
+ TRACE("IdlePing ppi %p\n", ppi);
if ( ppi && ppi->InputIdleEvent )
{
TRACE("InputIdleEvent\n");
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
- TRACE("IdlePong ppi 0x%x\n",ppi);
+ TRACE("IdlePong ppi %p\n", ppi);
if ( ppi && ppi->InputIdleEvent )
{
KeClearEvent(ppi->InputIdleEvent);
{
LRESULT lRes;
USER_REFERENCE_ENTRY Ref;
+// PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
if (!pWnd ||
pWnd == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
{
PWND Window = (PWND)wparam;
if (wparam) UserRefObjectCo(Window, &Ref);
- lRes = (LRESULT)co_IntSetActiveWindow(Window,NULL,(BOOL)lparam,TRUE,TRUE);
+ lRes = (LRESULT)co_IntSetActiveWindow(Window,(BOOL)lparam,TRUE,TRUE);
if (wparam) UserDerefObjectCo(Window);
return lRes;
}
LRESULT retval = 0;
PTHREADINFO pti;
PWND Window = NULL;
- HRGN hrgn;
BOOL DoCallBack = TRUE;
if (pMsg->hwnd)
WM_TIMER,
pMsg->wParam,
(LPARAM)Time,
- 0);
+ -1);
}
return retval;
}
pMsg->message,
pMsg->wParam,
pMsg->lParam,
- 0);
+ -1);
if (pMsg->message == WM_PAINT)
{
+ PREGION Rgn;
Window->state2 &= ~WNDS2_WMPAINTSENT;
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
- hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
- co_UserGetUpdateRgn( Window, hrgn, TRUE );
- GreDeleteObject(hrgn);
+ Rgn = IntSysCreateRectpRgn( 0, 0, 0, 0 );
+ co_UserGetUpdateRgn( Window, Rgn, TRUE );
+ REGION_Delete(Rgn);
}
return retval;
/*
* Internal version of PeekMessage() doing all the work
+ *
+ * MSDN:
+ * Sent messages
+ * Posted messages
+ * Input (hardware) messages and system internal events
+ * Sent messages (again)
+ * WM_PAINT messages
+ * WM_TIMER messages
*/
BOOL FASTCALL
co_IntPeekMessage( PMSG Msg,
RemoveMessages = RemoveMsg & PM_REMOVE;
ProcessMask = HIWORD(RemoveMsg);
-
+
/* Hint, "If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns
all available messages (that is, no range filtering is performed)". */
if (!ProcessMask) ProcessMask = (QS_ALLPOSTMESSAGE|QS_ALLINPUT);
return TRUE;
}
- /* Check for hardware events. */
if ((ProcessMask & QS_MOUSE) &&
co_MsqPeekMouseMove( pti,
RemoveMessages,
return TRUE;
}
+ /* Check for hardware events. */
if ((ProcessMask & QS_INPUT) &&
co_MsqPeekHardwareMessage( pti,
RemoveMessages,
}
BOOL FASTCALL
-UserPostThreadMessage( DWORD idThread,
+UserPostThreadMessage( PTHREADINFO pti,
UINT Msg,
WPARAM wParam,
LPARAM lParam )
{
MSG Message;
- PETHREAD peThread;
- PTHREADINFO pThread;
LARGE_INTEGER LargeTickCount;
- NTSTATUS Status;
if (is_pointer_message(Msg))
{
EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
+ Message.hwnd = NULL;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
+ Message.pt = gpsi->ptCursor;
- Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
-
- if( Status == STATUS_SUCCESS )
- {
- pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
- if( !pThread ||
- !pThread->MessageQueue ||
- (pThread->TIF_flags & TIF_INCLEANUP))
- {
- ObDereferenceObject( peThread );
- return FALSE;
- }
-
- Message.hwnd = NULL;
- Message.message = Msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
- Message.pt = gpsi->ptCursor;
+ KeQueryTickCount(&LargeTickCount);
+ Message.time = MsqCalculateMessageTime(&LargeTickCount);
+ MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0);
+ return TRUE;
+}
- KeQueryTickCount(&LargeTickCount);
- Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(pThread, &Message, FALSE, QS_POSTMESSAGE, 0);
- ObDereferenceObject( peThread );
- return TRUE;
- }
- else
- {
- SetLastNtError( Status );
- }
- return FALSE;
+PTHREADINFO FASTCALL
+IntSendTo(PWND Window, PTHREADINFO ptiCur, UINT Msg)
+{
+ if ( ptiCur )
+ {
+ if (!Window ||
+ Window->head.pti->MessageQueue == ptiCur->MessageQueue )
+ {
+ return NULL;
+ }
+ }
+ return Window ? Window->head.pti : NULL;
}
BOOL FASTCALL
if (!Wnd)
{
- return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
+ pti = PsGetCurrentThreadWin32Thread();
+ return UserPostThreadMessage( pti,
Msg,
wParam,
lParam);
Window = UserGetWindowObject(Wnd);
if ( !Window )
{
- ERR("UserPostMessage: Invalid handle 0x%p!\n",Wnd);
+ ERR("UserPostMessage: Invalid handle 0x%p Msg %d!\n",Wnd,Msg);
return FALSE;
}
pti = Window->head.pti;
if ( pti->TIF_flags & TIF_INCLEANUP )
{
- ERR("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd);
+ ERR("Attempted to post message to window %p when the thread is in cleanup!\n", Wnd);
return FALSE;
}
if ( Window->state & WNDS_DESTROYED )
{
- ERR("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
+ ERR("Attempted to post message to window %p that is being destroyed!\n", Wnd);
/* FIXME: Last error code? */
return FALSE;
}
if (WM_QUIT == Msg)
{
- MsqPostQuitMessage(Window->head.pti, wParam);
+ MsqPostQuitMessage(pti, wParam);
}
else
{
- MsqPostMessage(Window->head.pti, &Message, FALSE, QS_POSTMESSAGE, 0);
+ MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0);
}
}
return TRUE;
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
LPARAM lParamPacked;
- PTHREADINFO Win32Thread;
+ PTHREADINFO Win32Thread, ptiSendTo = NULL;
ULONG_PTR Hi, Lo, Result = 0;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
Win32Thread = PsGetCurrentThreadWin32Thread();
- if ( Win32Thread &&
- Window->head.pti == Win32Thread)
+ ptiSendTo = IntSendTo(Window, Win32Thread, Msg);
+
+ if ( !ptiSendTo )
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
else
{
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ // If zero, do not allow callback on client side to allocate a buffer!!!!! See CORE-7695.
+ if (!lParamBufferSize) lParamBufferSize = -1;
}
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
RETURN( TRUE);
}
- if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti))
+ if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(ptiSendTo))
{
// FIXME: Set window hung and add to a list.
/* FIXME: Set a LastError? */
if (Window->state & WNDS_DESTROYED)
{
/* FIXME: Last error? */
- ERR("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
+ ERR("Attempted to send message to window %p that is being destroyed!\n", hWnd);
RETURN( FALSE);
}
do
{
- Status = co_MsqSendMessage( Window->head.pti,
+ Status = co_MsqSendMessage( ptiSendTo,
hWnd,
Msg,
wParam,
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
- !MsqIsHung(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)
{
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
LPARAM lParamPacked;
- PTHREADINFO Win32Thread;
+ PTHREADINFO Win32Thread, ptiSendTo = NULL;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
PUSER_SENT_MESSAGE Message;
if (Window->state & WNDS_DESTROYED)
{
/* FIXME: last error? */
- ERR("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
+ ERR("Attempted to send message to window %p that is being destroyed!\n", hWnd);
RETURN(FALSE);
}
RETURN(FALSE);
}
+ ptiSendTo = IntSendTo(Window, Win32Thread, Msg);
+
if (Msg & 0x80000000 &&
- Window->head.pti == Win32Thread)
+ !ptiSendTo)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP) RETURN( FALSE);
else
{
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ if (!lParamBufferSize) lParamBufferSize = -1;
}
- if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti != Win32Thread)))
+ if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, !!ptiSendTo)))
{
ERR("Failed to pack message parameters\n");
RETURN( FALSE);
}
/* If it can be sent now, then send it. */
- if (Window->head.pti == Win32Thread)
+ if ( !ptiSendTo )
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
}
}
- if (Window->head.pti == Win32Thread)
+ if ( !ptiSendTo)
{
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
Message->Result = 0;
Message->lResult = 0;
Message->QS_Flags = 0;
- Message->ptiReceiver = Window->head.pti;
+ Message->ptiReceiver = ptiSendTo;
Message->ptiSender = NULL; // mjmartin, you are right! This is null.
Message->ptiCallBackSender = Win32Thread;
Message->DispatchingListEntry.Flink = NULL;
Message->QS_Flags = QS_SENDMESSAGE;
if (Msg & 0x80000000) // Higher priority event message!
- InsertHeadList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry);
+ InsertHeadList(&ptiSendTo->SentMessagesListHead, &Message->ListEntry);
else
- InsertTailList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry);
- MsqWakeQueue(Window->head.pti, QS_SENDMESSAGE, TRUE);
+ InsertTailList(&ptiSendTo->SentMessagesListHead, &Message->ListEntry);
+ MsqWakeQueue(ptiSendTo, QS_SENDMESSAGE, TRUE);
RETURN(TRUE);
pti = PsGetCurrentThreadWin32Thread();
- if ( Window->head.pti->MessageQueue != pti->MessageQueue &&
+ if ( IntSendTo(Window, pti, Msg) &&
FindMsgMemory(Msg) == 0 )
{
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
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)
{
ERR("co_IntDoSendMessage Window Exiting!\n");
}
- /* See if the current thread can handle the message */
- //pti = PsGetCurrentThreadWin32Thread();
-
- UserModeMsg.hwnd = hWnd;
- UserModeMsg.message = Msg;
- UserModeMsg.wParam = wParam;
- UserModeMsg.lParam = lParam;
- MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
+ /* See if the current thread can handle this message */
+ ptiSendTo = IntSendTo(Window, gptiCurrent, Msg);
- 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)
&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;
return FALSE;
}
+BOOL FASTCALL
+IntCallMsgFilter( LPMSG lpmsg, INT code)
+{
+ BOOL Ret = FALSE;
+
+ if ( co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)lpmsg))
+ {
+ Ret = TRUE;
+ }
+ else
+ {
+ Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)lpmsg);
+ }
+ return Ret;
+}
+
/** Functions ******************************************************************/
BOOL
ULONG wDragWidth, wDragHeight;
DECLARE_RETURN(BOOL);
- TRACE("Enter NtUserDragDetect(%x)\n", hWnd);
+ TRACE("Enter NtUserDragDetect(%p)\n", hWnd);
UserEnterExclusive();
wDragWidth = UserGetSystemMetrics(SM_CXDRAG);
WPARAM wParam,
LPARAM lParam)
{
- BOOL ret;
+ BOOL ret = FALSE;
+ PETHREAD peThread;
+ PTHREADINFO pThread;
+ NTSTATUS Status;
UserEnterExclusive();
- ret = UserPostThreadMessage( idThread, Msg, wParam, lParam);
+ Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
+ if ( Status == STATUS_SUCCESS )
+ {
+ pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
+ if( !pThread ||
+ !pThread->MessageQueue ||
+ (pThread->TIF_flags & TIF_INCLEANUP))
+ {
+ ObDereferenceObject( peThread );
+ goto exit;
+ }
+ ret = UserPostThreadMessage( pThread, Msg, wParam, lParam);
+ ObDereferenceObject( peThread );
+ }
+ else
+ {
+ SetLastNtError( Status );
+ }
+exit:
UserLeave();
-
return ret;
}
}
else
{
- TRACE("No Window for Translate. hwnd 0x%p Msg %d\n",SafeMsg.hwnd,SafeMsg.message);
+ TRACE("No Window for Translate. hwnd 0x%p Msg %u\n", SafeMsg.hwnd, SafeMsg.message);
Ret = FALSE;
}
UserLeave();
CWP.message = Msg;
CWP.wParam = wParam;
CWP.lParam = lParam;
- TRACE("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
+ TRACE("WH_CALLWNDPROC: Hook %p NextHook %p\n", Hook, NextObj);
lResult = co_IntCallHookProc( Hook->HookId,
HC_ACTION,
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
(LPARAM)&CWP,
Hook->Proc,
+ Hook->ihmod,
+ Hook->offPfn,
Hook->Ansi,
&Hook->ModuleName);
}
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
(LPARAM)&CWPR,
Hook->Proc,
+ Hook->ihmod,
+ Hook->offPfn,
Hook->Ansi,
&Hook->ModuleName);
}
Status = ObReferenceObjectByHandle(hProcess,
PROCESS_QUERY_INFORMATION,
- PsProcessType,
+ *PsProcessType,
UserMode,
(PVOID*)&Process,
NULL);
pti->pClientInfo->dwTIFlags = pti->TIF_flags;
}
- TRACE("WFII: ppi 0x%x\n",W32Process);
+ TRACE("WFII: ppi %p\n", W32Process);
TRACE("WFII: waiting for %p\n", Handles[1] );
+
+ /*
+ * We must add a refcount to our current PROCESSINFO,
+ * because anything could happen (including process death) we're leaving win32k
+ */
+ IntReferenceProcessInfo(W32Process);
+
do
{
UserLeave();
pti->pClientInfo->dwTIFlags = pti->TIF_flags;
}
W32Process->W32PF_flags &= ~W32PF_WAITFORINPUTIDLE;
+ IntDereferenceProcessInfo(W32Process);
ObDereferenceObject(Process);
UserLeave();
return Status;