第 6 章 进程间通信 — 6.8 本地过程调用(LPC)与 6.9 视窗报文(Message)
本章深入剖析 Windows/ReactOS 中两种核心进程间通信机制:LPC(本地过程调用)和视窗报文系统。
概述
进程间通信(IPC)是现代操作系统的核心功能,Windows 提供了多种 IPC 机制来满足不同场景的需求。本章重点介绍两种特殊的IPC机制:
LPC 和视窗报文的本质区别是什么?
LPC 是内核级的高性能请求-响应机制,专为系统组件间的高效通信设计;视窗报文系统则是用户态GUI应用的事件驱动核心,实现窗口间的消息传递。两者服务于不同层次,但共同构成了Windows的通信基础设施。
想象一个企业办公场景:
- LPC:部门之间的内部电话系统,快速、可靠的请求-响应交互;
- 视窗报文:办公室的公告板和内部邮件系统,异步消息传递和事件通知;
- CSRSS与应用程序通信:员工通过内部电话向IT部门(CSRSS)请求服务;
- 窗口消息循环:员工查看公告板(消息队列)处理日常事务。
本章内容概览
- 6.8.0 LPC框架图:LPC机制完整架构;
- 6.8.1 LPC概述:定义、特点和应用场景;
- 6.8.2 LPC端口对象:端口类型和结构定义;
- 6.8.3 LPC通信流程:创建、连接、消息传递;
- 6.8.4 LPC安全机制:身份验证和模拟;
- 6.9.0 视窗报文框架图:消息系统架构;
- 6.9.1 消息机制概述:消息驱动架构;
- 6.9.2 消息发送方式:同步与异步;
- 6.9.3 消息队列与分发:队列结构和处理流程;
- 6.9.4 消息钩子与广播:监控和通知机制;
- 设计哲学问答:关键设计问题深入解答。
学习目标
读完本章后,读者应当能够:
- 理解LPC机制的内核实现原理;
- 掌握LPC端口类型和通信流程;
- 分析视窗报文系统的消息驱动模型;
- 理解SendMessage和PostMessage的区别;
- 掌握消息钩子和广播机制;
- 区分两种IPC机制的适用场景。
涉及的内核子系统
| 子系统 | 职责 |
|---|---|
| ntoskrnl/lpc | LPC核心实现(端口管理、消息传递) |
| win32ss/user/ntuser | 用户态消息处理(消息队列、钩子) |
| csrss | Win32子系统进程(LPC服务端) |
| ntdll | LPC用户态API(NtConnectPort等) |
6.8.0 LPC框架图
┌──────────────────────────────────────────────────────────────────────────────────────┐ │ LPC 机制完整架构 │ ├──────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 用户态 API 层 │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ ntdll.dll │ │ │ │ ├─► NtCreatePort 创建连接端口 │ │ │ │ ├─► NtCreateWaitablePort 创建可等待端口 │ │ │ │ ├─► NtConnectPort 连接到端口 │ │ │ │ ├─► NtSecureConnectPort 安全连接(SID验证) │ │ │ │ ├─► NtRequestPort 发送数据报消息 │ │ │ │ ├─► NtRequestWaitReplyPort 发送请求并等待回复 │ │ │ │ ├─► NtListenPort 监听连接请求 │ │ │ │ ├─► NtAcceptConnectPort 接受连接 │ │ │ │ ├─► NtReplyPort 发送回复消息 │ │ │ │ └─► NtReplyWaitReceivePort 回复并等待下一条消息 │ │ │ └────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ 内核态实现层 │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ ntoskrnl/lpc/ │ │ │ │ ├─► create.c: NtCreatePort, NtCreateWaitablePort │ │ │ │ ├─► connect.c: NtConnectPort, NtSecureConnectPort │ │ │ │ ├─► send.c: NtRequestPort, NtRequestWaitReplyPort │ │ │ │ ├─► receive.c: NtListenPort, NtAcceptConnectPort │ │ │ │ ├─► reply.c: NtReplyPort, NtReplyWaitReceivePort │ │ │ │ └─► close.c: LpcExitThread, LpcpDeletePort │ │ │ │ │ │ │ │ 核心数据结构 │ │ │ │ ├─► LPCP_PORT_OBJECT: 端口对象 │ │ │ │ ├─► LPCP_MESSAGE: 消息结构 │ │ │ │ ├─► PORT_MESSAGE: 消息头部 │ │ │ │ └─► PORT_VIEW: Section视图信息 │ │ │ └────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ CSRSS 端口服务层 │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ csrss.exe │ │ │ │ ├─► \Windows\ApiPort Win32 API请求处理 │ │ │ │ ├─► \Windows\SbApiPort 会话管理器接口 │ │ │ │ ├─► \Windows\SmApiPort 子系统管理接口 │ │ │ │ └─► \Console\LpcPort 控制台I/O接口 │ │ │ └────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ LPC 通信模型 │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ 客户端进程 内核层 服务端进程 │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ClientPort │─────────────►│ │◄─────────────│ConnPort │ │ │ │ │ │(客户端端口)│ NtConnectPort│ │NtListenPort │(连接端口)│ │ │ │ │ └────┬─────┘ │ │ └────┬─────┘ │ │ │ │ │ │ LPC子系统│ │ │ │ │ │ │ NtRequestWaitReplyPort │ NtAcceptConnectPort │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ ▼ │ │ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ │ │ │CommPort │◄─────────────│ │─────────────►│CommPort │ │ │ │ │ │(通信端口)│ NtReplyPort │ │NtRequestPort │(通信端口)│ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ │ │ │ └────────────────────────────────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────────────────────────────────┘6.8.1 LPC概述
6.8.1.1 LPC定义与核心特点
LPC(Local Procedure Call,本地过程调用)是Windows内核提供的高性能进程间通信机制:
核心特点:
| 特点 | 说明 |
|---|---|
| 内核级实现 | 直接在内核中传递消息,无需文件系统介入 |
| 请求-响应模型 | 同步通信,客户端阻塞等待服务器响应 |
| 消息大小限制 | 256字节(32位)/ 512字节(64位) |
| Section共享 | 支持大数据传输的内存映射机制 |
| 安全机制完善 | 支持SID验证和客户端身份模拟 |
| 仅限本地 | 不支持跨机器通信 |
6.8.1.2 LPC与其他IPC机制对比
| 特性 | LPC | 命名管道 | 共享内存 |
|---|---|---|---|
| 性能 | 最高 | 中等 | 最高 |
| 消息大小 | 有限 | 无限制 | 无限制 |
| 同步性 | 同步请求-响应 | 流模式 | 需额外同步 |
| 安全支持 | 完整 | 部分 | 需额外处理 |
| 通信范围 | 本地 | 本地/远程 | 本地 |
| 典型应用 | CSRSS通信 | 服务通信 | 大数据共享 |
6.8.1.3 LPC在Windows子系统中的应用
LPC是Win32子系统通信的核心:
CSRSS LPC端口架构 ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ 应用程序 ──► NtConnectPort ──► \Windows\ApiPort ──► CSRSS │ │ │ │ │ │ │ CreateWindow请求 │ 创建窗口 │ │ │◄───────────── 窗口句柄 ────────────│ │ │ │ │ 应用程序 ──► NtConnectPort ──► \Console\LpcPort ──► CSRSS │ │ │ │ │ │ │ 控制台输入输出请求 │ 处理I/O │ │ │◄───────────── 结果 ──────────────│ │ │ │ └─────────────────────────────────────────────────────────────────────┘6.8.2 LPC端口对象
6.8.2.1 端口类型
LPC支持四种端口类型:
| 端口类型 | 创建方式 | 用途 |
|---|---|---|
| 连接端口 | NtCreatePort | 服务端监听端口,接受连接请求 |
| 客户端端口 | NtConnectPort | 客户端连接端口,发起连接 |
| 通信端口 | 自动创建 | 连接建立后用于实际通信 |
| 可等待端口 | NtCreateWaitablePort | 可作为同步事件使用 |
6.8.2.2 LPCP_PORT_OBJECT结构
typedefstruct_LPCP_PORT_OBJECT{struct_LPCP_PORT_OBJECT*ConnectionPort;// 连接端口引用struct_LPCP_PORT_OBJECT*ConnectedPort;// 已连接端口LPCP_PORT_QUEUE MsgQueue;// 消息队列CLIENT_ID Creator;// 创建者标识PVOID ClientSectionBase;// 客户端Section基址PVOID ServerSectionBase;// 服务器Section基址PVOID PortContext;// 端口上下文SECURITY_QUALITY_OF_SERVICE SecurityQos;// 安全服务质量ULONG MaxMessageLength;// 最大消息长度ULONG Flags;// 端口标志KEVENT WaitEvent;// 等待事件}LPCP_PORT_OBJECT,*PLPCP_PORT_OBJECT;源码位置:[sdk/include/ndk/lpctypes.h#L209](file:///d:/reactos/sdk/include/ndk/lpctypes.h#L209)
6.8.2.3 PORT_MESSAGE消息头部
typedefstruct_PORT_MESSAGE{USHORT DataLength;// 消息数据长度USHORT TotalLength;// 总长度(含头部)union{CLIENT_ID ClientId;// 客户端标识ULONG_PTR ClientUniqueId;// 客户端唯一标识};ULONG MessageId;// 消息IDULONG MessageType;// 消息类型}PORT_MESSAGE,*PPORT_MESSAGE;消息类型枚举:
LPC_REQUEST:客户端请求LPC_REPLY:服务器回复LPC_DATAGRAM:数据报LPC_CONNECTION_REQUEST:连接请求
6.8.3 LPC通信流程
6.8.3.1 端口创建与连接
服务端创建连接端口:
NTSTATUS NTAPINtCreatePort(OUT PHANDLE PortHandle,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PSECURITY_DESCRIPTOR SecurityDescriptor,IN ULONG MaxMessageLength,IN ULONG MaxConnectionInfoLength){// 验证参数if(MaxMessageLength>LPC_MAX_MESSAGE_LENGTH)returnSTATUS_INVALID_PARAMETER;// 创建端口对象Status=ObCreateObject(ExGetPreviousMode(),LpcPortObjectType,ObjectAttributes,PreviousMode,NULL,sizeof(LPCP_PORT_OBJECT),0,0,(PVOID*)&Port);// 初始化端口队列InitializeListHead(&Port->MsgQueue.ListHead);// 设置端口标志为连接端口Port->Flags=LPCP_CONNECTION_PORT;returnSTATUS_SUCCESS;}源码位置:[ntoskrnl/lpc/create.c#L222](file:///d:/reactos/ntoskrnl/lpc/create.c#L222)
客户端连接到端口:
NTSTATUS NTAPINtConnectPort(OUT PHANDLE PortHandle,IN PUNICODE_STRING PortName,IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,IN OUT PLPC_SECTION_WRITE_DATA SectionData,OUT PLPC_SECTION_READ_DATA*ReadData,OUT PULONG ConnectionInfoLength,IN PVOID ConnectionInfo,IN ULONG ConnectionInfoLength){// 解析端口名称// 查找连接端口对象// 创建客户端端口// 发送连接请求// 等待服务器接受// 返回Section信息(如果有)}源码位置:[ntoskrnl/lpc/connect.c#L777](file:///d:/reactos/ntoskrnl/lpc/connect.c#L777)
6.8.3.2 消息发送与接收
客户端发送请求(请求-响应模式):
NTSTATUS NTAPINtRequestWaitReplyPort(IN HANDLE PortHandle,IN PPORT_MESSAGE RequestMessage,OUT PPORT_MESSAGE ReplyMessage){// 验证消息长度// 将消息放入目标端口队列// 阻塞等待回复// 返回回复消息}源码位置:[ntoskrnl/lpc/send.c#L470](file:///d:/reactos/ntoskrnl/lpc/send.c#L470)
服务端接收并回复:
NTSTATUS NTAPINtReplyWaitReceivePort(IN HANDLE PortHandle,OUT PULONG MessageType,OUT PPORT_MESSAGE ReplyMessage,OUT PPORT_MESSAGE RequestMessage){// 发送回复消息// 等待下一条请求// 返回请求消息}源码位置:[ntoskrnl/lpc/reply.c#L743](file:///d:/reactos/ntoskrnl/lpc/reply.c#L743)
6.8.3.3 Section共享机制
PORT_VIEW结构:
typedefstruct_PORT_VIEW{PVOID SectionBase;// Section基址ULONG SectionSize;// Section大小ULONG ViewSize;// 视图大小ULONG ViewOffset;// 视图偏移}PORT_VIEW,*PPORT_VIEW;Section共享流程:
- 服务端创建Section对象;
- 连接时传递PORT_VIEW信息;
- 客户端映射Section到自己的地址空间;
- 双方通过共享内存传输大数据。
6.8.4 LPC安全机制
6.8.4.1 安全上下文传递
LPC支持两种安全跟踪模式:
| 模式 | 说明 |
|---|---|
| 静态安全跟踪 | 连接时建立安全上下文,后续通信复用 |
| 动态安全跟踪 | 每次消息发送时重新验证 |
6.8.4.2 客户端身份模拟
NTSTATUS NTAPINtImpersonateClientOfPort(IN HANDLE PortHandle){// 获取端口的安全上下文// 将当前线程的令牌替换为客户端令牌// 后续操作以客户端身份执行}应用场景:服务器需要以客户端身份访问资源时使用。
6.9.0 视窗报文框架图
┌──────────────────────────────────────────────────────────────────────────────────────┐ │ 视窗报文系统完整架构 │ ├──────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 用户态 API 层 │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ user32.dll │ │ │ │ ├─► SendMessage 同步发送消息 │ │ │ │ ├─► PostMessage 异步投递消息 │ │ │ │ ├─► SendNotifyMessage 同步发送不等待回复 │ │ │ │ ├─► SendMessageTimeout 同步发送带超时 │ │ │ │ ├─► GetMessage 获取消息(阻塞) │ │ │ │ ├─► PeekMessage 查看消息(非阻塞) │ │ │ │ ├─► DispatchMessage 分发消息到窗口过程 │ │ │ │ ├─► SetWindowsHookEx 设置消息钩子 │ │ │ │ └─► BroadcastSystemMessage 广播消息 │ │ │ └────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ 内核态实现层 │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ win32ss/user/ntuser/ │ │ │ │ ├─► message.c: NtUserSendMessage, NtUserPostMessage │ │ │ │ ├─► msgqueue.c: 消息队列管理 │ │ │ │ ├─► hook.c: 消息钩子实现 │ │ │ │ └─► winproc.c: 窗口过程调用 │ │ │ │ │ │ │ │ 核心数据结构 │ │ │ │ ├─► THREADINFO: 线程信息(含消息队列) │ │ │ │ ├─► MSG: 消息结构 │ │ │ │ └─► HOOK: 钩子结构 │ │ │ └────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ 消息队列层 │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ SentMessagesListHead 发送消息队列(同步) │ │ │ │ PostedMessagesListHead 投递消息队列(异步) │ │ │ │ HardwareMessagesListHead 硬件输入队列 │ │ │ │ NotifyMessagesListHead 通知消息队列 │ │ │ └────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ 消息处理流程 │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ 发送方线程 内核层 接收方线程 │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │SendMessage│─────────────►│ │─────────────►│窗口过程 │ │ │ │ │ │(同步阻塞) │ │ 消息子系统│ │(直接调用) │ │ │ │ │ │◄─────────│ │ │ │ │ │ │ │ │ │ 等待回复 │ │ │ │◄─────────│ │ │ │ │ └──────────┘ └──────────┘ │ 返回结果 │ │ │ │ │ └──────────┘ │ │ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │PostMessage│─────────────►│ 消息队列 │◄─────────────│GetMessage│ │ │ │ │ │(异步返回) │ │ │ │(阻塞等待) │ │ │ │ │ └──────────┘ │ │ └────┬─────┘ │ │ │ │ │ │ │ │ │ │ │ └──────────┘ ▼ │ │ │ │ ┌──────────┐ │ │ │ │ │DispatchMsg│ │ │ │ │ │(分发消息) │ │ │ │ │ └──────────┘ │ │ │ └────────────────────────────────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────────────────────────────────┘6.9.1 消息机制概述
6.9.1.1 消息驱动架构
Windows采用事件驱动模型,所有用户交互通过消息传递:
消息驱动架构 ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ 用户操作 ──► 系统生成消息 ──► 消息队列 ──► 消息循环 ──► 窗口过程 │ │ │ │ │ │ │ ▼ │ │ │ 处理消息并响应 │ │ │◄───────────────────────────────────│ │ │ │ └─────────────────────────────────────────────────────────────────────┘6.9.1.2 消息类型分类
| 类型 | 示例 | 说明 |
|---|---|---|
| 窗口消息 | WM_CREATE, WM_DESTROY, WM_PAINT | 窗口生命周期和绘制 |
| 输入消息 | WM_KEYDOWN, WM_MOUSEMOVE | 用户输入 |
| 系统消息 | WM_TIMER, WM_QUIT | 系统通知 |
| 用户消息 | WM_USER+1, WM_APP+100 | 应用自定义消息 |
6.9.1.3 MSG结构
typedefstructtagMSG{HWND hwnd;// 消息目标窗口UINT message;// 消息标识符WPARAM wParam;// 消息参数1LPARAM lParam;// 消息参数2DWORD time;// 消息时间戳POINT pt;// 消息发生时的鼠标位置}MSG,*PMSG;6.9.2 消息发送方式
6.9.2.1 SendMessage(同步发送)
LRESULT WINAPISendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam){// 验证参数// 检查是否跨线程/进程// 直接调用目标窗口过程或排队等待// 返回处理结果}源码位置:[win32ss/user/ntuser/message.c#L1707](file:///d:/reactos/win32ss/user/ntuser/message.c#L1707)(co_IntSendMessageTimeout)
特点:同步阻塞,等待目标窗口过程返回。
6.9.2.2 PostMessage(异步投递)
BOOL WINAPIPostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam){// 验证参数// 将消息放入目标线程队列// 立即返回}源码位置:[win32ss/user/ntuser/message.c#L2275](file:///d:/reactos/win32ss/user/ntuser/message.c#L2275)(NtUserPostMessage)
特点:异步非阻塞,消息放入队列后立即返回。
6.9.2.3 发送方式对比
| 特性 | SendMessage | PostMessage |
|---|---|---|
| 同步性 | 同步阻塞 | 异步非阻塞 |
| 返回值 | 窗口过程返回值 | 投递是否成功 |
| 消息队列 | 不使用队列 | 使用投递队列 |
| 跨进程 | 支持(需特殊处理) | 支持(需特殊处理) |
| 优先级 | 高(立即处理) | 低(排队处理) |
6.9.3 消息队列与分发
6.9.3.1 线程消息队列结构
typedefstruct_THREADINFO{// 消息队列LIST_ENTRY SentMessagesListHead;// 发送消息队列LIST_ENTRY PostedMessagesListHead;// 投递消息队列LIST_ENTRY HardwareMessagesListHead;// 硬件输入队列// 等待标志ULONG fsWakeBits;// 当前等待标志ULONG fsWakeBitsMask;// 等待掩码// 消息事件KEVENT MessageEvent;// 消息到达事件// 消息钩子PHOOK aphkStart[WH_MAXHOOK];// 钩子数组}THREADINFO,*PTHREADINFO;6.9.3.2 GetMessage处理流程
源码位置:[win32ss/user/ntuser/message.c#L2343](file:///d:/reactos/win32ss/user/ntuser/message.c#L2343)(NtUserGetMessage)
GetMessage处理顺序 1. 检查QS_SENDMESSAGE → 处理发送消息队列 2. 检查QS_POSTMESSAGE → 处理投递消息队列 3. 检查QS_INPUT → 处理硬件输入队列 4. 检查QS_PAINT → 生成WM_PAINT消息 5. 检查QS_TIMER → 生成WM_TIMER消息 6. 无消息 → 等待MessageEvent6.9.3.3 标准消息循环
MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);// 转换键盘消息DispatchMessage(&msg);// 分发到窗口过程}源码位置:[win32ss/user/ntuser/message.c#L890](file:///d:/reactos/win32ss/user/ntuser/message.c#L890)(IntDispatchMessage)
6.9.4 消息钩子与广播
6.9.4.1 消息钩子类型
| 钩子类型 | 触发时机 | 用途 |
|---|---|---|
| WH_CALLWNDPROC | 窗口过程调用前 | 监控SendMessage |
| WH_CALLWNDPROCRET | 窗口过程返回后 | 监控消息返回值 |
| WH_GETMESSAGE | GetMessage返回后 | 监控投递消息 |
| WH_KEYBOARD | 键盘消息到达时 | 键盘钩子 |
| WH_MOUSE | 鼠标消息到达时 | 鼠标钩子 |
6.9.4.2 钩子处理流程
源码位置:[win32ss/user/ntuser/hook.c#L1102](file:///d:/reactos/win32ss/user/ntuser/hook.c#L1102)(co_HOOK_CallHooks)
消息钩子链 消息产生 ──► Hook1 ──► Hook2 ──► ... ──► 窗口过程 │ │ CallNextHookEx CallNextHookEx6.9.4.3 广播消息
BroadcastSystemMessage:向指定类型接收者发送消息;
HWND_BROADCAST:向所有顶层窗口发送消息(内核实现:[win32ss/user/ntuser/message.c#L2654](file:///d:/reactos/win32ss/user/ntuser/message.c#L2654));
// 发送系统设置变更通知SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,(LPARAM)L"Environment");设计哲学问答
Q1:LPC为什么限制消息大小为256/512字节?
A:LPC设计目标是高性能的请求-响应通信,小消息可以:
- 使用Lookaside列表快速分配;
- 避免复杂的内存管理;
- 保证快速的消息传递。
大数据传输通过Section共享机制实现。
Q2:为什么SendMessage需要同步阻塞?
A:SendMessage用于需要立即获取结果的场景,如获取窗口文本、查询状态等。同步阻塞保证调用者能立即获得返回值。
Q3:LPC如何保证安全性?
A:LPC通过以下机制保证安全:
- SID验证(NtSecureConnectPort);
- 安全上下文传递;
- 客户端身份模拟;
- 静态/动态安全跟踪。
Q4:消息队列为什么分为发送队列和投递队列?
A:发送队列用于同步消息(SendMessage),需要立即处理;投递队列用于异步消息(PostMessage),按顺序处理。分离设计提高了消息处理效率。
Q5:LPC和视窗报文的适用场景有何不同?
A:LPC适用于系统级组件间的高性能请求-响应通信;视窗报文适用于GUI应用的事件驱动交互。LPC是内核级机制,视窗报文是用户态机制。
源码索引
LPC核心源码
| 文件路径 | 行号 | 说明 |
|---|---|---|
sdk/include/ndk/lpctypes.h | 121 | PORT_MESSAGE结构定义 |
sdk/include/ndk/lpctypes.h | 209 | LPCP_PORT_OBJECT结构定义 |
sdk/include/ndk/lpctypes.h | 281 | PORT_VIEW结构定义 |
ntoskrnl/include/internal/lpc.h | 100 | LPC内部函数声明 |
ntoskrnl/include/internal/lpc_x.h | 99 | LpcpAllocateFromPortZone等内联函数 |
ntoskrnl/lpc/create.c | 222 | NtCreatePort实现 |
ntoskrnl/lpc/connect.c | 80 | NtSecureConnectPort实现 |
ntoskrnl/lpc/connect.c | 777 | NtConnectPort实现 |
ntoskrnl/lpc/send.c | 440 | NtRequestPort实现 |
ntoskrnl/lpc/send.c | 470 | NtRequestWaitReplyPort实现 |
ntoskrnl/lpc/reply.c | 190 | NtReplyPort实现 |
ntoskrnl/lpc/reply.c | 360 | NtReplyWaitReceivePortEx实现 |
ntoskrnl/lpc/reply.c | 743 | NtReplyWaitReceivePort实现 |
ntoskrnl/lpc/listen.c | 22 | NtListenPort实现 |
ntoskrnl/lpc/complete.c | 40 | NtAcceptConnectPort实现 |
ntoskrnl/lpc/close.c | 25 | LpcExitThread、LpcpDeletePort |
视窗报文核心源码
| 文件路径 | 行号 | 说明 |
|---|---|---|
win32ss/user/ntuser/message.c | 890 | IntDispatchMessage分发消息 |
win32ss/user/ntuser/message.c | 1285 | 消息指针处理逻辑 |
win32ss/user/ntuser/message.c | 1376 | UserPostMessage投递消息 |
win32ss/user/ntuser/message.c | 1510 | SendMessageTimeoutSingle |
win32ss/user/ntuser/message.c | 1707 | co_IntSendMessageTimeout |
win32ss/user/ntuser/message.c | 2275 | NtUserPostMessage内核调用 |
win32ss/user/ntuser/message.c | 2343 | NtUserGetMessage获取消息 |
win32ss/user/ntuser/message.c | 2464 | NtUserDispatchMessage |
win32ss/user/ntuser/msgqueue.c | 731 | MsqCreateMessage创建消息 |
win32ss/user/ntuser/msgqueue.c | 1355 | 消息入队处理 |
win32ss/user/ntuser/msgqueue.c | 2396 | MsqCreateMessageQueue |
win32ss/user/ntuser/hook.c | 1102 | co_HOOK_CallHooks调用钩子 |
win32ss/user/ntuser/hook.c | 1429 | NtUserSetWindowsHookEx设置钩子 |
总结
LPC核心要点
- 内核级IPC:高性能本地通信,直接在内核中传递消息;
- 请求-响应模型:同步通信,客户端阻塞等待服务器响应;
- 端口对象:四种端口类型,支持连接、通信和同步;
- Section共享:支持大数据传输,避免消息复制开销;
- 安全机制:支持SID验证和客户端身份模拟;
- 典型应用:CSRSS与应用程序通信。
视窗报文核心要点
- 消息驱动:Windows GUI的核心事件处理机制;
- 同步与异步:SendMessage同步,PostMessage异步;
- 消息队列:发送队列、投递队列、输入队列分离;
- 钩子机制:允许监控和拦截消息;
- 广播消息:支持系统级通知。
两种IPC机制对比
| 特性 | LPC | 视窗报文 |
|---|---|---|
| 层次 | 内核态 | 用户态/内核态 |
| 通信模式 | 请求-响应 | 同步/异步消息传递 |
| 数据大小 | 有限(256/512字节) | 消息参数限制 |
| 大数据支持 | Section共享 | WM_COPYDATA |
| 典型应用 | CSRSS通信 | GUI消息循环 |
| 性能 | 极高 | 中高 |
文档完成
本章详细介绍了Windows/ReactOS中的两种核心IPC机制:LPC和视窗报文系统。LPC作为内核级IPC机制,为系统组件提供高性能通信;视窗报文系统则是GUI应用的核心,实现了窗口间的消息传递。理解这两种机制对于深入理解Windows操作系统的工作原理至关重要。