- Revert 51255 that was committed on accident. The patch is not ready yet.

svn path=/trunk/; revision=51256
This commit is contained in:
Michael Martin 2011-04-04 22:08:39 +00:00
parent 771f834c43
commit 862d46f96e
4 changed files with 65 additions and 154 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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);