mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[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:
parent
95aa3be8eb
commit
e781fb11a4
5 changed files with 224 additions and 352 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -692,6 +692,4 @@ NtUserMenuItemInfo 5
|
|||
NtUserMonitorFromPoint 3
|
||||
NtUserMonitorFromRect 2
|
||||
NtUserMonitorFromWindow 2
|
||||
NtUserSendMessage 5
|
||||
NtUserSendMessageTimeout 8
|
||||
NtUserSetScrollBarInfo 3
|
||||
|
|
Loading…
Reference in a new issue