- ATI fixup CORE-6551.
- Giannis Adamopoulos fragment patch 18.

svn path=/trunk/; revision=58986
This commit is contained in:
James Tabor 2013-05-10 22:28:18 +00:00
parent 7647f53075
commit 016d53260e
15 changed files with 395 additions and 432 deletions

View file

@ -76,6 +76,10 @@
/* Non SDK Queue state flags. */
#define QS_SMRESULT 0x8000 /* see "Undoc. Windows" */
//
#define QS_EVENT 0x2000
#define QS_SYSEVENT (QS_EVENT|QS_SENDMESSAGE)
//
//
// Definitions used by WM_CLIENTSHUTDOWN

View file

@ -113,7 +113,7 @@ IntCallLowLevelEvent( PEVENTHOOK pEH,
/* FIXME: Should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
Status = co_MsqSendMessage( pEH->head.pti->MessageQueue,
Status = co_MsqSendMessage( pEH->head.pti,
hwnd,
event,
0,

View file

@ -296,18 +296,18 @@ IntFindChildWindowToOwner(PWND Root, PWND Owner)
VOID FASTCALL
FindRemoveAsyncMsg(PWND Wnd)
{
PUSER_MESSAGE_QUEUE MessageQueue;
PTHREADINFO pti;
PUSER_SENT_MESSAGE Message;
PLIST_ENTRY Entry;
if (!Wnd) return;
MessageQueue = Wnd->head.pti->MessageQueue;
pti = Wnd->head.pti;
if (!IsListEmpty(&MessageQueue->SentMessagesListHead))
if (!IsListEmpty(&pti->SentMessagesListHead))
{
// Scan sent queue messages to see if we received async messages.
Entry = MessageQueue->SentMessagesListHead.Flink;
Entry = pti->SentMessagesListHead.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
do
{
@ -321,7 +321,7 @@ FindRemoveAsyncMsg(PWND Wnd)
Entry = Message->ListEntry.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
}
while (Entry != &MessageQueue->SentMessagesListHead);
while (Entry != &pti->SentMessagesListHead);
}
}
@ -787,7 +787,7 @@ co_UserSetCapture(HWND hWnd)
}
}
hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd);
hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);
if (hWndPrev)
{
@ -815,8 +815,8 @@ co_UserSetCapture(HWND hWnd)
MOUSEINPUT mi;
/// These are HACKS!
/* Also remove other windows if not capturing anymore */
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL);
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL);
MsqSetStateWindow(pti, MSQ_STATE_MENUOWNER, NULL);
MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, NULL);
///
/* Somebody may have missed some mouse movements */
mi.dx = 0;

View file

@ -295,7 +295,7 @@ co_IntCallLowLevelHook(PHOOK Hook,
/* FIXME: Should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
Status = co_MsqSendMessage( pti->MessageQueue,
Status = co_MsqSendMessage( pti,
IntToPtr(Code), // hWnd
Hook->HookId, // Msg
wParam,

View file

@ -763,6 +763,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
{
WORD wSimpleVk = 0, wFixedVk, wVk2;
PUSER_MESSAGE_QUEUE pFocusQueue;
PTHREADINFO pti;
BOOL bExt = (dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE;
@ -873,6 +874,14 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
Wnd = pFocusQueue->spwndActive;
}
if ( !Wnd || Wnd->state2 & WNDS2_INDESTROY || Wnd->state & WNDS_DESTROYED )
{
ERR("ProcessKeyEvent Active Focus window is dead!\n");
return FALSE;
}
pti = Wnd->head.pti;
/* Init message */
Msg.hwnd = UserHMGetHandle(Wnd);
Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */
@ -900,7 +909,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
/* Post a keyboard message */
TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY, 0);
MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0);
}
return TRUE;
@ -913,7 +922,6 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
PKL pKl = NULL;
PKBDTABLES pKbdTbl;
PUSER_MESSAGE_QUEUE pFocusQueue;
struct _ETHREAD *pFocusThread;
LARGE_INTEGER LargeTickCount;
DWORD dwTime;
BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
@ -923,11 +931,9 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
/* Find the target thread whose locale is in effect */
pFocusQueue = IntGetFocusMessageQueue();
if (pFocusQueue)
if (pFocusQueue && pFocusQueue->ptiOwner)
{
pFocusThread = pFocusQueue->Thread;
if (pFocusThread && pFocusThread->Tcb.Win32Thread)
pKl = ((PTHREADINFO)pFocusThread->Tcb.Win32Thread)->KeyboardLayout;
pKl = pFocusQueue->ptiOwner->KeyboardLayout;
}
if (!pKl)
@ -997,7 +1003,6 @@ UserProcessKeyboardInput(
PKL pKl = NULL;
PKBDTABLES pKbdTbl;
PUSER_MESSAGE_QUEUE pFocusQueue;
struct _ETHREAD *pFocusThread;
/* Calculate scan code with prefix */
wScanCode = pKbdInputData->MakeCode & 0x7F;
@ -1009,11 +1014,9 @@ UserProcessKeyboardInput(
/* Find the target thread whose locale is in effect */
pFocusQueue = IntGetFocusMessageQueue();
if (pFocusQueue)
if (pFocusQueue && pFocusQueue->ptiOwner)
{
pFocusThread = pFocusQueue->Thread;
if (pFocusThread && pFocusThread->Tcb.Win32Thread)
pKl = ((PTHREADINFO)pFocusThread->Tcb.Win32Thread)->KeyboardLayout;
pKl = pFocusQueue->ptiOwner->KeyboardLayout;
}
if (!pKl)
@ -1121,7 +1124,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
NewMsg.wParam = HIWORD(lpMsg->lParam);
NewMsg.lParam = LOWORD(lpMsg->lParam);
MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0);
MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0);
return TRUE;
}
@ -1150,7 +1153,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
{
TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
NewMsg.wParam = wch[i];
MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0);
MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0);
}
bResult = TRUE;
}

View file

@ -254,6 +254,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
int i;
NTSTATUS Status = STATUS_SUCCESS;
PTEB pTeb;
LARGE_INTEGER LargeTickCount;
Process = Thread->ThreadsProcess;
@ -281,8 +282,13 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
/* Initialize the THREADINFO */
IntReferenceThreadInfo(ptiCurrent);
InitializeListHead(&ptiCurrent->WindowListHead);
InitializeListHead(&ptiCurrent->W32CallbackListHead);
InitializeListHead(&ptiCurrent->PostedMessagesListHead);
InitializeListHead(&ptiCurrent->SentMessagesListHead);
InitializeListHead(&ptiCurrent->DispatchingMessagesHead);
InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead);
InitializeListHead(&ptiCurrent->PtiLink);
for (i = 0; i < NB_HOOKS; i++)
{
@ -293,6 +299,27 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
ptiCurrent->ppi->ptiList = ptiCurrent;
ptiCurrent->ppi->cThreads++;
ptiCurrent->hEventQueueClient = NULL;
Status = ZwCreateEvent(&ptiCurrent->hEventQueueClient, EVENT_ALL_ACCESS,
NULL, SynchronizationEvent, FALSE);
if (!NT_SUCCESS(Status))
{
goto error;
}
Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
ExEventObjectType, KernelMode,
(PVOID*)&ptiCurrent->pEventQueueServer, NULL);
if (!NT_SUCCESS(Status))
{
ZwClose(ptiCurrent->hEventQueueClient);
ptiCurrent->hEventQueueClient = NULL;
goto error;
}
KeQueryTickCount(&LargeTickCount);
ptiCurrent->timeLast = LargeTickCount.u.LowPart;
ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent);
if(ptiCurrent->MessageQueue == NULL)
{
@ -402,6 +429,35 @@ error:
return Status;
}
/*
Called from IntDereferenceThreadInfo.
*/
VOID
FASTCALL
UserDeleteW32Thread(PTHREADINFO pti)
{
if (!pti->RefCount)
{
ERR_CH(UserThread,"UserDeleteW32Thread pti 0x%p\n",pti);
if (pti->hEventQueueClient != NULL)
ZwClose(pti->hEventQueueClient);
pti->hEventQueueClient = NULL;
/* Free the message queue */
if (pti->MessageQueue)
{
MsqDestroyMessageQueue(pti);
}
MsqCleanupThreadMsgs(pti);
IntSetThreadDesktop(NULL, TRUE);
PsSetThreadWin32Thread(pti->pEThread, NULL);
ExFreePoolWithTag(pti, USERTAG_THREADINFO);
}
}
NTSTATUS
NTAPI
UserDestroyThreadInfo(struct _ETHREAD *Thread)
@ -439,7 +495,7 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread)
if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue)
{
PTHREADINFO ptiTo;
ptiTo = PsGetThreadWin32Thread(ptiCurrent->MessageQueue->Thread);
ptiTo = ptiCurrent->MessageQueue->ptiOwner;
TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n");
if (ptiTo) UserAttachThreadInput( ptiCurrent, ptiTo, FALSE);
else
@ -487,7 +543,7 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread)
HOOK_DestroyThreadHooks(Thread);
EVENT_DestroyThreadEvents(Thread);
DestroyTimersForThread(ptiCurrent);
KeSetEvent(ptiCurrent->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
KeSetEvent(ptiCurrent->pEventQueueServer, IO_NO_INCREMENT, FALSE);
UnregisterThreadHotKeys(Thread);
/*
if (IsListEmpty(&ptiCurrent->WindowListHead))
@ -520,12 +576,6 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread)
}
}
/* Free the message queue */
if (ptiCurrent->MessageQueue)
{
MsqDestroyMessageQueue(ptiCurrent);
}
/* Find the THREADINFO in the PROCESSINFO's list */
ppti = &ppiCurrent->ptiList;
while (*ppti != NULL && *ppti != ptiCurrent)
@ -547,8 +597,7 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread)
TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);
/* Free the THREADINFO */
PsSetThreadWin32Thread(Thread, NULL);
ExFreePoolWithTag(ptiCurrent, USERTAG_THREADINFO);
IntDereferenceThreadInfo(ptiCurrent);
return STATUS_SUCCESS;
}

View file

@ -508,7 +508,7 @@ IdlePing(VOID)
ForegroundQueue = IntGetFocusMessageQueue();
if (ForegroundQueue)
ptiForeground = ForegroundQueue->Thread->Tcb.Win32Thread;
ptiForeground = ForegroundQueue->ptiOwner;
pti = PsGetCurrentThreadWin32Thread();
@ -762,22 +762,15 @@ co_IntPeekMessage( PMSG Msg,
{
PTHREADINFO pti;
LARGE_INTEGER LargeTickCount;
PUSER_MESSAGE_QUEUE ThreadQueue;
BOOL RemoveMessages;
UINT ProcessMask;
BOOL Hit = FALSE;
pti = PsGetCurrentThreadWin32Thread();
ThreadQueue = pti->MessageQueue;
RemoveMessages = RemoveMsg & PM_REMOVE;
ProcessMask = HIWORD(RemoveMsg);
if (ThreadQueue->ptiSysLock && ThreadQueue->ptiSysLock != pti)
{
ERR("PeekMessage: Thread Q 0x%p is locked 0x%p to another pti 0x%p!\n", ThreadQueue, ThreadQueue->ptiSysLock, pti );
}
/* 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);
@ -787,11 +780,11 @@ co_IntPeekMessage( PMSG Msg,
do
{
KeQueryTickCount(&LargeTickCount);
ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
pti->timeLast = LargeTickCount.u.LowPart;
pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart;
/* Dispatch sent messages here. */
while ( co_MsqDispatchOneSentMessage(ThreadQueue) )
while ( co_MsqDispatchOneSentMessage(pti) )
{
/* if some PM_QS* flags were specified, only handle sent messages from now on */
if (HIWORD(RemoveMsg) && !bGMSG) Hit = TRUE; // wine does this; ProcessMask = QS_SENDMESSAGE;
@ -816,7 +809,7 @@ co_IntPeekMessage( PMSG Msg,
/* Now check for normal messages. */
if (( (ProcessMask & QS_POSTMESSAGE) ||
(ProcessMask & QS_HOTKEY) ) &&
MsqPeekMessage( ThreadQueue,
MsqPeekMessage( pti,
RemoveMessages,
Window,
MsgFilterMin,
@ -828,18 +821,18 @@ co_IntPeekMessage( PMSG Msg,
}
/* Now look for a quit message. */
if (ThreadQueue->QuitPosted)
if (pti->QuitPosted)
{
/* According to the PSDK, WM_QUIT messages are always returned, regardless
of the filter specified */
Msg->hwnd = NULL;
Msg->message = WM_QUIT;
Msg->wParam = ThreadQueue->QuitExitCode;
Msg->wParam = pti->exitCode;
Msg->lParam = 0;
if (RemoveMessages)
{
ThreadQueue->QuitPosted = FALSE;
ClearMsgBitsMask(ThreadQueue, QS_POSTMESSAGE);
pti->QuitPosted = FALSE;
ClearMsgBitsMask(pti, QS_POSTMESSAGE);
pti->pcti->fsWakeBits &= ~QS_ALLPOSTMESSAGE;
pti->pcti->fsChangeBits &= ~QS_ALLPOSTMESSAGE;
}
@ -848,7 +841,7 @@ co_IntPeekMessage( PMSG Msg,
/* Check for hardware events. */
if ((ProcessMask & QS_MOUSE) &&
co_MsqPeekMouseMove( ThreadQueue,
co_MsqPeekMouseMove( pti,
RemoveMessages,
Window,
MsgFilterMin,
@ -859,7 +852,7 @@ co_IntPeekMessage( PMSG Msg,
}
if ((ProcessMask & QS_INPUT) &&
co_MsqPeekHardwareMessage( ThreadQueue,
co_MsqPeekHardwareMessage( pti,
RemoveMessages,
Window,
MsgFilterMin,
@ -871,7 +864,7 @@ co_IntPeekMessage( PMSG Msg,
}
/* Check for sent messages again. */
while ( co_MsqDispatchOneSentMessage(ThreadQueue) )
while ( co_MsqDispatchOneSentMessage(pti) )
{
if (HIWORD(RemoveMsg) && !bGMSG) Hit = TRUE;
}
@ -912,12 +905,10 @@ co_IntWaitMessage( PWND Window,
UINT MsgFilterMax )
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue;
NTSTATUS Status = STATUS_SUCCESS;
MSG Msg;
pti = PsGetCurrentThreadWin32Thread();
ThreadQueue = pti->MessageQueue;
do
{
@ -932,7 +923,7 @@ co_IntWaitMessage( PWND Window,
}
/* Nothing found. Wait for new messages. */
Status = co_MsqWaitForNewMessages( ThreadQueue,
Status = co_MsqWaitForNewMessages( pti,
Window,
MsgFilterMin,
MsgFilterMax);
@ -1027,7 +1018,7 @@ co_IntGetPeekMessage( PMSG pMsg,
if ( bGMSG )
{
Status = co_MsqWaitForNewMessages( pti->MessageQueue,
Status = co_MsqWaitForNewMessages( pti,
Window,
MsgFilterMin,
MsgFilterMax);
@ -1105,7 +1096,7 @@ UserPostThreadMessage( DWORD idThread,
KeQueryTickCount(&LargeTickCount);
Message.time = MsqCalculateMessageTime(&LargeTickCount);
MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE, 0);
MsqPostMessage(pThread, &Message, FALSE, QS_POSTMESSAGE, 0);
ObDereferenceObject( peThread );
return TRUE;
}
@ -1224,11 +1215,11 @@ UserPostMessage( HWND Wnd,
if (WM_QUIT == Msg)
{
MsqPostQuitMessage(Window->head.pti->MessageQueue, wParam);
MsqPostQuitMessage(Window->head.pti, wParam);
}
else
{
MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE, 0);
MsqPostMessage(Window->head.pti, &Message, FALSE, QS_POSTMESSAGE, 0);
}
}
return TRUE;
@ -1279,7 +1270,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
Win32Thread = PsGetCurrentThreadWin32Thread();
if ( Win32Thread &&
Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
Window->head.pti == Win32Thread)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
@ -1365,7 +1356,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
RETURN( TRUE);
}
if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti->MessageQueue))
if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti))
{
// FIXME: Set window hung and add to a list.
/* FIXME: Set a LastError? */
@ -1381,7 +1372,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
do
{
Status = co_MsqSendMessage( Window->head.pti->MessageQueue,
Status = co_MsqSendMessage( Window->head.pti,
hWnd,
Msg,
wParam,
@ -1393,7 +1384,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
!MsqIsHung(Window->head.pti->MessageQueue)); // FIXME: Set window hung and add to a list.
!MsqIsHung(Window->head.pti)); // FIXME: Set window hung and add to a list.
if (STATUS_TIMEOUT == Status)
{
@ -1553,7 +1544,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
}
if (Msg & 0x80000000 &&
Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
Window->head.pti == Win32Thread)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP) RETURN( FALSE);
@ -1574,14 +1565,14 @@ co_IntSendMessageWithCallBack( HWND hWnd,
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
}
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti->MessageQueue != Win32Thread->MessageQueue)))
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti != Win32Thread)))
{
ERR("Failed to pack message parameters\n");
RETURN( FALSE);
}
/* If it can be sent now, then send it. */
if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
if (Window->head.pti == Win32Thread)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
@ -1631,7 +1622,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
}
}
if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
if (Window->head.pti == Win32Thread)
{
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
@ -1646,12 +1637,6 @@ co_IntSendMessageWithCallBack( HWND hWnd,
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;
@ -1660,8 +1645,9 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->Result = 0;
Message->lResult = 0;
Message->QS_Flags = 0;
Message->SenderQueue = NULL; // mjmartin, you are right! This is null.
Message->CallBackSenderQueue = Win32Thread->MessageQueue;
Message->ptiReceiver = Window->head.pti;
Message->ptiSender = NULL; // mjmartin, you are right! This is null.
Message->ptiCallBackSender = Win32Thread;
Message->DispatchingListEntry.Flink = NULL;
Message->CompletionCallback = CompletionCallback;
Message->CompletionCallbackContext = CompletionCallbackContext;
@ -1669,9 +1655,11 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->HasPackedLParam = (lParamBufferSize > 0);
Message->QS_Flags = QS_SENDMESSAGE;
InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, TRUE);
IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
if (Msg & 0x80000000) // Higher priority event message!
InsertHeadList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry);
else
InsertTailList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(Window->head.pti, QS_SENDMESSAGE, TRUE);
RETURN(TRUE);
@ -2351,7 +2339,7 @@ NtUserMessageCall( HWND hWnd,
if ( parm.flags & BSF_IGNORECURRENTTASK )
{
if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue )
if ( pwnd->head.pti == gptiCurrent )
continue;
}
co_IntSendMessageTimeout( List[i],
@ -2406,7 +2394,7 @@ NtUserMessageCall( HWND hWnd,
if ( parm.flags & BSF_IGNORECURRENTTASK )
{
if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue )
if ( pwnd->head.pti == gptiCurrent )
continue;
}
UserPostMessage(List[i], Msg, wParam, lParam);
@ -2432,7 +2420,7 @@ NtUserMessageCall( HWND hWnd,
if ( parm.flags & BSF_IGNORECURRENTTASK )
{
if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue )
if ( pwnd->head.pti == gptiCurrent )
continue;
}
UserSendNotifyMessage(List[i], Msg, wParam, lParam);
@ -2489,7 +2477,7 @@ NtUserMessageCall( HWND hWnd,
if ( parm.flags & BSF_IGNORECURRENTTASK )
{
if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue )
if ( pwnd->head.pti == gptiCurrent )
continue;
}
co_IntSendMessageTimeout( List[i],
@ -2543,7 +2531,7 @@ NtUserMessageCall( HWND hWnd,
if ( parm.flags & BSF_IGNORECURRENTTASK )
{
if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue )
if ( pwnd->head.pti == gptiCurrent )
continue;
}
UserPostMessage(List[i], Msg, wParam, lParam);
@ -2569,7 +2557,7 @@ NtUserMessageCall( HWND hWnd,
if ( parm.flags & BSF_IGNORECURRENTTASK )
{
if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue )
if ( pwnd->head.pti == gptiCurrent )
continue;
}
UserSendNotifyMessage(List[i], Msg, wParam, lParam);
@ -2812,7 +2800,7 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
Handles[0] = Process;
Handles[1] = W32Process->InputIdleEvent;
Handles[2] = pti->MessageQueue->NewMessages; // pEventQueueServer; IntMsqSetWakeMask returns hEventQueueClient
Handles[2] = pti->pEventQueueServer; // IntMsqSetWakeMask returns hEventQueueClient
if (!Handles[1])
{

View file

@ -188,7 +188,7 @@ NtUserGetThreadState(
ret = ISMEX_NOSEND;
if (Message)
{
if (Message->SenderQueue)
if (Message->ptiSender)
ret = ISMEX_SEND;
else
{
@ -213,7 +213,7 @@ NtUserGetThreadState(
LARGE_INTEGER LargeTickCount;
pti = PsGetCurrentThreadWin32Thread();
KeQueryTickCount(&LargeTickCount);
pti->MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
pti->timeLast = LargeTickCount.u.LowPart;
pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart;
}
break;

View file

@ -347,7 +347,6 @@ HANDLE FASTCALL
IntMsqSetWakeMask(DWORD WakeMask)
{
PTHREADINFO Win32Thread;
PUSER_MESSAGE_QUEUE MessageQueue;
HANDLE MessageEventHandle;
DWORD dwFlags = HIWORD(WakeMask);
@ -355,9 +354,8 @@ IntMsqSetWakeMask(DWORD WakeMask)
if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
return 0;
MessageQueue = Win32Thread->MessageQueue;
// Win32Thread->pEventQueueServer; IntMsqSetWakeMask returns Win32Thread->hEventQueueClient
MessageEventHandle = MessageQueue->NewMessagesHandle;
MessageEventHandle = Win32Thread->hEventQueueClient;
if (Win32Thread->pcti)
{
@ -365,7 +363,7 @@ IntMsqSetWakeMask(DWORD WakeMask)
( (dwFlags & MWMO_INPUTAVAILABLE) && (Win32Thread->pcti->fsWakeBits & LOWORD(WakeMask)) ) )
{
ERR("Chg 0x%x Wake 0x%x Mask 0x%x\n",Win32Thread->pcti->fsChangeBits, Win32Thread->pcti->fsWakeBits, WakeMask);
KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); // Wake it up!
KeSetEvent(Win32Thread->pEventQueueServer, IO_NO_INCREMENT, FALSE); // Wake it up!
return MessageEventHandle;
}
}
@ -396,55 +394,64 @@ IntMsqClearWakeMask(VOID)
and even if the bits are all cleared. The same as cTimers/cPaintsReady.
I think this is the best solution... (jt) */
VOID FASTCALL
MsqWakeQueue(PUSER_MESSAGE_QUEUE Queue, DWORD MessageBits, BOOL KeyEvent)
MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent)
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE Queue;
Queue = pti->MessageQueue;
if (Queue->QF_flags & QF_INDESTROY)
{
ERR("This Message Queue is in Destroy!\n");
}
pti = Queue->Thread->Tcb.Win32Thread;
pti->pcti->fsWakeBits |= MessageBits;
pti->pcti->fsChangeBits |= MessageBits;
// Start bit accounting to help clear the main set of bits.
if (MessageBits & QS_KEY) Queue->nCntsQBits[QSRosKey]++;
if (MessageBits & QS_MOUSEMOVE) Queue->nCntsQBits[QSRosMouseMove]++;
if (MessageBits & QS_MOUSEBUTTON) Queue->nCntsQBits[QSRosMouseButton]++;
if (MessageBits & QS_POSTMESSAGE) Queue->nCntsQBits[QSRosPostMessage]++;
if (MessageBits & QS_SENDMESSAGE) Queue->nCntsQBits[QSRosSendMessage]++;
if (MessageBits & QS_HOTKEY) Queue->nCntsQBits[QSRosHotKey]++;
if (MessageBits & QS_KEY)
{
pti->nCntsQBits[QSRosKey]++;
}
if (MessageBits & QS_MOUSE)
{
if (MessageBits & QS_MOUSEMOVE) pti->nCntsQBits[QSRosMouseMove]++;
if (MessageBits & QS_MOUSEBUTTON) pti->nCntsQBits[QSRosMouseButton]++;
}
if (MessageBits & QS_POSTMESSAGE) pti->nCntsQBits[QSRosPostMessage]++;
if (MessageBits & QS_SENDMESSAGE) pti->nCntsQBits[QSRosSendMessage]++;
if (MessageBits & QS_HOTKEY) pti->nCntsQBits[QSRosHotKey]++;
if (MessageBits & QS_EVENT) pti->nCntsQBits[QSRosEvent]++;
if (KeyEvent)
KeSetEvent(Queue->NewMessages, IO_NO_INCREMENT, FALSE);
KeSetEvent(pti->pEventQueueServer, IO_NO_INCREMENT, FALSE);
}
VOID FASTCALL
ClearMsgBitsMask(PUSER_MESSAGE_QUEUE Queue, UINT MessageBits)
ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE Queue;
UINT ClrMask = 0;
pti = Queue->Thread->Tcb.Win32Thread;
Queue = pti->MessageQueue;
if (MessageBits & QS_KEY)
{
if (--Queue->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY;
if (--pti->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY;
}
if (MessageBits & QS_MOUSEMOVE) // ReactOS hard coded.
{ // Account for tracking mouse moves..
if (--Queue->nCntsQBits[QSRosMouseMove] == 0) ClrMask |= QS_MOUSEMOVE;
if (--pti->nCntsQBits[QSRosMouseMove] == 0) ClrMask |= QS_MOUSEMOVE;
// Handle mouse move bits here.
if (Queue->MouseMoved) ClrMask |= QS_MOUSEMOVE;
}
if (MessageBits & QS_MOUSEBUTTON)
{
if (--Queue->nCntsQBits[QSRosMouseButton] == 0) ClrMask |= QS_MOUSEBUTTON;
if (--pti->nCntsQBits[QSRosMouseButton] == 0) ClrMask |= QS_MOUSEBUTTON;
}
if (MessageBits & QS_POSTMESSAGE)
{
if (--Queue->nCntsQBits[QSRosPostMessage] == 0) ClrMask |= QS_POSTMESSAGE;
if (--pti->nCntsQBits[QSRosPostMessage] == 0) ClrMask |= QS_POSTMESSAGE;
}
if (MessageBits & QS_TIMER) // ReactOS hard coded.
{ // Handle timer bits here.
@ -462,11 +469,11 @@ ClearMsgBitsMask(PUSER_MESSAGE_QUEUE Queue, UINT MessageBits)
}
if (MessageBits & QS_SENDMESSAGE)
{
if (--Queue->nCntsQBits[QSRosSendMessage] == 0) ClrMask |= QS_SENDMESSAGE;
if (--pti->nCntsQBits[QSRosSendMessage] == 0) ClrMask |= QS_SENDMESSAGE;
}
if (MessageBits & QS_HOTKEY)
{
if (--Queue->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY;
if (--pti->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY;
}
pti->pcti->fsWakeBits &= ~ClrMask;
@ -474,26 +481,24 @@ ClearMsgBitsMask(PUSER_MESSAGE_QUEUE Queue, UINT MessageBits)
}
VOID FASTCALL
MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
MsqIncPaintCountQueue(PTHREADINFO pti)
{
PTHREADINFO pti;
pti = Queue->Thread->Tcb.Win32Thread;
pti->cPaintsReady++;
MsqWakeQueue(Queue, QS_PAINT, TRUE);
MsqWakeQueue(pti, QS_PAINT, TRUE);
}
VOID FASTCALL
MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
MsqDecPaintCountQueue(PTHREADINFO pti)
{
ClearMsgBitsMask(Queue, QS_PAINT);
ClearMsgBitsMask(pti, QS_PAINT);
}
VOID FASTCALL
MsqPostMouseMove(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg)
MsqPostMouseMove(PTHREADINFO pti, MSG* Msg)
{
MessageQueue->MouseMoveMsg = *Msg;
MessageQueue->MouseMoved = TRUE;
MsqWakeQueue(MessageQueue, QS_MOUSEMOVE, TRUE);
pti->MessageQueue->MouseMoveMsg = *Msg;
pti->MessageQueue->MouseMoved = TRUE;
MsqWakeQueue(pti, QS_MOUSEMOVE, TRUE);
}
VOID FASTCALL
@ -504,6 +509,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
PDESKTOP pDesk;
PWND pwnd, pwndDesktop;
HDC hdcScreen;
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE MessageQueue;
PSYSTEM_CURSORINFO CurInfo;
@ -564,9 +570,10 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
/* Check if we found a window */
if (Msg->hwnd != NULL && pwnd != NULL)
{
MessageQueue = pwnd->head.pti->MessageQueue;
pti = pwnd->head.pti;
MessageQueue = pti->MessageQueue;
if ( pwnd->head.pti->TIF_flags & TIF_INCLEANUP || MessageQueue->QF_flags & QF_INDESTROY)
if ( pti->TIF_flags & TIF_INCLEANUP || MessageQueue->QF_flags & QF_INDESTROY)
{
ERR("Mouse is over the Window Thread is Dead!\n");
return;
@ -617,12 +624,12 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
gpqCursor = MessageQueue;
/* Mouse move is a special case */
MsqPostMouseMove(MessageQueue, Msg);
MsqPostMouseMove(pti, Msg);
}
else
{
TRACE("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd));
MsqPostMessage(MessageQueue, Msg, TRUE, QS_MOUSEBUTTON, 0);
MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0);
}
}
else if (hdcScreen)
@ -675,7 +682,7 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
KeQueryTickCount(&LargeTickCount);
Mesg.time = MsqCalculateMessageTime(&LargeTickCount);
Mesg.pt = gpsi->ptCursor;
MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, Type, 0);
MsqPostMessage(Window->head.pti, &Mesg, FALSE, Type, 0);
UserDereferenceObject(Window);
ObDereferenceObject (Thread);
@ -704,41 +711,38 @@ MsqDestroyMessage(PUSER_MESSAGE Message)
}
BOOLEAN FASTCALL
co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue)
co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti)
{
PUSER_SENT_MESSAGE SaveMsg, Message;
PLIST_ENTRY Entry;
PTHREADINFO pti;
BOOL Ret;
LRESULT Result = 0;
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
if (IsListEmpty(&pti->SentMessagesListHead))
{
return(FALSE);
}
/* remove it from the list of pending messages */
Entry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
Entry = RemoveHeadList(&pti->SentMessagesListHead);
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
pti = MessageQueue->Thread->Tcb.Win32Thread;
SaveMsg = pti->pusmCurrent;
pti->pusmCurrent = Message;
// Processing a message sent to it from another thread.
if ( ( Message->SenderQueue && MessageQueue != Message->SenderQueue) ||
( Message->CallBackSenderQueue && MessageQueue != Message->CallBackSenderQueue ))
if ( ( Message->ptiSender && pti != Message->ptiSender) ||
( Message->ptiCallBackSender && pti != Message->ptiCallBackSender ))
{ // most likely, but, to be sure.
pti->pcti->CTI_flags |= CTI_INSENDMESSAGE; // Let the user know...
}
/* insert it to the list of messages that are currently dispatched by this
message queue */
InsertTailList(&MessageQueue->LocalDispatchingMessagesHead,
InsertTailList(&pti->LocalDispatchingMessagesHead,
&Message->ListEntry);
ClearMsgBitsMask(MessageQueue, Message->QS_Flags);
ClearMsgBitsMask(pti, Message->QS_Flags);
if (Message->HookMessage == MSQ_ISHOOK)
{ // Direct Hook Call processor
@ -761,7 +765,7 @@ co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue)
Message->Msg.wParam);
}
else if ((Message->CompletionCallback) &&
(Message->CallBackSenderQueue == MessageQueue))
(Message->ptiCallBackSender == pti))
{ /* Call the callback routine */
if (Message->QS_Flags & QS_SMRESULT)
{
@ -777,7 +781,7 @@ co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue)
{
/* The message has not been processed yet, reinsert it. */
RemoveEntryList(&Message->ListEntry);
InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry);
InsertTailList(&Message->ptiCallBackSender->SentMessagesListHead, &Message->ListEntry);
TRACE("Callback Message not processed yet. Requeuing the message\n");
Ret = FALSE;
goto Exit;
@ -798,22 +802,21 @@ co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue)
/* If the message is a callback, insert it in the callback senders MessageQueue */
if (Message->CompletionCallback)
{
if (Message->CallBackSenderQueue)
if (Message->ptiCallBackSender)
{
Message->lResult = Result;
Message->QS_Flags |= QS_SMRESULT;
/* insert it in the callers message queue */
InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(Message->CallBackSenderQueue, QS_SENDMESSAGE, TRUE);
IntDereferenceMessageQueue(Message->CallBackSenderQueue);
InsertTailList(&Message->ptiCallBackSender->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(Message->ptiCallBackSender, QS_SENDMESSAGE, TRUE);
}
Ret = TRUE;
goto Exit;
}
/* remove the message from the dispatching list if needed, so lock the sender's message queue */
if (Message->SenderQueue)
if (Message->ptiSender)
{
if (Message->DispatchingListEntry.Flink != NULL)
{
@ -847,14 +850,6 @@ co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue)
KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
}
/* if the message has a sender */
if (Message->SenderQueue)
{
/* dereference our and the sender's message queue */
IntDereferenceMessageQueue(Message->SenderQueue);
IntDereferenceMessageQueue(MessageQueue);
}
/* free the message */
ExFreePoolWithTag(Message, TAG_USRMSG);
Ret = TRUE;
@ -867,22 +862,20 @@ Exit:
}
VOID APIENTRY
MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
MsqRemoveWindowMessagesFromQueue(PWND Window)
{
PTHREADINFO pti;
PUSER_SENT_MESSAGE SentMessage;
PUSER_MESSAGE PostedMessage;
PUSER_MESSAGE_QUEUE MessageQueue;
PLIST_ENTRY CurrentEntry, ListHead;
PWND Window = pWindow;
ASSERT(Window);
MessageQueue = Window->head.pti->MessageQueue;
ASSERT(MessageQueue);
pti = Window->head.pti;
/* remove the posted messages for this window */
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
ListHead = &MessageQueue->PostedMessagesListHead;
CurrentEntry = pti->PostedMessagesListHead.Flink;
ListHead = &pti->PostedMessagesListHead;
while (CurrentEntry != ListHead)
{
PostedMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
@ -890,9 +883,9 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
if (PostedMessage->Msg.hwnd == Window->head.h)
{
RemoveEntryList(&PostedMessage->ListEntry);
ClearMsgBitsMask(MessageQueue, PostedMessage->QS_Flags);
ClearMsgBitsMask(pti, PostedMessage->QS_Flags);
MsqDestroyMessage(PostedMessage);
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
CurrentEntry = pti->PostedMessagesListHead.Flink;
}
else
{
@ -900,12 +893,9 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
}
}
/* Reference we message queue, so it won't get deleted */
IntReferenceMessageQueue(MessageQueue);
/* remove the sent messages for this window */
CurrentEntry = MessageQueue->SentMessagesListHead.Flink;
ListHead = &MessageQueue->SentMessagesListHead;
CurrentEntry = pti->SentMessagesListHead.Flink;
ListHead = &pti->SentMessagesListHead;
while (CurrentEntry != ListHead)
{
SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
@ -915,15 +905,10 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n");
RemoveEntryList(&SentMessage->ListEntry);
ClearMsgBitsMask(MessageQueue, SentMessage->QS_Flags);
ClearMsgBitsMask(pti, SentMessage->QS_Flags);
/* if it is a callback and this queue is not the sender queue, dereference queue */
if ((SentMessage->CompletionCallback) && (SentMessage->CallBackSenderQueue != MessageQueue))
{
IntDereferenceMessageQueue(SentMessage->CallBackSenderQueue);
}
/* Only if the message has a sender was the queue referenced */
if ((SentMessage->SenderQueue)
if ((SentMessage->ptiSender)
&& (SentMessage->DispatchingListEntry.Flink != NULL))
{
RemoveEntryList(&SentMessage->DispatchingListEntry);
@ -941,27 +926,16 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
ExFreePool((PVOID)SentMessage->Msg.lParam);
}
/* if the message has a sender */
if (SentMessage->SenderQueue)
{
/* dereference our and the sender's message queue */
IntDereferenceMessageQueue(MessageQueue);
IntDereferenceMessageQueue(SentMessage->SenderQueue);
}
/* free the message */
ExFreePoolWithTag(SentMessage, TAG_USRMSG);
CurrentEntry = MessageQueue->SentMessagesListHead.Flink;
CurrentEntry = pti->SentMessagesListHead.Flink;
}
else
{
CurrentEntry = CurrentEntry->Flink;
}
}
/* Remove the reference we added */
IntDereferenceMessageQueue(MessageQueue);
}
BOOL FASTCALL
@ -1000,8 +974,9 @@ co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
Message->CompletionEvent = NULL;
Message->Result = 0;
Message->lResult = 0;
Message->SenderQueue = NULL;
Message->CallBackSenderQueue = ptiSender->MessageQueue;
Message->ptiReceiver = ptiReceiver;
Message->ptiSender = NULL;
Message->ptiCallBackSender = ptiSender;
Message->DispatchingListEntry.Flink = NULL;
Message->CompletionCallback = CompletionCallback;
Message->CompletionCallbackContext = CompletionCallbackContext;
@ -1009,33 +984,29 @@ co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
Message->HasPackedLParam = HasPackedLParam;
Message->QS_Flags = QS_SENDMESSAGE;
InsertTailList(&ptiReceiver->MessageQueue->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(ptiReceiver->MessageQueue, QS_SENDMESSAGE, TRUE);
IntDereferenceMessageQueue(ptiReceiver->MessageQueue);
InsertTailList(&ptiReceiver->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(ptiReceiver, QS_SENDMESSAGE, TRUE);
return TRUE;
}
NTSTATUS FASTCALL
co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
co_MsqSendMessage(PTHREADINFO ptirec,
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
UINT uTimeout, BOOL Block, INT HookMessage,
ULONG_PTR *uResult)
{
PTHREADINFO pti, ptirec;
PTHREADINFO pti;
PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
NTSTATUS WaitStatus;
PUSER_MESSAGE_QUEUE ThreadQueue;
LARGE_INTEGER Timeout;
PLIST_ENTRY Entry;
PWND pWnd;
LRESULT Result = 0; //// Result could be trashed. ////
pti = PsGetCurrentThreadWin32Thread();
ThreadQueue = pti->MessageQueue;
ptirec = MessageQueue->Thread->Tcb.Win32Thread;
ASSERT(ThreadQueue != MessageQueue);
ASSERT(pti != ptirec);
ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!!
/* Don't send from or to a dying thread */
@ -1105,24 +1076,22 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
Message->Result = &Result;
Message->lResult = 0;
Message->QS_Flags = 0;
Message->SenderQueue = ThreadQueue;
Message->CallBackSenderQueue = NULL;
IntReferenceMessageQueue(ThreadQueue);
Message->ptiReceiver = ptirec;
Message->ptiSender = pti;
Message->ptiCallBackSender = NULL;
Message->CompletionCallback = NULL;
Message->CompletionCallbackContext = 0;
Message->HookMessage = HookMessage;
Message->HasPackedLParam = FALSE;
IntReferenceMessageQueue(MessageQueue);
/* Add it to the list of pending messages */
InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry);
InsertTailList(&pti->DispatchingMessagesHead, &Message->DispatchingListEntry);
/* Queue it in the destination's message queue */
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
InsertTailList(&ptirec->SentMessagesListHead, &Message->ListEntry);
Message->QS_Flags = QS_SENDMESSAGE;
MsqWakeQueue(MessageQueue, QS_SENDMESSAGE, TRUE);
MsqWakeQueue(ptirec, QS_SENDMESSAGE, TRUE);
/* We can't access the Message anymore since it could have already been deleted! */
@ -1140,8 +1109,8 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
{
/* Look up if the message has not yet dispatched, if so
make sure it can't pass a result and it must not set the completion event anymore */
Entry = MessageQueue->SentMessagesListHead.Flink;
while (Entry != &MessageQueue->SentMessagesListHead)
Entry = ptirec->SentMessagesListHead.Flink;
while (Entry != &ptirec->SentMessagesListHead)
{
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry)
== Message)
@ -1157,8 +1126,8 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
/* Remove from the local dispatching list so the other thread knows,
it can't pass a result and it must not set the completion event anymore */
Entry = ThreadQueue->DispatchingMessagesHead.Flink;
while (Entry != &ThreadQueue->DispatchingMessagesHead)
Entry = pti->DispatchingMessagesHead.Flink;
while (Entry != &pti->DispatchingMessagesHead)
{
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, DispatchingListEntry)
== Message)
@ -1178,7 +1147,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
TRACE("MsqSendMessage (blocked) timed out 1\n");
}
while (co_MsqDispatchOneSentMessage(ThreadQueue))
while (co_MsqDispatchOneSentMessage(ptirec))
;
}
else
@ -1186,7 +1155,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PVOID WaitObjects[2];
WaitObjects[0] = &CompletionEvent;
WaitObjects[1] = ThreadQueue->NewMessages;
WaitObjects[1] = pti->pEventQueueServer;
do
{
UserLeaveCo();
@ -1200,8 +1169,8 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
{
/* Look up if the message has not yet been dispatched, if so
make sure it can't pass a result and it must not set the completion event anymore */
Entry = MessageQueue->SentMessagesListHead.Flink;
while (Entry != &MessageQueue->SentMessagesListHead)
Entry = ptirec->SentMessagesListHead.Flink;
while (Entry != &ptirec->SentMessagesListHead)
{
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry)
== Message)
@ -1217,8 +1186,8 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
/* Remove from the local dispatching list so the other thread knows,
it can't pass a result and it must not set the completion event anymore */
Entry = ThreadQueue->DispatchingMessagesHead.Flink;
while (Entry != &ThreadQueue->DispatchingMessagesHead)
Entry = pti->DispatchingMessagesHead.Flink;
while (Entry != &pti->DispatchingMessagesHead)
{
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, DispatchingListEntry)
== Message)
@ -1239,7 +1208,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
TRACE("MsqSendMessage timed out 2\n");
break;
}
while (co_MsqDispatchOneSentMessage(ThreadQueue))
while (co_MsqDispatchOneSentMessage(pti))
;
}
while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus);
@ -1252,27 +1221,30 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
}
VOID FASTCALL
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
MsqPostMessage(PTHREADINFO pti,
MSG* Msg,
BOOLEAN HardwareMessage,
DWORD MessageBits,
DWORD dwQEvent)
{
PUSER_MESSAGE Message;
PUSER_MESSAGE_QUEUE MessageQueue;
if(!(Message = MsqCreateMessage(Msg)))
{
return;
}
MessageQueue = pti->MessageQueue;
if (dwQEvent)
{
InsertHeadList(&MessageQueue->PostedMessagesListHead,
InsertHeadList(&pti->PostedMessagesListHead,
&Message->ListEntry);
}
else if (!HardwareMessage)
{
InsertTailList(&MessageQueue->PostedMessagesListHead,
InsertTailList(&pti->PostedMessagesListHead,
&Message->ListEntry);
}
else
@ -1284,15 +1256,15 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
Message->dwQEvent = dwQEvent;
Message->QS_Flags = MessageBits;
//Message->pti = pti; Fixed in ATI changes. See CORE-6551
MsqWakeQueue(MessageQueue, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE));
MsqWakeQueue(pti, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE));
}
VOID FASTCALL
MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode)
MsqPostQuitMessage(PTHREADINFO pti, ULONG ExitCode)
{
MessageQueue->QuitPosted = TRUE;
MessageQueue->QuitExitCode = ExitCode;
MsqWakeQueue(MessageQueue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE, TRUE);
pti->QuitPosted = TRUE;
pti->exitCode = ExitCode;
MsqWakeQueue(pti, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE, TRUE);
}
/***********************************************************************
@ -1719,7 +1691,7 @@ BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, UINT first, UI
}
BOOL APIENTRY
co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
co_MsqPeekMouseMove(IN PTHREADINFO pti,
IN BOOL Remove,
IN PWND Window,
IN UINT MsgFilterLow,
@ -1728,7 +1700,7 @@ co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
{
BOOL AcceptMessage;
MSG msg;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
if(!(MessageQueue->MouseMoved))
return FALSE;
@ -1754,7 +1726,7 @@ co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
if(Remove)
{
ClearMsgBitsMask(MessageQueue, QS_MOUSEMOVE);
ClearMsgBitsMask(pti, QS_MOUSEMOVE);
MessageQueue->MouseMoved = FALSE;
}
@ -1781,7 +1753,7 @@ filter_contains_hw_range( UINT first, UINT last )
}
BOOL APIENTRY
co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
co_MsqPeekHardwareMessage(IN PTHREADINFO pti,
IN BOOL Remove,
IN PWND Window,
IN UINT MsgFilterLow,
@ -1795,7 +1767,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
PLIST_ENTRY ListHead, CurrentEntry = NULL;
MSG msg;
BOOL Ret = FALSE;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
if (!filter_contains_hw_range( MsgFilterLow, MsgFilterHigh )) return FALSE;
@ -1843,7 +1815,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
if (Remove)
{
RemoveEntryList(&CurrentMessage->ListEntry);
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
ClearMsgBitsMask(pti, CurrentMessage->QS_Flags);
MsqDestroyMessage(CurrentMessage);
}
@ -1865,7 +1837,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
}
BOOLEAN APIENTRY
MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
MsqPeekMessage(IN PTHREADINFO pti,
IN BOOLEAN Remove,
IN PWND Window,
IN UINT MsgFilterLow,
@ -1877,25 +1849,12 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_MESSAGE CurrentMessage;
PLIST_ENTRY ListHead;
BOOL Ret = FALSE;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
ListHead = &MessageQueue->PostedMessagesListHead;
CurrentEntry = pti->PostedMessagesListHead.Flink;
ListHead = &pti->PostedMessagesListHead;
if (IsListEmpty(CurrentEntry)) return FALSE;
if (!MessageQueue->ptiSysLock)
{
MessageQueue->ptiSysLock = pti;
pti->pcti->CTI_flags |= CTI_THREADSYSLOCK;
}
if (MessageQueue->ptiSysLock != pti)
{
ERR("MsqPeekMessage: Thread Q is locked to another pti!\n");
return FALSE;
}
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
do
@ -1920,7 +1879,7 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
if (Remove)
{
RemoveEntryList(&CurrentMessage->ListEntry);
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
ClearMsgBitsMask(pti, CurrentMessage->QS_Flags);
MsqDestroyMessage(CurrentMessage);
}
Ret = TRUE;
@ -1931,18 +1890,16 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
}
while (CurrentEntry != ListHead);
MessageQueue->ptiSysLock = NULL;
pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK;
return Ret;
}
NTSTATUS FASTCALL
co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
co_MsqWaitForNewMessages(PTHREADINFO pti, PWND WndFilter,
UINT MsgFilterMin, UINT MsgFilterMax)
{
NTSTATUS ret;
UserLeaveCo();
ret = KeWaitForSingleObject( MessageQueue->NewMessages,
ret = KeWaitForSingleObject( pti->pEventQueueServer,
UserRequest,
UserMode,
FALSE,
@ -1952,12 +1909,12 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
}
BOOL FASTCALL
MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue)
MsqIsHung(PTHREADINFO pti)
{
LARGE_INTEGER LargeTickCount;
KeQueryTickCount(&LargeTickCount);
return ((LargeTickCount.u.LowPart - MessageQueue->LastMsgRead) > MSQ_HUNG);
return ((LargeTickCount.u.LowPart - pti->timeLast) > MSQ_HUNG);
}
VOID
@ -1972,83 +1929,46 @@ HungAppSysTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
BOOLEAN FASTCALL
MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue)
{
struct _ETHREAD *Thread;
LARGE_INTEGER LargeTickCount;
NTSTATUS Status;
Thread = pti->pEThread;
MessageQueue->Thread = Thread;
MessageQueue->ptiOwner = pti;
MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1);
InitializeListHead(&MessageQueue->PostedMessagesListHead);
InitializeListHead(&MessageQueue->SentMessagesListHead);
InitializeListHead(&MessageQueue->HardwareMessagesListHead);
InitializeListHead(&MessageQueue->DispatchingMessagesHead);
InitializeListHead(&MessageQueue->LocalDispatchingMessagesHead);
MessageQueue->QuitPosted = FALSE;
MessageQueue->QuitExitCode = 0;
KeQueryTickCount(&LargeTickCount);
MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
MessageQueue->spwndFocus = NULL;
MessageQueue->NewMessagesHandle = NULL;
MessageQueue->iCursorLevel = 0;
MessageQueue->CursorObject = NULL;
RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
Status = ZwCreateEvent(&MessageQueue->NewMessagesHandle, EVENT_ALL_ACCESS,
NULL, SynchronizationEvent, FALSE);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
Status = ObReferenceObjectByHandle(MessageQueue->NewMessagesHandle, 0,
ExEventObjectType, KernelMode,
(PVOID*)&MessageQueue->NewMessages, NULL);
if (!NT_SUCCESS(Status))
{
ZwClose(MessageQueue->NewMessagesHandle);
MessageQueue->NewMessagesHandle = NULL;
return FALSE;
}
MessageQueue->ptiMouse = pti;
MessageQueue->ptiKeyboard = pti;
MessageQueue->cThreads++;
return TRUE;
}
VOID FASTCALL
MsqCleanupMessageQueue(PTHREADINFO pti)
MsqCleanupThreadMsgs(PTHREADINFO pti)
{
PUSER_MESSAGE_QUEUE MessageQueue;
PLIST_ENTRY CurrentEntry;
PUSER_MESSAGE CurrentMessage;
PUSER_SENT_MESSAGE CurrentSentMessage;
MessageQueue = pti->MessageQueue;
/* cleanup posted messages */
while (!IsListEmpty(&MessageQueue->PostedMessagesListHead))
while (!IsListEmpty(&pti->PostedMessagesListHead))
{
CurrentEntry = RemoveHeadList(&MessageQueue->PostedMessagesListHead);
CurrentEntry = RemoveHeadList(&pti->PostedMessagesListHead);
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
MsqDestroyMessage(CurrentMessage);
}
/* remove the messages that have not yet been dispatched */
while (!IsListEmpty(&MessageQueue->SentMessagesListHead))
while (!IsListEmpty(&pti->SentMessagesListHead))
{
CurrentEntry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
CurrentEntry = RemoveHeadList(&pti->SentMessagesListHead);
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
ListEntry);
/* if it is a callback and this queue is not the sender queue, dereference queue */
if ((CurrentSentMessage->CompletionCallback) && (CurrentSentMessage->CallBackSenderQueue != MessageQueue))
{
IntDereferenceMessageQueue(CurrentSentMessage->CallBackSenderQueue);
}
TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n");
/* Only if the message has a sender was the message in the DispatchingList */
if ((CurrentSentMessage->SenderQueue)
if ((CurrentSentMessage->ptiSender)
&& (CurrentSentMessage->DispatchingListEntry.Flink != NULL))
{
RemoveEntryList(&CurrentSentMessage->DispatchingListEntry);
@ -2065,33 +1985,19 @@ MsqCleanupMessageQueue(PTHREADINFO pti)
if (CurrentSentMessage->Msg.lParam)
ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
}
/* if the message has a sender */
if (CurrentSentMessage->SenderQueue)
{
/* dereference our and the sender's message queue */
IntDereferenceMessageQueue(MessageQueue);
IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
}
/* free the message */
ExFreePool(CurrentSentMessage);
}
/* notify senders of dispatching messages. This needs to be cleaned up if e.g.
ExitThread() was called in a SendMessage() umode callback */
while (!IsListEmpty(&MessageQueue->LocalDispatchingMessagesHead))
while (!IsListEmpty(&pti->LocalDispatchingMessagesHead))
{
CurrentEntry = RemoveHeadList(&MessageQueue->LocalDispatchingMessagesHead);
CurrentEntry = RemoveHeadList(&pti->LocalDispatchingMessagesHead);
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
ListEntry);
/* if it is a callback and this queue is not the sender queue, dereference queue */
if ((CurrentSentMessage->CompletionCallback) && (CurrentSentMessage->CallBackSenderQueue != MessageQueue))
{
IntDereferenceMessageQueue(CurrentSentMessage->CallBackSenderQueue);
}
/* remove the message from the dispatching list */
if(CurrentSentMessage->DispatchingListEntry.Flink != NULL)
{
@ -2112,22 +2018,14 @@ MsqCleanupMessageQueue(PTHREADINFO pti)
ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
}
/* if the message has a sender */
if (CurrentSentMessage->SenderQueue)
{
/* dereference our and the sender's message queue */
IntDereferenceMessageQueue(MessageQueue);
IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
}
/* free the message */
ExFreePool(CurrentSentMessage);
}
/* tell other threads not to bother returning any info to us */
while (! IsListEmpty(&MessageQueue->DispatchingMessagesHead))
while (! IsListEmpty(&pti->DispatchingMessagesHead))
{
CurrentEntry = RemoveHeadList(&MessageQueue->DispatchingMessagesHead);
CurrentEntry = RemoveHeadList(&pti->DispatchingMessagesHead);
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
DispatchingListEntry);
CurrentSentMessage->CompletionEvent = NULL;
@ -2144,12 +2042,27 @@ MsqCleanupMessageQueue(PTHREADINFO pti)
pti->pcti->fsChangeBits = 0;
}
MessageQueue->nCntsQBits[QSRosKey] = 0;
MessageQueue->nCntsQBits[QSRosMouseMove] = 0;
MessageQueue->nCntsQBits[QSRosMouseButton] = 0;
MessageQueue->nCntsQBits[QSRosPostMessage] = 0;
MessageQueue->nCntsQBits[QSRosSendMessage] = 0;
MessageQueue->nCntsQBits[QSRosHotKey] = 0;
pti->nCntsQBits[QSRosKey] = 0;
pti->nCntsQBits[QSRosMouseMove] = 0;
pti->nCntsQBits[QSRosMouseButton] = 0;
pti->nCntsQBits[QSRosPostMessage] = 0;
pti->nCntsQBits[QSRosSendMessage] = 0;
pti->nCntsQBits[QSRosHotKey] = 0;
}
VOID FASTCALL
MsqCleanupMessageQueue(PTHREADINFO pti)
{
PUSER_MESSAGE_QUEUE MessageQueue;
MessageQueue = pti->MessageQueue;
MessageQueue->cThreads--;
if (MessageQueue->cThreads)
{
if (MessageQueue->ptiSysLock == pti) MessageQueue->ptiSysLock = NULL;
}
if (MessageQueue->CursorObject)
{
@ -2171,6 +2084,19 @@ MsqCleanupMessageQueue(PTHREADINFO pti)
UserDereferenceObject(pCursor);
}
if (gpqForeground == MessageQueue)
{
IntSetFocusMessageQueue(NULL);
}
if (gpqForegroundPrev == MessageQueue)
{
gpqForegroundPrev = NULL;
}
if (gpqCursor == MessageQueue)
{
gpqCursor = NULL;
}
}
PUSER_MESSAGE_QUEUE FASTCALL
@ -2218,9 +2144,6 @@ MsqDestroyMessageQueue(PTHREADINFO pti)
/* clean it up */
MsqCleanupMessageQueue(pti);
if (MessageQueue->NewMessagesHandle != NULL)
ZwClose(MessageQueue->NewMessagesHandle);
MessageQueue->NewMessagesHandle = NULL;
/* decrease the reference counter, if it hits zero, the queue will be freed */
IntDereferenceMessageQueue(MessageQueue);
}
@ -2276,7 +2199,7 @@ co_MsqReplyMessage( LRESULT lResult )
if (Message->QS_Flags & QS_SMRESULT) return FALSE;
// SendMessageXxx || Callback msg and not a notify msg
if (Message->SenderQueue || Message->CompletionCallback)
if (Message->ptiSender || Message->CompletionCallback)
{
Message->lResult = lResult;
Message->QS_Flags |= QS_SMRESULT;
@ -2286,9 +2209,12 @@ co_MsqReplyMessage( LRESULT lResult )
}
HWND FASTCALL
MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd)
MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
{
HWND Prev;
PUSER_MESSAGE_QUEUE MessageQueue;
MessageQueue = pti->MessageQueue;
switch(Type)
{

View file

@ -6,18 +6,6 @@
#define MSQ_ISEVENT 2
#define MSQ_INJECTMODULE 3
#define QSIDCOUNTS 6
typedef enum _QS_ROS_TYPES
{
QSRosKey = 0,
QSRosMouseMove,
QSRosMouseButton,
QSRosPostMessage,
QSRosSendMessage,
QSRosHotKey,
}QS_ROS_TYPES,*PQS_ROS_TYPES;
typedef struct _USER_MESSAGE
{
LIST_ENTRY ListEntry;
@ -38,9 +26,10 @@ typedef struct _USER_SENT_MESSAGE
PKEVENT CompletionEvent;
LRESULT* Result;
LRESULT lResult;
struct _USER_MESSAGE_QUEUE* SenderQueue;
struct _USER_MESSAGE_QUEUE* CallBackSenderQueue;
PTHREADINFO ptiSender;
PTHREADINFO ptiReceiver;
SENDASYNCPROC CompletionCallback;
PTHREADINFO ptiCallBackSender;
ULONG_PTR CompletionCallbackContext;
/* entry in the dispatching list of the sender's message queue */
LIST_ENTRY DispatchingListEntry;
@ -53,13 +42,16 @@ typedef struct _USER_MESSAGE_QUEUE
/* Reference counter, only access this variable with interlocked functions! */
LONG References;
PTHREADINFO ptiOwner; // temp..
/* Desktop that the message queue is attached to */
struct _DESKTOP *Desktop;
PTHREADINFO ptiSysLock;
/* Owner of the message queue */
struct _ETHREAD *Thread;
/* Queue of messages sent to the queue. */
LIST_ENTRY SentMessagesListHead;
/* Queue of messages posted to the queue. */
LIST_ENTRY PostedMessagesListHead;
// struct _ETHREAD *Thread;
PTHREADINFO ptiMouse;
PTHREADINFO ptiKeyboard;
/* Queue for hardware messages for the queue. */
LIST_ENTRY HardwareMessagesListHead;
/* True if a WM_MOUSEMOVE is pending */
@ -68,16 +60,6 @@ typedef struct _USER_MESSAGE_QUEUE
MSG MouseMoveMsg;
/* Last click message for translating double clicks */
MSG msgDblClk;
/* True if a WM_QUIT message is pending. */
BOOLEAN QuitPosted;
/* The quit exit code. */
ULONG QuitExitCode;
/* Set if there are new messages specified by WakeMask in any of the queues. */
PKEVENT NewMessages;
/* Handle for the above event (in the context of the process owning the queue). */
HANDLE NewMessagesHandle;
/* Last time PeekMessage() was called. */
ULONG LastMsgRead;
/* Current capture window for this queue. */
PWND spwndCapture;
/* Current window with focus (ie. receives keyboard input) for this queue. */
@ -97,13 +79,6 @@ typedef struct _USER_MESSAGE_QUEUE
DWORD QF_flags;
DWORD cThreads; // Shared message queue counter.
/* Queue state tracking */
// Send list QS_SENDMESSAGE
// Post list QS_POSTMESSAGE|QS_HOTKEY|QS_PAINT|QS_TIMER|QS_KEY
// Hard list QS_MOUSE|QS_KEY only
// Accounting of queue bit sets, the rest are flags. QS_TIMER QS_PAINT counts are handled in thread information.
DWORD nCntsQBits[QSIDCOUNTS]; // QS_KEY QS_MOUSEMOVE QS_MOUSEBUTTON QS_POSTMESSAGE QS_SENDMESSAGE QS_HOTKEY
/* Extra message information */
LPARAM ExtraInfo;
@ -116,13 +91,6 @@ typedef struct _USER_MESSAGE_QUEUE
/* Cursor object */
PCURICON_OBJECT CursorObject;
/* Messages that are currently dispatched by other threads */
LIST_ENTRY DispatchingMessagesHead;
/* Messages that are currently dispatched by this message queue, required for cleanup */
LIST_ENTRY LocalDispatchingMessagesHead;
/* Desktop that the message queue is attached to */
struct _DESKTOP *Desktop;
} USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
#define QF_UPDATEKEYSTATE 0x00000001
@ -152,17 +120,17 @@ enum internal_event_message
WM_ASYNC_SETACTIVEWINDOW
};
BOOL FASTCALL MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue);
BOOL FASTCALL MsqIsHung(PTHREADINFO pti);
VOID CALLBACK HungAppSysTimerProc(HWND,UINT,UINT_PTR,DWORD);
NTSTATUS FASTCALL co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
NTSTATUS FASTCALL co_MsqSendMessage(PTHREADINFO ptirec,
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult);
PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg);
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message);
VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE, MSG*, BOOLEAN, DWORD, DWORD);
VOID FASTCALL MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode);
VOID FASTCALL MsqPostMessage(PTHREADINFO, MSG*, BOOLEAN, DWORD, DWORD);
VOID FASTCALL MsqPostQuitMessage(PTHREADINFO pti, ULONG ExitCode);
BOOLEAN APIENTRY
MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
MsqPeekMessage(IN PTHREADINFO pti,
IN BOOLEAN Remove,
IN PWND Window,
IN UINT MsgFilterLow,
@ -170,7 +138,7 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
IN UINT QSflags,
OUT PMSG Message);
BOOL APIENTRY
co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
co_MsqPeekHardwareMessage(IN PTHREADINFO pti,
IN BOOL Remove,
IN PWND Window,
IN UINT MsgFilterLow,
@ -178,7 +146,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
IN UINT QSflags,
OUT MSG* pMsg);
BOOL APIENTRY
co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
co_MsqPeekMouseMove(IN PTHREADINFO pti,
IN BOOL Remove,
IN PWND Window,
IN UINT MsgFilterLow,
@ -186,14 +154,15 @@ co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
OUT MSG* pMsg);
BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO, PUSER_MESSAGE_QUEUE);
PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO);
VOID FASTCALL MsqCleanupThreadMsgs(PTHREADINFO);
VOID FASTCALL MsqDestroyMessageQueue(PTHREADINFO);
INIT_FUNCTION NTSTATUS NTAPI MsqInitializeImpl(VOID);
BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue);
BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(PTHREADINFO pti);
NTSTATUS FASTCALL
co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
co_MsqWaitForNewMessages(PTHREADINFO pti, PWND WndFilter,
UINT MsgFilterMin, UINT MsgFilterMax);
VOID FASTCALL MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue);
VOID FASTCALL MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue);
VOID FASTCALL MsqIncPaintCountQueue(PTHREADINFO);
VOID FASTCALL MsqDecPaintCountQueue(PTHREADINFO);
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL co_IntPostOrSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL
@ -235,13 +204,13 @@ VOID FASTCALL MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARA
VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove);
BOOL FASTCALL MsqIsDblClk(LPMSG Msg, BOOL Remove);
HWND FASTCALL MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd);
HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd);
BOOL APIENTRY IntInitMessagePumpHook(VOID);
BOOL APIENTRY IntUninitMessagePumpHook(VOID);
LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam);
LPARAM FASTCALL MsqGetMessageExtraInfo(VOID);
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PWND pWindow);
#define IntReferenceMessageQueue(MsgQueue) \
InterlockedIncrement(&(MsgQueue)->References)
@ -250,9 +219,7 @@ VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers,
do { \
if(InterlockedDecrement(&(MsgQueue)->References) == 0) \
{ \
TRACE("Free message queue 0x%p\n", (MsgQueue)); \
if ((MsgQueue)->NewMessages != NULL) \
ObDereferenceObject((MsgQueue)->NewMessages); \
ERR("Free message queue 0x%p\n", (MsgQueue)); \
ExFreePoolWithTag((MsgQueue), USERTAG_Q); \
} \
} while(0)
@ -289,8 +256,8 @@ MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount)
VOID FASTCALL IdlePing(VOID);
VOID FASTCALL IdlePong(VOID);
BOOL FASTCALL co_MsqReplyMessage(LRESULT);
VOID FASTCALL MsqWakeQueue(PUSER_MESSAGE_QUEUE,DWORD,BOOL);
VOID FASTCALL ClearMsgBitsMask(PUSER_MESSAGE_QUEUE,UINT);
VOID FASTCALL MsqWakeQueue(PTHREADINFO,DWORD,BOOL);
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO,UINT);
int UserShowCursor(BOOL bShow);
PCURICON_OBJECT

View file

@ -97,13 +97,12 @@ IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse)
VOID FASTCALL
IntSendSyncPaint(PWND Wnd, ULONG Flags)
{
PTHREADINFO ptiCur;
PUSER_MESSAGE_QUEUE MessageQueue;
PTHREADINFO ptiCur, ptiWnd;
PUSER_SENT_MESSAGE Message;
PLIST_ENTRY Entry;
BOOL bSend = TRUE;
MessageQueue = Wnd->head.pti->MessageQueue;
ptiWnd = Wnd->head.pti;
ptiCur = PsGetCurrentThreadWin32Thread();
/*
Not the current thread, Wnd is in send Nonclient paint also in send erase background and it is visiable.
@ -115,10 +114,10 @@ IntSendSyncPaint(PWND Wnd, ULONG Flags)
{
// For testing, if you see this, break out the Champagne and have a party!
ERR("SendSyncPaint Wnd in State!\n");
if (!IsListEmpty(&MessageQueue->SentMessagesListHead))
if (!IsListEmpty(&ptiWnd->SentMessagesListHead))
{
// Scan sent queue messages to see if we received sync paint messages.
Entry = MessageQueue->SentMessagesListHead.Flink;
Entry = ptiWnd->SentMessagesListHead.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
do
{
@ -133,7 +132,7 @@ IntSendSyncPaint(PWND Wnd, ULONG Flags)
Entry = Message->ListEntry.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
}
while (Entry != &MessageQueue->SentMessagesListHead);
while (Entry != &ptiWnd->SentMessagesListHead);
}
if (bSend)
{
@ -270,7 +269,7 @@ IntGetNCUpdateRgn(PWND Window, BOOL Validate)
Window->state &= ~WNDS_UPDATEDIRTY;
Window->hrgnUpdate = NULL;
if (!(Window->state & WNDS_INTERNALPAINT))
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
MsqDecPaintCountQueue(Window->head.pti);
}
}
@ -557,9 +556,9 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
if (HadPaintMessage != IntIsWindowDirty(Wnd))
{
if (HadPaintMessage)
MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue);
MsqDecPaintCountQueue(Wnd->head.pti);
else
MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue);
MsqIncPaintCountQueue(Wnd->head.pti);
}
TRACE("IntInvalidateWindows exit\n");
}
@ -781,7 +780,7 @@ IntGetPaintMessage(
{
PaintWnd->state &= ~WNDS_INTERNALPAINT;
if (!PaintWnd->hrgnUpdate)
MsqDecPaintCountQueue(Thread->MessageQueue);
MsqDecPaintCountQueue(Thread);
}
PaintWnd->state2 &= ~WNDS2_WMPAINTSENT;
PaintWnd->state &= ~WNDS_UPDATEDIRTY;
@ -955,7 +954,7 @@ IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
if (Window->hrgnUpdate != NULL)
{
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
MsqDecPaintCountQueue(Window->head.pti);
GdiGetClipBox(Ps->hdc, &Ps->rcPaint);
IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
/* The region is part of the dc now and belongs to the process! */
@ -964,7 +963,7 @@ IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
else
{
if (Window->state & WNDS_INTERNALPAINT)
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
MsqDecPaintCountQueue(Window->head.pti);
IntGetClientRect(Window, &Ps->rcPaint);
}

View file

@ -156,7 +156,7 @@ NtUserCallOneParam(
{
PTHREADINFO pti;
pti = PsGetCurrentThreadWin32Thread();
MsqPostQuitMessage(pti->MessageQueue, Param);
MsqPostQuitMessage(pti, Param);
RETURN(TRUE);
}
@ -419,10 +419,9 @@ NtUserCallTwoParam(
case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
{
PUSER_MESSAGE_QUEUE MsgQueue = ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->MessageQueue;
ASSERT(MsgQueue);
RETURN( (DWORD_PTR)MsqSetStateWindow(MsgQueue, (ULONG)Param1, (HWND)Param2));
PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
ASSERT(pti->MessageQueue);
RETURN( (DWORD_PTR)MsqSetStateWindow(pti, (ULONG)Param1, (HWND)Param2));
}
case TWOPARAM_ROUTINE_ENABLEWINDOW:

View file

@ -409,7 +409,7 @@ PostTimerMessages(PWND Window)
Msg.wParam = (WPARAM) pTmr->nID;
Msg.lParam = (LPARAM) pTmr->pfn;
MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER, 0);
MsqPostMessage(pti, &Msg, FALSE, QS_TIMER, 0);
pTmr->flags &= ~TMRF_READY;
pti->cTimersReady++;
Hit = TRUE;
@ -484,8 +484,8 @@ ProcessTimers(VOID)
// Set thread message queue for this timer.
if (pTmr->pti->MessageQueue)
{ // Wakeup thread
ASSERT(pTmr->pti->MessageQueue->NewMessages != NULL);
KeSetEvent(pTmr->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
ASSERT(pTmr->pti->pEventQueueServer != NULL);
KeSetEvent(pTmr->pti->pEventQueueServer, IO_NO_INCREMENT, FALSE);
}
}
}

View file

@ -32,8 +32,8 @@
#define W32PF_MANUALGUICHECK (0x02000000)
#define W32PF_CREATEDWINORDC (0x04000000)
#define W32PF_APIHOOKLOADED (0x08000000)
/*
#define QSIDCOUNTS 6
#define QSIDCOUNTS 7
typedef enum _QS_ROS_TYPES
{
@ -43,8 +43,9 @@ typedef enum _QS_ROS_TYPES
QSRosPostMessage,
QSRosSendMessage,
QSRosHotKey,
QSRosEvent,
}QS_ROS_TYPES,*PQS_ROS_TYPES;
*/
extern BOOL ClientPfnInit;
extern HINSTANCE hModClient;
extern HANDLE hModuleWin; // This Win32k Instance.
@ -65,7 +66,7 @@ typedef struct _TL
typedef struct _W32THREAD
{
PETHREAD pEThread;
ULONG RefCount;
LONG RefCount;
PTL ptlW32;
PVOID pgdiDcattr;
PVOID pgdiBrushAttr;
@ -89,13 +90,18 @@ typedef struct _THREADINFO
PCLIENTINFO pClientInfo;
FLONG TIF_flags;
PUNICODE_STRING pstrAppName;
LIST_ENTRY psmsSent; // DispatchingMessagesHead
/* Messages that are currently dispatched to other threads */
LIST_ENTRY DispatchingMessagesHead; // psmsSent
struct _USER_SENT_MESSAGE *pusmCurrent;
LIST_ENTRY psmsReceiveList; // SentMessagesListHead
/* Queue of messages sent to the queue. */
LIST_ENTRY SentMessagesListHead; // psmsReceiveList
/* Last time PeekMessage() was called. */
LONG timeLast;
ULONG_PTR idLast;
/* True if a WM_QUIT message is pending. */
BOOLEAN QuitPosted;
INT exitCode; // QuitExitCode
/* The quit exit code. */
INT exitCode;
HDESK hdesk;
UINT cPaintsReady; /* Count of paints pending. */
UINT cTimersReady; /* Count of timers pending. */
@ -109,26 +115,32 @@ typedef struct _THREADINFO
LPARAM lParamHkCurrent;
WPARAM wParamHkCurrent;
struct tagSBTRACK* pSBTrack;
HANDLE hEventQueueClient; // NewMessagesHandle
PKEVENT pEventQueueServer; // NewMessages
/* Set if there are new messages specified by WakeMask in any of the queues. */
HANDLE hEventQueueClient;
/* Handle for the above event (in the context of the process owning the queue). */
PKEVENT pEventQueueServer;
LIST_ENTRY PtiLink;
INT iCursorLevel;
POINT ptLast;
LIST_ENTRY mlPost; // PostedMessagesListHead
/* Queue of messages posted to the queue. */
LIST_ENTRY PostedMessagesListHead; // mlPost
UINT cWindows;
UINT cVisWindows;
LIST_ENTRY aphkStart[NB_HOOKS];
CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL.
/* ReactOS */
/* Queue state tracking */
/* Thread Queue state tracking */
// Send list QS_SENDMESSAGE
// Post list QS_POSTMESSAGE|QS_HOTKEY|QS_PAINT|QS_TIMER|QS_KEY
// Hard list QS_MOUSE|QS_KEY only
// Accounting of queue bit sets, the rest are flags. QS_TIMER QS_PAINT counts are handled in thread information.
//DWORD nCntsQBits[QSIDCOUNTS]; // QS_KEY QS_MOUSEMOVE QS_MOUSEBUTTON QS_POSTMESSAGE QS_SENDMESSAGE QS_HOTKEY
DWORD nCntsQBits[QSIDCOUNTS]; // QS_KEY QS_MOUSEMOVE QS_MOUSEBUTTON QS_POSTMESSAGE QS_SENDMESSAGE QS_HOTKEY
/* Messages that are currently dispatched by this message queue, required for cleanup */
LIST_ENTRY LocalDispatchingMessagesHead;
LIST_ENTRY WindowListHead;
LIST_ENTRY W32CallbackListHead;
@ -142,6 +154,22 @@ typedef struct _THREADINFO
#include <poppack.h>
#define IntReferenceThreadInfo(pti) \
InterlockedIncrement(&(pti)->RefCount)
VOID FASTCALL UserDeleteW32Thread(PTHREADINFO);
#define IntDereferenceThreadInfo(pti) \
do { \
if(InterlockedDecrement(&(pti)->RefCount) == 0) \
{ \
ASSERT(pti->TIF_flags &= (TIF_INCLEANUP|TIF_DONTATTACHQUEUE) == (TIF_INCLEANUP|TIF_DONTATTACHQUEUE)); \
UserDeleteW32Thread(pti); \
} \
} while(0)
typedef struct _W32HEAP_USER_MAPPING
{
struct _W32HEAP_USER_MAPPING *Next;
@ -195,9 +223,9 @@ typedef struct _PROCESSINFO
PTHREADINFO ptiList;
PTHREADINFO ptiMainThread;
struct _DESKTOP* rpdeskStartup;
PPROCESSINFO ppiNext;
PCLS pclsPrivateList;
PCLS pclsPublicList;
PPROCESSINFO ppiNext;
INT cThreads;
HDESK hdeskStartup;
DWORD dwhmodLibLoadedMask;

View file

@ -3779,7 +3779,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
break;
case QUERY_WINDOW_ISHUNG:
Result = (DWORD)MsqIsHung(pWnd->head.pti->MessageQueue);
Result = (DWORD)MsqIsHung(pWnd->head.pti);
break;
case QUERY_WINDOW_REAL_ID: