2003-05-18 17:16:18 +00:00
|
|
|
/*
|
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2004-04-16 18:53:53 +00:00
|
|
|
/* $Id: msgqueue.c,v 1.90 2004/04/16 18:53:53 weiden Exp $
|
2001-06-12 17:51:51 +00:00
|
|
|
*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: Message queues
|
|
|
|
* FILE: subsys/win32k/ntuser/msgqueue.c
|
|
|
|
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
|
|
* REVISION HISTORY:
|
|
|
|
* 06-06-2001 CSH Created
|
|
|
|
*/
|
2002-01-13 22:52:08 +00:00
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <ddk/ntddk.h>
|
|
|
|
#include <win32k/win32k.h>
|
|
|
|
#include <include/msgqueue.h>
|
2002-07-04 19:56:38 +00:00
|
|
|
#include <include/callback.h>
|
2002-10-31 00:03:31 +00:00
|
|
|
#include <include/window.h>
|
|
|
|
#include <include/winpos.h>
|
2003-11-23 11:39:48 +00:00
|
|
|
#include <include/winsta.h>
|
2003-12-07 19:29:33 +00:00
|
|
|
#include <include/desktop.h>
|
2002-10-31 00:03:31 +00:00
|
|
|
#include <include/class.h>
|
2003-09-29 19:38:30 +00:00
|
|
|
#include <include/object.h>
|
2003-10-09 06:13:05 +00:00
|
|
|
#include <include/input.h>
|
2003-11-21 16:36:26 +00:00
|
|
|
#include <include/cursoricon.h>
|
2003-11-30 20:03:47 +00:00
|
|
|
#include <include/focus.h>
|
2003-12-20 15:42:47 +00:00
|
|
|
#include <include/caret.h>
|
2004-02-19 21:12:11 +00:00
|
|
|
#include <include/tags.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
2003-09-29 19:38:30 +00:00
|
|
|
#include <win32k/debug1.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <debug.h>
|
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
2002-10-31 00:03:31 +00:00
|
|
|
#define SYSTEM_MESSAGE_QUEUE_SIZE (256)
|
|
|
|
|
|
|
|
static MSG SystemMessageQueue[SYSTEM_MESSAGE_QUEUE_SIZE];
|
|
|
|
static ULONG SystemMessageQueueHead = 0;
|
|
|
|
static ULONG SystemMessageQueueTail = 0;
|
|
|
|
static ULONG SystemMessageQueueCount = 0;
|
2003-08-26 19:26:02 +00:00
|
|
|
static ULONG SystemMessageQueueMouseMove = -1;
|
2002-10-31 00:03:31 +00:00
|
|
|
static KSPIN_LOCK SystemMessageQueueLock;
|
|
|
|
|
2003-12-14 00:45:39 +00:00
|
|
|
static ULONG volatile HardwareMessageQueueStamp = 0;
|
2002-10-31 00:03:31 +00:00
|
|
|
static LIST_ENTRY HardwareMessageQueueHead;
|
2004-02-08 21:47:10 +00:00
|
|
|
static KMUTEX HardwareMessageQueueLock;
|
2002-10-31 00:03:31 +00:00
|
|
|
|
|
|
|
static KEVENT HardwareMessageEvent;
|
2002-01-13 22:52:08 +00:00
|
|
|
|
2003-07-25 23:53:36 +00:00
|
|
|
static PAGED_LOOKASIDE_LIST MessageLookasideList;
|
|
|
|
|
2004-02-24 13:27:03 +00:00
|
|
|
#define IntLockSystemMessageQueue(OldIrql) \
|
|
|
|
KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql)
|
2002-01-13 22:52:08 +00:00
|
|
|
|
2004-02-24 13:27:03 +00:00
|
|
|
#define IntUnLockSystemMessageQueue(OldIrql) \
|
|
|
|
KeReleaseSpinLock(&SystemMessageQueueLock, OldIrql)
|
|
|
|
|
|
|
|
#define IntUnLockSystemHardwareMessageQueueLock(Wait) \
|
|
|
|
KeReleaseMutex(&HardwareMessageQueueLock, Wait)
|
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
2003-08-02 16:53:08 +00:00
|
|
|
|
|
|
|
/* set some queue bits */
|
|
|
|
inline VOID MsqSetQueueBits( PUSER_MESSAGE_QUEUE Queue, WORD Bits )
|
|
|
|
{
|
|
|
|
Queue->WakeBits |= Bits;
|
|
|
|
Queue->ChangedBits |= Bits;
|
|
|
|
if (MsqIsSignaled( Queue )) KeSetEvent(&Queue->NewMessages, IO_NO_INCREMENT, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear some queue bits */
|
|
|
|
inline VOID MsqClearQueueBits( PUSER_MESSAGE_QUEUE Queue, WORD Bits )
|
|
|
|
{
|
|
|
|
Queue->WakeBits &= ~Bits;
|
|
|
|
Queue->ChangedBits &= ~Bits;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-07-04 19:56:38 +00:00
|
|
|
MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
|
|
|
|
{
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(Queue);
|
2002-07-04 19:56:38 +00:00
|
|
|
Queue->PaintCount++;
|
|
|
|
Queue->PaintPosted = TRUE;
|
2003-05-21 22:58:43 +00:00
|
|
|
KeSetEvent(&Queue->NewMessages, IO_NO_INCREMENT, FALSE);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(Queue);
|
2002-07-04 19:56:38 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-07-04 19:56:38 +00:00
|
|
|
MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
|
|
|
|
{
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(Queue);
|
2002-07-04 19:56:38 +00:00
|
|
|
Queue->PaintCount--;
|
|
|
|
if (Queue->PaintCount == 0)
|
|
|
|
{
|
|
|
|
Queue->PaintPosted = FALSE;
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(Queue);
|
2002-07-04 19:56:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS FASTCALL
|
2002-01-13 22:52:08 +00:00
|
|
|
MsqInitializeImpl(VOID)
|
|
|
|
{
|
2002-10-31 00:03:31 +00:00
|
|
|
/*CurrentFocusMessageQueue = NULL;*/
|
|
|
|
InitializeListHead(&HardwareMessageQueueHead);
|
|
|
|
KeInitializeEvent(&HardwareMessageEvent, NotificationEvent, 0);
|
|
|
|
KeInitializeSpinLock(&SystemMessageQueueLock);
|
2004-02-08 21:47:10 +00:00
|
|
|
KeInitializeMutex(&HardwareMessageQueueLock, 0);
|
2003-07-25 23:53:36 +00:00
|
|
|
|
|
|
|
ExInitializePagedLookasideList(&MessageLookasideList,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
sizeof(USER_MESSAGE),
|
|
|
|
0,
|
|
|
|
256);
|
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2004-04-16 18:53:53 +00:00
|
|
|
MsqInsertSystemMessage(MSG* Msg)
|
2003-08-26 19:26:02 +00:00
|
|
|
{
|
2003-12-21 20:06:45 +00:00
|
|
|
LARGE_INTEGER LargeTickCount;
|
2002-10-31 00:03:31 +00:00
|
|
|
KIRQL OldIrql;
|
2003-08-25 14:54:06 +00:00
|
|
|
ULONG mmov = (ULONG)-1;
|
2003-12-21 20:06:45 +00:00
|
|
|
|
|
|
|
KeQueryTickCount(&LargeTickCount);
|
|
|
|
Msg->time = LargeTickCount.u.LowPart;
|
2002-10-31 00:03:31 +00:00
|
|
|
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockSystemMessageQueue(OldIrql);
|
2003-08-26 19:26:02 +00:00
|
|
|
|
2003-08-25 14:26:30 +00:00
|
|
|
/* only insert WM_MOUSEMOVE messages if not already in system message queue */
|
2004-04-16 18:53:53 +00:00
|
|
|
if(Msg->message == WM_MOUSEMOVE)
|
2003-08-26 19:26:02 +00:00
|
|
|
mmov = SystemMessageQueueMouseMove;
|
|
|
|
|
2003-08-25 14:54:06 +00:00
|
|
|
if(mmov != (ULONG)-1)
|
2003-08-25 14:26:30 +00:00
|
|
|
{
|
2003-08-25 23:55:46 +00:00
|
|
|
/* insert message at the queue head */
|
2003-08-26 19:26:02 +00:00
|
|
|
while (mmov != SystemMessageQueueHead )
|
2003-08-25 14:54:06 +00:00
|
|
|
{
|
2003-08-26 19:26:02 +00:00
|
|
|
ULONG prev = mmov ? mmov - 1 : SYSTEM_MESSAGE_QUEUE_SIZE - 1;
|
2003-12-14 00:45:39 +00:00
|
|
|
ASSERT(mmov >= 0);
|
|
|
|
ASSERT(mmov < SYSTEM_MESSAGE_QUEUE_SIZE);
|
2003-08-26 19:26:02 +00:00
|
|
|
SystemMessageQueue[mmov] = SystemMessageQueue[prev];
|
|
|
|
mmov = prev;
|
2003-08-25 14:54:06 +00:00
|
|
|
}
|
|
|
|
SystemMessageQueue[SystemMessageQueueHead] = *Msg;
|
2003-08-25 14:26:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (SystemMessageQueueCount == SYSTEM_MESSAGE_QUEUE_SIZE)
|
2002-10-31 00:03:31 +00:00
|
|
|
{
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockSystemMessageQueue(OldIrql);
|
2002-10-31 00:03:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2003-08-25 14:26:30 +00:00
|
|
|
SystemMessageQueue[SystemMessageQueueTail] = *Msg;
|
2003-08-26 19:26:02 +00:00
|
|
|
if(Msg->message == WM_MOUSEMOVE)
|
|
|
|
SystemMessageQueueMouseMove = SystemMessageQueueTail;
|
|
|
|
SystemMessageQueueTail =
|
2003-08-25 14:26:30 +00:00
|
|
|
(SystemMessageQueueTail + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
|
|
|
|
SystemMessageQueueCount++;
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockSystemMessageQueue(OldIrql);
|
2002-10-31 00:03:31 +00:00
|
|
|
KeSetEvent(&HardwareMessageEvent, IO_NO_INCREMENT, FALSE);
|
|
|
|
}
|
|
|
|
|
2004-04-15 23:36:03 +00:00
|
|
|
BOOL FASTCALL
|
|
|
|
MsqIsDblClk(LPMSG Msg, BOOL Remove)
|
2003-12-21 20:06:45 +00:00
|
|
|
{
|
2003-12-21 21:20:31 +00:00
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
|
|
|
NTSTATUS Status;
|
|
|
|
LONG dX, dY;
|
|
|
|
BOOL Res;
|
|
|
|
|
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
CurInfo = &WinStaObject->SystemCursor;
|
2004-04-15 23:36:03 +00:00
|
|
|
Res = (Msg->hwnd == (HWND)CurInfo->LastClkWnd) &&
|
|
|
|
((Msg->time - CurInfo->LastBtnDown) < CurInfo->DblClickSpeed);
|
2003-12-21 21:20:31 +00:00
|
|
|
if(Res)
|
|
|
|
{
|
|
|
|
|
2004-04-15 23:36:03 +00:00
|
|
|
dX = CurInfo->LastBtnDownX - Msg->pt.x;
|
|
|
|
dY = CurInfo->LastBtnDownY - Msg->pt.y;
|
2003-12-21 21:20:31 +00:00
|
|
|
if(dX < 0) dX = -dX;
|
|
|
|
if(dY < 0) dY = -dY;
|
|
|
|
|
|
|
|
Res = (dX <= CurInfo->DblClickWidth) &&
|
|
|
|
(dY <= CurInfo->DblClickHeight);
|
2004-02-08 21:47:10 +00:00
|
|
|
}
|
2003-12-21 21:20:31 +00:00
|
|
|
|
2004-02-08 21:47:10 +00:00
|
|
|
if(Remove)
|
|
|
|
{
|
|
|
|
if (Res)
|
2003-12-21 21:20:31 +00:00
|
|
|
{
|
2003-12-25 12:26:35 +00:00
|
|
|
CurInfo->LastBtnDown = 0;
|
2004-04-15 23:36:03 +00:00
|
|
|
CurInfo->LastBtnDownX = Msg->pt.x;
|
|
|
|
CurInfo->LastBtnDownY = Msg->pt.y;
|
2003-12-25 12:26:35 +00:00
|
|
|
CurInfo->LastClkWnd = NULL;
|
2003-12-21 21:20:31 +00:00
|
|
|
}
|
2004-02-08 21:47:10 +00:00
|
|
|
else
|
2003-12-21 21:20:31 +00:00
|
|
|
{
|
2004-04-15 23:36:03 +00:00
|
|
|
CurInfo->LastBtnDownX = Msg->pt.x;
|
|
|
|
CurInfo->LastBtnDownY = Msg->pt.y;
|
|
|
|
CurInfo->LastClkWnd = (HANDLE)Msg->hwnd;
|
|
|
|
CurInfo->LastBtnDown = Msg->time;
|
2003-12-21 21:20:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return Res;
|
2003-12-21 20:06:45 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
BOOL STATIC STDCALL
|
2004-04-15 23:36:03 +00:00
|
|
|
MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT FilterLow, UINT FilterHigh,
|
2004-04-16 18:53:53 +00:00
|
|
|
PUSER_MESSAGE Message, BOOL Remove, PBOOL Freed,
|
2004-04-15 23:36:03 +00:00
|
|
|
PWINDOW_OBJECT ScopeWin, PPOINT ScreenPoint, BOOL FromGlobalQueue)
|
2002-10-31 00:03:31 +00:00
|
|
|
{
|
|
|
|
USHORT Msg = Message->Msg.message;
|
2004-04-09 20:03:21 +00:00
|
|
|
PWINDOW_OBJECT Window = NULL;
|
|
|
|
HWND CaptureWin;
|
2003-11-22 12:22:07 +00:00
|
|
|
|
|
|
|
CaptureWin = IntGetCaptureWindow();
|
2003-11-30 20:03:47 +00:00
|
|
|
if (CaptureWin == NULL)
|
2003-09-29 19:38:30 +00:00
|
|
|
{
|
2003-12-15 15:08:33 +00:00
|
|
|
if(Msg == WM_MOUSEWHEEL)
|
|
|
|
{
|
|
|
|
Window = IntGetWindowObject(IntGetFocusWindow());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-04-15 23:36:03 +00:00
|
|
|
WinPosWindowFromPoint(ScopeWin, NULL, &Message->Msg.pt, &Window);
|
2003-12-15 15:08:33 +00:00
|
|
|
}
|
2003-09-29 19:38:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-04-15 23:36:03 +00:00
|
|
|
/* FIXME - window messages should go to the right window if no buttons are
|
|
|
|
pressed */
|
2003-11-30 20:03:47 +00:00
|
|
|
Window = IntGetWindowObject(CaptureWin);
|
2003-09-29 19:38:30 +00:00
|
|
|
}
|
2002-10-31 00:03:31 +00:00
|
|
|
|
2003-09-29 19:38:30 +00:00
|
|
|
if (Window == NULL)
|
|
|
|
{
|
2004-04-16 18:53:53 +00:00
|
|
|
if(!FromGlobalQueue)
|
2004-03-23 22:24:27 +00:00
|
|
|
{
|
|
|
|
RemoveEntryList(&Message->ListEntry);
|
2004-04-16 18:53:53 +00:00
|
|
|
if(MessageQueue->MouseMoveMsg == Message)
|
|
|
|
{
|
|
|
|
MessageQueue->MouseMoveMsg = NULL;
|
|
|
|
}
|
2004-03-23 22:24:27 +00:00
|
|
|
}
|
2003-09-29 19:38:30 +00:00
|
|
|
ExFreePool(Message);
|
2003-12-14 22:14:45 +00:00
|
|
|
*Freed = TRUE;
|
2003-09-29 19:38:30 +00:00
|
|
|
return(FALSE);
|
|
|
|
}
|
2004-02-28 00:44:28 +00:00
|
|
|
|
2004-04-15 23:36:03 +00:00
|
|
|
if (Window->MessageQueue != MessageQueue)
|
2003-09-29 19:38:30 +00:00
|
|
|
{
|
2004-01-20 23:35:59 +00:00
|
|
|
if (! FromGlobalQueue)
|
|
|
|
{
|
|
|
|
DPRINT("Moving msg between private queues\n");
|
|
|
|
/* This message is already queued in a private queue, but we need
|
|
|
|
* to move it to a different queue, perhaps because a new window
|
|
|
|
* was created which now covers the screen area previously taken
|
|
|
|
* by another window. To move it, we need to take it out of the
|
2004-02-28 00:44:28 +00:00
|
|
|
* old queue. Note that we're already holding the lock mutexes of the
|
2004-01-20 23:35:59 +00:00
|
|
|
* old queue */
|
|
|
|
RemoveEntryList(&Message->ListEntry);
|
2004-02-28 00:44:28 +00:00
|
|
|
|
|
|
|
/* remove the pointer for the current WM_MOUSEMOVE message in case we
|
|
|
|
just removed it */
|
2004-04-15 23:36:03 +00:00
|
|
|
if(MessageQueue->MouseMoveMsg == Message)
|
2004-02-28 00:44:28 +00:00
|
|
|
{
|
2004-04-15 23:36:03 +00:00
|
|
|
MessageQueue->MouseMoveMsg = NULL;
|
2004-02-28 00:44:28 +00:00
|
|
|
}
|
2004-01-20 23:35:59 +00:00
|
|
|
}
|
2004-04-14 17:19:38 +00:00
|
|
|
|
|
|
|
/* lock the destination message queue, so we don't get in trouble with other
|
|
|
|
threads, messing with it at the same time */
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockHardwareMessageQueue(Window->MessageQueue);
|
2004-04-14 17:19:38 +00:00
|
|
|
InsertTailList(&Window->MessageQueue->HardwareMessagesListHead,
|
|
|
|
&Message->ListEntry);
|
|
|
|
if(Message->Msg.message == WM_MOUSEMOVE)
|
2004-02-28 00:44:28 +00:00
|
|
|
{
|
2004-04-14 17:19:38 +00:00
|
|
|
if(Window->MessageQueue->MouseMoveMsg)
|
2004-02-28 00:44:28 +00:00
|
|
|
{
|
2004-04-14 17:19:38 +00:00
|
|
|
/* remove the old WM_MOUSEMOVE message, we're processing a more recent
|
|
|
|
one */
|
|
|
|
RemoveEntryList(&Window->MessageQueue->MouseMoveMsg->ListEntry);
|
|
|
|
ExFreePool(Window->MessageQueue->MouseMoveMsg);
|
2004-02-28 00:44:28 +00:00
|
|
|
}
|
2004-04-14 17:19:38 +00:00
|
|
|
/* save the pointer to the WM_MOUSEMOVE message in the new queue */
|
|
|
|
Window->MessageQueue->MouseMoveMsg = Message;
|
2004-02-28 00:44:28 +00:00
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockHardwareMessageQueue(Window->MessageQueue);
|
2004-04-14 17:19:38 +00:00
|
|
|
|
2003-09-29 19:38:30 +00:00
|
|
|
KeSetEvent(&Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
|
2004-04-14 17:19:38 +00:00
|
|
|
*Freed = FALSE;
|
2003-12-15 15:08:33 +00:00
|
|
|
IntReleaseWindowObject(Window);
|
2003-09-29 19:38:30 +00:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
2004-04-14 17:19:38 +00:00
|
|
|
/* From here on, we're in the same message queue as the caller! */
|
2003-09-29 19:38:30 +00:00
|
|
|
|
|
|
|
*ScreenPoint = Message->Msg.pt;
|
|
|
|
|
2004-04-14 17:35:47 +00:00
|
|
|
if((hWnd != NULL && Window->Self != hWnd) ||
|
|
|
|
((FilterLow != 0 || FilterLow != 0) && (Msg < FilterLow || Msg > FilterHigh)))
|
2004-04-14 17:19:38 +00:00
|
|
|
{
|
|
|
|
/* Reject the message because it doesn't match the filter */
|
|
|
|
|
|
|
|
if(FromGlobalQueue)
|
|
|
|
{
|
|
|
|
/* Lock the message queue so no other thread can mess with it.
|
|
|
|
Our own message queue is not locked while fetching from the global
|
|
|
|
queue, so we have to make sure nothing interferes! */
|
|
|
|
IntLockHardwareMessageQueue(Window->MessageQueue);
|
|
|
|
/* if we're from the global queue, we need to add our message to our
|
|
|
|
private queue so we don't loose it! */
|
|
|
|
InsertTailList(&Window->MessageQueue->HardwareMessagesListHead,
|
|
|
|
&Message->ListEntry);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Message->Msg.message == WM_MOUSEMOVE)
|
|
|
|
{
|
2004-04-14 17:35:47 +00:00
|
|
|
if(Window->MessageQueue->MouseMoveMsg &&
|
|
|
|
(Window->MessageQueue->MouseMoveMsg != Message))
|
2004-04-14 17:19:38 +00:00
|
|
|
{
|
|
|
|
/* delete the old message */
|
|
|
|
RemoveEntryList(&Window->MessageQueue->MouseMoveMsg->ListEntry);
|
|
|
|
ExFreePool(Window->MessageQueue->MouseMoveMsg);
|
|
|
|
}
|
|
|
|
/* always save a pointer to this WM_MOUSEMOVE message here because we're
|
|
|
|
sure that the message is in the private queue */
|
|
|
|
Window->MessageQueue->MouseMoveMsg = Message;
|
|
|
|
}
|
|
|
|
if(FromGlobalQueue)
|
|
|
|
{
|
|
|
|
IntUnLockHardwareMessageQueue(Window->MessageQueue);
|
|
|
|
}
|
|
|
|
|
|
|
|
IntReleaseWindowObject(Window);
|
|
|
|
*Freed = FALSE;
|
|
|
|
return(FALSE);
|
|
|
|
}
|
2004-04-15 23:36:03 +00:00
|
|
|
|
|
|
|
/* FIXME - only assign if removing? */
|
|
|
|
Message->Msg.hwnd = Window->Self;
|
|
|
|
Message->Msg.message = Msg;
|
|
|
|
Message->Msg.lParam = MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y);
|
2003-12-14 22:14:45 +00:00
|
|
|
|
2004-04-14 19:06:02 +00:00
|
|
|
/* remove the reference to the current WM_(NC)MOUSEMOVE message, if this message
|
2004-04-14 17:19:38 +00:00
|
|
|
is it */
|
2004-04-14 19:06:02 +00:00
|
|
|
if (Message->Msg.message == WM_MOUSEMOVE ||
|
|
|
|
Message->Msg.message == WM_NCMOUSEMOVE)
|
2004-04-14 17:19:38 +00:00
|
|
|
{
|
|
|
|
if(FromGlobalQueue)
|
|
|
|
{
|
|
|
|
/* Lock the message queue so no other thread can mess with it.
|
|
|
|
Our own message queue is not locked while fetching from the global
|
|
|
|
queue, so we have to make sure nothing interferes! */
|
|
|
|
IntLockHardwareMessageQueue(Window->MessageQueue);
|
|
|
|
if(Window->MessageQueue->MouseMoveMsg)
|
|
|
|
{
|
2004-04-14 19:06:02 +00:00
|
|
|
/* delete the WM_(NC)MOUSEMOVE message in the private queue, we're dealing
|
2004-04-14 17:19:38 +00:00
|
|
|
with one that's been sent later */
|
|
|
|
RemoveEntryList(&Window->MessageQueue->MouseMoveMsg->ListEntry);
|
|
|
|
ExFreePool(Window->MessageQueue->MouseMoveMsg);
|
|
|
|
/* our message is not in the private queue so we can remove the pointer
|
|
|
|
instead of setting it to the current message we're processing */
|
|
|
|
Window->MessageQueue->MouseMoveMsg = NULL;
|
|
|
|
}
|
|
|
|
IntUnLockHardwareMessageQueue(Window->MessageQueue);
|
|
|
|
}
|
|
|
|
else if(Window->MessageQueue->MouseMoveMsg == Message)
|
|
|
|
{
|
|
|
|
Window->MessageQueue->MouseMoveMsg = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-12-15 15:08:33 +00:00
|
|
|
IntReleaseWindowObject(Window);
|
2003-12-14 22:14:45 +00:00
|
|
|
*Freed = FALSE;
|
2002-10-31 00:03:31 +00:00
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
BOOL STDCALL
|
2003-08-26 19:26:02 +00:00
|
|
|
MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
|
2002-10-31 00:03:31 +00:00
|
|
|
UINT FilterLow, UINT FilterHigh, BOOL Remove,
|
|
|
|
PUSER_MESSAGE* Message)
|
|
|
|
{
|
|
|
|
KIRQL OldIrql;
|
|
|
|
POINT ScreenPoint;
|
2003-12-14 22:14:45 +00:00
|
|
|
BOOL Accept, Freed;
|
2002-10-31 00:03:31 +00:00
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PWINDOW_OBJECT DesktopWindow;
|
2004-02-08 21:47:10 +00:00
|
|
|
PVOID WaitObjects[2];
|
|
|
|
NTSTATUS WaitStatus;
|
2002-10-31 00:03:31 +00:00
|
|
|
|
2003-10-09 06:13:05 +00:00
|
|
|
if( !IntGetScreenDC() ||
|
|
|
|
PsGetWin32Thread()->MessageQueue == W32kGetPrimitiveMessageQueue() )
|
2003-12-14 00:45:39 +00:00
|
|
|
{
|
2003-10-09 06:13:05 +00:00
|
|
|
return FALSE;
|
2003-12-14 00:45:39 +00:00
|
|
|
}
|
|
|
|
|
2003-08-19 11:48:50 +00:00
|
|
|
DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
|
2002-10-31 00:03:31 +00:00
|
|
|
|
2004-02-23 20:08:35 +00:00
|
|
|
WaitObjects[1] = &MessageQueue->NewMessages;
|
|
|
|
WaitObjects[0] = &HardwareMessageQueueLock;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
|
|
|
|
UserMode, TRUE, NULL, NULL);
|
|
|
|
while (MsqDispatchOneSentMessage(MessageQueue))
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus);
|
|
|
|
|
2002-10-31 00:03:31 +00:00
|
|
|
/* Process messages in the message queue itself. */
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockHardwareMessageQueue(MessageQueue);
|
2002-10-31 00:03:31 +00:00
|
|
|
CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
|
|
|
|
while (CurrentEntry != &MessageQueue->HardwareMessagesListHead)
|
|
|
|
{
|
2003-08-26 19:26:02 +00:00
|
|
|
PUSER_MESSAGE Current =
|
2002-10-31 00:03:31 +00:00
|
|
|
CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
2003-08-26 19:26:02 +00:00
|
|
|
if (Current->Msg.message >= WM_MOUSEFIRST &&
|
2002-10-31 00:03:31 +00:00
|
|
|
Current->Msg.message <= WM_MOUSELAST)
|
|
|
|
{
|
2004-04-15 23:36:03 +00:00
|
|
|
Accept = MsqTranslateMouseMessage(MessageQueue, hWnd, FilterLow, FilterHigh,
|
2004-04-16 18:53:53 +00:00
|
|
|
Current, Remove, &Freed,
|
2004-04-15 23:36:03 +00:00
|
|
|
DesktopWindow, &ScreenPoint, FALSE);
|
2002-10-31 00:03:31 +00:00
|
|
|
if (Accept)
|
|
|
|
{
|
2003-05-21 22:58:43 +00:00
|
|
|
if (Remove)
|
|
|
|
{
|
|
|
|
RemoveEntryList(&Current->ListEntry);
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockHardwareMessageQueue(MessageQueue);
|
|
|
|
IntUnLockSystemHardwareMessageQueueLock(FALSE);
|
2002-10-31 00:03:31 +00:00
|
|
|
*Message = Current;
|
2003-08-19 11:48:50 +00:00
|
|
|
IntReleaseWindowObject(DesktopWindow);
|
2002-10-31 00:03:31 +00:00
|
|
|
return(TRUE);
|
|
|
|
}
|
2004-03-23 22:24:27 +00:00
|
|
|
|
2002-10-31 00:03:31 +00:00
|
|
|
}
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockHardwareMessageQueue(MessageQueue);
|
2002-10-31 00:03:31 +00:00
|
|
|
|
|
|
|
/* Now try the global queue. */
|
2004-02-08 21:47:10 +00:00
|
|
|
|
2002-10-31 00:03:31 +00:00
|
|
|
/* Transfer all messages from the DPC accessible queue to the main queue. */
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockSystemMessageQueue(OldIrql);
|
2002-10-31 00:03:31 +00:00
|
|
|
while (SystemMessageQueueCount > 0)
|
2003-08-26 19:26:02 +00:00
|
|
|
{
|
2002-10-31 00:03:31 +00:00
|
|
|
PUSER_MESSAGE UserMsg;
|
|
|
|
MSG Msg;
|
|
|
|
|
2003-12-14 00:45:39 +00:00
|
|
|
ASSERT(SystemMessageQueueHead < SYSTEM_MESSAGE_QUEUE_SIZE);
|
2002-10-31 00:03:31 +00:00
|
|
|
Msg = SystemMessageQueue[SystemMessageQueueHead];
|
2003-08-26 19:26:02 +00:00
|
|
|
SystemMessageQueueHead =
|
2002-10-31 00:03:31 +00:00
|
|
|
(SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
|
|
|
|
SystemMessageQueueCount--;
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockSystemMessageQueue(OldIrql);
|
2003-07-25 23:53:36 +00:00
|
|
|
UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
|
2003-12-14 00:45:39 +00:00
|
|
|
/* What to do if out of memory? For now we just panic a bit in debug */
|
|
|
|
ASSERT(UserMsg);
|
2002-10-31 00:03:31 +00:00
|
|
|
UserMsg->Msg = Msg;
|
|
|
|
InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockSystemMessageQueue(OldIrql);
|
2002-10-31 00:03:31 +00:00
|
|
|
}
|
2003-08-26 19:26:02 +00:00
|
|
|
/*
|
|
|
|
* we could set this to -1 conditionally if we find one, but
|
|
|
|
* this is more efficient and just as effective.
|
|
|
|
*/
|
|
|
|
SystemMessageQueueMouseMove = -1;
|
2002-10-31 00:03:31 +00:00
|
|
|
HardwareMessageQueueStamp++;
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockSystemMessageQueue(OldIrql);
|
2002-10-31 00:03:31 +00:00
|
|
|
|
|
|
|
/* Process messages in the queue until we find one to return. */
|
|
|
|
CurrentEntry = HardwareMessageQueueHead.Flink;
|
|
|
|
while (CurrentEntry != &HardwareMessageQueueHead)
|
|
|
|
{
|
2003-08-26 19:26:02 +00:00
|
|
|
PUSER_MESSAGE Current =
|
2002-10-31 00:03:31 +00:00
|
|
|
CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
|
|
RemoveEntryList(&Current->ListEntry);
|
2003-12-14 00:45:39 +00:00
|
|
|
HardwareMessageQueueStamp++;
|
2003-08-26 19:26:02 +00:00
|
|
|
if (Current->Msg.message >= WM_MOUSEFIRST &&
|
2002-10-31 00:03:31 +00:00
|
|
|
Current->Msg.message <= WM_MOUSELAST)
|
|
|
|
{
|
2003-12-14 00:45:39 +00:00
|
|
|
const ULONG ActiveStamp = HardwareMessageQueueStamp;
|
2002-10-31 00:03:31 +00:00
|
|
|
/* Translate the message. */
|
2004-04-15 23:36:03 +00:00
|
|
|
Accept = MsqTranslateMouseMessage(MessageQueue, hWnd, FilterLow, FilterHigh,
|
2004-04-16 18:53:53 +00:00
|
|
|
Current, Remove, &Freed,
|
2004-04-15 23:36:03 +00:00
|
|
|
DesktopWindow, &ScreenPoint, TRUE);
|
2002-10-31 00:03:31 +00:00
|
|
|
if (Accept)
|
|
|
|
{
|
|
|
|
/* Check for no more messages in the system queue. */
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockSystemMessageQueue(OldIrql);
|
2002-10-31 00:03:31 +00:00
|
|
|
if (SystemMessageQueueCount == 0 &&
|
|
|
|
IsListEmpty(&HardwareMessageQueueHead))
|
|
|
|
{
|
|
|
|
KeClearEvent(&HardwareMessageEvent);
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockSystemMessageQueue(OldIrql);
|
2002-10-31 00:03:31 +00:00
|
|
|
|
2003-08-26 19:26:02 +00:00
|
|
|
/*
|
2002-10-31 00:03:31 +00:00
|
|
|
If we aren't removing the message then add it to the private
|
|
|
|
queue.
|
|
|
|
*/
|
|
|
|
if (!Remove)
|
|
|
|
{
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockHardwareMessageQueue(MessageQueue);
|
2004-04-16 01:27:44 +00:00
|
|
|
if(Current->Msg.message == WM_MOUSEMOVE)
|
|
|
|
{
|
|
|
|
if(MessageQueue->MouseMoveMsg)
|
2004-02-28 00:44:28 +00:00
|
|
|
{
|
2004-04-16 01:27:44 +00:00
|
|
|
RemoveEntryList(&MessageQueue->MouseMoveMsg->ListEntry);
|
|
|
|
ExFreePool(MessageQueue->MouseMoveMsg);
|
2004-02-28 00:44:28 +00:00
|
|
|
}
|
2004-04-16 01:27:44 +00:00
|
|
|
MessageQueue->MouseMoveMsg = Current;
|
2004-02-28 00:44:28 +00:00
|
|
|
}
|
2004-04-16 01:27:44 +00:00
|
|
|
InsertTailList(&MessageQueue->HardwareMessagesListHead,
|
|
|
|
&Current->ListEntry);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockHardwareMessageQueue(MessageQueue);
|
2002-10-31 00:03:31 +00:00
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockSystemHardwareMessageQueueLock(FALSE);
|
2003-05-21 22:58:43 +00:00
|
|
|
*Message = Current;
|
2003-08-19 11:48:50 +00:00
|
|
|
IntReleaseWindowObject(DesktopWindow);
|
2002-10-31 00:03:31 +00:00
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
/* If the contents of the queue changed then restart processing. */
|
|
|
|
if (HardwareMessageQueueStamp != ActiveStamp)
|
|
|
|
{
|
|
|
|
CurrentEntry = HardwareMessageQueueHead.Flink;
|
|
|
|
continue;
|
|
|
|
}
|
2003-08-26 19:26:02 +00:00
|
|
|
}
|
2002-10-31 00:03:31 +00:00
|
|
|
}
|
2004-02-24 01:30:58 +00:00
|
|
|
IntReleaseWindowObject(DesktopWindow);
|
2002-10-31 00:03:31 +00:00
|
|
|
/* Check if the system message queue is now empty. */
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockSystemMessageQueue(OldIrql);
|
2002-10-31 00:03:31 +00:00
|
|
|
if (SystemMessageQueueCount == 0 && IsListEmpty(&HardwareMessageQueueHead))
|
|
|
|
{
|
|
|
|
KeClearEvent(&HardwareMessageEvent);
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockSystemMessageQueue(OldIrql);
|
|
|
|
IntUnLockSystemHardwareMessageQueueLock(FALSE);
|
2002-10-31 00:03:31 +00:00
|
|
|
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
2004-04-13 13:50:31 +00:00
|
|
|
VOID FASTCALL
|
2002-01-13 22:52:08 +00:00
|
|
|
MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2003-07-05 16:04:01 +00:00
|
|
|
PUSER_MESSAGE_QUEUE FocusMessageQueue;
|
|
|
|
MSG Msg;
|
|
|
|
|
|
|
|
DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
|
|
|
|
uMsg, wParam, lParam);
|
2002-01-13 22:52:08 +00:00
|
|
|
|
2003-11-24 00:22:53 +00:00
|
|
|
Msg.hwnd = 0;
|
|
|
|
Msg.message = uMsg;
|
|
|
|
Msg.wParam = wParam;
|
|
|
|
Msg.lParam = lParam;
|
|
|
|
/* FIXME: Initialize time and point. */
|
|
|
|
|
2003-08-19 11:48:50 +00:00
|
|
|
FocusMessageQueue = IntGetFocusMessageQueue();
|
2003-10-09 06:13:05 +00:00
|
|
|
if( !IntGetScreenDC() ) {
|
|
|
|
if( W32kGetPrimitiveMessageQueue() ) {
|
2004-03-11 16:17:25 +00:00
|
|
|
MsqPostMessage(W32kGetPrimitiveMessageQueue(), &Msg);
|
2003-07-05 16:04:01 +00:00
|
|
|
}
|
2003-10-09 06:13:05 +00:00
|
|
|
} else {
|
|
|
|
if (FocusMessageQueue == NULL)
|
|
|
|
{
|
|
|
|
DPRINT("No focus message queue\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FocusMessageQueue->FocusWindow != (HWND)0)
|
|
|
|
{
|
|
|
|
Msg.hwnd = FocusMessageQueue->FocusWindow;
|
2003-11-30 20:03:47 +00:00
|
|
|
DPRINT("Msg.hwnd = %x\n", Msg.hwnd);
|
2004-03-11 16:17:25 +00:00
|
|
|
MsqPostMessage(FocusMessageQueue, &Msg);
|
2003-10-09 06:13:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT("Invalid focus window handle\n");
|
|
|
|
}
|
|
|
|
}
|
2002-01-13 22:52:08 +00:00
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2004-04-13 13:50:31 +00:00
|
|
|
VOID FASTCALL
|
2003-11-03 18:52:21 +00:00
|
|
|
MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT Window;
|
|
|
|
PW32THREAD Win32Thread;
|
|
|
|
PW32PROCESS Win32Process;
|
|
|
|
MSG Mesg;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByPointer (Thread,
|
|
|
|
THREAD_ALL_ACCESS,
|
|
|
|
PsThreadType,
|
|
|
|
KernelMode);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return;
|
|
|
|
|
|
|
|
Win32Thread = ((PETHREAD)Thread)->Win32Thread;
|
|
|
|
if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
|
|
|
|
{
|
|
|
|
ObDereferenceObject ((PETHREAD)Thread);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Win32Process = ((PETHREAD)Thread)->ThreadsProcess->Win32Process;
|
|
|
|
if (Win32Process == NULL || Win32Process->WindowStation == NULL)
|
|
|
|
{
|
|
|
|
ObDereferenceObject ((PETHREAD)Thread);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ObmReferenceObjectByHandle(Win32Process->WindowStation->HandleTable,
|
|
|
|
hWnd, otWindow, (PVOID*)&Window);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ObDereferenceObject ((PETHREAD)Thread);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Mesg.hwnd = hWnd;
|
|
|
|
Mesg.message = WM_HOTKEY;
|
|
|
|
Mesg.wParam = wParam;
|
|
|
|
Mesg.lParam = lParam;
|
|
|
|
// Mesg.pt.x = PsGetWin32Process()->WindowStation->SystemCursor.x;
|
|
|
|
// Mesg.pt.y = PsGetWin32Process()->WindowStation->SystemCursor.y;
|
|
|
|
// KeQueryTickCount(&LargeTickCount);
|
|
|
|
// Mesg.time = LargeTickCount.u.LowPart;
|
2004-03-11 16:17:25 +00:00
|
|
|
MsqPostMessage(Window->MessageQueue, &Mesg);
|
2003-11-03 18:52:21 +00:00
|
|
|
ObmDereferenceObject(Window);
|
|
|
|
ObDereferenceObject (Thread);
|
|
|
|
|
2004-02-24 13:27:03 +00:00
|
|
|
// IntLockMessageQueue(pThread->MessageQueue);
|
2003-11-03 18:52:21 +00:00
|
|
|
// InsertHeadList(&pThread->MessageQueue->PostedMessagesListHead,
|
|
|
|
// &Message->ListEntry);
|
|
|
|
// KeSetEvent(&pThread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
|
2004-02-24 13:27:03 +00:00
|
|
|
// IntUnLockMessageQueue(pThread->MessageQueue);
|
2003-11-03 18:52:21 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
PUSER_MESSAGE FASTCALL
|
2002-01-13 22:52:08 +00:00
|
|
|
MsqCreateMessage(LPMSG Msg)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
PUSER_MESSAGE Message;
|
2003-08-26 19:26:02 +00:00
|
|
|
|
2003-07-25 23:53:36 +00:00
|
|
|
Message = ExAllocateFromPagedLookasideList(&MessageLookasideList);
|
2001-06-12 17:51:51 +00:00
|
|
|
if (!Message)
|
2002-01-13 22:52:08 +00:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2003-08-26 19:26:02 +00:00
|
|
|
|
2004-03-11 16:17:25 +00:00
|
|
|
RtlMoveMemory(&Message->Msg, Msg, sizeof(MSG));
|
2003-08-26 19:26:02 +00:00
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
return Message;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-01-13 22:52:08 +00:00
|
|
|
MsqDestroyMessage(PUSER_MESSAGE Message)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-07-25 23:53:36 +00:00
|
|
|
ExFreeToPagedLookasideList(&MessageLookasideList, Message);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
MsqDispatchSentNotifyMessages(PUSER_MESSAGE_QUEUE MessageQueue)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
PUSER_SENT_MESSAGE_NOTIFY Message;
|
|
|
|
|
|
|
|
while (!IsListEmpty(&MessageQueue->SentMessagesListHead))
|
|
|
|
{
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(MessageQueue);
|
2002-05-06 22:20:32 +00:00
|
|
|
ListEntry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
|
2003-08-26 19:26:02 +00:00
|
|
|
Message = CONTAINING_RECORD(ListEntry, USER_SENT_MESSAGE_NOTIFY,
|
2002-05-06 22:20:32 +00:00
|
|
|
ListEntry);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2002-05-06 22:20:32 +00:00
|
|
|
|
2003-08-19 11:48:50 +00:00
|
|
|
IntCallSentMessageCallback(Message->CompletionCallback,
|
2002-05-06 22:20:32 +00:00
|
|
|
Message->hWnd,
|
|
|
|
Message->Msg,
|
|
|
|
Message->CompletionCallbackContext,
|
|
|
|
Message->Result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
BOOLEAN FASTCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
MsqPeekSentMessages(PUSER_MESSAGE_QUEUE MessageQueue)
|
|
|
|
{
|
|
|
|
return(!IsListEmpty(&MessageQueue->SentMessagesListHead));
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
BOOLEAN FASTCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
|
|
|
{
|
|
|
|
PUSER_SENT_MESSAGE Message;
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
LRESULT Result;
|
|
|
|
PUSER_SENT_MESSAGE_NOTIFY NotifyMessage;
|
|
|
|
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(MessageQueue);
|
2002-07-04 19:56:38 +00:00
|
|
|
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
|
|
|
|
{
|
2004-03-28 21:46:26 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2002-07-04 19:56:38 +00:00
|
|
|
return(FALSE);
|
|
|
|
}
|
2002-05-06 22:20:32 +00:00
|
|
|
Entry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
|
|
|
|
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2002-05-06 22:20:32 +00:00
|
|
|
|
|
|
|
/* Call the window procedure. */
|
2003-12-15 19:32:32 +00:00
|
|
|
Result = IntSendMessage(Message->Msg.hwnd,
|
|
|
|
Message->Msg.message,
|
|
|
|
Message->Msg.wParam,
|
2003-12-26 22:52:12 +00:00
|
|
|
Message->Msg.lParam);
|
2002-05-06 22:20:32 +00:00
|
|
|
|
|
|
|
/* Let the sender know the result. */
|
|
|
|
if (Message->Result != NULL)
|
|
|
|
{
|
|
|
|
*Message->Result = Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Notify the sender. */
|
|
|
|
if (Message->CompletionEvent != NULL)
|
|
|
|
{
|
|
|
|
KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Notify the sender if they specified a callback. */
|
|
|
|
if (Message->CompletionCallback != NULL)
|
|
|
|
{
|
2004-02-19 21:12:11 +00:00
|
|
|
NotifyMessage = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG);
|
2003-08-26 19:26:02 +00:00
|
|
|
NotifyMessage->CompletionCallback =
|
2002-05-06 22:20:32 +00:00
|
|
|
Message->CompletionCallback;
|
|
|
|
NotifyMessage->CompletionCallbackContext =
|
|
|
|
Message->CompletionCallbackContext;
|
|
|
|
NotifyMessage->Result = Result;
|
|
|
|
NotifyMessage->hWnd = Message->Msg.hwnd;
|
|
|
|
NotifyMessage->Msg = Message->Msg.message;
|
2002-07-04 19:56:38 +00:00
|
|
|
MsqSendNotifyMessage(Message->CompletionQueue, NotifyMessage);
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ExFreePool(Message);
|
2002-07-04 19:56:38 +00:00
|
|
|
return(TRUE);
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
|
|
|
PUSER_SENT_MESSAGE_NOTIFY NotifyMessage)
|
|
|
|
{
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(MessageQueue);
|
2003-08-26 19:26:02 +00:00
|
|
|
InsertTailList(&MessageQueue->NotifyMessagesListHead,
|
2002-05-06 22:20:32 +00:00
|
|
|
&NotifyMessage->ListEntry);
|
2003-05-21 22:58:43 +00:00
|
|
|
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
2004-03-11 14:47:44 +00:00
|
|
|
NTSTATUS FASTCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
2004-03-11 14:47:44 +00:00
|
|
|
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
|
|
|
|
UINT uTimeout, BOOL Block, ULONG_PTR *uResult)
|
2002-05-06 22:20:32 +00:00
|
|
|
{
|
2003-12-29 10:09:33 +00:00
|
|
|
PUSER_SENT_MESSAGE Message;
|
|
|
|
KEVENT CompletionEvent;
|
|
|
|
NTSTATUS WaitStatus;
|
|
|
|
LRESULT Result;
|
|
|
|
PUSER_MESSAGE_QUEUE ThreadQueue;
|
2004-03-11 14:47:44 +00:00
|
|
|
LARGE_INTEGER Timeout;
|
2004-04-07 21:12:08 +00:00
|
|
|
PLIST_ENTRY Entry;
|
2003-12-29 10:09:33 +00:00
|
|
|
|
|
|
|
KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
|
|
|
|
|
2004-02-19 21:12:11 +00:00
|
|
|
Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG);
|
2003-12-29 10:09:33 +00:00
|
|
|
Message->Msg.hwnd = Wnd;
|
|
|
|
Message->Msg.message = Msg;
|
|
|
|
Message->Msg.wParam = wParam;
|
|
|
|
Message->Msg.lParam = lParam;
|
|
|
|
Message->CompletionEvent = &CompletionEvent;
|
|
|
|
Message->Result = &Result;
|
|
|
|
Message->CompletionQueue = NULL;
|
|
|
|
Message->CompletionCallback = NULL;
|
|
|
|
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(MessageQueue);
|
2002-05-06 22:20:32 +00:00
|
|
|
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2004-03-11 14:47:44 +00:00
|
|
|
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
|
|
|
|
|
|
|
|
Timeout.QuadPart = uTimeout * -10000;
|
|
|
|
|
2003-12-29 10:09:33 +00:00
|
|
|
ThreadQueue = PsGetWin32Thread()->MessageQueue;
|
2004-03-11 14:47:44 +00:00
|
|
|
if(Block)
|
|
|
|
{
|
|
|
|
/* don't process messages sent to the thread */
|
|
|
|
WaitStatus = KeWaitForSingleObject(&CompletionEvent, UserRequest, UserMode,
|
|
|
|
FALSE, (uTimeout ? &Timeout : NULL));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PVOID WaitObjects[2];
|
|
|
|
|
|
|
|
WaitObjects[0] = &CompletionEvent;
|
|
|
|
WaitObjects[1] = &ThreadQueue->NewMessages;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
|
|
|
|
UserMode, FALSE, (uTimeout ? &Timeout : NULL), NULL);
|
|
|
|
if(WaitStatus == STATUS_TIMEOUT)
|
2004-04-07 21:12:08 +00:00
|
|
|
{
|
|
|
|
IntLockMessageQueue(MessageQueue);
|
|
|
|
Entry = MessageQueue->SentMessagesListHead.Flink;
|
|
|
|
while (Entry != &MessageQueue->SentMessagesListHead)
|
|
|
|
{
|
|
|
|
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry)
|
|
|
|
== Message)
|
|
|
|
{
|
|
|
|
Message->CompletionEvent = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
|
|
|
DbgPrint("MsqSendMessage timed out\n");
|
2004-03-11 14:47:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (MsqDispatchOneSentMessage(ThreadQueue))
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(WaitStatus != STATUS_TIMEOUT)
|
|
|
|
*uResult = (STATUS_WAIT_0 == WaitStatus ? Result : -1);
|
|
|
|
|
|
|
|
return WaitStatus;
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2004-03-11 16:17:25 +00:00
|
|
|
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2004-03-11 16:17:25 +00:00
|
|
|
PUSER_MESSAGE Message;
|
|
|
|
|
|
|
|
if(!(Message = MsqCreateMessage(Msg)))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(MessageQueue);
|
2002-10-31 00:03:31 +00:00
|
|
|
InsertTailList(&MessageQueue->PostedMessagesListHead,
|
|
|
|
&Message->ListEntry);
|
2002-01-13 22:52:08 +00:00
|
|
|
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-21 22:58:43 +00:00
|
|
|
VOID FASTCALL
|
|
|
|
MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode)
|
|
|
|
{
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(MessageQueue);
|
2003-05-21 22:58:43 +00:00
|
|
|
MessageQueue->QuitPosted = TRUE;
|
|
|
|
MessageQueue->QuitExitCode = ExitCode;
|
|
|
|
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2003-05-21 22:58:43 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
BOOLEAN STDCALL
|
2002-01-13 22:52:08 +00:00
|
|
|
MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
|
|
|
IN BOOLEAN Hardware,
|
|
|
|
IN BOOLEAN Remove,
|
|
|
|
IN HWND Wnd,
|
|
|
|
IN UINT MsgFilterLow,
|
|
|
|
IN UINT MsgFilterHigh,
|
|
|
|
OUT PUSER_MESSAGE* Message)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
PLIST_ENTRY CurrentEntry;
|
2002-01-13 22:52:08 +00:00
|
|
|
PUSER_MESSAGE CurrentMessage;
|
|
|
|
PLIST_ENTRY ListHead;
|
2002-10-31 00:03:31 +00:00
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
if (Hardware)
|
|
|
|
{
|
2002-10-31 00:03:31 +00:00
|
|
|
return(MsqPeekHardwareMessage(MessageQueue, Wnd,
|
|
|
|
MsgFilterLow, MsgFilterHigh,
|
|
|
|
Remove, Message));
|
2002-01-13 22:52:08 +00:00
|
|
|
}
|
2003-08-26 19:26:02 +00:00
|
|
|
|
2004-02-24 13:27:03 +00:00
|
|
|
IntLockMessageQueue(MessageQueue);
|
2002-10-31 00:03:31 +00:00
|
|
|
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
|
|
|
|
ListHead = &MessageQueue->PostedMessagesListHead;
|
2002-01-13 22:52:08 +00:00
|
|
|
while (CurrentEntry != ListHead)
|
|
|
|
{
|
2003-08-26 19:26:02 +00:00
|
|
|
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
2002-01-13 22:52:08 +00:00
|
|
|
ListEntry);
|
|
|
|
if ((Wnd == 0 || Wnd == CurrentMessage->Msg.hwnd) &&
|
|
|
|
((MsgFilterLow == 0 && MsgFilterHigh == 0) ||
|
|
|
|
(MsgFilterLow <= CurrentMessage->Msg.message &&
|
|
|
|
MsgFilterHigh >= CurrentMessage->Msg.message)))
|
|
|
|
{
|
|
|
|
if (Remove)
|
|
|
|
{
|
|
|
|
RemoveEntryList(&CurrentMessage->ListEntry);
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2002-01-13 22:52:08 +00:00
|
|
|
*Message = CurrentMessage;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
|
|
}
|
2004-02-24 13:27:03 +00:00
|
|
|
IntUnLockMessageQueue(MessageQueue);
|
2002-01-13 22:52:08 +00:00
|
|
|
return(FALSE);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS FASTCALL
|
2002-01-13 22:52:08 +00:00
|
|
|
MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue)
|
|
|
|
{
|
2002-10-31 00:03:31 +00:00
|
|
|
PVOID WaitObjects[2] = {&MessageQueue->NewMessages, &HardwareMessageEvent};
|
|
|
|
return(KeWaitForMultipleObjects(2,
|
|
|
|
WaitObjects,
|
|
|
|
WaitAny,
|
|
|
|
Executive,
|
|
|
|
UserMode,
|
|
|
|
TRUE,
|
|
|
|
NULL,
|
|
|
|
NULL));
|
2002-01-13 22:52:08 +00:00
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2004-03-11 14:47:44 +00:00
|
|
|
BOOL FASTCALL
|
|
|
|
MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue)
|
|
|
|
{
|
|
|
|
LARGE_INTEGER LargeTickCount;
|
|
|
|
|
|
|
|
KeQueryTickCount(&LargeTickCount);
|
|
|
|
return ((LargeTickCount.u.LowPart - MessageQueue->LastMsgRead) > MSQ_HUNG);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2003-11-18 23:33:31 +00:00
|
|
|
MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQueue)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2004-03-11 14:47:44 +00:00
|
|
|
LARGE_INTEGER LargeTickCount;
|
|
|
|
|
2003-11-18 23:33:31 +00:00
|
|
|
MessageQueue->Thread = Thread;
|
2003-12-20 15:42:47 +00:00
|
|
|
MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1);
|
2002-01-13 22:52:08 +00:00
|
|
|
InitializeListHead(&MessageQueue->PostedMessagesListHead);
|
|
|
|
InitializeListHead(&MessageQueue->SentMessagesListHead);
|
2002-10-31 00:03:31 +00:00
|
|
|
InitializeListHead(&MessageQueue->HardwareMessagesListHead);
|
2004-04-07 21:12:08 +00:00
|
|
|
KeInitializeMutex(&MessageQueue->HardwareLock, 0);
|
2002-01-13 22:52:08 +00:00
|
|
|
ExInitializeFastMutex(&MessageQueue->Lock);
|
|
|
|
MessageQueue->QuitPosted = FALSE;
|
|
|
|
MessageQueue->QuitExitCode = 0;
|
2003-05-21 22:58:43 +00:00
|
|
|
KeInitializeEvent(&MessageQueue->NewMessages, SynchronizationEvent, FALSE);
|
2004-03-11 14:47:44 +00:00
|
|
|
KeQueryTickCount(&LargeTickCount);
|
|
|
|
MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
|
2002-01-13 22:52:08 +00:00
|
|
|
MessageQueue->FocusWindow = NULL;
|
2003-11-21 17:01:16 +00:00
|
|
|
MessageQueue->PaintPosted = FALSE;
|
|
|
|
MessageQueue->PaintCount = 0;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-01-13 22:52:08 +00:00
|
|
|
MsqFreeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2002-01-13 22:52:08 +00:00
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PUSER_MESSAGE CurrentMessage;
|
2003-08-26 19:26:02 +00:00
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
|
|
|
|
while (CurrentEntry != &MessageQueue->PostedMessagesListHead)
|
|
|
|
{
|
2003-08-26 19:26:02 +00:00
|
|
|
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
2002-01-13 22:52:08 +00:00
|
|
|
ListEntry);
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
2003-07-25 23:53:36 +00:00
|
|
|
MsqDestroyMessage(CurrentMessage);
|
2002-01-13 22:52:08 +00:00
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
PUSER_MESSAGE_QUEUE FASTCALL
|
2003-11-18 23:33:31 +00:00
|
|
|
MsqCreateMessageQueue(struct _ETHREAD *Thread)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
PUSER_MESSAGE_QUEUE MessageQueue;
|
|
|
|
|
2004-02-19 21:12:11 +00:00
|
|
|
MessageQueue = (PUSER_MESSAGE_QUEUE)ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(USER_MESSAGE_QUEUE) + sizeof(THRDCARETINFO),
|
|
|
|
TAG_MSGQ);
|
2004-02-22 12:25:02 +00:00
|
|
|
RtlZeroMemory(MessageQueue, sizeof(USER_MESSAGE_QUEUE) + sizeof(THRDCARETINFO));
|
2001-06-12 17:51:51 +00:00
|
|
|
if (!MessageQueue)
|
2002-01-13 22:52:08 +00:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2003-08-26 19:26:02 +00:00
|
|
|
|
2003-11-18 23:33:31 +00:00
|
|
|
MsqInitializeMessageQueue(Thread, MessageQueue);
|
2003-08-26 19:26:02 +00:00
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
return MessageQueue;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-01-13 22:52:08 +00:00
|
|
|
MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
MsqFreeMessageQueue(MessageQueue);
|
|
|
|
ExFreePool(MessageQueue);
|
|
|
|
}
|
|
|
|
|
2003-12-12 14:22:37 +00:00
|
|
|
PHOOKTABLE FASTCALL
|
|
|
|
MsqGetHooks(PUSER_MESSAGE_QUEUE Queue)
|
|
|
|
{
|
|
|
|
return Queue->Hooks;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID FASTCALL
|
|
|
|
MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks)
|
|
|
|
{
|
|
|
|
Queue->Hooks = Hooks;
|
|
|
|
}
|
|
|
|
|
2003-12-19 19:30:05 +00:00
|
|
|
LPARAM FASTCALL
|
|
|
|
MsqSetMessageExtraInfo(LPARAM lParam)
|
|
|
|
{
|
|
|
|
LPARAM Ret;
|
|
|
|
PUSER_MESSAGE_QUEUE MessageQueue;
|
|
|
|
|
|
|
|
MessageQueue = PsGetWin32Thread()->MessageQueue;
|
|
|
|
if(!MessageQueue)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ret = MessageQueue->ExtraInfo;
|
|
|
|
MessageQueue->ExtraInfo = lParam;
|
|
|
|
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
LPARAM FASTCALL
|
|
|
|
MsqGetMessageExtraInfo(VOID)
|
|
|
|
{
|
|
|
|
PUSER_MESSAGE_QUEUE MessageQueue;
|
|
|
|
|
|
|
|
MessageQueue = PsGetWin32Thread()->MessageQueue;
|
|
|
|
if(!MessageQueue)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MessageQueue->ExtraInfo;
|
|
|
|
}
|
|
|
|
|
2004-04-15 23:36:03 +00:00
|
|
|
HWND FASTCALL
|
|
|
|
MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd)
|
|
|
|
{
|
|
|
|
HWND Prev;
|
|
|
|
|
|
|
|
switch(Type)
|
|
|
|
{
|
|
|
|
case MSQ_STATE_CAPTURE:
|
|
|
|
Prev = MessageQueue->CaptureWindow;
|
|
|
|
MessageQueue->CaptureWindow = hWnd;
|
|
|
|
return Prev;
|
|
|
|
case MSQ_STATE_ACTIVE:
|
|
|
|
Prev = MessageQueue->ActiveWindow;
|
|
|
|
MessageQueue->ActiveWindow = hWnd;
|
|
|
|
return Prev;
|
|
|
|
case MSQ_STATE_FOCUS:
|
|
|
|
Prev = MessageQueue->FocusWindow;
|
|
|
|
MessageQueue->FocusWindow = hWnd;
|
|
|
|
return Prev;
|
|
|
|
case MSQ_STATE_MENUOWNER:
|
|
|
|
Prev = MessageQueue->MenuOwner;
|
|
|
|
MessageQueue->MenuOwner = hWnd;
|
|
|
|
return Prev;
|
|
|
|
case MSQ_STATE_MOVESIZE:
|
|
|
|
Prev = MessageQueue->MoveSize;
|
|
|
|
MessageQueue->MoveSize = hWnd;
|
|
|
|
return Prev;
|
|
|
|
case MSQ_STATE_CARET:
|
|
|
|
ASSERT(MessageQueue->CaretInfo);
|
|
|
|
Prev = MessageQueue->CaretInfo->hWnd;
|
|
|
|
MessageQueue->CaretInfo->hWnd = hWnd;
|
|
|
|
return Prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
/* EOF */
|