[Win32k|User32]

- Remove the old send message API and use NtUserMessageCall.
- Send messages do not pass the Ansi bit. This was evident during the hook changes. User32 knows the caller is Ansi and with a Unicode window user32 can make the apropate switch. Win32k on the other hand, assumes, based on the Unicode window the caller is Unicode. Hook tests enabled in send message, forces the call to win32k, and the Ansi product is Unicode data. Using NtUserMessageCall this bit can be passed forward to allow win32k to make the correct switch going to callback.

svn path=/trunk/; revision=49950
This commit is contained in:
James Tabor 2010-12-04 17:51:17 +00:00
parent 95aa3be8eb
commit e781fb11a4
5 changed files with 224 additions and 352 deletions

View file

@ -266,14 +266,6 @@ MsgiUMToKMCleanup(PMSG UMMsg, PMSG KMMsg)
return;
}
static BOOL FASTCALL
MsgiUMToKMReply(PMSG UMMsg, PMSG KMMsg, LRESULT *Result)
{
MsgiUMToKMCleanup(UMMsg, KMMsg);
return TRUE;
}
static BOOL FASTCALL
MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg)
{
@ -1074,6 +1066,7 @@ GetMessagePos(VOID)
{
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
return(MAKELONG(ThreadData->LastMessage.pt.x, ThreadData->LastMessage.pt.y));
//return NtUserCallNoParam(NOPARAM_ROUTINE_GETMSESSAGEPOS);
}
@ -2103,7 +2096,6 @@ SendMessageW(HWND Wnd,
LPARAM lParam)
{
MSG UMMsg, KMMsg;
NTUSERSENDMESSAGEINFO Info;
LRESULT Result;
PWND Window;
PTHREADINFO ti = GetW32ThreadInfo();
@ -2137,32 +2129,21 @@ SendMessageW(HWND Wnd,
UMMsg.message = Msg;
UMMsg.wParam = wParam;
UMMsg.lParam = lParam;
if (! MsgiUMToKMMessage(&UMMsg, &KMMsg, FALSE))
{
return FALSE;
}
Info.Ansi = FALSE;
Result = NtUserSendMessage( KMMsg.hwnd,
KMMsg.message,
Result = NtUserMessageCall( KMMsg.hwnd,
KMMsg.message,
KMMsg.wParam,
KMMsg.lParam,
&Info);
if (! Info.HandledByKernel)
{
MsgiUMToKMCleanup(&UMMsg, &KMMsg);
/* We need to send the message ourselves */
Result = IntCallWindowProcW( Info.Ansi,
Info.Proc,
Window,
UMMsg.hwnd,
UMMsg.message,
UMMsg.wParam,
UMMsg.lParam);
}
else if (! MsgiUMToKMReply(&UMMsg, &KMMsg, &Result))
{
return FALSE;
}
(ULONG_PTR)&Result,
FNID_SENDMESSAGE,
FALSE);
MsgiUMToKMCleanup(&UMMsg, &KMMsg);
return Result;
}
@ -2174,10 +2155,8 @@ SendMessageW(HWND Wnd,
LRESULT WINAPI
SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
MSG AnsiMsg, UcMsg;
MSG KMMsg;
MSG AnsiMsg, UcMsg, KMMsg;
LRESULT Result;
NTUSERSENDMESSAGEINFO Info;
PWND Window;
PTHREADINFO ti = GetW32ThreadInfo();
@ -2210,57 +2189,28 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
if (! MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
{
return FALSE;
}
if (! MsgiUMToKMMessage(&UcMsg, &KMMsg, FALSE))
{
if (!MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
{
return FALSE;
}
if (!MsgiUMToKMMessage(&UcMsg, &KMMsg, FALSE))
{
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
return FALSE;
}
Info.Ansi = TRUE;
Result = NtUserSendMessage( KMMsg.hwnd,
KMMsg.message,
}
Result = NtUserMessageCall( KMMsg.hwnd,
KMMsg.message,
KMMsg.wParam,
KMMsg.lParam,
&Info);
if (! Info.HandledByKernel)
{
/* We need to send the message ourselves */
if (Info.Ansi)
{
/* Ansi message and Ansi window proc, that's easy. Clean up
the Unicode message though */
MsgiUMToKMCleanup(&UcMsg, &KMMsg);
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
Result = IntCallWindowProcA(Info.Ansi, Info.Proc, Window, Wnd, Msg, wParam, lParam);
}
else
{
/* Unicode winproc. Although we started out with an Ansi message we
already converted it to Unicode for the kernel call. Reuse that
message to avoid another conversion */
Result = IntCallWindowProcW( Info.Ansi,
Info.Proc,
Window,
UcMsg.hwnd,
UcMsg.message,
UcMsg.wParam,
UcMsg.lParam);
if (! MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result))
{
return FALSE;
}
}
}
/* Message sent by kernel. Convert back to Ansi */
else if (! MsgiUMToKMReply(&UcMsg, &KMMsg, &Result) ||
! MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result))
{
return FALSE;
}
(ULONG_PTR)&Result,
FNID_SENDMESSAGE,
TRUE);
MsgiUMToKMCleanup(&UcMsg, &KMMsg);
MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result);
return Result;
}
@ -2278,18 +2228,34 @@ SendMessageCallbackA(
SENDASYNCPROC lpCallBack,
ULONG_PTR dwData)
{
BOOL Result;
MSG AnsiMsg, UcMsg;
CALL_BACK_INFO CallBackInfo;
CallBackInfo.CallBack = lpCallBack;
CallBackInfo.Context = dwData;
return NtUserMessageCall(hWnd,
Msg,
wParam,
lParam,
(ULONG_PTR)&CallBackInfo,
FNID_SENDMESSAGECALLBACK,
TRUE);
AnsiMsg.hwnd = hWnd;
AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
if (!MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
{
return FALSE;
}
Result = NtUserMessageCall( UcMsg.hwnd,
UcMsg.message,
UcMsg.wParam,
UcMsg.lParam,
(ULONG_PTR)&CallBackInfo,
FNID_SENDMESSAGECALLBACK,
TRUE);
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
return Result;
}
/*
@ -2305,7 +2271,6 @@ SendMessageCallbackW(
SENDASYNCPROC lpCallBack,
ULONG_PTR dwData)
{
CALL_BACK_INFO CallBackInfo;
CallBackInfo.CallBack = lpCallBack;
@ -2334,76 +2299,47 @@ SendMessageTimeoutA(
UINT uTimeout,
PDWORD_PTR lpdwResult)
{
MSG AnsiMsg;
MSG UcMsg;
MSG AnsiMsg, UcMsg;
LRESULT Result;
NTUSERSENDMESSAGEINFO Info;
DOSENDMESSAGE dsm;
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
if ( Msg & ~WM_MAXIMUM || fuFlags & ~(SMTO_NOTIMEOUTIFNOTHUNG|SMTO_ABORTIFHUNG|SMTO_BLOCK))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (lpdwResult) *lpdwResult = 0;
dsm.uFlags = fuFlags;
dsm.uTimeout = uTimeout;
AnsiMsg.hwnd = hWnd;
AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
if (! MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
{
return FALSE;
}
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
Info.Ansi = TRUE;
Result = NtUserSendMessageTimeout(UcMsg.hwnd, UcMsg.message,
UcMsg.wParam, UcMsg.lParam,
fuFlags, uTimeout, (ULONG_PTR*)lpdwResult, &Info);
if(!Result)
{
SPY_ExitMessage(SPY_RESULT_OK, hWnd, Msg, Result, wParam, lParam);
return FALSE;
}
if (! Info.HandledByKernel)
{
PWND pWnd;
pWnd = ValidateHwnd(hWnd);
/* We need to send the message ourselves */
if (Info.Ansi)
{
/* Ansi message and Ansi window proc, that's easy. Clean up
the Unicode message though */
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
Result = IntCallWindowProcA(Info.Ansi, Info.Proc, pWnd, hWnd, Msg, wParam, lParam);
}
else
{
/* Unicode winproc. Although we started out with an Ansi message we
already converted it to Unicode for the kernel call. Reuse that
message to avoid another conversion */
Result = IntCallWindowProcW( Info.Ansi,
Info.Proc,
pWnd,
UcMsg.hwnd,
UcMsg.message,
UcMsg.wParam,
UcMsg.lParam);
if (! MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result))
{
SPY_ExitMessage(SPY_RESULT_OK, hWnd, Msg, Result, wParam, lParam);
return FALSE;
}
}
if(lpdwResult)
*lpdwResult = Result;
Result = TRUE;
}
else
{
/* Message sent by kernel. Convert back to Ansi */
if (! MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result))
{
SPY_ExitMessage(SPY_RESULT_OK, hWnd, Msg, Result, wParam, lParam);
return FALSE;
}
}
Result = NtUserMessageCall( UcMsg.hwnd,
UcMsg.message,
UcMsg.wParam,
UcMsg.lParam,
(ULONG_PTR)&dsm,
FNID_SENDMESSAGETIMEOUT,
TRUE);
MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result);
if (lpdwResult) *lpdwResult = dsm.Result;
SPY_ExitMessage(SPY_RESULT_OK, hWnd, Msg, Result, wParam, lParam);
return Result;
}
@ -2422,28 +2358,34 @@ SendMessageTimeoutW(
UINT uTimeout,
PDWORD_PTR lpdwResult)
{
NTUSERSENDMESSAGEINFO Info;
LRESULT Result;
DOSENDMESSAGE dsm;
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
Info.Ansi = FALSE;
Result = NtUserSendMessageTimeout(hWnd, Msg, wParam, lParam, fuFlags, uTimeout,
lpdwResult, &Info);
if (! Info.HandledByKernel)
{
PWND pWnd;
pWnd = ValidateHwnd(hWnd);
/* We need to send the message ourselves */
Result = IntCallWindowProcW(Info.Ansi, Info.Proc, pWnd, hWnd, Msg, wParam, lParam);
if(lpdwResult)
*lpdwResult = Result;
if ( Msg & ~WM_MAXIMUM || fuFlags & ~(SMTO_NOTIMEOUTIFNOTHUNG|SMTO_ABORTIFHUNG|SMTO_BLOCK))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (lpdwResult) *lpdwResult = 0;
SPY_ExitMessage(SPY_RESULT_OK, hWnd, Msg, Result, wParam, lParam);
return TRUE;
}
dsm.uFlags = fuFlags;
dsm.uTimeout = uTimeout;
Result = NtUserMessageCall( hWnd,
Msg,
wParam,
lParam,
(ULONG_PTR)&dsm,
FNID_SENDMESSAGETIMEOUT,
FALSE);
if (lpdwResult) *lpdwResult = dsm.Result;
SPY_ExitMessage(SPY_RESULT_OK, hWnd, Msg, Result, wParam, lParam);
return Result;
}

View file

@ -2255,6 +2255,15 @@ NtUserMapVirtualKeyEx( UINT keyCode,
UINT transType,
DWORD keyboardId,
HKL dwhkl );
typedef struct tagDOSENDMESSAGE
{
UINT uFlags;
UINT uTimeout;
ULONG_PTR Result;
}
DOSENDMESSAGE, *PDOSENDMESSAGE;
BOOL
NTAPI
NtUserMessageCall(
@ -3302,33 +3311,6 @@ NtUserMonitorFromWindow(
IN HWND hWnd,
IN DWORD dwFlags);
typedef struct tagNTUSERSENDMESSAGEINFO
{
BOOL HandledByKernel;
BOOL Ansi;
WNDPROC Proc;
} NTUSERSENDMESSAGEINFO, *PNTUSERSENDMESSAGEINFO;
/* use NtUserMessageCall */
LRESULT NTAPI
NtUserSendMessage(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
PNTUSERSENDMESSAGEINFO Info);
/* use NtUserMessageCall */
LRESULT NTAPI
NtUserSendMessageTimeout(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT uFlags,
UINT uTimeout,
ULONG_PTR *uResult,
PNTUSERSENDMESSAGEINFO Info);
typedef struct _SETSCROLLBARINFO
{
int nTrackPos;

View file

@ -19,14 +19,6 @@ BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process);
#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
typedef struct
{
UINT uFlags;
UINT uTimeout;
ULONG_PTR Result;
}
DOSENDMESSAGE, *PDOSENDMESSAGE;
/* FUNCTIONS *****************************************************************/
NTSTATUS FASTCALL
@ -864,6 +856,8 @@ co_IntGetPeekMessage( PMSG pMsg,
RemoveMsg |= ((GetWakeMask( MsgFilterMin, MsgFilterMax ))<< 16);
}
pti = PsGetCurrentThreadWin32Thread();
do
{
Present = co_IntPeekMessage( pMsg,
@ -874,6 +868,9 @@ co_IntGetPeekMessage( PMSG pMsg,
bGMSG );
if (Present)
{
pti->timeLast = pMsg->time;
pti->ptLast = pMsg->pt;
// The WH_GETMESSAGE hook enables an application to monitor messages about to
// be returned by the GetMessage or PeekMessage function.
@ -911,7 +908,6 @@ co_IntGetPeekMessage( PMSG pMsg,
}
while( bGMSG && !Present );
pti = PsGetCurrentThreadWin32Thread();
// Been spinning, time to swap vinyl...
if (pti->pClientInfo->cSpins >= 100)
{
@ -962,7 +958,7 @@ UserPostThreadMessage( DWORD idThread,
Message.pt = gpsi->ptCursor;
KeQueryTickCount(&LargeTickCount);
pThread->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
Message.time = MsqCalculateMessageTime(&LargeTickCount);
MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
ObDereferenceObject( peThread );
return TRUE;
@ -1052,7 +1048,7 @@ UserPostMessage( HWND Wnd,
Message.lParam = lParam;
Message.pt = gpsi->ptCursor;
KeQueryTickCount(&LargeTickCount);
pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
Message.time = MsqCalculateMessageTime(&LargeTickCount);
MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
}
}
@ -1451,29 +1447,21 @@ co_IntDoSendMessage( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
PDOSENDMESSAGE dsm,
PNTUSERSENDMESSAGEINFO UnsafeInfo )
PDOSENDMESSAGE dsm)
{
PTHREADINFO pti;
LRESULT Result = TRUE;
NTSTATUS Status;
PWND Window = NULL;
NTUSERSENDMESSAGEINFO Info;
MSG UserModeMsg;
MSG KernelModeMsg;
PMSGMEMORY MsgMemoryEntry;
RtlZeroMemory(&Info, sizeof(NTUSERSENDMESSAGEINFO));
/* FIXME: Call hooks. */
if (HWND_BROADCAST != hWnd)
{
Window = UserGetWindowObject(hWnd);
if ( !Window )
{
/* Tell usermode to not touch this one */
Info.HandledByKernel = TRUE;
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
return 0;
}
}
@ -1487,85 +1475,47 @@ co_IntDoSendMessage( HWND hWnd,
/* See if the current thread can handle the message */
pti = PsGetCurrentThreadWin32Thread();
// This is checked in user mode!!!!!!!
if ( HWND_BROADCAST != hWnd &&
NULL != pti &&
Window->head.pti->MessageQueue == pti->MessageQueue &&
!ISITHOOKED(WH_CALLWNDPROC) &&
!ISITHOOKED(WH_CALLWNDPROCRET) &&
( Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST ) )
UserModeMsg.hwnd = hWnd;
UserModeMsg.message = Msg;
UserModeMsg.wParam = wParam;
UserModeMsg.lParam = lParam;
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
{
/* Gather the information usermode needs to call the window proc directly */
Info.HandledByKernel = FALSE;
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return (dsm ? 0 : -1);
}
Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi), sizeof(BOOL));
if (! NT_SUCCESS(Status))
{
Info.Ansi = ! Window->Unicode;
}
Info.Ansi = !Window->Unicode;
Info.Proc = Window->lpfnWndProc;
if (!dsm)
{
Result = co_IntSendMessage( KernelModeMsg.hwnd,
KernelModeMsg.message,
KernelModeMsg.wParam,
KernelModeMsg.lParam );
}
else
{
/* Must be handled by other thread */
// if (HWND_BROADCAST != hWnd)
// {
// UserDereferenceObject(Window);
// }
Info.HandledByKernel = TRUE;
UserModeMsg.hwnd = hWnd;
UserModeMsg.message = Msg;
UserModeMsg.wParam = wParam;
UserModeMsg.lParam = lParam;
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
{
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return (dsm ? 0 : -1);
}
if(!dsm)
{
Result = co_IntSendMessage( KernelModeMsg.hwnd,
KernelModeMsg.message,
KernelModeMsg.wParam,
KernelModeMsg.lParam );
}
else
{
Result = co_IntSendMessageTimeout( KernelModeMsg.hwnd,
KernelModeMsg.message,
KernelModeMsg.wParam,
KernelModeMsg.lParam,
dsm->uFlags,
dsm->uTimeout,
&dsm->Result );
}
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
if (! NT_SUCCESS(Status))
{
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return(dsm ? 0 : -1);
}
Result = co_IntSendMessageTimeout( KernelModeMsg.hwnd,
KernelModeMsg.message,
KernelModeMsg.wParam,
KernelModeMsg.lParam,
dsm->uFlags,
dsm->uTimeout,
&dsm->Result );
}
Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
if (! NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return(dsm ? 0 : -1);
}
return (LRESULT)Result;
}
BOOL FASTCALL
UserSendNotifyMessage( HWND hWnd,
UINT Msg,
@ -1709,68 +1659,6 @@ NtUserPostThreadMessage(DWORD idThread,
return ret;
}
////////// API on the way out!
LRESULT APIENTRY
NtUserSendMessageTimeout( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT uFlags,
UINT uTimeout,
ULONG_PTR *uResult,
PNTUSERSENDMESSAGEINFO UnsafeInfo )
{
DOSENDMESSAGE dsm;
LRESULT Result;
DPRINT("Enter NtUserSendMessageTimeout\n");
dsm.uFlags = uFlags;
dsm.uTimeout = uTimeout;
UserEnterExclusive();
Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
UserLeave();
if(uResult != NULL && Result != 0)
{
_SEH2_TRY
{
ProbeForWrite(uResult, sizeof(ULONG_PTR), 1);
RtlCopyMemory(uResult, &dsm.Result, sizeof(ULONG_PTR));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);;
Result = FALSE;
}
_SEH2_END;
}
return Result;
}
LRESULT APIENTRY
NtUserSendMessage( HWND Wnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
PNTUSERSENDMESSAGEINFO UnsafeInfo )
{
BOOL ret;
UserEnterExclusive();
ret = co_IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo);
UserLeave();
return ret;
}
//////////
BOOL APIENTRY
NtUserWaitMessage(VOID)
{
@ -2220,32 +2108,32 @@ NtUserMessageCall( HWND hWnd,
if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG)
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
wParam,
lParam,
SMTO_ABORTIFHUNG,
2000,
&RetVal);
Msg,
wParam,
lParam,
SMTO_ABORTIFHUNG,
2000,
&RetVal);
}
else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG)
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
Msg,
wParam,
lParam,
SMTO_NOTIMEOUTIFNOTHUNG,
2000,
&RetVal);
lParam,
SMTO_NOTIMEOUTIFNOTHUNG,
2000,
&RetVal);
}
else
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
wParam,
lParam,
SMTO_NORMAL,
2000,
&RetVal);
Msg,
wParam,
lParam,
SMTO_NORMAL,
2000,
&RetVal);
}
Ret = RetVal;
}
@ -2275,6 +2163,62 @@ NtUserMessageCall( HWND hWnd,
}
}
break;
case FNID_SENDMESSAGE:
{
Ret = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, 0);
if (ResultInfo)
{
_SEH2_TRY
{
ProbeForWrite((PVOID)ResultInfo, sizeof(ULONG_PTR), 1);
RtlCopyMemory((PVOID)ResultInfo, &Ret, sizeof(ULONG_PTR));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Ret = FALSE;
_SEH2_YIELD(break);
}
_SEH2_END;
}
break;
}
case FNID_SENDMESSAGETIMEOUT:
{
DOSENDMESSAGE dsm, *pdsm = (PDOSENDMESSAGE)ResultInfo;
if (ResultInfo)
{
_SEH2_TRY
{
ProbeForRead(pdsm, sizeof(DOSENDMESSAGE), 1);
RtlCopyMemory(&dsm, pdsm, sizeof(DOSENDMESSAGE));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Ret = FALSE;
_SEH2_YIELD(break);
}
_SEH2_END;
}
Ret = co_IntDoSendMessage( hWnd, Msg, wParam, lParam, &dsm );
if (pdsm)
{
_SEH2_TRY
{
ProbeForWrite(pdsm, sizeof(DOSENDMESSAGE), 1);
RtlCopyMemory(pdsm, &dsm, sizeof(DOSENDMESSAGE));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Ret = FALSE;
_SEH2_YIELD(break);
}
_SEH2_END;
}
break;
}
// CallNextHook bypass.
case FNID_CALLWNDPROC:
case FNID_CALLWNDPROCRET:

View file

@ -113,6 +113,12 @@ NtUserCallNoParam(DWORD Routine)
case NOPARAM_ROUTINE_MSQCLEARWAKEMASK:
RETURN( (DWORD_PTR)IntMsqClearWakeMask());
case NOPARAM_ROUTINE_GETMSESSAGEPOS:
{
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
RETURN( (DWORD_PTR)MAKELONG(pti->ptLast.x, pti->ptLast.y));
}
default:
DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine);
SetLastWin32Error(ERROR_INVALID_PARAMETER);

View file

@ -692,6 +692,4 @@ NtUserMenuItemInfo 5
NtUserMonitorFromPoint 3
NtUserMonitorFromRect 2
NtUserMonitorFromWindow 2
NtUserSendMessage 5
NtUserSendMessageTimeout 8
NtUserSetScrollBarInfo 3