reactos操作系统实现(169)

前端之家收集整理的这篇文章主要介绍了reactos操作系统实现(169)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

当用USER32.DLL调用获取消息之后,就调用WIN32K.SYS里处理的函数NtUserGetMessage,这个函数实现的代码如下:

#001 BOOL APIENTRY

#002 NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,

#003 HWND hWnd,

#004 UINT MsgFilterMin,

#005 UINT MsgFilterMax)

#006 /*

#007 * FUNCTION: Get a message from the calling thread's message queue.

#008 * ARGUMENTS:

#009 * UnsafeMsg - Pointer to the structure which receives the returned message.

#010 * Wnd - Window whose messages are to be retrieved.

#011 * MsgFilterMin - Integer value of the lowest message value to be

#012 * retrieved.

#013 * MsgFilterMax - Integer value of the highest message value to be

#014 * retrieved.

#015 */

#016 {

#017 BOOL GotMessage;

#018 NTUSERGETMESSAGEINFO Info;

#019 NTSTATUS Status;

#020 /* FIXME: if initialization is removed,gcc complains that this may be used before initialization. Please review */

#021 PWINDOW_OBJECT Window = NULL;

#022 PMSGMEMORY MsgMemoryEntry;

#023 PVOID UserMem;

#024 UINT Size;

#025 USER_MESSAGE Msg;

#026 DECLARE_RETURN(BOOL);

#027 // USER_REFERENCE_ENTRY Ref;

#028

#029 DPRINT("Enter NtUserGetMessage/n");

进入临界区代码

#030 UserEnterExclusive();

#031

#032 /* Validate input */

获取窗口对象,并检查窗口句柄是否有效。

#033 if (hWnd && !(Window = UserGetWindowObject(hWnd)))

#034 {

#035 RETURN(-1);

#036 }

#037

#038 // if (Window) UserRefObjectCo(Window,&Ref);

#039

如果设置消息最大值比最小值还小,就使用缺省的方式。

#040 if (MsgFilterMax < MsgFilterMin)

#041 {

#042 MsgFilterMin = 0;

#043 MsgFilterMax = 0;

#044 }

#045

循环地获取消息,直到成功为止。

#046 do

#047 {

这里调用函数co_IntPeekMessage来查看消息队列是否有消息。

#048 GotMessage = co_IntPeekMessage(&Msg,hWnd,MsgFilterMin,MsgFilterMax,PM_REMOVE);

#049 if (GotMessage)

#050 {

如果获取消息成功。

#051 Info.Msg = Msg.Msg;

#052 /* See if this message type is present in the table */

查找消息是否在消息表里,如果不在里面不需要分配消息保存的内存,否则就需要给消息分配内存。

#053 MsgMemoryEntry = FindMsgMemory(Info.Msg.message);

#054 if (NULL == MsgMemoryEntry)

#055 {

#056 /* Not present,no copying needed */

#057 Info.LParamSize = 0;

#058 }

#059 else

#060 {

检测消息所需要内存的大小。

#061 /* Determine required size */

#062 Size = MsgMemorySize(MsgMemoryEntry,Info.Msg.wParam,

#063 Info.Msg.lParam);

#064 /* Allocate required amount of user-mode memory */

#065 Info.LParamSize = Size;

#066 UserMem = NULL;

用户分配消息占用的内存。

#067 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),&UserMem,

#068 &Info.LParamSize,MEM_COMMIT,PAGE_READWRITE);

#069

#070 if (! NT_SUCCESS(Status))

#071 {

#072 SetLastNtError(Status);

#073 RETURN( (BOOL) -1);

#074 }

#075 /* Transfer lParam data to user-mode mem */

把消息拷贝到用户空间的内存。

#076 Status = MmCopyToCaller(UserMem,(PVOID) Info.Msg.lParam,Size);

#077 if (! NT_SUCCESS(Status))

#078 {

#079 ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID *) &UserMem,

#080 &Info.LParamSize,MEM_DECOMMIT);

#081 SetLastNtError(Status);

#082 RETURN( (BOOL) -1);

#083 }

#084 Info.Msg.lParam = (LPARAM) UserMem;

#085 }

#086 if (Msg.FreeLParam && 0 != Msg.Msg.lParam)

#087 {

#088 ExFreePool((void *) Msg.Msg.lParam);

#089 }

#090 Status = MmCopyToCaller(UnsafeInfo,&Info,sizeof(NTUSERGETMESSAGEINFO));

#091 if (! NT_SUCCESS(Status))

#092 {

#093 SetLastNtError(Status);

#094 RETURN( (BOOL) -1);

#095 }

#096 }

在这里调用co_IntWaitMessage函数继续等到窗口出现消息。

#097 else if (! co_IntWaitMessage(hWnd,MsgFilterMax))

#098 {

#099 RETURN( (BOOL) -1);

#100 }

#101 }

#102 while (! GotMessage);

#103

如果消息不等于退出消息,就返回TRUE,否则返回FALSE,也就是0值。

#104 RETURN( WM_QUIT != Info.Msg.message);

#105

#106 CLEANUP:

#107 // if (Window) UserDerefObjectCo(Window);

#108

#109 DPRINT("Leave NtUserGetMessage/n");

#110 UserLeave();

#111 END_CLEANUP;

#112}

原文链接:https://www.f2er.com/react/308352.html

猜你在找的React相关文章