#include <debug.h>
BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process);
-HWND FASTCALL co_UserSetCapture(HWND hWnd);
#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
{
PMSGMEMORY MsgMemoryEntry;
PVOID PackedData;
+ SIZE_T size;
MsgMemoryEntry = FindMsgMemory(Msg);
/* Keep previous behavior */
return STATUS_SUCCESS;
}
- PackedData = ExAllocatePoolWithTag(NonPagedPool, MsgMemorySize(MsgMemoryEntry, wParam, lParam), TAG_MSG);
+ size = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ if (!size)
+ {
+ DPRINT1("No size for lParamPacked\n");
+ return STATUS_SUCCESS;
+ }
+ PackedData = ExAllocatePoolWithTag(NonPagedPool, size, TAG_MSG);
RtlCopyMemory(PackedData, (PVOID)lParam, MsgMemorySize(MsgMemoryEntry, wParam, lParam));
*lParamPacked = (LPARAM)PackedData;
}
}
/* Now check for normal messages. */
- if ((ProcessMask & QS_POSTMESSAGE) &&
+ if (( (ProcessMask & QS_POSTMESSAGE) ||
+ (ProcessMask & QS_HOTKEY) ) &&
MsqPeekMessage( ThreadQueue,
RemoveMessages,
Window,
{
SetLastNtError(Status);
DPRINT1("Exit co_IntWaitMessage on error!\n");
-
return FALSE;
}
+ if (Status == STATUS_USER_APC || Status == STATUS_TIMEOUT)
+ {
+ return FALSE;
+ }
}
while ( TRUE );
co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)pMsg);
- if ( bGMSG )
- {
- Present = (WM_QUIT != pMsg->message);
- break;
- }
+ if ( bGMSG ) break;
}
if ( bGMSG )
Window,
MsgFilterMin,
MsgFilterMax);
- if ( !NT_SUCCESS(Status) )
+ if ( !NT_SUCCESS(Status) ||
+ Status == STATUS_USER_APC ||
+ Status == STATUS_TIMEOUT )
{
Present = -1;
break;
PTHREADINFO pti;
MSG Message, KernelModeMsg;
LARGE_INTEGER LargeTickCount;
- PMSGMEMORY MsgMemoryEntry;
Message.hwnd = Wnd;
Message.message = Msg;
KeQueryTickCount(&LargeTickCount);
Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsgMemoryEntry = FindMsgMemory(Message.message);
+ if (is_pointer_message(Message.message))
+ {
+ EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
if( Msg >= WM_DDE_FIRST && Msg <= WM_DDE_LAST )
{
NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
+
+ MsgMemoryEntry = FindMsgMemory(Message.message);
Status = CopyMsgToKernelMem(&KernelModeMsg, &Message, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
return TRUE;
}
- if (is_pointer_message(Message.message))
- {
- EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
- return FALSE;
- }
-
if (!Wnd)
{
return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
if (STATUS_TIMEOUT == Status)
{
- /*
-MSDN says:
+/*
+ MSDN says:
Microsoft Windows 2000: If GetLastError returns zero, then the function
timed out.
XP+ : If the function fails or times out, the return value is zero.
Win32Thread = PsGetCurrentThreadWin32Thread();
- IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
-
if (Win32Thread == NULL)
{
- ASSERT(FALSE);
- RETURN(FALSE);
- }
-
- if (Win32Thread->TIF_flags & TIF_INCLEANUP)
- {
- /* Never send messages to exiting threads */
RETURN(FALSE);
}
RETURN( FALSE);
}
- /* If this is not a callback and it can be sent now, then send it. */
- if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+ /* If it can be sent now, then send it. */
+ if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
{
+ if (Win32Thread->TIF_flags & TIF_INCLEANUP)
+ {
+ UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE);
+ /* Never send messages to exiting threads */
+ RETURN(FALSE);
+ }
+
+ IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+
ObReferenceObject(Win32Thread->pEThread);
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
*uResult = Result;
}
ObDereferenceObject(Win32Thread->pEThread);
+
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+
+ if (CompletionCallback)
+ {
+ co_IntCallSentMessageCallback(CompletionCallback,
+ hWnd,
+ Msg,
+ CompletionCallbackContext,
+ Result);
+ }
}
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
- if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+
+ if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
{
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
RETURN( FALSE);
}
+ IntReferenceMessageQueue(Window->head.pti->MessageQueue);
+ /* Take reference on this MessageQueue if its a callback. It will be released
+ when message is processed or removed from target hwnd MessageQueue */
+ if (CompletionCallback)
+ IntReferenceMessageQueue(Win32Thread->MessageQueue);
+
Message->Msg.hwnd = hWnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
Message->QS_Flags = 0;
Message->SenderQueue = NULL; // mjmartin, you are right! This is null.
Message->CallBackSenderQueue = Win32Thread->MessageQueue;
-
- IntReferenceMessageQueue(Window->head.pti->MessageQueue);
+ Message->DispatchingListEntry.Flink = NULL;
Message->CompletionCallback = CompletionCallback;
Message->CompletionCallbackContext = CompletionCallbackContext;
- Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
+ Message->HookMessage = MSQ_NORMAL;
Message->HasPackedLParam = (lParamBufferSize > 0);
-
Message->QS_Flags = QS_SENDMESSAGE;
- MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE);
InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
+ MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, TRUE);
IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
RETURN(TRUE);
UserLeave();
- if (Ret)
+ if (Ret == TRUE)
{
_SEH2_TRY
{
_SEH2_END;
}
+ if ((INT)Ret != -1)
+ Ret = Ret ? (WM_QUIT != pMsg->message) : FALSE;
+
return Ret;
}