⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 message.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 *  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 + -