From 5af5f51b748acd2482c7aa7bd47f4233aca01c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Wed, 21 May 2003 22:58:43 +0000 Subject: [PATCH] - Implement WaitMessage() - Rearrange message code to avoid code duplication - Fix bugs, mainly in signaling new messages - Include Hartmut's fix of 2003/03/26 svn path=/trunk/; revision=4738 --- reactos/lib/user32/windows/message.c | 5 +- reactos/subsys/win32k/include/msgqueue.h | 2 + reactos/subsys/win32k/ntuser/message.c | 572 +++++++++++++---------- reactos/subsys/win32k/ntuser/msgqueue.c | 35 +- 4 files changed, 343 insertions(+), 271 deletions(-) diff --git a/reactos/lib/user32/windows/message.c b/reactos/lib/user32/windows/message.c index 9b9b5c50551..1b7e12b9d10 100644 --- a/reactos/lib/user32/windows/message.c +++ b/reactos/lib/user32/windows/message.c @@ -1,4 +1,4 @@ -/* $Id: message.c,v 1.15 2003/05/19 20:11:17 gvg Exp $ +/* $Id: message.c,v 1.16 2003/05/21 22:58:43 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -524,8 +524,7 @@ WINBOOL STDCALL WaitMessage(VOID) { - UNIMPLEMENTED; - return FALSE; + return NtUserWaitMessage(); } UINT STDCALL diff --git a/reactos/subsys/win32k/include/msgqueue.h b/reactos/subsys/win32k/include/msgqueue.h index 65b83019e29..22d2f58674e 100644 --- a/reactos/subsys/win32k/include/msgqueue.h +++ b/reactos/subsys/win32k/include/msgqueue.h @@ -77,6 +77,8 @@ MsqDestroyMessage(PUSER_MESSAGE Message); VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, PUSER_MESSAGE Message); +VOID FASTCALL +MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode); BOOLEAN STDCALL MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, IN BOOLEAN Hardware, diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index 7ad93e80f3d..abce7d30d88 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: message.c,v 1.19 2003/05/18 22:07:02 gvg Exp $ +/* $Id: message.c,v 1.20 2003/05/21 22:58:42 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -40,6 +40,7 @@ #include #include #include +#include #define NDEBUG #include @@ -49,179 +50,339 @@ NTSTATUS FASTCALL W32kInitMessageImpl(VOID) { - return(STATUS_SUCCESS); + return STATUS_SUCCESS; } NTSTATUS FASTCALL W32kCleanupMessageImpl(VOID) { - return(STATUS_SUCCESS); + return STATUS_SUCCESS; } LRESULT STDCALL -NtUserDispatchMessage(CONST MSG* lpMsg) +NtUserDispatchMessage(CONST MSG* UnsafeMsg) { LRESULT Result; PWINDOW_OBJECT WindowObject; NTSTATUS Status; + MSG Msg; + + Status = MmCopyFromCaller(&Msg, (PVOID) UnsafeMsg, sizeof(MSG)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return 0; + } /* Process timer messages. */ - if (lpMsg->message == WM_TIMER) + if (Msg.message == WM_TIMER) { - if (lpMsg->lParam) + if (Msg.lParam) { /* FIXME: Call hooks. */ /* FIXME: Check for continuing validity of timer. */ - return(W32kCallWindowProc((WNDPROC)lpMsg->lParam, - lpMsg->hwnd, - lpMsg->message, - lpMsg->wParam, - 0 /* GetTickCount() */)); + return W32kCallWindowProc((WNDPROC)Msg.lParam, + Msg.hwnd, + Msg.message, + Msg.wParam, + 0 /* GetTickCount() */); } } /* Get the window object. */ Status = ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable, - lpMsg->hwnd, + Msg.hwnd, otWindow, (PVOID*)&WindowObject); if (!NT_SUCCESS(Status)) { - return(0); + SetLastNtError(Status); + return 0; } /* FIXME: Call hook procedures. */ /* Call the window procedure. */ Result = W32kCallWindowProc(NULL /* WndProc */, - lpMsg->hwnd, - lpMsg->message, - lpMsg->wParam, - lpMsg->lParam); + Msg.hwnd, + Msg.message, + Msg.wParam, + Msg.lParam); - return(Result); + return Result; } -BOOL STDCALL -NtUserGetMessage(LPMSG lpMsg, - HWND hWnd, - UINT wMsgFilterMin, - UINT wMsgFilterMax) /* - * FUNCTION: Get a message from the calling thread's message queue. - * ARGUMENTS: - * lpMsg - Pointer to the structure which receives the returned message. - * hWnd - Window whose messages are to be retrieved. - * wMsgFilterMin - Integer value of the lowest message value to be - * retrieved. - * wMsgFilterMax - Integer value of the highest message value to be - * retrieved. + * Internal version of PeekMessage() doing all the work */ +BOOL STDCALL +W32kPeekMessage(LPMSG Msg, + HWND Wnd, + UINT MsgFilterMin, + UINT MsgFilterMax, + UINT RemoveMsg) { PUSER_MESSAGE_QUEUE ThreadQueue; BOOLEAN Present; PUSER_MESSAGE Message; + BOOLEAN RemoveMessages; + + /* The queues and order in which they are checked are documented in the MSDN + article on GetMessage() */ + + ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; + + /* Inspect RemoveMsg flags */ + /* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */ + RemoveMessages = RemoveMsg & PM_REMOVE; + + /* Dispatch sent messages here. */ + while (MsqDispatchOneSentMessage(ThreadQueue)) + ; + + /* Now look for a quit message. */ + /* FIXME: WINE checks the message number filter here. */ + if (ThreadQueue->QuitPosted) + { + Msg->hwnd = Wnd; + Msg->message = WM_QUIT; + Msg->wParam = ThreadQueue->QuitExitCode; + Msg->lParam = 0; + if (RemoveMessages) + { + ThreadQueue->QuitPosted = FALSE; + } + return TRUE; + } + + /* Now check for normal messages. */ + Present = MsqFindMessage(ThreadQueue, + FALSE, + RemoveMessages, + Wnd, + MsgFilterMin, + MsgFilterMax, + &Message); + if (Present) + { + RtlCopyMemory(Msg, &Message->Msg, sizeof(MSG)); + if (RemoveMessages) + { + ExFreePool(Message); + } + return TRUE; + } + + /* Check for hardware events. */ + Present = MsqFindMessage(ThreadQueue, + TRUE, + RemoveMessages, + Wnd, + MsgFilterMin, + MsgFilterMax, + &Message); + if (Present) + { + RtlCopyMemory(Msg, &Message->Msg, sizeof(MSG)); + if (RemoveMessages) + { + ExFreePool(Message); + } + return TRUE; + } + + /* Check for sent messages again. */ + while (MsqDispatchOneSentMessage(ThreadQueue)) + ; + + /* Check for paint messages. */ + if (ThreadQueue->PaintPosted) + { + PWINDOW_OBJECT WindowObject; + + Msg->hwnd = PaintingFindWinToRepaint(Wnd, PsGetWin32Thread()); + Msg->message = WM_PAINT; + Msg->wParam = Msg->lParam = 0; + + WindowObject = W32kGetWindowObject(Msg->hwnd); + if (WindowObject != NULL) + { + if (WindowObject->Style & WS_MINIMIZE && + (HICON)NtUserGetClassLong(Msg->hwnd, GCL_HICON) != NULL) + { + Msg->message = WM_PAINTICON; + Msg->wParam = 1; + } + + if (Msg->hwnd == NULL || Msg->hwnd == Wnd || + W32kIsChildWindow(Wnd, Msg->hwnd)) + { + if (WindowObject->Flags & WINDOWOBJECT_NEED_INTERNALPAINT && + WindowObject->UpdateRegion == NULL) + { + WindowObject->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; + if (RemoveMessages) + { + MsqDecPaintCountQueue(WindowObject->MessageQueue); + } + } + } + W32kReleaseWindowObject(WindowObject); + } + + return TRUE; + } + + return FALSE; +} + +BOOL STDCALL +NtUserPeekMessage(LPMSG UnsafeMsg, + HWND Wnd, + UINT MsgFilterMin, + UINT MsgFilterMax, + UINT RemoveMsg) +{ + MSG SafeMsg; NTSTATUS Status; + BOOL Present; + PWINDOW_OBJECT Window; /* Initialize the thread's win32 state if necessary. */ W32kGuiCheck(); + /* Validate input */ + if (NULL != Wnd) + { + Status = ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable, + Wnd, otWindow, (PVOID*)&Window); + if (!NT_SUCCESS(Status)) + { + Wnd = NULL; + } + else + { + ObmDereferenceObject(Window); + } + } + if (MsgFilterMax < MsgFilterMin) + { + MsgFilterMin = 0; + MsgFilterMax = 0; + } + + Present = W32kPeekMessage(&SafeMsg, Wnd, MsgFilterMin, MsgFilterMax, RemoveMsg); + if (Present) + { + Status = MmCopyToCaller(UnsafeMsg, &SafeMsg, sizeof(MSG)); + if (! NT_SUCCESS(Status)) + { + /* There is error return documented for PeekMessage(). + Do the best we can */ + SetLastNtError(Status); + return FALSE; + } + } + + return Present; +} + +static BOOL STDCALL +W32kWaitMessage(HWND Wnd, + UINT MsgFilterMin, + UINT MsgFilterMax) +{ + PUSER_MESSAGE_QUEUE ThreadQueue; + NTSTATUS Status; + MSG Msg; + ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; do { - /* Dispatch sent messages here. */ - while (MsqDispatchOneSentMessage(ThreadQueue)); - - /* Now look for a quit message. */ - /* FIXME: WINE checks the message number filter here. */ - if (ThreadQueue->QuitPosted) + if (W32kPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_NOREMOVE)) { - lpMsg->hwnd = hWnd; - lpMsg->message = WM_QUIT; - lpMsg->wParam = ThreadQueue->QuitExitCode; - lpMsg->lParam = 0; - ThreadQueue->QuitPosted = FALSE; - return(FALSE); + return TRUE; } - /* Now check for normal messages. */ - Present = MsqFindMessage(ThreadQueue, - FALSE, - TRUE, - hWnd, - wMsgFilterMin, - wMsgFilterMax, - &Message); - if (Present) - { - RtlCopyMemory(lpMsg, &Message->Msg, sizeof(MSG)); - ExFreePool(Message); - return(TRUE); - } - - /* Check for hardware events. */ - Present = MsqFindMessage(ThreadQueue, - TRUE, - TRUE, - hWnd, - wMsgFilterMin, - wMsgFilterMax, - &Message); - if (Present) - { - RtlCopyMemory(lpMsg, &Message->Msg, sizeof(MSG)); - ExFreePool(Message); - return(TRUE); - } - - /* Check for sent messages again. */ - while (MsqDispatchOneSentMessage(ThreadQueue)); - - /* Check for paint messages. */ - if (ThreadQueue->PaintPosted) - { - PWINDOW_OBJECT WindowObject; - - lpMsg->hwnd = PaintingFindWinToRepaint(hWnd, PsGetWin32Thread()); - lpMsg->message = WM_PAINT; - lpMsg->wParam = lpMsg->lParam = 0; - - WindowObject = W32kGetWindowObject(lpMsg->hwnd); - if (WindowObject != NULL) - { - if (WindowObject->Style & WS_MINIMIZE && - (HICON)NtUserGetClassLong(lpMsg->hwnd, GCL_HICON) != NULL) - { - lpMsg->message = WM_PAINTICON; - lpMsg->wParam = 1; - } - - if (lpMsg->hwnd == NULL || lpMsg->hwnd == hWnd || - W32kIsChildWindow(hWnd, lpMsg->hwnd)) - { - if (WindowObject->Flags & WINDOWOBJECT_NEED_INTERNALPAINT && - WindowObject->UpdateRegion == NULL) - { - WindowObject->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; - MsqDecPaintCountQueue(WindowObject->MessageQueue); - } - } - W32kReleaseWindowObject(WindowObject); - } - - return(TRUE); - } - - /* Nothing found so far. Wait for new messages. */ + /* Nothing found. Wait for new messages. */ Status = MsqWaitForNewMessages(ThreadQueue); } - while (Status >= STATUS_WAIT_0 && Status <= STATUS_WAIT_63); - return((BOOLEAN)(-1)); + while (STATUS_WAIT_0 <= STATUS_WAIT_0 && Status <= STATUS_WAIT_63); + + SetLastNtError(Status); + + return FALSE; +} + +BOOL STDCALL +NtUserGetMessage(LPMSG UnsafeMsg, + HWND Wnd, + UINT MsgFilterMin, + UINT MsgFilterMax) +/* + * FUNCTION: Get a message from the calling thread's message queue. + * ARGUMENTS: + * UnsafeMsg - Pointer to the structure which receives the returned message. + * Wnd - Window whose messages are to be retrieved. + * MsgFilterMin - Integer value of the lowest message value to be + * retrieved. + * MsgFilterMax - Integer value of the highest message value to be + * retrieved. + */ +{ + BOOL GotMessage; + MSG SafeMsg; + NTSTATUS Status; + PWINDOW_OBJECT Window; + + /* Initialize the thread's win32 state if necessary. */ + W32kGuiCheck(); + + /* Validate input */ + if (NULL != Wnd) + { + Status = ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable, + Wnd, otWindow, (PVOID*)&Window); + if (!NT_SUCCESS(Status)) + { + Wnd = NULL; + } + else + { + ObmDereferenceObject(Window); + } + } + if (MsgFilterMax < MsgFilterMin) + { + MsgFilterMin = 0; + MsgFilterMax = 0; + } + + do + { + GotMessage = W32kPeekMessage(&SafeMsg, Wnd, MsgFilterMin, MsgFilterMax, PM_REMOVE); + if (GotMessage) + { + Status = MmCopyToCaller(UnsafeMsg, &SafeMsg, sizeof(MSG)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return (BOOL) -1; + } + } + else + { + W32kWaitMessage(Wnd, MsgFilterMin, MsgFilterMax); + } + } + while (! GotMessage); + + return WM_QUIT != SafeMsg.message; } DWORD @@ -240,149 +401,41 @@ NtUserMessageCall( return 0; } -BOOL STDCALL -NtUserPeekMessage(LPMSG lpMsg, - HWND hWnd, - UINT wMsgFilterMin, - UINT wMsgFilterMax, - UINT wRemoveMsg) -/* - * FUNCTION: Get a message from the calling thread's message queue. - * ARGUMENTS: - * lpMsg - Pointer to the structure which receives the returned message. - * hWnd - Window whose messages are to be retrieved. - * wMsgFilterMin - Integer value of the lowest message value to be - * retrieved. - * wMsgFilterMax - Integer value of the highest message value to be - * retrieved. - * wRemoveMsg - Specificies whether or not to remove messages from the queue after processing - */ -{ - PUSER_MESSAGE_QUEUE ThreadQueue; - BOOLEAN Present; - PUSER_MESSAGE Message; - BOOLEAN RemoveMessages; - - /* Initialize the thread's win32 state if necessary. */ - W32kGuiCheck(); - - ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; - - /* Inspect wRemoveMsg flags */ - /* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */ - RemoveMessages = wRemoveMsg & PM_REMOVE; - - /* Dispatch sent messages here. */ - while (MsqDispatchOneSentMessage(ThreadQueue)); - - /* Now look for a quit message. */ - /* FIXME: WINE checks the message number filter here. */ - if (ThreadQueue->QuitPosted) - { - lpMsg->hwnd = hWnd; - lpMsg->message = WM_QUIT; - lpMsg->wParam = ThreadQueue->QuitExitCode; - lpMsg->lParam = 0; - ThreadQueue->QuitPosted = FALSE; - return(FALSE); - } - - /* Now check for normal messages. */ - Present = MsqFindMessage(ThreadQueue, - FALSE, - RemoveMessages, - hWnd, - wMsgFilterMin, - wMsgFilterMax, - &Message); - if (Present) - { - RtlCopyMemory(lpMsg, &Message->Msg, sizeof(MSG)); - ExFreePool(Message); - return(TRUE); - } - - /* Check for hardware events. */ - Present = MsqFindMessage(ThreadQueue, - TRUE, - RemoveMessages, - hWnd, - wMsgFilterMin, - wMsgFilterMax, - &Message); - if (Present) - { - RtlCopyMemory(lpMsg, &Message->Msg, sizeof(MSG)); - ExFreePool(Message); - return(TRUE); - } - - /* Check for sent messages again. */ - while (MsqDispatchOneSentMessage(ThreadQueue)); - - /* Check for paint messages. */ - - /* Check for paint messages. */ - if (ThreadQueue->PaintPosted) - { - PWINDOW_OBJECT WindowObject; - - lpMsg->hwnd = PaintingFindWinToRepaint(hWnd, PsGetWin32Thread()); - lpMsg->message = WM_PAINT; - lpMsg->wParam = lpMsg->lParam = 0; - - WindowObject = W32kGetWindowObject(lpMsg->hwnd); - if (WindowObject != NULL) - { - if (WindowObject->Style & WS_MINIMIZE && - (HICON)NtUserGetClassLong(lpMsg->hwnd, GCL_HICON) != NULL) - { - lpMsg->message = WM_PAINTICON; - lpMsg->wParam = 1; - } - - if (lpMsg->hwnd == NULL || lpMsg->hwnd == hWnd || - W32kIsChildWindow(hWnd, lpMsg->hwnd)) - { - if (WindowObject->Flags & WINDOWOBJECT_NEED_INTERNALPAINT && - WindowObject->UpdateRegion == NULL) - { - WindowObject->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; - MsqDecPaintCountQueue(WindowObject->MessageQueue); - } - } - W32kReleaseWindowObject(WindowObject); - } - - return(TRUE); - } - - return FALSE; -} - BOOL STDCALL NtUserPostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { - PUSER_MESSAGE_QUEUE ThreadQueue; + PWINDOW_OBJECT Window; + MSG Mesg; + PUSER_MESSAGE Message; + NTSTATUS Status; - switch (Msg) - { - case WM_NULL: - break; + /* Initialize the thread's win32 state if necessary. */ + W32kGuiCheck(); - case WM_QUIT: - ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; - ThreadQueue->QuitPosted = TRUE; - ThreadQueue->QuitExitCode = wParam; - break; - - default: - DPRINT1("Unhandled message: %u\n", Msg); - return FALSE; - } + if (WM_QUIT == Msg) + { + MsqPostQuitMessage(PsGetWin32Thread()->MessageQueue, wParam); + } + else + { + Status = ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable, + hWnd, otWindow, (PVOID*)&Window); + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + Mesg.hwnd = hWnd; + Mesg.message = Msg; + Mesg.wParam = wParam; + Mesg.lParam = lParam; + Message = MsqCreateMessage(&Mesg); + MsqPostMessage(Window->MessageQueue, Message); + ObmDereferenceObject(Window); + } return TRUE; } @@ -428,7 +481,7 @@ W32kSendMessage(HWND hWnd, (PVOID*)&Window); if (!NT_SUCCESS(Status)) { - return(FALSE); + return 0; } /* FIXME: Check for an exiting window. */ @@ -440,12 +493,12 @@ W32kSendMessage(HWND hWnd, { Result = W32kCallTrampolineWindowProc(NULL, hWnd, Msg, wParam, lParam); - return(Result); + return Result; } else { Result = W32kCallWindowProc(NULL, hWnd, Msg, wParam, lParam); - return(Result); + return Result; } } else @@ -475,22 +528,22 @@ W32kSendMessage(HWND hWnd, NULL); if (Status == STATUS_WAIT_0) { - return(Result); + return Result; } else { - return(FALSE); + return FALSE; } } } LRESULT STDCALL -NtUserSendMessage(HWND hWnd, +NtUserSendMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) { - return(W32kSendMessage(hWnd, Msg, wParam, lParam, FALSE)); + return W32kSendMessage(Wnd, Msg, wParam, lParam, FALSE); } BOOL STDCALL @@ -503,7 +556,7 @@ NtUserSendMessageCallback(HWND hWnd, { UNIMPLEMENTED; - return(0); + return 0; } BOOL STDCALL @@ -520,9 +573,10 @@ NtUserSendNotifyMessage(HWND hWnd, BOOL STDCALL NtUserWaitMessage(VOID) { - UNIMPLEMENTED; + /* Initialize the thread's win32 state if necessary. */ + W32kGuiCheck(); - return 0; + return W32kWaitMessage(NULL, 0, 0); } /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/msgqueue.c b/reactos/subsys/win32k/ntuser/msgqueue.c index e057567812c..49408117284 100644 --- a/reactos/subsys/win32k/ntuser/msgqueue.c +++ b/reactos/subsys/win32k/ntuser/msgqueue.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: msgqueue.c,v 1.8 2003/05/18 17:16:17 ea Exp $ +/* $Id: msgqueue.c,v 1.9 2003/05/21 22:58:42 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -64,6 +64,7 @@ MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue) ExAcquireFastMutex(&Queue->Lock); Queue->PaintCount++; Queue->PaintPosted = TRUE; + KeSetEvent(&Queue->NewMessages, IO_NO_INCREMENT, FALSE); ExReleaseFastMutex(&Queue->Lock); } @@ -205,9 +206,12 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh, } } - Message->Msg.hwnd = Window->Self; - Message->Msg.message = Msg; - Message->Msg.lParam = MAKELONG(Point.x, Point.y); + if (Remove) + { + Message->Msg.hwnd = Window->Self; + Message->Msg.message = Msg; + Message->Msg.lParam = MAKELONG(Point.x, Point.y); + } return(TRUE); } @@ -236,7 +240,6 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, PUSER_MESSAGE Current = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry); CurrentEntry = CurrentEntry->Flink; - RemoveEntryList(&Current->ListEntry); if (Current->Msg.message >= WM_MOUSEFIRST && Current->Msg.message <= WM_MOUSELAST) { @@ -246,14 +249,16 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, &ScreenPoint, &MouseClick); if (Accept) { - RemoveEntryList(&Current->ListEntry); + if (Remove) + { + RemoveEntryList(&Current->ListEntry); + } ExReleaseFastMutex(&MessageQueue->Lock); *Message = Current; W32kReleaseWindowObject(DesktopWindow); return(TRUE); } } - CurrentEntry = CurrentEntry->Flink; } ExReleaseFastMutex(&MessageQueue->Lock); @@ -319,7 +324,7 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, &Current->ListEntry); } ExReleaseFastMutex(&HardwareMessageQueueLock); - *Message = Current; + *Message = Current; W32kReleaseWindowObject(DesktopWindow); return(TRUE); } @@ -486,6 +491,7 @@ MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue, ExAcquireFastMutex(&MessageQueue->Lock); InsertTailList(&MessageQueue->NotifyMessagesListHead, &NotifyMessage->ListEntry); + KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); ExReleaseFastMutex(&MessageQueue->Lock); } @@ -495,6 +501,7 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, { ExAcquireFastMutex(&MessageQueue->Lock); InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry); + KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); ExReleaseFastMutex(&MessageQueue->Lock); } @@ -508,6 +515,16 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, PUSER_MESSAGE Message) ExReleaseFastMutex(&MessageQueue->Lock); } +VOID FASTCALL +MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode) +{ + ExAcquireFastMutex(&MessageQueue->Lock); + MessageQueue->QuitPosted = TRUE; + MessageQueue->QuitExitCode = ExitCode; + KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + ExReleaseFastMutex(&MessageQueue->Lock); +} + BOOLEAN STDCALL MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, IN BOOLEAN Hardware, @@ -577,7 +594,7 @@ MsqInitializeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) ExInitializeFastMutex(&MessageQueue->Lock); MessageQueue->QuitPosted = FALSE; MessageQueue->QuitExitCode = 0; - KeInitializeEvent(&MessageQueue->NewMessages, NotificationEvent, FALSE); + KeInitializeEvent(&MessageQueue->NewMessages, SynchronizationEvent, FALSE); MessageQueue->QueueStatus = 0; MessageQueue->FocusWindow = NULL; }