mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 22:47:28 +00:00
[Win32k]
- Fix implementation of message callbacks, now callbacks can be called across processes. - Fix some comments. svn path=/trunk/; revision=51332
This commit is contained in:
parent
1968375672
commit
3203ddd6e1
|
@ -1425,8 +1425,8 @@ co_IntSendMessageWithCallBack( HWND hWnd,
|
|||
RETURN( FALSE);
|
||||
}
|
||||
|
||||
/* If this is not a callback and it can be sent now, then send it. */
|
||||
if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
|
||||
/* If it can be sent now, then send it. */
|
||||
if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
|
||||
{
|
||||
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
|
||||
{
|
||||
|
@ -1452,11 +1452,20 @@ co_IntSendMessageWithCallBack( HWND hWnd,
|
|||
ObDereferenceObject(Win32Thread->pEThread);
|
||||
|
||||
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
|
||||
|
||||
if (CompletionCallback)
|
||||
{
|
||||
co_IntCallSentMessageCallback(CompletionCallback,
|
||||
hWnd,
|
||||
Msg,
|
||||
CompletionCallbackContext,
|
||||
Result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
|
||||
if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
|
||||
{
|
||||
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
|
||||
{
|
||||
|
@ -1471,6 +1480,12 @@ co_IntSendMessageWithCallBack( HWND hWnd,
|
|||
RETURN( FALSE);
|
||||
}
|
||||
|
||||
IntReferenceMessageQueue(Window->head.pti->MessageQueue);
|
||||
/* Take reference on this MessageQueue if its a callback. It will be released
|
||||
when message is processed or removed from target hwnd MessageQueue */
|
||||
if (CompletionCallback)
|
||||
IntReferenceMessageQueue(Win32Thread->MessageQueue);
|
||||
|
||||
Message->Msg.hwnd = hWnd;
|
||||
Message->Msg.message = Msg;
|
||||
Message->Msg.wParam = wParam;
|
||||
|
@ -1482,8 +1497,6 @@ co_IntSendMessageWithCallBack( HWND hWnd,
|
|||
Message->SenderQueue = NULL; // mjmartin, you are right! This is null.
|
||||
Message->CallBackSenderQueue = Win32Thread->MessageQueue;
|
||||
Message->DispatchingListEntry.Flink = NULL;
|
||||
|
||||
IntReferenceMessageQueue(Window->head.pti->MessageQueue);
|
||||
Message->CompletionCallback = CompletionCallback;
|
||||
Message->CompletionCallbackContext = CompletionCallbackContext;
|
||||
Message->HookMessage = MSQ_NORMAL;
|
||||
|
@ -1492,7 +1505,6 @@ co_IntSendMessageWithCallBack( HWND hWnd,
|
|||
|
||||
InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
|
||||
MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, TRUE);
|
||||
|
||||
IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
|
||||
|
||||
RETURN(TRUE);
|
||||
|
|
|
@ -588,6 +588,28 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
Message->Msg.wParam,
|
||||
Message->Msg.lParam);
|
||||
}
|
||||
else if ((Message->CompletionCallback)
|
||||
&& (Message->CallBackSenderQueue == MessageQueue))
|
||||
{ /* Call the callback routine */
|
||||
if (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
|
||||
{
|
||||
/* The message has not been processed yet, reinsert it. */
|
||||
RemoveEntryList(&Message->ListEntry);
|
||||
InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry);
|
||||
DPRINT("Callback Message not processed yet. Requeuing the message\n");
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* Call the window procedure. */
|
||||
Result = co_IntSendMessage( Message->Msg.hwnd,
|
||||
|
@ -600,6 +622,22 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
to be cleaned up on thread termination anymore */
|
||||
RemoveEntryList(&Message->ListEntry);
|
||||
|
||||
/* If the message is a callback, insert it in the callback senders MessageQueue */
|
||||
if (Message->CompletionCallback)
|
||||
{
|
||||
if (Message->CallBackSenderQueue)
|
||||
{
|
||||
Message->lResult = Result;
|
||||
Message->QS_Flags |= QS_SMRESULT;
|
||||
|
||||
/* insert it in the callers message queue */
|
||||
InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry);
|
||||
MsqWakeQueue(Message->CallBackSenderQueue, QS_SENDMESSAGE, TRUE);
|
||||
IntDereferenceMessageQueue(Message->CallBackSenderQueue);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* remove the message from the dispatching list if needed, so lock the sender's message queue */
|
||||
if (Message->SenderQueue)
|
||||
{
|
||||
|
@ -635,19 +673,10 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
|
||||
/* 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 the message has a sender was the queue referenced */
|
||||
/* if the message has a sender */
|
||||
if (Message->SenderQueue)
|
||||
{
|
||||
/* dereference our and the sender's message queue */
|
||||
IntDereferenceMessageQueue(Message->SenderQueue);
|
||||
IntDereferenceMessageQueue(MessageQueue);
|
||||
}
|
||||
|
@ -710,6 +739,11 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
|
|||
RemoveEntryList(&SentMessage->ListEntry);
|
||||
ClearMsgBitsMask(MessageQueue, SentMessage->QS_Flags);
|
||||
|
||||
/* if it is a callback and this queue is not the sender queue, dereference queue */
|
||||
if ((SentMessage->CompletionCallback) && (SentMessage->CallBackSenderQueue != MessageQueue))
|
||||
{
|
||||
IntDereferenceMessageQueue(SentMessage->CallBackSenderQueue);
|
||||
}
|
||||
/* Only if the message has a sender was the queue referenced */
|
||||
if ((SentMessage->SenderQueue)
|
||||
&& (SentMessage->DispatchingListEntry.Flink != NULL))
|
||||
|
@ -729,7 +763,7 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
|
|||
ExFreePool((PVOID)SentMessage->Msg.lParam);
|
||||
}
|
||||
|
||||
/* Only if the message has a sender was the queue referenced */
|
||||
/* if the message has a sender */
|
||||
if (SentMessage->SenderQueue)
|
||||
{
|
||||
/* dereference our and the sender's message queue */
|
||||
|
@ -1573,8 +1607,14 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
|
||||
ListEntry);
|
||||
|
||||
/* if it is a callback and this queue is not the sender queue, dereference queue */
|
||||
if ((CurrentSentMessage->CompletionCallback) && (CurrentSentMessage->CallBackSenderQueue != MessageQueue))
|
||||
{
|
||||
IntDereferenceMessageQueue(CurrentSentMessage->CallBackSenderQueue);
|
||||
}
|
||||
|
||||
DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
|
||||
/* Only if the message has a sender was the queue referenced */
|
||||
/* Only if the message has a sender was the message in the DispatchingList */
|
||||
if ((CurrentSentMessage->SenderQueue)
|
||||
&& (CurrentSentMessage->DispatchingListEntry.Flink != NULL))
|
||||
{
|
||||
|
@ -1593,7 +1633,7 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
|
||||
}
|
||||
|
||||
/* Only if the message has a sender was the queue referenced */
|
||||
/* if the message has a sender */
|
||||
if (CurrentSentMessage->SenderQueue)
|
||||
{
|
||||
/* dereference our and the sender's message queue */
|
||||
|
@ -1613,6 +1653,12 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
|
||||
ListEntry);
|
||||
|
||||
/* if it is a callback and this queue is not the sender queue, dereference queue */
|
||||
if ((CurrentSentMessage->CompletionCallback) && (CurrentSentMessage->CallBackSenderQueue != MessageQueue))
|
||||
{
|
||||
IntDereferenceMessageQueue(CurrentSentMessage->CallBackSenderQueue);
|
||||
}
|
||||
|
||||
/* remove the message from the dispatching list */
|
||||
if(CurrentSentMessage->DispatchingListEntry.Flink != NULL)
|
||||
{
|
||||
|
@ -1633,7 +1679,7 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
|
||||
}
|
||||
|
||||
/* Only if the message has a sender was the queue referenced */
|
||||
/* if the message has a sender */
|
||||
if (CurrentSentMessage->SenderQueue)
|
||||
{
|
||||
/* dereference our and the sender's message queue */
|
||||
|
|
Loading…
Reference in a new issue