From e781fb11a4e840b62cc7d690262bf2cf6c1d1f20 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 4 Dec 2010 17:51:17 +0000 Subject: [PATCH] [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 --- reactos/dll/win32/user32/windows/message.c | 260 +++++++---------- reactos/include/reactos/win32k/ntuser.h | 36 +-- .../subsystems/win32/win32k/ntuser/message.c | 272 +++++++----------- .../win32/win32k/ntuser/simplecall.c | 6 + reactos/subsystems/win32/win32k/w32ksvc.db | 2 - 5 files changed, 224 insertions(+), 352 deletions(-) diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index 93bb170214c..c0b2813d8f5 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -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; } diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index e6745d9f7fc..936b4f87f58 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -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; diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index 7c339b8dee7..426c0b3ddaf 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -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: diff --git a/reactos/subsystems/win32/win32k/ntuser/simplecall.c b/reactos/subsystems/win32/win32k/ntuser/simplecall.c index df2f1e4b00a..d1c5e0bec90 100644 --- a/reactos/subsystems/win32/win32k/ntuser/simplecall.c +++ b/reactos/subsystems/win32/win32k/ntuser/simplecall.c @@ -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); diff --git a/reactos/subsystems/win32/win32k/w32ksvc.db b/reactos/subsystems/win32/win32k/w32ksvc.db index 00701aa1f28..0ff90f786d8 100644 --- a/reactos/subsystems/win32/win32k/w32ksvc.db +++ b/reactos/subsystems/win32/win32k/w32ksvc.db @@ -692,6 +692,4 @@ NtUserMenuItemInfo 5 NtUserMonitorFromPoint 3 NtUserMonitorFromRect 2 NtUserMonitorFromWindow 2 -NtUserSendMessage 5 -NtUserSendMessageTimeout 8 NtUserSetScrollBarInfo 3