PUNICODE_STRING ClassName;
UINT Size = 0;
- _SEH_TRY
+ _SEH2_TRY
{
if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
{
Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
break;
+ case WM_COPYGLOBALDATA:
+ Size = wParam;
+ break;
+
default:
assert(FALSE);
Size = 0;
Size = MsgMemoryEntry->Size;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH_GetExceptionCode());
+ DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH2_GetExceptionCode());
Size = 0;
}
- _SEH_END;
+ _SEH2_END;
return Size;
}
return STATUS_INVALID_PARAMETER;
}
+static
+VOID
+FASTCALL
+IntCallWndProc
+( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ BOOL SameThread = FALSE;
+
+ if (Window->ti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->ThreadInfo)
+ SameThread = TRUE;
+
+ if ((!SameThread && (Window->ti->fsHooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) ||
+ (SameThread && ISITHOOKED(WH_CALLWNDPROC)) )
+ {
+ CWPSTRUCT CWP;
+ CWP.hwnd = hWnd;
+ CWP.message = Msg;
+ CWP.wParam = wParam;
+ CWP.lParam = lParam;
+ co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
+ }
+}
+static
+VOID
+FASTCALL
+IntCallWndProcRet
+( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult)
+{
+ BOOL SameThread = FALSE;
+
+ if (Window->ti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->ThreadInfo)
+ SameThread = TRUE;
+
+ if ((!SameThread && (Window->ti->fsHooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
+ (SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) )
+ {
+ CWPRETSTRUCT CWPR;
+ CWPR.hwnd = hWnd;
+ CWPR.message = Msg;
+ CWPR.wParam = wParam;
+ CWPR.lParam = lParam;
+ CWPR.lResult = *uResult;
+ co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
+ }
+}
+
+LRESULT
+FASTCALL
+IntDispatchMessage(PMSG pMsg)
+{
+ LARGE_INTEGER TickCount;
+ LONG Time;
+ LRESULT retval;
+ PWINDOW_OBJECT Window = NULL;
+
+ if (pMsg->hwnd)
+ {
+ Window = UserGetWindowObject(pMsg->hwnd);
+ if (!Window || !Window->Wnd) return 0;
+ }
+
+ if (((pMsg->message == WM_SYSTIMER) ||
+ (pMsg->message == WM_TIMER)) &&
+ (pMsg->lParam) )
+ {
+ if (pMsg->message == WM_TIMER)
+ {
+ if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),Window,pMsg->wParam,pMsg->lParam))
+ {
+ KeQueryTickCount(&TickCount);
+ Time = MsqCalculateMessageTime(&TickCount);
+ return co_IntCallWindowProc((WNDPROC)pMsg->lParam,
+ TRUE,
+ pMsg->hwnd,
+ WM_TIMER,
+ pMsg->wParam,
+ (LPARAM)Time,
+ sizeof(LPARAM));
+ }
+ return 0;
+ }
+ else
+ {
+ PTIMER pTimer = FindSystemTimer(pMsg);
+ if (pTimer && pTimer->pfn)
+ {
+ KeQueryTickCount(&TickCount);
+ Time = MsqCalculateMessageTime(&TickCount);
+ pTimer->pfn(pMsg->hwnd, WM_SYSTIMER, (UINT)pMsg->wParam, Time);
+ }
+ return 0;
+ }
+ }
+ // Need a window!
+ if (!Window) return 0;
+
+ retval = co_IntPostOrSendMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
+
+ if (pMsg->message == WM_PAINT)
+ {
+ /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
+ HRGN hrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
+ co_UserGetUpdateRgn( Window, hrgn, TRUE );
+ GreDeleteObject( hrgn );
+ }
+ return retval;
+}
+
+
BOOL
-STDCALL
+APIENTRY
NtUserCallMsgFilter(
LPMSG lpmsg,
INT code)
UserEnterExclusive();
if (lpmsg)
{
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForRead((PVOID)lpmsg,
sizeof(MSG),
(PVOID)lpmsg,
sizeof(MSG));
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
BadChk = TRUE;
}
- _SEH_END;
+ _SEH2_END;
}
else
RETURN( FALSE);
Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
}
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForWrite((PVOID)lpmsg,
sizeof(MSG),
&Msg,
sizeof(MSG));
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
BadChk = TRUE;
}
- _SEH_END;
+ _SEH2_END;
if (BadChk) RETURN( FALSE);
RETURN( Ret)
END_CLEANUP;
}
-LRESULT STDCALL
-NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
+LRESULT APIENTRY
+NtUserDispatchMessage(PMSG UnsafeMsgInfo)
{
- NTSTATUS Status;
- NTUSERDISPATCHMESSAGEINFO MsgInfo;
- LRESULT Result = TRUE;
- DECLARE_RETURN(LRESULT);
-
- DPRINT("Enter NtUserDispatchMessage\n");
- UserEnterExclusive();
-
- Status = MmCopyFromCaller(&MsgInfo, UnsafeMsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( 0);
- }
-
- /* Process timer messages. */
- if (WM_TIMER == MsgInfo.Msg.message && 0 != MsgInfo.Msg.lParam)
- {
- LARGE_INTEGER LargeTickCount;
- /* FIXME: Call hooks. */
-
- /* FIXME: Check for continuing validity of timer. */
+ LRESULT Res = 0;
+ BOOL Hit = FALSE;
+ MSG SafeMsg;
- MsgInfo.HandledByKernel = FALSE;
- KeQueryTickCount(&LargeTickCount);
- MsgInfo.Proc = (WNDPROC) MsgInfo.Msg.lParam;
- MsgInfo.Msg.lParam = (LPARAM)LargeTickCount.u.LowPart;
- }
- else if (NULL == MsgInfo.Msg.hwnd)
- {
- MsgInfo.HandledByKernel = TRUE;
- Result = 0;
- }
- else
- {
- PWINDOW_OBJECT Window;
-
- /* Get the window object. */
- Window = UserGetWindowObject(MsgInfo.Msg.hwnd);
- if (NULL == Window)
- {
- MsgInfo.HandledByKernel = TRUE;
- Result = 0;
- }
- else
- {
- if (Window->OwnerThread != PsGetCurrentThread())
- {
- DPRINT1("Window doesn't belong to the calling thread!\n");
- MsgInfo.HandledByKernel = TRUE;
- Result = 0;
- }
- else
- {
- /* FIXME: Call hook procedures. */
-
- MsgInfo.HandledByKernel = FALSE;
- Result = 0;
-
- if (Window->Wnd->IsSystem)
- {
- MsgInfo.Proc = (!MsgInfo.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
- }
- else
- {
- MsgInfo.Ansi = !Window->Wnd->Unicode;
- MsgInfo.Proc = Window->Wnd->WndProc;
- }
- }
- }
- }
- Status = MmCopyToCaller(UnsafeMsgInfo, &MsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( 0);
- }
-
- RETURN( Result);
+ UserEnterExclusive();
+ _SEH2_TRY
+ {
+ ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
+ RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Hit = TRUE;
+ }
+ _SEH2_END;
+
+ if (!Hit) Res = IntDispatchMessage(&SafeMsg);
-CLEANUP:
- DPRINT("Leave NtUserDispatchMessage. ret=%i\n", _ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+ return Res;
}
-BOOL STDCALL
+BOOL APIENTRY
NtUserTranslateMessage(LPMSG lpMsg,
HKL dwhkl)
{
}
Parent = IntGetParent(MsgWindow);//fixme: deref retval?
- /* fixme: abort if no parent ? */
+
+ /* If no parent window, pass MsgWindows HWND as wParam. Fixes bug #3111 */
Result = co_IntSendMessage(MsgWindow->hSelf,
WM_MOUSEACTIVATE,
- (WPARAM) (Parent ? Parent->hSelf : NULL),
+ (WPARAM) (Parent ? Parent->hSelf : MsgWindow->hSelf),
(LPARAM)MAKELONG(*HitTest, Msg->message)
);
{
/* generate double click messages, if necessary */
if ((((*HitTest) != HTCLIENT) ||
- (Window->Wnd->Class->Style & CS_DBLCLKS)) &&
+ (Window->Wnd->pcls->style & CS_DBLCLKS)) &&
MsqIsDblClk(Msg, Remove))
{
Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
{
/* NOTE: Msg->pt should remain in screen coordinates. -- FiN */
Msg->lParam = MAKELONG(
- Msg->pt.x - (WORD)Window->Wnd->ClientRect.left,
- Msg->pt.y - (WORD)Window->Wnd->ClientRect.top);
+ Msg->pt.x - (WORD)Window->Wnd->rcClient.left,
+ Msg->pt.y - (WORD)Window->Wnd->rcClient.top);
}
}
*/
BOOL FASTCALL
co_IntPeekMessage(PUSER_MESSAGE Msg,
- HWND hWnd,
+ PWINDOW_OBJECT Window,
UINT MsgFilterMin,
UINT MsgFilterMax,
UINT RemoveMsg)
{
+ PTHREADINFO pti;
LARGE_INTEGER LargeTickCount;
PUSER_MESSAGE_QUEUE ThreadQueue;
PUSER_MESSAGE Message;
/* The queues and order in which they are checked are documented in the MSDN
article on GetMessage() */
- ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetCurrentThreadWin32Thread()->MessageQueue;
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
/* Inspect RemoveMsg flags */
/* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
Present = co_MsqFindMessage(ThreadQueue,
FALSE,
RemoveMessages,
- hWnd,
+ Window,
MsgFilterMin,
MsgFilterMax,
&Message);
Present = co_MsqFindMessage(ThreadQueue,
TRUE,
RemoveMessages,
- hWnd,
+ Window,
MsgFilterMin,
MsgFilterMax,
&Message);
;
/* Check for paint messages. */
- if (IntGetPaintMessage(hWnd, MsgFilterMin, MsgFilterMax, PsGetCurrentThreadWin32Thread(), &Msg->Msg, RemoveMessages))
+ if (IntGetPaintMessage(Window, MsgFilterMin, MsgFilterMax, pti, &Msg->Msg, RemoveMessages))
{
Msg->FreeLParam = FALSE;
goto MsgExit;
}
+ if (ThreadQueue->WakeMask & QS_TIMER)
+ if (PostTimerMessages(Window)) // If there are timers ready,
+ goto CheckMessages; // go back and process them.
+
+ // LOL! Polling Timer Queue? How much time is spent doing this?
/* Check for WM_(SYS)TIMER messages */
- Present = MsqGetTimerMessage(ThreadQueue, hWnd, MsgFilterMin, MsgFilterMax,
+ Present = MsqGetTimerMessage(ThreadQueue, Window, MsgFilterMin, MsgFilterMax,
&Msg->Msg, RemoveMessages);
if (Present)
{
MHook.hwnd = Msg->Msg.hwnd;
MHook.wHitTestCode = HitTest;
MHook.dwExtraInfo = 0;
- co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED,
+ co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED,
Msg->Msg.message, (LPARAM)&MHook);
}
return FALSE;
return Present;
}
-BOOL STDCALL
+BOOL APIENTRY
NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
HWND hWnd,
UINT MsgFilterMin,
PWINDOW_OBJECT Window;
PMSGMEMORY MsgMemoryEntry;
PVOID UserMem;
- UINT Size;
+ SIZE_T Size;
USER_MESSAGE Msg;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserPeekMessage\n");
UserEnterExclusive();
+ if (hWnd == (HWND)-1 || hWnd == (HWND)0x0000FFFF || hWnd == (HWND)0xFFFFFFFF)
+ hWnd = (HWND)1;
+
/* Validate input */
- if (hWnd && hWnd != INVALID_HANDLE_VALUE)
+ if (hWnd && hWnd != (HWND)1)
{
if (!(Window = UserGetWindowObject(hWnd)))
{
RETURN(-1);
}
}
+ else
+ {
+ Window = (PWINDOW_OBJECT)hWnd;
+ }
if (MsgFilterMax < MsgFilterMin)
{
MsgFilterMax = 0;
}
- Present = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
+ Present = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, RemoveMsg);
if (Present)
{
Info.LParamSize = Size;
UserMem = NULL;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
- &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
+ &Size, MEM_COMMIT, PAGE_READWRITE);
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( (BOOL) -1);
}
/* Transfer lParam data to user-mode mem */
- Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
+ Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Info.LParamSize);
if (! NT_SUCCESS(Status))
{
ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
- &Info.LParamSize, MEM_RELEASE);
+ &Size, MEM_RELEASE);
SetLastNtError(Status);
RETURN( (BOOL) -1);
}
}
static BOOL FASTCALL
-co_IntWaitMessage(HWND Wnd,
+co_IntWaitMessage(PWINDOW_OBJECT Window,
UINT MsgFilterMin,
UINT MsgFilterMax)
{
+ PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue;
NTSTATUS Status;
USER_MESSAGE Msg;
- ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetCurrentThreadWin32Thread()->MessageQueue;
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
do
{
- if (co_IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_NOREMOVE))
+ if (co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, PM_NOREMOVE))
{
return TRUE;
}
/* Nothing found. Wait for new messages. */
- Status = co_MsqWaitForNewMessages(ThreadQueue, Wnd, MsgFilterMin, MsgFilterMax);
+ Status = co_MsqWaitForNewMessages(ThreadQueue, Window, MsgFilterMin, MsgFilterMax);
}
while ((STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) || STATUS_TIMEOUT == Status);
return FALSE;
}
-BOOL STDCALL
+BOOL APIENTRY
NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
HWND hWnd,
UINT MsgFilterMin,
BOOL GotMessage;
NTUSERGETMESSAGEINFO Info;
NTSTATUS Status;
+ /* FIXME: if initialization is removed, gcc complains that this may be used before initialization. Please review */
PWINDOW_OBJECT Window = NULL;
PMSGMEMORY MsgMemoryEntry;
PVOID UserMem;
- UINT Size;
+ SIZE_T Size;
USER_MESSAGE Msg;
DECLARE_RETURN(BOOL);
// USER_REFERENCE_ENTRY Ref;
do
{
- GotMessage = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE);
+ GotMessage = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, PM_REMOVE);
if (GotMessage)
{
Info.Msg = Msg.Msg;
Info.LParamSize = Size;
UserMem = NULL;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
- &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
+ &Size, MEM_COMMIT, PAGE_READWRITE);
if (! NT_SUCCESS(Status))
{
RETURN( (BOOL) -1);
}
/* Transfer lParam data to user-mode mem */
- Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
+ Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Info.LParamSize);
if (! NT_SUCCESS(Status))
{
ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
- &Info.LParamSize, MEM_DECOMMIT);
+ &Size, MEM_DECOMMIT);
SetLastNtError(Status);
RETURN( (BOOL) -1);
}
RETURN( (BOOL) -1);
}
}
- else if (! co_IntWaitMessage(hWnd, MsgFilterMin, MsgFilterMax))
+ else if (! co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax))
{
RETURN( (BOOL) -1);
}
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
- ExFreePool(KernelMem);
+ ExFreePoolWithTag(KernelMem, TAG_MSG);
return Status;
}
}
return STATUS_SUCCESS;
}
+BOOL FASTCALL
+UserPostThreadMessage( DWORD idThread,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ MSG Message;
+ PETHREAD peThread;
+ PTHREADINFO pThread;
+ LARGE_INTEGER LargeTickCount;
+ NTSTATUS Status;
+
+ DPRINT1("UserPostThreadMessage wParam 0x%x lParam 0x%x\n", wParam,lParam);
+
+ if (FindMsgMemory(Msg) != 0)
+ {
+ SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
+
+ Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
+
+ if( Status == STATUS_SUCCESS )
+ {
+ pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
+ if( !pThread || !pThread->MessageQueue )
+ {
+ ObDereferenceObject( peThread );
+ return FALSE;
+ }
+
+ Message.hwnd = NULL;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
+ IntGetCursorLocation(pThread->Desktop->WindowStation, &Message.pt);
+ KeQueryTickCount(&LargeTickCount);
+ pThread->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
+ MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
+ ObDereferenceObject( peThread );
+ return TRUE;
+ }
+ else
+ {
+ SetLastNtError( Status );
+ }
+ return FALSE;
+}
+
BOOL FASTCALL
UserPostMessage(HWND Wnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
- MSG UserModeMsg, KernelModeMsg;
+ PTHREADINFO pti;
+ MSG Message;
LARGE_INTEGER LargeTickCount;
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
- if (WM_QUIT == Msg)
+ if (FindMsgMemory(Msg) != 0)
{
- MsqPostQuitMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, wParam);
+ SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
}
- else if (Wnd == HWND_BROADCAST)
+
+ if (!Wnd)
+ return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
+ Msg,
+ wParam,
+ lParam);
+
+ pti = PsGetCurrentThreadWin32Thread();
+ if (Wnd == HWND_BROADCAST)
{
HWND *List;
PWINDOW_OBJECT DesktopWindow;
return FALSE;
}
- UserModeMsg.hwnd = Wnd;
- UserModeMsg.message = Msg;
- UserModeMsg.wParam = wParam;
- UserModeMsg.lParam = lParam;
- MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
- Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
- if (! NT_SUCCESS(Status))
+ if (WM_QUIT == Msg)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
+ MsqPostQuitMessage(Window->MessageQueue, wParam);
+ }
+ else
+ {
+ Message.hwnd = Wnd;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
+ IntGetCursorLocation(pti->Desktop->WindowStation, &Message.pt);
+ KeQueryTickCount(&LargeTickCount);
+ pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
+ MsqPostMessage(Window->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
}
- IntGetCursorLocation(PsGetCurrentThreadWin32Thread()->Desktop->WindowStation,
- &KernelModeMsg.pt);
- KeQueryTickCount(&LargeTickCount);
- KernelModeMsg.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(Window->MessageQueue, &KernelModeMsg,
- NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
- QS_POSTMESSAGE);
}
-
return TRUE;
}
-BOOL STDCALL
+BOOL APIENTRY
NtUserPostMessage(HWND hWnd,
UINT Msg,
WPARAM wParam,
DPRINT("Enter NtUserPostMessage\n");
UserEnterExclusive();
- RETURN(UserPostMessage(hWnd, Msg, wParam, lParam));
+ RETURN( UserPostMessage(hWnd, Msg, wParam, lParam));
CLEANUP:
DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
-BOOL STDCALL
+BOOL APIENTRY
NtUserPostThreadMessage(DWORD idThread,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
- MSG UserModeMsg, KernelModeMsg;
- PETHREAD peThread;
- PW32THREAD pThread;
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserPostThreadMessage\n");
UserEnterExclusive();
- Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
-
- if( Status == STATUS_SUCCESS )
- {
- pThread = (PW32THREAD)peThread->Tcb.Win32Thread;
- if( !pThread || !pThread->MessageQueue )
- {
- ObDereferenceObject( peThread );
- RETURN( FALSE);
- }
-
- UserModeMsg.hwnd = NULL;
- UserModeMsg.message = Msg;
- UserModeMsg.wParam = wParam;
- UserModeMsg.lParam = lParam;
- MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
- Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
- if (! NT_SUCCESS(Status))
- {
- ObDereferenceObject( peThread );
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( FALSE);
- }
- MsqPostMessage(pThread->MessageQueue, &KernelModeMsg,
- NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
- QS_POSTMESSAGE);
- ObDereferenceObject( peThread );
- RETURN( TRUE);
- }
- else
- {
- SetLastNtError( Status );
- RETURN( FALSE);
- }
+ RETURN( UserPostThreadMessage( idThread,
+ Msg,
+ wParam,
+ lParam));
CLEANUP:
DPRINT("Leave NtUserPostThreadMessage, ret=%i\n",_ret_);
END_CLEANUP;
}
-DWORD STDCALL
+DWORD APIENTRY
NtUserQuerySendMessage(DWORD Unknown0)
{
UNIMPLEMENTED;
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
LPARAM lParamPacked;
- PW32THREAD Win32Thread;
+ PTHREADINFO Win32Thread;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
- BOOL SameThread = FALSE;
if (!(Window = UserGetWindowObject(hWnd)))
{
Win32Thread = PsGetCurrentThreadWin32Thread();
- if (Window->ti == Win32Thread->ThreadInfo)
- SameThread = TRUE;
+ IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
- if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) ||
- (SameThread && ISITHOOKED(WH_CALLWNDPROC)) )
- {
- CWPSTRUCT CWP;
- CWP.hwnd = hWnd;
- CWP.message = Msg;
- CWP.wParam = wParam;
- CWP.lParam = lParam;
- co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
- }
-
if (NULL != Win32Thread &&
Window->MessageQueue == Win32Thread->MessageQueue)
{
RETURN( FALSE);
}
- Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->WndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
+ Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->lpfnWndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
lParamPacked,lParamBufferSize);
if(uResult)
*uResult = Result;
}
- if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
- (SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) )
- {
- CWPRETSTRUCT CWPR;
- CWPR.hwnd = hWnd;
- CWPR.message = Msg;
- CWPR.wParam = wParam;
- CWPR.lParam = lParam;
- CWPR.lResult = Result;
- co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
- }
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam)))
{
lParam,
uTimeout,
(uFlags & SMTO_BLOCK),
- FALSE,
+ MSQ_NORMAL,
uResult);
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
!MsqIsHung(Window->MessageQueue));
- if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
- (SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) )
- {
- CWPRETSTRUCT CWPR;
- CWPR.hwnd = hWnd;
- CWPR.message = Msg;
- CWPR.wParam = wParam;
- CWPR.lParam = lParam;
- CWPR.lResult = *uResult;
- co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
- }
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
if (STATUS_TIMEOUT == Status)
{
-/*
+/*
MSDN says:
Microsoft Windows 2000: If GetLastError returns zero, then the function
timed out.
LPARAM lParam)
{
ULONG_PTR Result;
+ PTHREADINFO pti;
PWINDOW_OBJECT Window;
if(hWnd == HWND_BROADCAST)
return 0;
}
- if(Window->MessageQueue != PsGetCurrentThreadWin32Thread()->MessageQueue)
+ pti = PsGetCurrentThreadWin32Thread();
+ if(Window->MessageQueue != pti->MessageQueue && FindMsgMemory(Msg) ==0)
{
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
}
PDOSENDMESSAGE dsm,
PNTUSERSENDMESSAGEINFO UnsafeInfo)
{
+ PTHREADINFO pti;
LRESULT Result = TRUE;
NTSTATUS Status;
- PWINDOW_OBJECT Window;
+ PWINDOW_OBJECT Window = NULL;
NTUSERSENDMESSAGEINFO Info;
MSG UserModeMsg;
MSG KernelModeMsg;
/* FIXME: Check for an exiting window. */
/* See if the current thread can handle the message */
- if (HWND_BROADCAST != hWnd && NULL != PsGetCurrentThreadWin32Thread() &&
- Window->MessageQueue == PsGetCurrentThreadWin32Thread()->MessageQueue)
+ pti = PsGetCurrentThreadWin32Thread();
+ if (HWND_BROADCAST != hWnd && NULL != pti &&
+ Window->MessageQueue == pti->MessageQueue)
{
/* Gather the information usermode needs to call the window proc directly */
Info.HandledByKernel = FALSE;
Info.Ansi = ! Window->Wnd->Unicode;
}
+ IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+
if (Window->Wnd->IsSystem)
{
- Info.Proc = (!Info.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
+ Info.Proc = (!Info.Ansi ? Window->Wnd->lpfnWndProc : Window->Wnd->WndProcExtra);
}
else
{
Info.Ansi = !Window->Wnd->Unicode;
- Info.Proc = Window->Wnd->WndProc;
+ Info.Proc = Window->Wnd->lpfnWndProc;
}
+
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result);
+
}
else
{
return (LRESULT)Result;
}
-LRESULT STDCALL
+LRESULT APIENTRY
NtUserSendMessageTimeout(HWND hWnd,
UINT Msg,
WPARAM wParam,
END_CLEANUP;
}
-LRESULT STDCALL
+LRESULT APIENTRY
NtUserSendMessage(HWND Wnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
BOOL Result = TRUE;
+
+ if (FindMsgMemory(Msg) != 0)
+ {
+ SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
+
// Basicly the same as IntPostOrSendMessage
if (hWnd == HWND_BROADCAST) //Handle Broadcast
{
else
{
ULONG_PTR PResult;
+ PTHREADINFO pti;
PWINDOW_OBJECT Window;
- NTSTATUS Status;
- MSG UserModeMsg;
- MSG KernelModeMsg;
- PMSGMEMORY MsgMemoryEntry;
+ MSG Message;
if(!(Window = UserGetWindowObject(hWnd))) return FALSE;
- if(Window->MessageQueue != PsGetCurrentThreadWin32Thread()->MessageQueue)
+ pti = PsGetCurrentThreadWin32Thread();
+ if(Window->MessageQueue != pti->MessageQueue)
{ // Send message w/o waiting for it.
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
}
else
{ // Handle message and callback.
- 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))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- Result = co_IntSendMessageTimeoutSingle(
- KernelModeMsg.hwnd, KernelModeMsg.message,
- KernelModeMsg.wParam, KernelModeMsg.lParam,
- SMTO_NORMAL, 0, &PResult);
+ Message.hwnd = hWnd;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
- Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
- if (! NT_SUCCESS(Status))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ Result = co_IntSendMessageTimeoutSingle( hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &PResult);
}
}
return Result;
}
-BOOL STDCALL
-NtUserSendNotifyMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- DECLARE_RETURN(BOOL);
-
- DPRINT("EnterNtUserSendNotifyMessage\n");
- UserEnterExclusive();
-
- RETURN(UserSendNotifyMessage(hWnd, Msg, wParam, lParam));
-
-CLEANUP:
- DPRINT("Leave NtUserSendNotifyMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-
-}
-
-
-BOOL STDCALL
+BOOL APIENTRY
NtUserWaitMessage(VOID)
{
DECLARE_RETURN(BOOL);
END_CLEANUP;
}
-DWORD STDCALL
+DWORD APIENTRY
IntGetQueueStatus(BOOL ClearChanges)
{
+ PTHREADINFO pti;
PUSER_MESSAGE_QUEUE Queue;
DWORD Result;
DECLARE_RETURN(DWORD);
DPRINT("Enter IntGetQueueStatus\n");
- Queue = PsGetCurrentThreadWin32Thread()->MessageQueue;
+ pti = PsGetCurrentThreadWin32Thread();
+ Queue = pti->MessageQueue;
Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
if (ClearChanges)
END_CLEANUP;
}
-BOOL STDCALL
+BOOL APIENTRY
IntInitMessagePumpHook()
{
- if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
+ if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
{
- ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook++;
+ ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook++;
return TRUE;
}
return FALSE;
}
-BOOL STDCALL
+BOOL APIENTRY
IntUninitMessagePumpHook()
{
- if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
+ if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
{
- if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook <= 0)
+ if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook <= 0)
{
return FALSE;
}
- ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook--;
+ ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook--;
return TRUE;
}
return FALSE;
}
-LRESULT STDCALL
+BOOL APIENTRY
NtUserMessageCall(
HWND hWnd,
UINT Msg,
BOOL Ansi)
{
LRESULT lResult = 0;
+ BOOL Ret = FALSE;
+ BOOL BadChk = FALSE;
PWINDOW_OBJECT Window = NULL;
USER_REFERENCE_ENTRY Ref;
/* Validate input */
if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
{
- return 0;
- }
+ UserLeave();
+ return FALSE;
+ }
switch(dwType)
{
case FNID_DEFWINDOWPROC:
UserRefObjectCo(Window, &Ref);
lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
+ Ret = TRUE;
UserDerefObjectCo(Window);
break;
+ case FNID_SENDNOTIFYMESSAGE:
+ Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam);
+ break;
case FNID_BROADCASTSYSTEMMESSAGE:
{
- PBROADCASTPARM parm;
- BOOL BadChk = FALSE;
+ BROADCASTPARM parm;
DWORD_PTR RetVal = 0;
- lResult = -1;
if (ResultInfo)
{
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForWrite((PVOID)ResultInfo,
sizeof(BROADCASTPARM),
- 1);
- parm = (PBROADCASTPARM)ResultInfo;
+ 1);
+ RtlCopyMemory(&parm, (PVOID)ResultInfo, sizeof(BROADCASTPARM));
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
BadChk = TRUE;
}
- _SEH_END;
+ _SEH2_END;
if (BadChk) break;
}
else
break;
- if ( parm->recipients & BSM_ALLDESKTOPS ||
- parm->recipients == BSM_ALLCOMPONENTS )
+ if ( parm.recipients & BSM_ALLDESKTOPS ||
+ parm.recipients == BSM_ALLCOMPONENTS )
{
}
- else if (parm->recipients & BSM_APPLICATIONS)
+ else if (parm.recipients & BSM_APPLICATIONS)
{
- if (parm->flags & BSF_QUERY)
+ if (parm.flags & BSF_QUERY)
{
- if (parm->flags & BSF_FORCEIFHUNG || parm->flags & BSF_NOHANG)
+ if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG)
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
2000,
&RetVal);
}
- else if (parm->flags & BSF_NOTIMEOUTIFNOTHUNG)
+ else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG)
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
&RetVal);
}
}
- else if (parm->flags & BSF_POSTMESSAGE)
+ else if (parm.flags & BSF_POSTMESSAGE)
{
- lResult = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
}
- else if ( parm->flags & BSF_SENDNOTIFYMESSAGE)
+ else if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
{
- lResult = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
}
}
}
case FNID_CALLWNDPROC:
case FNID_CALLWNDPROCRET:
{
- PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
+ PCLIENTINFO ClientInfo = GetWin32ClientInfo();
PHOOK NextObj, Hook = ClientInfo->phkCurrent;
if (!ClientInfo || !Hook) break;
-
+
UserReferenceObject(Hook);
if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
NextObj = IntGetNextHook(Hook);
ClientInfo->phkCurrent = NextObj;
-
+
if ( Hook->HookId == WH_CALLWNDPROC)
{
CWPSTRUCT CWP;
CWP.wParam = wParam;
CWP.lParam = lParam;
DPRINT("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
-
+
lResult = co_IntCallHookProc( Hook->HookId,
HC_ACTION,
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
- (LPARAM)&CWP,
+ (LPARAM)&CWP,
Hook->Proc,
Hook->Ansi,
&Hook->ModuleName);
HC_ACTION,
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
(LPARAM)&CWPR,
- Hook->Proc,
+ Hook->Proc,
Hook->Ansi,
&Hook->ModuleName);
}
}
break;
}
+
+ switch(dwType)
+ {
+ case FNID_DEFWINDOWPROC:
+ case FNID_CALLWNDPROC:
+ case FNID_CALLWNDPROCRET:
+ if (ResultInfo)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite((PVOID)ResultInfo, sizeof(LRESULT), 1);
+ RtlCopyMemory((PVOID)ResultInfo, &lResult, sizeof(LRESULT));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ BadChk = TRUE;
+ }
+ _SEH2_END;
+ }
+ break;
+ default:
+ break;
+ }
+
UserLeave();
- return lResult;
+
+ return BadChk ? FALSE : Ret;
}
#define INFINITE 0xFFFFFFFF
#define WAIT_FAILED ((DWORD)0xFFFFFFFF)
DWORD
-NTAPI
+APIENTRY
NtUserWaitForInputIdle(
IN HANDLE hProcess,
IN DWORD dwMilliseconds,
IN BOOL Unknown2)
{
PEPROCESS Process;
- PW32PROCESS W32Process;
+ PPROCESSINFO W32Process;
NTSTATUS Status;
HANDLE Handles[2];
- LARGE_INTEGER Timeout;
+ LARGE_INTEGER Timeout;
ULONGLONG StartTime, Run, Elapsed = 0;
UserEnterExclusive();
return WAIT_FAILED;
}
- W32Process = (PW32PROCESS)Process->Win32Process;
+ W32Process = (PPROCESSINFO)Process->Win32Process;
if (!W32Process)
{
ObDereferenceObject(Process);
return STATUS_SUCCESS; /* no event to wait on */
}
- StartTime = ((ULONGLONG)SharedUserData->TickCountLowDeprecated *
- SharedUserData->TickCountMultiplier / 16777216);
+ StartTime = EngGetTickCount();
Run = dwMilliseconds;
if (dwMilliseconds != INFINITE)
{
- Elapsed = ((ULONGLONG)SharedUserData->TickCountLowDeprecated *
- SharedUserData->TickCountMultiplier / 16777216)
- - StartTime;
+ Elapsed = EngGetTickCount() - StartTime;
if (Elapsed > Run)
Status = STATUS_TIMEOUT;