[Win32k|User32]

- Finish 50030 (work by Giannis), Now PostMessage passes all the correct data based on Get/PeekMessage. Example: Post A, Get/Peek A, Translate A, Dispatch A, should be that simple. FYI: DDE memory handling should be in win32k not user32 and why,,,,, ~see next point~
- Patch up problems (at a minimum) going into the SendMessage/Timeout A2U U2A support in win32k and fixed SMTO callback if local.

svn path=/trunk/; revision=50047
This commit is contained in:
James Tabor 2010-12-17 01:09:42 +00:00
parent f21a470fe6
commit e8264b6759
4 changed files with 216 additions and 205 deletions

View file

@ -116,7 +116,6 @@ typedef struct _USER32_TRACKINGLIST {
typedef struct _USER32_THREAD_DATA typedef struct _USER32_THREAD_DATA
{ {
MSG LastMessage;
USER32_TRACKINGLIST tracking_info; /* TrackMouseEvent stuff */ USER32_TRACKINGLIST tracking_info; /* TrackMouseEvent stuff */
} USER32_THREAD_DATA, *PUSER32_THREAD_DATA; } USER32_THREAD_DATA, *PUSER32_THREAD_DATA;

View file

@ -145,7 +145,8 @@ DdeGetPair(HGLOBAL ServerMem)
return Ret; return Ret;
} }
static BOOL FASTCALL static
BOOL FASTCALL
MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted) MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
{ {
*KMMsg = *UMMsg; *KMMsg = *UMMsg;
@ -249,7 +250,8 @@ MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
return TRUE; return TRUE;
} }
static VOID FASTCALL static
VOID FASTCALL
MsgiUMToKMCleanup(PMSG UMMsg, PMSG KMMsg) MsgiUMToKMCleanup(PMSG UMMsg, PMSG KMMsg)
{ {
switch (KMMsg->message) switch (KMMsg->message)
@ -949,9 +951,7 @@ DWORD
WINAPI WINAPI
GetMessagePos(VOID) GetMessagePos(VOID)
{ {
PUSER32_THREAD_DATA ThreadData = User32GetThreadData(); return NtUserCallNoParam(NOPARAM_ROUTINE_GETMSESSAGEPOS);
return(MAKELONG(ThreadData->LastMessage.pt.x, ThreadData->LastMessage.pt.y));
//return NtUserCallNoParam(NOPARAM_ROUTINE_GETMSESSAGEPOS);
} }
@ -961,9 +961,7 @@ GetMessagePos(VOID)
LONG WINAPI LONG WINAPI
GetMessageTime(VOID) GetMessageTime(VOID)
{ {
PUSER32_THREAD_DATA ThreadData = User32GetThreadData(); return NtUserGetThreadState(THREADSTATE_GETMESSAGETIME);
return(ThreadData->LastMessage.time);
// return NtUserGetThreadState(THREADSTATE_GETMESSAGETIME);
} }
@ -1602,7 +1600,12 @@ GetMessageA(LPMSG lpMsg,
UINT wMsgFilterMax) UINT wMsgFilterMax)
{ {
BOOL Res; BOOL Res;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
if ( (wMsgFilterMin|wMsgFilterMax) & ~WM_MAXIMUM )
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
if (-1 == (int) Res) if (-1 == (int) Res)
@ -1610,11 +1613,6 @@ GetMessageA(LPMSG lpMsg,
return Res; return Res;
} }
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
ThreadData->LastMessage = *lpMsg;
}
return Res; return Res;
} }
@ -1628,7 +1626,12 @@ GetMessageW(LPMSG lpMsg,
UINT wMsgFilterMax) UINT wMsgFilterMax)
{ {
BOOL Res; BOOL Res;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
if ( (wMsgFilterMin|wMsgFilterMax) & ~WM_MAXIMUM )
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
if (-1 == (int) Res) if (-1 == (int) Res)
@ -1636,16 +1639,11 @@ GetMessageW(LPMSG lpMsg,
return Res; return Res;
} }
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
ThreadData->LastMessage = *lpMsg;
}
return Res; return Res;
} }
BOOL WINAPI BOOL WINAPI
PeekMessageWorker(PMSG pMsg, PeekMessageWorker( PMSG pMsg,
HWND hWnd, HWND hWnd,
UINT wMsgFilterMin, UINT wMsgFilterMin,
UINT wMsgFilterMax, UINT wMsgFilterMax,
@ -1692,7 +1690,6 @@ PeekMessageA(LPMSG lpMsg,
UINT wRemoveMsg) UINT wRemoveMsg)
{ {
BOOL Res; BOOL Res;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
Res = PeekMessageWorker(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); Res = PeekMessageWorker(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
if (-1 == (int) Res || !Res) if (-1 == (int) Res || !Res)
@ -1700,11 +1697,6 @@ PeekMessageA(LPMSG lpMsg,
return FALSE; return FALSE;
} }
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
ThreadData->LastMessage = *lpMsg;
}
return Res; return Res;
} }
@ -1722,7 +1714,6 @@ PeekMessageW(
UINT wRemoveMsg) UINT wRemoveMsg)
{ {
BOOL Res; BOOL Res;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
Res = PeekMessageWorker(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); Res = PeekMessageWorker(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
if (-1 == (int) Res || !Res) if (-1 == (int) Res || !Res)
@ -1730,46 +1721,9 @@ PeekMessageW(
return FALSE; return FALSE;
} }
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
ThreadData->LastMessage = *lpMsg;
}
return Res; return Res;
} }
//
// Worker function for post message.
//
BOOL
FASTCALL
PostMessageWorker(
HWND Wnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
MSG UMMsg, KMMsg;
LRESULT Result;
UMMsg.hwnd = Wnd;
UMMsg.message = Msg;
UMMsg.wParam = wParam;
UMMsg.lParam = lParam;
if (! MsgiUMToKMMessage(&UMMsg, &KMMsg, TRUE))
{
return FALSE;
}
Result = NtUserPostMessage( Wnd,
KMMsg.message,
KMMsg.wParam,
KMMsg.lParam);
MsgiUMToKMCleanup(&UMMsg, &KMMsg);
return Result;
}
/* /*
* @implemented * @implemented
*/ */
@ -1781,24 +1735,38 @@ PostMessageA(
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
MSG AnsiMsg, UcMsg; LRESULT Ret;
BOOL Ret;
AnsiMsg.hwnd = hWnd; /* Check for combo box or a list box to send names. */
AnsiMsg.message = Msg; if (Msg == CB_DIR || Msg == LB_DIR)
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
if (!MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
{ {
return FALSE; /*
Set DDL_POSTMSGS, so use the PostMessage function to send messages to the
combo/list box. Forces a call like DlgDirListComboBox.
*/
//wParam |= DDL_POSTMSGS;
return NtUserPostMessage(hWnd, Msg, wParam, lParam);
} }
Ret = PostMessageW( hWnd, UcMsg.message, UcMsg.wParam, UcMsg.lParam); /* No drop files or current Process, just post message. */
if ( (Msg != WM_DROPFILES) ||
( NtUserQueryWindow( hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
PtrToUint(NtCurrentTeb()->ClientId.UniqueProcess) ) )
{
return NtUserPostMessage(hWnd, Msg, wParam, lParam);
}
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg); /* We have drop files and this is not the same process for this window. */
return Ret; /* Just incase, check wParam for Global memory handle and send size. */
Ret = SendMessageA( hWnd,
WM_COPYGLOBALDATA,
(WPARAM)GlobalSize((HGLOBAL)wParam), // Zero if not a handle.
(LPARAM)wParam); // Send wParam as lParam.
if ( Ret ) return NtUserPostMessage(hWnd, Msg, (WPARAM)Ret, lParam);
return FALSE;
} }
/* /*
@ -1821,8 +1789,8 @@ PostMessageW(
Set DDL_POSTMSGS, so use the PostMessage function to send messages to the Set DDL_POSTMSGS, so use the PostMessage function to send messages to the
combo/list box. Forces a call like DlgDirListComboBox. combo/list box. Forces a call like DlgDirListComboBox.
*/ */
wParam |= DDL_POSTMSGS; //wParam |= DDL_POSTMSGS;
return PostMessageWorker(hWnd, Msg, wParam, lParam); return NtUserPostMessage(hWnd, Msg, wParam, lParam);
} }
/* No drop files or current Process, just post message. */ /* No drop files or current Process, just post message. */
@ -1830,7 +1798,7 @@ PostMessageW(
( NtUserQueryWindow( hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) == ( NtUserQueryWindow( hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
PtrToUint(NtCurrentTeb()->ClientId.UniqueProcess) ) ) PtrToUint(NtCurrentTeb()->ClientId.UniqueProcess) ) )
{ {
return PostMessageWorker(hWnd, Msg, wParam, lParam); return NtUserPostMessage(hWnd, Msg, wParam, lParam);
} }
/* We have drop files and this is not the same process for this window. */ /* We have drop files and this is not the same process for this window. */
@ -1841,7 +1809,7 @@ PostMessageW(
(WPARAM)GlobalSize((HGLOBAL)wParam), // Zero if not a handle. (WPARAM)GlobalSize((HGLOBAL)wParam), // Zero if not a handle.
(LPARAM)wParam); // Send wParam as lParam. (LPARAM)wParam); // Send wParam as lParam.
if ( Ret ) return PostMessageWorker(hWnd, Msg, (WPARAM)Ret, lParam); if ( Ret ) return NtUserPostMessage(hWnd, Msg, (WPARAM)Ret, lParam);
return FALSE; return FALSE;
} }
@ -1902,11 +1870,16 @@ SendMessageW(HWND Wnd,
PWND Window; PWND Window;
PTHREADINFO ti = GetW32ThreadInfo(); PTHREADINFO ti = GetW32ThreadInfo();
Window = ValidateHwnd(Wnd); if ( Msg & ~WM_MAXIMUM )
if (!Window) return FALSE; {
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST)) if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{ {
Window = ValidateHwnd(Wnd);
if ( Window != NULL && if ( Window != NULL &&
Window->head.pti == ti && Window->head.pti == ti &&
// !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug. // !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
@ -1937,7 +1910,7 @@ SendMessageW(HWND Wnd,
return FALSE; return FALSE;
} }
Result = NtUserMessageCall( KMMsg.hwnd, Result = NtUserMessageCall( Wnd,
KMMsg.message, KMMsg.message,
KMMsg.wParam, KMMsg.wParam,
KMMsg.lParam, KMMsg.lParam,
@ -1962,11 +1935,16 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
PWND Window; PWND Window;
PTHREADINFO ti = GetW32ThreadInfo(); PTHREADINFO ti = GetW32ThreadInfo();
Window = ValidateHwnd(Wnd); if ( Msg & ~WM_MAXIMUM )
if (!Window) return FALSE; {
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST)) if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{ {
Window = ValidateHwnd(Wnd);
if ( Window != NULL && if ( Window != NULL &&
Window->head.pti == ti && Window->head.pti == ti &&
// !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug. // !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
@ -2003,7 +1981,7 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
return FALSE; return FALSE;
} }
Result = NtUserMessageCall( KMMsg.hwnd, Result = NtUserMessageCall( Wnd,
KMMsg.message, KMMsg.message,
KMMsg.wParam, KMMsg.wParam,
KMMsg.lParam, KMMsg.lParam,
@ -2047,7 +2025,7 @@ SendMessageCallbackA(
return FALSE; return FALSE;
} }
Result = NtUserMessageCall( UcMsg.hwnd, Result = NtUserMessageCall( hWnd,
UcMsg.message, UcMsg.message,
UcMsg.wParam, UcMsg.wParam,
UcMsg.lParam, UcMsg.lParam,
@ -2104,8 +2082,8 @@ SendMessageTimeoutA(
MSG AnsiMsg, UcMsg; MSG AnsiMsg, UcMsg;
LRESULT Result; LRESULT Result;
DOSENDMESSAGE dsm; DOSENDMESSAGE dsm;
PWND Window;
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam); PTHREADINFO ti = GetW32ThreadInfo();
if ( Msg & ~WM_MAXIMUM || fuFlags & ~(SMTO_NOTIMEOUTIFNOTHUNG|SMTO_ABORTIFHUNG|SMTO_BLOCK)) if ( Msg & ~WM_MAXIMUM || fuFlags & ~(SMTO_NOTIMEOUTIFNOTHUNG|SMTO_ABORTIFHUNG|SMTO_BLOCK))
{ {
@ -2115,6 +2093,23 @@ SendMessageTimeoutA(
if (lpdwResult) *lpdwResult = 0; if (lpdwResult) *lpdwResult = 0;
if (hWnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{
Window = ValidateHwnd(hWnd);
if ( Window != NULL &&
Window->head.pti == ti &&
!ISITHOOKED(WH_CALLWNDPROC) &&
!ISITHOOKED(WH_CALLWNDPROCRET) &&
!(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
{
Result = IntCallMessageProc(Window, hWnd, Msg, wParam, lParam, TRUE);
if (lpdwResult) *lpdwResult = Result;
return TRUE;
}
}
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
dsm.uFlags = fuFlags; dsm.uFlags = fuFlags;
dsm.uTimeout = uTimeout; dsm.uTimeout = uTimeout;
@ -2128,7 +2123,7 @@ SendMessageTimeoutA(
return FALSE; return FALSE;
} }
Result = NtUserMessageCall( UcMsg.hwnd, Result = NtUserMessageCall( hWnd,
UcMsg.message, UcMsg.message,
UcMsg.wParam, UcMsg.wParam,
UcMsg.lParam, UcMsg.lParam,
@ -2162,8 +2157,8 @@ SendMessageTimeoutW(
{ {
LRESULT Result; LRESULT Result;
DOSENDMESSAGE dsm; DOSENDMESSAGE dsm;
PWND Window;
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam); PTHREADINFO ti = GetW32ThreadInfo();
if ( Msg & ~WM_MAXIMUM || fuFlags & ~(SMTO_NOTIMEOUTIFNOTHUNG|SMTO_ABORTIFHUNG|SMTO_BLOCK)) if ( Msg & ~WM_MAXIMUM || fuFlags & ~(SMTO_NOTIMEOUTIFNOTHUNG|SMTO_ABORTIFHUNG|SMTO_BLOCK))
{ {
@ -2173,6 +2168,23 @@ SendMessageTimeoutW(
if (lpdwResult) *lpdwResult = 0; if (lpdwResult) *lpdwResult = 0;
if (hWnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{
Window = ValidateHwnd(hWnd);
if ( Window != NULL &&
Window->head.pti == ti &&
!ISITHOOKED(WH_CALLWNDPROC) &&
!ISITHOOKED(WH_CALLWNDPROCRET) &&
!(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
{
Result = IntCallMessageProc(Window, hWnd, Msg, wParam, lParam, FALSE);
if (lpdwResult) *lpdwResult = Result;
return TRUE;
}
}
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
dsm.uFlags = fuFlags; dsm.uFlags = fuFlags;
dsm.uTimeout = uTimeout; dsm.uTimeout = uTimeout;

View file

@ -61,6 +61,7 @@ static MSGMEMORY MsgMemory[] =
{ WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ }, { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
{ WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE }, { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
{ WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ }, { WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
{ WM_COPYGLOBALDATA, MMS_SIZE_WPARAM, MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ }, { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE }, { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
}; };
@ -134,10 +135,6 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData; Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
break; break;
case WM_COPYGLOBALDATA:
Size = wParam;
break;
default: default:
ASSERT(FALSE); ASSERT(FALSE);
Size = 0; Size = 0;
@ -243,7 +240,6 @@ PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Non
ASSERT(CsData == (PCHAR) PackedCs + Size); ASSERT(CsData == (PCHAR) PackedCs + Size);
*lParamPacked = (LPARAM) PackedCs; *lParamPacked = (LPARAM) PackedCs;
} }
else if (PoolType == NonPagedPool) else if (PoolType == NonPagedPool)
{ {
PMSGMEMORY MsgMemoryEntry; PMSGMEMORY MsgMemoryEntry;
@ -317,6 +313,100 @@ UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL No
return STATUS_INVALID_PARAMETER; 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. // Wakeup any thread/process waiting on idle input.
// //
@ -654,100 +744,6 @@ co_IntPeekMessage( PMSG 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 static BOOL FASTCALL
co_IntWaitMessage( PWND Window, co_IntWaitMessage( PWND Window,
UINT MsgFilterMin, UINT MsgFilterMin,
@ -834,6 +830,7 @@ co_IntGetPeekMessage( PMSG pMsg,
} }
pti = PsGetCurrentThreadWin32Thread(); pti = PsGetCurrentThreadWin32Thread();
pti->pClientInfo->cSpins++; // Bump up the spin count.
do do
{ {
@ -848,8 +845,11 @@ co_IntGetPeekMessage( PMSG pMsg,
/* GetMessage or PostMessage must never get messages that contain pointers */ /* GetMessage or PostMessage must never get messages that contain pointers */
ASSERT(FindMsgMemory(pMsg->message) == NULL); ASSERT(FindMsgMemory(pMsg->message) == NULL);
if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
{
pti->timeLast = pMsg->time; pti->timeLast = pMsg->time;
pti->ptLast = pMsg->pt; pti->ptLast = pMsg->pt;
}
// The WH_GETMESSAGE hook enables an application to monitor messages about to // The WH_GETMESSAGE hook enables an application to monitor messages about to
// be returned by the GetMessage or PeekMessage function. // be returned by the GetMessage or PeekMessage function.
@ -984,7 +984,7 @@ UserPostMessage( HWND Wnd,
KernelModeMsg.wParam, KernelModeMsg.wParam,
KernelModeMsg.lParam); KernelModeMsg.lParam);
if(MsgMemoryEntry) if (MsgMemoryEntry && KernelModeMsg.lParam)
ExFreePool((PVOID) KernelModeMsg.lParam); ExFreePool((PVOID) KernelModeMsg.lParam);
return TRUE; return TRUE;
@ -1019,7 +1019,7 @@ UserPostMessage( HWND Wnd,
{ {
UserPostMessage(List[i], Msg, wParam, lParam); UserPostMessage(List[i], Msg, wParam, lParam);
} }
ExFreePool(List); ExFreePoolWithTag(List,TAG_WINLIST);//ExFreePool(List);
} }
} }
else else

View file

@ -1624,7 +1624,7 @@ co_MsqReplyMessage( LRESULT lResult )
pti = PsGetCurrentThreadWin32Thread(); pti = PsGetCurrentThreadWin32Thread();
Message = pti->pusmCurrent; Message = pti->pusmCurrent;
if(!Message) return FALSE; if (!Message) return FALSE;
if (Message->QS_Flags & QS_SMRESULT) return FALSE; if (Message->QS_Flags & QS_SMRESULT) return FALSE;