📄 message.c
字号:
/*
* ReactOS W32 Subsystem
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: message.c 27952 2007-07-28 17:16:51Z weiden $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Messages
* FILE: subsys/win32k/ntuser/message.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created
*/
/* INCLUDES ******************************************************************/
#include <w32k.h>
#define NDEBUG
#include <debug.h>
typedef struct
{
UINT uFlags;
UINT uTimeout;
ULONG_PTR Result;
}
DOSENDMESSAGE, *PDOSENDMESSAGE;
/* FUNCTIONS *****************************************************************/
NTSTATUS FASTCALL
IntInitMessageImpl(VOID)
{
return STATUS_SUCCESS;
}
NTSTATUS FASTCALL
IntCleanupMessageImpl(VOID)
{
return STATUS_SUCCESS;
}
#define MMS_SIZE_WPARAM -1
#define MMS_SIZE_WPARAMWCHAR -2
#define MMS_SIZE_LPARAMSZ -3
#define MMS_SIZE_SPECIAL -4
#define MMS_FLAG_READ 0x01
#define MMS_FLAG_WRITE 0x02
#define MMS_FLAG_READWRITE (MMS_FLAG_READ | MMS_FLAG_WRITE)
typedef struct tagMSGMEMORY
{
UINT Message;
UINT Size;
INT Flags;
}
MSGMEMORY, *PMSGMEMORY;
static MSGMEMORY MsgMemory[] =
{
{ WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
{ WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ },
{ WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ },
{ WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
{ WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
{ WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
{ WM_NCCREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
{ WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
{ WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
{ WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
{ WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
};
static PMSGMEMORY FASTCALL
FindMsgMemory(UINT Msg)
{
PMSGMEMORY MsgMemoryEntry;
/* See if this message type is present in the table */
for (MsgMemoryEntry = MsgMemory;
MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
MsgMemoryEntry++)
{
if (Msg == MsgMemoryEntry->Message)
{
return MsgMemoryEntry;
}
}
return NULL;
}
static UINT FASTCALL
MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
{
CREATESTRUCTW *Cs;
PUNICODE_STRING WindowName;
PUNICODE_STRING ClassName;
UINT Size = 0;
_SEH_TRY
{
if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
{
Size = (UINT)wParam;
}
else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
{
Size = (UINT) (wParam * sizeof(WCHAR));
}
else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
{
Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
}
else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
{
switch(MsgMemoryEntry->Message)
{
case WM_CREATE:
case WM_NCCREATE:
Cs = (CREATESTRUCTW *) lParam;
WindowName = (PUNICODE_STRING) Cs->lpszName;
ClassName = (PUNICODE_STRING) Cs->lpszClass;
Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
if (IS_ATOM(ClassName->Buffer))
{
Size += sizeof(WCHAR) + sizeof(ATOM);
}
else
{
Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
}
break;
case WM_NCCALCSIZE:
Size = wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
break;
case WM_COPYDATA:
Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
break;
default:
assert(FALSE);
Size = 0;
break;
}
}
else
{
Size = MsgMemoryEntry->Size;
}
}
_SEH_HANDLE
{
DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH_GetExceptionCode());
Size = 0;
}
_SEH_END;
return Size;
}
static NTSTATUS
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
{
NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
NCCALCSIZE_PARAMS *PackedNcCalcsize;
CREATESTRUCTW *UnpackedCs;
CREATESTRUCTW *PackedCs;
PUNICODE_STRING WindowName;
PUNICODE_STRING ClassName;
UINT Size;
PCHAR CsData;
*lParamPacked = lParam;
if (WM_NCCALCSIZE == Msg && wParam)
{
UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
if (UnpackedNcCalcsize->lppos != (PWINDOWPOS) (UnpackedNcCalcsize + 1))
{
PackedNcCalcsize = ExAllocatePoolWithTag(PagedPool,
sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
TAG_MSG);
if (NULL == PackedNcCalcsize)
{
DPRINT1("Not enough memory to pack lParam\n");
return STATUS_NO_MEMORY;
}
RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
*lParamPacked = (LPARAM) PackedNcCalcsize;
}
}
else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
{
UnpackedCs = (CREATESTRUCTW *) lParam;
WindowName = (PUNICODE_STRING) UnpackedCs->lpszName;
ClassName = (PUNICODE_STRING) UnpackedCs->lpszClass;
Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
if (IS_ATOM(ClassName->Buffer))
{
Size += sizeof(WCHAR) + sizeof(ATOM);
}
else
{
Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
}
PackedCs = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
if (NULL == PackedCs)
{
DPRINT1("Not enough memory to pack lParam\n");
return STATUS_NO_MEMORY;
}
RtlCopyMemory(PackedCs, UnpackedCs, sizeof(CREATESTRUCTW));
CsData = (PCHAR) (PackedCs + 1);
PackedCs->lpszName = (LPCWSTR) (CsData - (PCHAR) PackedCs);
RtlCopyMemory(CsData, WindowName->Buffer, WindowName->Length);
CsData += WindowName->Length;
*((WCHAR *) CsData) = L'\0';
CsData += sizeof(WCHAR);
PackedCs->lpszClass = (LPCWSTR) (CsData - (PCHAR) PackedCs);
if (IS_ATOM(ClassName->Buffer))
{
*((WCHAR *) CsData) = L'A';
CsData += sizeof(WCHAR);
*((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
CsData += sizeof(ATOM);
}
else
{
*((WCHAR *) CsData) = L'S';
CsData += sizeof(WCHAR);
RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
CsData += ClassName->Length;
*((WCHAR *) CsData) = L'\0';
CsData += sizeof(WCHAR);
}
ASSERT(CsData == (PCHAR) PackedCs + Size);
*lParamPacked = (LPARAM) PackedCs;
}
return STATUS_SUCCESS;
}
static NTSTATUS
UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
{
NCCALCSIZE_PARAMS *UnpackedParams;
NCCALCSIZE_PARAMS *PackedParams;
PWINDOWPOS UnpackedWindowPos;
if (lParamPacked == lParam)
{
return STATUS_SUCCESS;
}
if (WM_NCCALCSIZE == Msg && wParam)
{
PackedParams = (NCCALCSIZE_PARAMS *) lParamPacked;
UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
UnpackedWindowPos = UnpackedParams->lppos;
RtlCopyMemory(UnpackedParams, PackedParams, sizeof(NCCALCSIZE_PARAMS));
UnpackedParams->lppos = UnpackedWindowPos;
RtlCopyMemory(UnpackedWindowPos, PackedParams + 1, sizeof(WINDOWPOS));
ExFreePool((PVOID) lParamPacked);
return STATUS_SUCCESS;
}
else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
{
ExFreePool((PVOID) lParamPacked);
return STATUS_SUCCESS;
}
ASSERT(FALSE);
return STATUS_INVALID_PARAMETER;
}
BOOL
STDCALL
NtUserCallMsgFilter(
LPMSG msg,
INT code)
{
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserCallMsgFilter\n");
UserEnterExclusive();
if (co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg))
RETURN( TRUE);
RETURN( co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg));
CLEANUP:
DPRINT("Leave NtUserCallMsgFilter. ret=%i\n", _ret_);
UserLeave();
END_CLEANUP;
}
LRESULT STDCALL
NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
{
NTSTATUS Status;
NTUSERDISPATCHMESSAGEINFO MsgInfo;
LRESULT Result = TRUE;
DECLARE_RETURN(LRESULT);
DPRINT("Enter NtUserDispatchMessage\n");
UserEnterExclusive();
Status = MmCopyFromCaller(&MsgInfo, UnsafeMsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( 0);
}
/* Process timer messages. */
if (WM_TIMER == MsgInfo.Msg.message && 0 != MsgInfo.Msg.lParam)
{
LARGE_INTEGER LargeTickCount;
/* FIXME: Call hooks. */
/* FIXME: Check for continuing validity of timer. */
MsgInfo.HandledByKernel = FALSE;
KeQueryTickCount(&LargeTickCount);
MsgInfo.Proc = (WNDPROC) MsgInfo.Msg.lParam;
MsgInfo.Msg.lParam = (LPARAM)LargeTickCount.u.LowPart;
}
else if (NULL == MsgInfo.Msg.hwnd)
{
MsgInfo.HandledByKernel = TRUE;
Result = 0;
}
else
{
PWINDOW_OBJECT Window;
/* Get the window object. */
Window = UserGetWindowObject(MsgInfo.Msg.hwnd);
if (NULL == Window)
{
MsgInfo.HandledByKernel = TRUE;
Result = 0;
}
else
{
if (Window->OwnerThread != PsGetCurrentThread())
{
DPRINT1("Window doesn't belong to the calling thread!\n");
MsgInfo.HandledByKernel = TRUE;
Result = 0;
}
else
{
/* FIXME: Call hook procedures. */
MsgInfo.HandledByKernel = FALSE;
Result = 0;
if (Window->IsSystem)
{
MsgInfo.Proc = (!MsgInfo.Ansi ? Window->WndProc : Window->WndProcExtra);
}
else
{
MsgInfo.Ansi = !Window->Unicode;
MsgInfo.Proc = Window->WndProc;
}
}
}
}
Status = MmCopyToCaller(UnsafeMsgInfo, &MsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( 0);
}
RETURN( Result);
CLEANUP:
DPRINT("Leave NtUserDispatchMessage. ret=%i\n", _ret_);
UserLeave();
END_CLEANUP;
}
BOOL STDCALL
NtUserTranslateMessage(LPMSG lpMsg,
HKL dwhkl)
{
NTSTATUS Status;
MSG SafeMsg;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserTranslateMessage\n");
UserEnterExclusive();
Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( FALSE);
}
RETURN( IntTranslateKbdMessage(&SafeMsg, dwhkl));
CLEANUP:
DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
VOID FASTCALL
co_IntSendHitTestMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
{
if(!Msg->hwnd || ThreadQueue->CaptureWindow)
{
return;
}
switch(Msg->message)
{
case WM_MOUSEMOVE:
{
co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
break;
}
case WM_NCMOUSEMOVE:
{
co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
break;
}
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_XBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_XBUTTONDBLCLK:
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -