From 862d46f96e0e49f4bcf58972b49906c03bf4a809 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Mon, 4 Apr 2011 22:08:39 +0000 Subject: [PATCH] - Revert 51255 that was committed on accident. The patch is not ready yet. svn path=/trunk/; revision=51256 --- .../subsystems/win32/win32k/ntuser/event.c | 10 +- reactos/subsystems/win32/win32k/ntuser/hook.c | 10 +- .../subsystems/win32/win32k/ntuser/message.c | 49 ++---- .../subsystems/win32/win32k/ntuser/msgqueue.c | 150 +++++------------- 4 files changed, 65 insertions(+), 154 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/event.c b/reactos/subsystems/win32/win32k/ntuser/event.c index 0af97a25449..18bde4ca040 100644 --- a/reactos/subsystems/win32/win32k/ntuser/event.c +++ b/reactos/subsystems/win32/win32k/ntuser/event.c @@ -115,19 +115,15 @@ IntCallLowLevelEvent( PEVENTHOOK pEH, /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage( ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, - pEH->head.pti->MessageQueue, + Status = co_MsqSendMessage( pEH->head.pti->MessageQueue, hwnd, event, 0, - (LPARAM)pEP, - FALSE, - NULL, - 0, + (LPARAM)pEP, 300, TRUE, MSQ_ISEVENT, - &uResult); + &uResult); if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(pEP, TAG_HOOK); diff --git a/reactos/subsystems/win32/win32k/ntuser/hook.c b/reactos/subsystems/win32/win32k/ntuser/hook.c index d41e3218a9b..40d847b12ae 100644 --- a/reactos/subsystems/win32/win32k/ntuser/hook.c +++ b/reactos/subsystems/win32/win32k/ntuser/hook.c @@ -88,19 +88,15 @@ IntCallLowLevelHook( PHOOK Hook, /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage( ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, - pti->MessageQueue, + Status = co_MsqSendMessage( pti->MessageQueue, IntToPtr(Code), // hWnd Hook->HookId, // Msg wParam, - (LPARAM)pHP, - FALSE, - NULL, - 0, + (LPARAM)pHP, uTimeout, Block, MSQ_ISHOOK, - &uResult); + &uResult); if (!NT_SUCCESS(Status)) { DPRINT1("Error Hook Call SendMsg. %d Status: 0x%x\n", Hook->HookId, Status); diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index 922aa6d3197..4081267b8c3 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -1261,15 +1261,11 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, do { - Status = co_MsqSendMessage(((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, - Window->head.pti->MessageQueue, + Status = co_MsqSendMessage( Window->head.pti->MessageQueue, hWnd, Msg, wParam, lParam, - FALSE, - NULL, - 0, uTimeout, (uFlags & SMTO_BLOCK), MSQ_NORMAL, @@ -1358,7 +1354,6 @@ co_IntSendMessageNoWait(HWND hWnd, LPARAM lParam) { ULONG_PTR Result = 0; - /* Piggyback off CallBack */ co_IntSendMessageWithCallBack(hWnd, Msg, wParam, @@ -1377,12 +1372,12 @@ co_IntSendMessageNoWait(HWND hWnd, */ LRESULT FASTCALL co_IntSendMessageWithCallBack( HWND hWnd, - UINT Msg, - WPARAM wParam, - LPARAM lParam, - SENDASYNCPROC CompletionCallback, - ULONG_PTR CompletionCallbackContext, - ULONG_PTR *uResult) + UINT Msg, + WPARAM wParam, + LPARAM lParam, + SENDASYNCPROC CompletionCallback, + ULONG_PTR CompletionCallbackContext, + ULONG_PTR *uResult) { ULONG_PTR Result; PWND Window = NULL; @@ -1442,7 +1437,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, } /* If this is not a callback and it can be sent now, then send it. */ - if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue) + if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) { ObReferenceObject(Win32Thread->pEThread); Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc, @@ -1457,20 +1452,11 @@ co_IntSendMessageWithCallBack( HWND hWnd, *uResult = Result; } ObDereferenceObject(Win32Thread->pEThread); - - if (CompletionCallback) - { - co_IntCallSentMessageCallback(CompletionCallback, - hWnd, - Msg, - CompletionCallbackContext, - Result); - } } IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); - if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue) + if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { @@ -1494,21 +1480,18 @@ co_IntSendMessageWithCallBack( HWND hWnd, Message->lResult = 0; Message->QS_Flags = 0; Message->SenderQueue = NULL; // mjmartin, you are right! This is null. - if (CompletionCallback) - Message->CallBackSenderQueue = Win32Thread->MessageQueue; - else - Message->CallBackSenderQueue = NULL; + Message->CallBackSenderQueue = Win32Thread->MessageQueue; + IntReferenceMessageQueue(Window->head.pti->MessageQueue); Message->CompletionCallback = CompletionCallback; Message->CompletionCallbackContext = CompletionCallbackContext; - Message->HookMessage = MSQ_NORMAL; - Message->HasPackedLParam = (lParamBufferSize > -1); + Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT; + Message->HasPackedLParam = (lParamBufferSize > 0); Message->QS_Flags = QS_SENDMESSAGE; - if (CompletionCallback) - InsertTailList(&Win32Thread->MessageQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); - InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry); MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE); + + InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry); IntDereferenceMessageQueue(Window->head.pti->MessageQueue); RETURN(TRUE); @@ -2129,7 +2112,7 @@ NtUserMessageCall( HWND hWnd, { co_IntSendMessageTimeout( HWND_BROADCAST, Msg, - wParam, + wParam, lParam, SMTO_NORMAL, 2000, diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index be62390ffa4..db8ca7c97b8 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -423,7 +423,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) PLIST_ENTRY Entry; LRESULT Result; PTHREADINFO pti; - + if (IsListEmpty(&MessageQueue->SentMessagesListHead)) { return(FALSE); @@ -466,18 +466,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) Message->Msg.wParam, Message->Msg.lParam); } - else if ((Message->CompletionCallback) - && (Message->CallBackSenderQueue == MessageQueue)) - { /* Call the callback routine */ - ASSERT(Message->QS_Flags & QS_SMRESULT); - co_IntCallSentMessageCallback(Message->CompletionCallback, - Message->Msg.hwnd, - Message->Msg.message, - Message->CompletionCallbackContext, - Message->lResult); - /* Set callback to NULL to prevent reentry */ - Message->CompletionCallback = NULL; - } else { /* Call the window procedure. */ Result = co_IntSendMessage( Message->Msg.hwnd, @@ -490,23 +478,8 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) to be cleaned up on thread termination anymore */ RemoveEntryList(&Message->ListEntry); - if (Message->CompletionCallback) - { - if (Message->CallBackSenderQueue) - { - Message->lResult = Result; - Message->QS_Flags |= QS_SMRESULT; - - /* queue it in the callers message queue */ - InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry); - MsqWakeQueue(Message->CallBackSenderQueue, QS_SENDMESSAGE, TRUE); - IntDereferenceMessageQueue(Message->CallBackSenderQueue); - } - return (TRUE); - } - - /* remove the message from the dispatching list if there is a SenderQueue, so lock the sender's message queue */ - if ((Message->SenderQueue) || (Message->CallBackSenderQueue)) + /* remove the message from the dispatching list if needed, so lock the sender's message queue */ + if (!(Message->HookMessage & MSQ_SENTNOWAIT)) { if (Message->DispatchingListEntry.Flink != NULL) { @@ -540,8 +513,18 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); } - /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ - if (Message->SenderQueue) + /* Call the callback if the message was sent with SendMessageCallback */ + if (Message->CompletionCallback != NULL) + { + co_IntCallSentMessageCallback(Message->CompletionCallback, + Message->Msg.hwnd, + Message->Msg.message, + Message->CompletionCallbackContext, + Result); + } + + /* Only if it is not a no wait message */ + if (!(Message->HookMessage & MSQ_SENTNOWAIT)) { IntDereferenceMessageQueue(Message->SenderQueue); IntDereferenceMessageQueue(MessageQueue); @@ -605,11 +588,10 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) RemoveEntryList(&SentMessage->ListEntry); ClearMsgBitsMask(MessageQueue, SentMessage->QS_Flags); - /* If there was a SenderQueue then remove the message from this threads dispatching list */ - if (((SentMessage->SenderQueue) || (SentMessage->CallBackSenderQueue)) + /* remove the message from the dispatching list if neede */ + if ((!(SentMessage->HookMessage & MSQ_SENTNOWAIT)) && (SentMessage->DispatchingListEntry.Flink != NULL)) { - SentMessage->CallBackSenderQueue = NULL; RemoveEntryList(&SentMessage->DispatchingListEntry); } @@ -625,8 +607,8 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) ExFreePool((PVOID)SentMessage->Msg.lParam); } - /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ - if (SentMessage->SenderQueue) + /* Only if it is not a no wait message */ + if (!(SentMessage->HookMessage & MSQ_SENTNOWAIT)) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue); @@ -646,9 +628,8 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) } NTSTATUS FASTCALL -co_MsqSendMessage(PUSER_MESSAGE_QUEUE ThreadQueue, PUSER_MESSAGE_QUEUE MessageQueue, - HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL HasPackedLParam, - SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext, +co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, + HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult) { @@ -656,87 +637,49 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE ThreadQueue, PUSER_MESSAGE_QUEUE MessageQu PUSER_SENT_MESSAGE Message; KEVENT CompletionEvent; NTSTATUS WaitStatus; + PUSER_MESSAGE_QUEUE ThreadQueue; LARGE_INTEGER Timeout; PLIST_ENTRY Entry; - BOOL WaitForCompletion; LRESULT Result = 0; //// Result could be trashed. //// - /* Notification messages and some internal messages sent from the subsystem must not block current - thread and therefore pass NULL as ThreadQueue. Callbacks also do not block */ - WaitForCompletion = ((ThreadQueue) && (!CompletionCallback)); - if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG))) { DPRINT1("MsqSendMessage(): Not enough memory to allocate a message"); return STATUS_INSUFFICIENT_RESOURCES; } - /* Initialize event if calling thread will wait on completion */ - if (WaitForCompletion) - KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE); + KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE); pti = PsGetCurrentThreadWin32Thread(); + ThreadQueue = pti->MessageQueue; ptirec = MessageQueue->Thread->Tcb.Win32Thread; ASSERT(ThreadQueue != MessageQueue); ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!! Timeout.QuadPart = (LONGLONG) uTimeout * (LONGLONG) -10000; + /* FIXME - increase reference counter of sender's message queue here */ + Message->Msg.hwnd = Wnd; Message->Msg.message = Msg; Message->Msg.wParam = wParam; Message->Msg.lParam = lParam; + Message->CompletionEvent = &CompletionEvent; + Message->Result = &Result; Message->lResult = 0; Message->QS_Flags = 0; - - if (WaitForCompletion) - { - /* Normal SendMessage that will block until the Windows Procedure handles the message */ - Message->SenderQueue = ThreadQueue; - Message->CompletionEvent = &CompletionEvent; - Message->Result = &Result; - } - else - { - /* Either a SendMessageCallback, Notify Message or Internal Message from Win32k */ - Message->SenderQueue = NULL; - Message->CompletionEvent = NULL; - Message->Result = NULL; - } - - if (CompletionCallback) - { - Message->CallBackSenderQueue = ThreadQueue; - } - else - { - Message->CallBackSenderQueue = NULL; - } - - /* Reference the ThreadQueue if there was one. For normal messages - the thread is dereferenced when the messages is processed by windows procedure. - For callbacks it dereferenced once the callback message is processed and placed back - into the sending message queue */ - if (ThreadQueue != NULL) - IntReferenceMessageQueue(ThreadQueue); - - Message->CompletionCallback = CompletionCallback; - Message->CompletionCallbackContext = CompletionCallbackContext; + Message->SenderQueue = ThreadQueue; + Message->CallBackSenderQueue = NULL; + IntReferenceMessageQueue(ThreadQueue); + Message->CompletionCallback = NULL; + Message->CompletionCallbackContext = 0; Message->HookMessage = HookMessage; - Message->HasPackedLParam = HasPackedLParam; + Message->HasPackedLParam = FALSE; - if (HasPackedLParam) - { - ASSERT(Message->SenderQueue == NULL); - } - IntReferenceMessageQueue(MessageQueue); - /* Add it to the list of pending messages if waiting on completion or if message is callback. - This is done for callbacks as if the Sender terminates it will set the CallBackSenderQueue member to NULL, - informing the windows procedure handling the message to discard the callback procedure */ - if (ThreadQueue != NULL) - InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); + /* add it to the list of pending messages */ + InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); /* queue it in the destination's message queue */ InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry); @@ -744,13 +687,6 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE ThreadQueue, PUSER_MESSAGE_QUEUE MessageQu Message->QS_Flags = QS_SENDMESSAGE; MsqWakeQueue(MessageQueue, QS_SENDMESSAGE, TRUE); - /* If not waiting on completion, dereference the MessageQueue and return */ - if (!WaitForCompletion) - { - IntDereferenceMessageQueue(MessageQueue); - return STATUS_SUCCESS; - } - /* we can't access the Message anymore since it could have already been deleted! */ if(Block) @@ -918,7 +854,7 @@ MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode) * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless * the window has the WS_EX_NOPARENTNOTIFY style. */ -void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt ) +static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt ) { PWND pwndDesktop = UserGetWindowObject(IntGetDesktopWindow()); @@ -1530,8 +1466,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n"); - /* remove the message from the dispatching list if there was a SenderQueue */ - if (((CurrentSentMessage->SenderQueue) || (CurrentSentMessage->CallBackSenderQueue)) + /* remove the message from the dispatching list if needed */ + if ((!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) && (CurrentSentMessage->DispatchingListEntry.Flink != NULL)) { RemoveEntryList(&CurrentSentMessage->DispatchingListEntry); @@ -1549,8 +1485,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ - if (CurrentSentMessage->SenderQueue) + /* Only if it is not a no wait message */ + if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue); @@ -1589,8 +1525,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ - if (CurrentSentMessage->SenderQueue) + /* Only if it is not a no wait message */ + if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue);