#include <debug.h>
BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process);
+HWND FASTCALL co_UserSetCapture(HWND hWnd);
#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
return STATUS_SUCCESS;
}
+/* From wine: */
+/* flag for messages that contain pointers */
+/* 32 messages per entry, messages 0..31 map to bits 0..31 */
+
+#define SET(msg) (1 << ((msg) & 31))
+
+static const unsigned int message_pointer_flags[] =
+{
+ /* 0x00 - 0x1f */
+ SET(WM_CREATE) | SET(WM_SETTEXT) | SET(WM_GETTEXT) |
+ SET(WM_WININICHANGE) | SET(WM_DEVMODECHANGE),
+ /* 0x20 - 0x3f */
+ SET(WM_GETMINMAXINFO) | SET(WM_DRAWITEM) | SET(WM_MEASUREITEM) | SET(WM_DELETEITEM) |
+ SET(WM_COMPAREITEM),
+ /* 0x40 - 0x5f */
+ SET(WM_WINDOWPOSCHANGING) | SET(WM_WINDOWPOSCHANGED) | SET(WM_COPYDATA) |
+ SET(WM_COPYGLOBALDATA) | SET(WM_NOTIFY) | SET(WM_HELP),
+ /* 0x60 - 0x7f */
+ SET(WM_STYLECHANGING) | SET(WM_STYLECHANGED),
+ /* 0x80 - 0x9f */
+ SET(WM_NCCREATE) | SET(WM_NCCALCSIZE) | SET(WM_GETDLGCODE),
+ /* 0xa0 - 0xbf */
+ SET(EM_GETSEL) | SET(EM_GETRECT) | SET(EM_SETRECT) | SET(EM_SETRECTNP),
+ /* 0xc0 - 0xdf */
+ SET(EM_REPLACESEL) | SET(EM_GETLINE) | SET(EM_SETTABSTOPS),
+ /* 0xe0 - 0xff */
+ SET(SBM_GETRANGE) | SET(SBM_SETSCROLLINFO) | SET(SBM_GETSCROLLINFO) | SET(SBM_GETSCROLLBARINFO),
+ /* 0x100 - 0x11f */
+ 0,
+ /* 0x120 - 0x13f */
+ 0,
+ /* 0x140 - 0x15f */
+ SET(CB_GETEDITSEL) | SET(CB_ADDSTRING) | SET(CB_DIR) | SET(CB_GETLBTEXT) |
+ SET(CB_INSERTSTRING) | SET(CB_FINDSTRING) | SET(CB_SELECTSTRING) |
+ SET(CB_GETDROPPEDCONTROLRECT) | SET(CB_FINDSTRINGEXACT),
+ /* 0x160 - 0x17f */
+ 0,
+ /* 0x180 - 0x19f */
+ SET(LB_ADDSTRING) | SET(LB_INSERTSTRING) | SET(LB_GETTEXT) | SET(LB_SELECTSTRING) |
+ SET(LB_DIR) | SET(LB_FINDSTRING) |
+ SET(LB_GETSELITEMS) | SET(LB_SETTABSTOPS) | SET(LB_ADDFILE) | SET(LB_GETITEMRECT),
+ /* 0x1a0 - 0x1bf */
+ SET(LB_FINDSTRINGEXACT),
+ /* 0x1c0 - 0x1df */
+ 0,
+ /* 0x1e0 - 0x1ff */
+ 0,
+ /* 0x200 - 0x21f */
+ SET(WM_NEXTMENU) | SET(WM_SIZING) | SET(WM_MOVING) | SET(WM_DEVICECHANGE),
+ /* 0x220 - 0x23f */
+ SET(WM_MDICREATE) | SET(WM_MDIGETACTIVE) | SET(WM_DROPOBJECT) |
+ SET(WM_QUERYDROPOBJECT) | SET(WM_DRAGLOOP) | SET(WM_DRAGSELECT) | SET(WM_DRAGMOVE),
+ /* 0x240 - 0x25f */
+ 0,
+ /* 0x260 - 0x27f */
+ 0,
+ /* 0x280 - 0x29f */
+ 0,
+ /* 0x2a0 - 0x2bf */
+ 0,
+ /* 0x2c0 - 0x2df */
+ 0,
+ /* 0x2e0 - 0x2ff */
+ 0,
+ /* 0x300 - 0x31f */
+ SET(WM_ASKCBFORMATNAME)
+};
+
+/* check whether a given message type includes pointers */
+static inline int is_pointer_message( UINT message )
+{
+ if (message >= 8*sizeof(message_pointer_flags)) return FALSE;
+ return (message_pointer_flags[message / 32] & SET(message)) != 0;
+}
+
#define MMS_SIZE_WPARAM -1
#define MMS_SIZE_WPARAMWCHAR -2
#define MMS_SIZE_LPARAMSZ -3
{ WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
{ WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
{ WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
+ { WM_COPYGLOBALDATA, MMS_SIZE_WPARAM, MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
};
Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
break;
- case WM_COPYGLOBALDATA:
- Size = wParam;
- break;
-
default:
ASSERT(FALSE);
Size = 0;
ASSERT(CsData == (PCHAR) PackedCs + Size);
*lParamPacked = (LPARAM) PackedCs;
}
-
else if (PoolType == NonPagedPool)
{
PMSGMEMORY MsgMemoryEntry;
return STATUS_INVALID_PARAMETER;
}
+static NTSTATUS FASTCALL
+CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
+{
+ NTSTATUS Status;
+
+ PVOID KernelMem;
+ UINT Size;
+
+ *KernelModeMsg = *UserModeMsg;
+
+ /* See if this message type is present in the table */
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
+ }
+
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+
+ if (0 != Size)
+ {
+ /* Allocate kernel mem */
+ KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
+ if (NULL == KernelMem)
+ {
+ DPRINT1("Not enough memory to copy message to kernel mem\n");
+ return STATUS_NO_MEMORY;
+ }
+ KernelModeMsg->lParam = (LPARAM) KernelMem;
+
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
+ {
+ Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
+ ExFreePoolWithTag(KernelMem, TAG_MSG);
+ return Status;
+ }
+ }
+ else
+ {
+ /* Make sure we don't pass any secrets to usermode */
+ RtlZeroMemory(KernelMem, Size);
+ }
+ }
+ else
+ {
+ KernelModeMsg->lParam = 0;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS FASTCALL
+CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
+{
+ NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
+ UINT Size;
+
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
+ }
+
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+
+ if (0 != Size)
+ {
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
+ {
+ Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
+ ExFreePool((PVOID) KernelModeMsg->lParam);
+ return Status;
+ }
+ }
+
+ ExFreePool((PVOID) KernelModeMsg->lParam);
+ }
+
+ return STATUS_SUCCESS;
+}
+
//
// Wakeup any thread/process waiting on idle input.
//
if (ForegroundQueue)
ptiForeground = ForegroundQueue->Thread->Tcb.Win32Thread;
-
+
pti = PsGetCurrentThreadWin32Thread();
- if ( pti )
+ if ( pti )
{
pti->pClientInfo->cSpins = 0; // Reset spins.
LARGE_INTEGER TickCount;
LONG Time;
LRESULT retval = 0;
- PMSGMEMORY MsgMemoryEntry;
- INT lParamBufferSize;
PTHREADINFO pti;
- LPARAM lParamPacked;
PWND Window = NULL;
if (pMsg->hwnd)
if ( Window->head.pti != pti)
{
- SetLastWin32Error( ERROR_MESSAGE_SYNC_ONLY );
+ EngSetLastError( ERROR_MESSAGE_SYNC_ONLY );
return 0;
}
{
if (pMsg->message == WM_TIMER)
{
- ObReferenceObject(pti->pEThread);
if (ValidateTimerCallback(pti,pMsg->lParam))
{
KeQueryTickCount(&TickCount);
WM_TIMER,
pMsg->wParam,
(LPARAM)Time,
- sizeof(LPARAM));
+ 0);
}
- ObDereferenceObject(pti->pEThread);
- return retval;
+ return retval;
}
else
{
// Need a window!
if ( !Window ) return 0;
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(pMsg->message);
- if ( !MsgMemoryEntry )
- {
- lParamBufferSize = -1;
- }
- else
- {
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam);
- }
+ /* Since we are doing a callback on the same thread right away, there is
+ no need to copy the lparam to kernel mode and then back to usermode.
+ We just pretend it isn't a pointer */
- if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
- {
- DPRINT1("Failed to pack message parameters\n");
- return 0;
- }
- ObReferenceObject(pti->pEThread);
retval = co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
pMsg->hwnd,
pMsg->message,
pMsg->wParam,
- lParamPacked,
- lParamBufferSize);
-
- if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
- {
- DPRINT1("Failed to unpack message parameters\n");
- }
+ pMsg->lParam,
+ 0);
if (pMsg->message == WM_PAINT)
{
co_UserGetUpdateRgn( Window, hrgn, TRUE );
REGION_FreeRgnByHandle( hrgn );
}
- ObDereferenceObject(pti->pEThread);
+
return retval;
}
}
if ((ProcessMask & QS_INPUT) &&
- co_MsqPeekHardwareMessage( ThreadQueue,
- RemoveMessages,
- Window,
- MsgFilterMin,
+ co_MsqPeekHardwareMessage( ThreadQueue,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
MsgFilterMax,
- ProcessMask,
+ ProcessMask,
Msg))
{
return TRUE;
return TRUE;
}
-static NTSTATUS FASTCALL
-CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
-{
- NTSTATUS Status;
-
- PVOID KernelMem;
- UINT Size;
-
- *KernelModeMsg = *UserModeMsg;
-
- /* See if this message type is present in the table */
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
- }
-
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
-
- if (0 != Size)
- {
- /* Allocate kernel mem */
- KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
- if (NULL == KernelMem)
- {
- DPRINT1("Not enough memory to copy message to kernel mem\n");
- return STATUS_NO_MEMORY;
- }
- KernelModeMsg->lParam = (LPARAM) KernelMem;
-
- /* Copy data if required */
- if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
- {
- Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
- ExFreePoolWithTag(KernelMem, TAG_MSG);
- return Status;
- }
- }
- else
- {
- /* Make sure we don't pass any secrets to usermode */
- RtlZeroMemory(KernelMem, Size);
- }
- }
- else
- {
- KernelModeMsg->lParam = 0;
- }
-
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS FASTCALL
-CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
-{
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
- UINT Size;
-
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
- }
-
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
-
- if (0 != Size)
- {
- /* Copy data if required */
- if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
- {
- Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
- ExFreePool((PVOID) KernelModeMsg->lParam);
- return Status;
- }
- }
-
- ExFreePool((PVOID) KernelModeMsg->lParam);
- }
-
- return STATUS_SUCCESS;
-}
-
static BOOL FASTCALL
co_IntWaitMessage( PWND Window,
UINT MsgFilterMin,
/* Nothing found. Wait for new messages. */
Status = co_MsqWaitForNewMessages( ThreadQueue,
- Window,
- MsgFilterMin,
- MsgFilterMax);
+ Window,
+ MsgFilterMin,
+ MsgFilterMax);
}
while ( (STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) ||
STATUS_TIMEOUT == Status );
}
pti = PsGetCurrentThreadWin32Thread();
+ pti->pClientInfo->cSpins++; // Bump up the spin count.
do
{
bGMSG );
if (Present)
{
- pti->timeLast = pMsg->time;
- pti->ptLast = pMsg->pt;
+ /* GetMessage or PostMessage must never get messages that contain pointers */
+ ASSERT(FindMsgMemory(pMsg->message) == NULL);
+
+ if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
+ {
+ 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.
LARGE_INTEGER LargeTickCount;
NTSTATUS Status;
- DPRINT1("UserPostThreadMessage wParam 0x%x lParam 0x%x\n", wParam,lParam);
-
- if (FindMsgMemory(Msg) != 0)
+ if (is_pointer_message(Msg))
{
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
Status = CopyMsgToKernelMem(&KernelModeMsg, &Message, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- co_IntSendMessageNoWait(KernelModeMsg.hwnd,
- KernelModeMsg.message,
- KernelModeMsg.wParam,
+ co_IntSendMessageNoWait(KernelModeMsg.hwnd,
+ KernelModeMsg.message,
+ KernelModeMsg.wParam,
KernelModeMsg.lParam);
- if(MsgMemoryEntry)
+ if (MsgMemoryEntry && KernelModeMsg.lParam)
ExFreePool((PVOID) KernelModeMsg.lParam);
return TRUE;
}
- if (MsgMemoryEntry)
+ if (is_pointer_message(Message.message))
{
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
{
UserPostMessage(List[i], Msg, wParam, lParam);
}
- ExFreePool(List);
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
}
else
/* FIXME - last error code? */
return FALSE;
}
-
+
if (WM_QUIT == Msg)
{
MsqPostQuitMessage(Window->head.pti->MessageQueue, wParam);
}
else
- {
+ {
MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
}
}
To get extended error information, call GetLastError. If GetLastError
returns ERROR_TIMEOUT, then the function timed out.
*/
- SetLastWin32Error(ERROR_TIMEOUT);
+ EngSetLastError(ERROR_TIMEOUT);
RETURN( FALSE);
}
else if (! NT_SUCCESS(Status))
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
if (NULL == DesktopWindow)
{
- SetLastWin32Error(ERROR_INTERNAL_ERROR);
+ EngSetLastError(ERROR_INTERNAL_ERROR);
return 0;
}
return (LRESULT) TRUE;
}
-LRESULT FASTCALL
+LRESULT FASTCALL
co_IntSendMessageNoWait(HWND hWnd,
UINT Msg,
WPARAM wParam,
Message->QS_Flags = QS_SENDMESSAGE;
MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE);
-
+
InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return (dsm ? 0 : -1);
}
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
if (! NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return(dsm ? 0 : -1);
}
{
BOOL Ret = TRUE;
- if (FindMsgMemory(Msg) != 0)
+ if (is_pointer_message(Msg))
{
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
for (i = 0; List[i]; i++)
{
Ret = UserSendNotifyMessage(List[i], Msg, wParam, lParam);
- if (!Ret)
- {
- DPRINT1("SendNotifyMessage: Failed in Broadcast!\n");
- break;
- }
}
ExFreePool(List);
}
// wine:
Changes &= (QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SMRESULT);
- /* High word, types of messages currently in the queue.
+ /* High word, types of messages currently in the queue.
Low word, types of messages that have been added to the queue and that
- are still in the queue
+ are still in the queue
*/
Result = MAKELONG(pti->pcti->fsChangeBits & Changes, pti->pcti->fsWakeBits & Changes);
/** Functions ******************************************************************/
+BOOL
+APIENTRY
+NtUserDragDetect(
+ HWND hWnd,
+ POINT pt) // Just like the User call.
+{
+ MSG msg;
+ RECT rect;
+ WORD wDragWidth, wDragHeight;
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserDragDetect(%x)\n", hWnd);
+ UserEnterExclusive();
+
+ wDragWidth = UserGetSystemMetrics(SM_CXDRAG);
+ wDragHeight= UserGetSystemMetrics(SM_CYDRAG);
+
+ rect.left = pt.x - wDragWidth;
+ rect.right = pt.x + wDragWidth;
+
+ rect.top = pt.y - wDragHeight;
+ rect.bottom = pt.y + wDragHeight;
+
+ co_UserSetCapture(hWnd);
+
+ for (;;)
+ {
+ while (co_IntGetPeekMessage( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE, FALSE ) ||
+ co_IntGetPeekMessage( &msg, 0, WM_QUEUESYNC, WM_QUEUESYNC, PM_REMOVE, FALSE ) ||
+ co_IntGetPeekMessage( &msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE, FALSE ) )
+ {
+ if ( msg.message == WM_LBUTTONUP )
+ {
+ co_UserSetCapture(NULL);
+ RETURN( FALSE);
+ }
+ if ( msg.message == WM_MOUSEMOVE )
+ {
+ POINT tmp;
+ tmp.x = (short)LOWORD(msg.lParam);
+ tmp.y = (short)HIWORD(msg.lParam);
+ if( !IntPtInRect( &rect, tmp ) )
+ {
+ co_UserSetCapture(NULL);
+ RETURN( TRUE);
+ }
+ }
+ if ( msg.message == WM_KEYDOWN )
+ {
+ if ( msg.wParam == VK_ESCAPE )
+ {
+ co_UserSetCapture(NULL);
+ RETURN( TRUE);
+ }
+ }
+ if ( msg.message == WM_QUEUESYNC )
+ {
+ co_HOOK_CallHooks( WH_CBT, HCBT_QS, 0, 0 );
+ }
+ }
+ co_IntWaitMessage(NULL, 0, 0);
+ }
+ RETURN( FALSE);
+
+CLEANUP:
+ DPRINT("Leave NtUserDragDetect, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
BOOL APIENTRY
NtUserPostMessage(HWND hWnd,
UINT Msg,
ret = UserPostThreadMessage( idThread, Msg, wParam, lParam);
UserLeave();
-
+
return ret;
}
ret = co_IntWaitMessage(NULL, 0, 0);
DPRINT("NtUserWaitMessage Leave\n");
UserLeave();
-
+
return ret;
}
-
BOOL APIENTRY
-NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
+NtUserGetMessage(PMSG pMsg,
HWND hWnd,
UINT MsgFilterMin,
UINT MsgFilterMax )
-/*
-* FUNCTION: Get a message from the calling thread's message queue.
-* ARGUMENTS:
-* UnsafeMsg - Pointer to the structure which receives the returned message.
-* Wnd - Window whose messages are to be retrieved.
-* MsgFilterMin - Integer value of the lowest message value to be
-* retrieved.
-* MsgFilterMax - Integer value of the highest message value to be
-* retrieved.
-*/
-{
- NTUSERGETMESSAGEINFO Info;
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
- PVOID UserMem;
- ULONG Size;
- MSG Msg;
- BOOL GotMessage;
-
- if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- UserEnterExclusive();
-
- RtlZeroMemory(&Msg, sizeof(MSG));
-
- GotMessage = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
-
- UserLeave();
-
- Info.Msg = Msg;
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
-
- _SEH2_TRY
- {
- ProbeForWrite(UnsafeInfo, sizeof(NTUSERGETMESSAGEINFO), 1);
- RtlCopyMemory(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
-
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- UnsafeInfo->LParamSize = 0;
- }
- else
- {
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam, Info.Msg.lParam);
-
- /* Allocate required amount of user-mode memory */
- Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
- &UserMem,
- 0,
- &Size,
- MEM_COMMIT,
- PAGE_READWRITE);
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- _SEH2_YIELD(return (BOOL) -1);
- }
-
- /* Transfer lParam data to user-mode mem */
- ProbeForWrite(UserMem, Size, 1);
- RtlCopyMemory(UserMem, (PVOID)Info.Msg.lParam, Size);
-
- UnsafeInfo->LParamSize = Size;
- UnsafeInfo->Msg.lParam = (LPARAM) UserMem;
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
-
- if(UserMem != NULL)
- {
- ZwFreeVirtualMemory(NtCurrentProcess(), &UserMem, &Size, MEM_RELEASE);
- }
-
- _SEH2_YIELD(return (BOOL) -1);
- }
- _SEH2_END;
-
- return GotMessage;
-}
-
-
-BOOL APIENTRY
-NtUserGetMessageX(PMSG pMsg,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax)
{
MSG Msg;
BOOL Ret;
if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
BOOL APIENTRY
-NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
+NtUserPeekMessage( PMSG pMsg,
HWND hWnd,
UINT MsgFilterMin,
UINT MsgFilterMax,
UINT RemoveMsg)
-{
- NTSTATUS Status;
- NTUSERGETMESSAGEINFO Info;
- PMSGMEMORY MsgMemoryEntry;
- PVOID UserMem = NULL;
- ULONG Size;
- MSG Msg;
- BOOL Ret;
-
- if ( RemoveMsg & PM_BADMSGFLAGS )
- {
- SetLastWin32Error(ERROR_INVALID_FLAGS);
- return FALSE;
- }
-
- UserEnterExclusive();
-
- RtlZeroMemory(&Msg, sizeof(MSG));
-
- Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
-
- UserLeave();
-
- if (Ret)
- {
- Info.Msg = Msg;
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
-
- _SEH2_TRY
- {
- ProbeForWrite(UnsafeInfo, sizeof(NTUSERGETMESSAGEINFO), 1);
- RtlCopyMemory(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
-
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- UnsafeInfo->LParamSize = 0;
- }
- else
- {
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam, Info.Msg.lParam);
-
- /* Allocate required amount of user-mode memory */
- Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
- &UserMem,
- 0,
- &Size,
- MEM_COMMIT,
- PAGE_READWRITE);
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- _SEH2_YIELD(return (BOOL) -1);
- }
-
- /* Transfer lParam data to user-mode mem */
- ProbeForWrite(UserMem, Size, 1);
- RtlCopyMemory(UserMem, (PVOID)Info.Msg.lParam, Size);
-
- UnsafeInfo->LParamSize = Size;
- UnsafeInfo->Msg.lParam = (LPARAM) UserMem;
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Ret = (BOOL) -1;
-
- if(UserMem != NULL)
- {
- ZwFreeVirtualMemory(NtCurrentProcess(), &UserMem, &Size, MEM_RELEASE);
- }
- }
- _SEH2_END;
- }
-
- return Ret;
-}
-
-BOOL APIENTRY
-NtUserPeekMessageX( PMSG pMsg,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax,
- UINT RemoveMsg)
{
MSG Msg;
BOOL Ret;
if ( RemoveMsg & PM_BADMSGFLAGS )
{
- SetLastWin32Error(ERROR_INVALID_FLAGS);
+ EngSetLastError(ERROR_INVALID_FLAGS);
return FALSE;
}
}
_SEH2_END;
}
-
+
return Ret;
}
BOOL APIENTRY
NtUserMessageCall( HWND hWnd,
- UINT Msg,
+ UINT Msg,
WPARAM wParam,
LPARAM lParam,
ULONG_PTR ResultInfo,
break;
case FNID_SENDMESSAGECALLBACK:
{
- PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo;
+ CALL_BACK_INFO CallBackInfo;
ULONG_PTR uResult;
- if (!CallBackInfo)
- break;
+ _SEH2_TRY
+ {
+ ProbeForRead((PVOID)ResultInfo, sizeof(CALL_BACK_INFO), 1);
+ RtlCopyMemory(&CallBackInfo, (PVOID)ResultInfo, sizeof(CALL_BACK_INFO));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ _SEH2_YIELD(break);
+ }
+ _SEH2_END;
if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
- CallBackInfo->CallBack, CallBackInfo->Context, &uResult))
+ CallBackInfo.CallBack, CallBackInfo.Context, &uResult))
{
DPRINT1("Callback failure!\n");
}
}
_SEH2_END;
}
-
+
Ret = co_IntDoSendMessage( hWnd, Msg, wParam, lParam, &dsm );
if (pdsm)
{
ObDereferenceObject(Process);
UserLeave();
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return WAIT_FAILED;
}