- Pass a pointer to a structure, that holds the CallBack procedure and data, as the 5th parameter to NtUserMessageCall.
- Fix a bug In User32CallSendAsyncProcForKernel, the ArgumentLength is the size of SENDASYNCPROC_CALLBACK_ARGUMENTS.
[win32k]
- For types FNID_SENDMESSAGECALLBACK call co_IntSendMessageWithCallBack to put the message in the send queue.
- Rewrite code for when messages have a completioncallback

svn path=/trunk/; revision=47434
This commit is contained in:
Michael Martin 2010-05-30 06:23:41 +00:00
parent c816943def
commit 7774953380
5 changed files with 42 additions and 22 deletions

View file

@ -60,6 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
* content). When a ACK message is generated, the list of pair is searched for a
* matching pair, so that the client memory handle can be returned.
*/
typedef struct tagDDEPAIR
{
HGLOBAL ClientMem;
@ -2214,11 +2215,16 @@ SendMessageCallbackA(
SENDASYNCPROC lpCallBack,
ULONG_PTR dwData)
{
CALL_BACK_INFO CallBackInfo;
CallBackInfo.CallBack = lpCallBack;
CallBackInfo.Context = dwData;
return NtUserMessageCall(hWnd,
Msg,
wParam,
lParam,
(ULONG_PTR)&lpCallBack,
(ULONG_PTR)&CallBackInfo,
FNID_SENDMESSAGECALLBACK,
TRUE);
}
@ -2236,11 +2242,17 @@ SendMessageCallbackW(
SENDASYNCPROC lpCallBack,
ULONG_PTR dwData)
{
CALL_BACK_INFO CallBackInfo;
CallBackInfo.CallBack = lpCallBack;
CallBackInfo.Context = dwData;
return NtUserMessageCall(hWnd,
Msg,
wParam,
lParam,
(ULONG_PTR)&lpCallBack,
(ULONG_PTR)&CallBackInfo,
FNID_SENDMESSAGECALLBACK,
FALSE);
}

View file

@ -29,9 +29,10 @@ User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;
TRACE("User32CallSendAsyncProcKernel()\n");
CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
if (ArgumentLength != sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS))
{
return(STATUS_INFO_LENGTH_MISMATCH);
}

View file

@ -33,6 +33,13 @@ typedef struct _SENDASYNCPROC_CALLBACK_ARGUMENTS
LRESULT Result;
} SENDASYNCPROC_CALLBACK_ARGUMENTS, *PSENDASYNCPROC_CALLBACK_ARGUMENTS;
typedef struct _CALL_BACK_INFO
{
SENDASYNCPROC CallBack;
ULONG_PTR Context;
} CALL_BACK_INFO, * PCALL_BACK_INFO;
typedef struct _HOOKPROC_CALLBACK_ARGUMENTS
{
INT HookId;

View file

@ -1625,12 +1625,11 @@ co_IntSendMessageWithCallBack( HWND hWnd,
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
if (Window->pti->MessageQueue == Win32Thread->MessageQueue)
if ((Window->pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
{
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
DPRINT1("Failed to unpack message parameters\n");
RETURN(TRUE);
}
RETURN(TRUE);
}
@ -2621,6 +2620,18 @@ NtUserMessageCall(
}
break;
case FNID_SENDMESSAGECALLBACK:
{
PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo;
if (!CallBackInfo)
break;
if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
CallBackInfo->CallBack, CallBackInfo->Context, NULL))
{
DPRINT1("Callback failure!\n");
}
}
break;
// CallNextHook bypass.
case FNID_CALLWNDPROC:

View file

@ -894,7 +894,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
PLIST_ENTRY Entry;
LRESULT Result;
BOOL SenderReturned;
PUSER_SENT_MESSAGE_NOTIFY NotifyMessage;
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
{
@ -965,26 +964,16 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
}
/* Notify the sender if they specified a callback. */
/* Call the callback if the message was sent with SendMessageCallback */
if (!SenderReturned && Message->CompletionCallback != NULL)
{
if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool,
sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG)))
{
DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n");
goto Notified;
}
NotifyMessage->CompletionCallback =
Message->CompletionCallback;
NotifyMessage->CompletionCallbackContext =
Message->CompletionCallbackContext;
NotifyMessage->Result = Result;
NotifyMessage->hWnd = Message->Msg.hwnd;
NotifyMessage->Msg = Message->Msg.message;
MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage);
co_IntCallSentMessageCallback(Message->CompletionCallback,
Message->Msg.hwnd,
Message->Msg.message,
Message->CompletionCallbackContext,
Result);
}
Notified:
/* Only if it is not a no wait message */
if (!(Message->HookMessage & MSQ_SENTNOWAIT))