mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[Win32k]
- ATI fixup CORE-6551. - Giannis Adamopoulos fragment patch 18. svn path=/trunk/; revision=58986
This commit is contained in:
parent
7647f53075
commit
016d53260e
15 changed files with 395 additions and 432 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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])
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue