当前位置: 首页 > news >正文

CSRSS 系统分析

CSRSS 系统分析

概述

CSRSS(Client Server Runtime Subsystem,客户端/服务器运行时子系统)是 ReactOS 中实现Win32 子系统服务器端的关键进程。它通过 LPC(本地过程调用)接收用户态应用程序的 Win32 API 调用(进程/线程管理、控制台、硬错误等),并提供相应的服务。


1. CSRSS 启动过程

1.1 SMSS 启动 CSRSS

文件:[smsubsys.c#L243](file:///d:/reactos/base/system/smss/smsubsys.c#L243)

SMSS → SmpLoadSubSystem("Windows" = csrss.exe) ├─ 1. SmpExecuteImage(csrss.exe) ← 创建进程 (挂起) ├─ 2. 等待 CSRSS 通过 \SmApiPort 连接 │ └─ SmpHandleConnectionRequest() │ ├─ NtAcceptConnectPort() │ ├─ NtCompleteConnectPort() │ └─ NtConnectPort(SbApiPort) └─ 3. NtResumeThread(CSRSS_Thread) ← 恢复运行

由于 CSRSS 是本机映像(IMAGE_SUBSYSTEM_NATIVE),它可以在 Win32 子系统本身可用之前启动,直接在原生模式下运行。

1.2 CSRSS 入口点 _main

文件:[csrss.c#L37](file:///d:/reactos/subsystems/csr/csrss/csrss.c#L37)

_main(VOID){// 1. 设置基础优先级NtSetInformationProcess(NtCurrentProcess(),ProcessBasePriority,&Priority,sizeof(Priority));// 2. (x86) 授予 IOPL 权限以访问 VGA 寄存器CsrpSetProcessIOPL();// ★ 3. 核心初始化 (CSRSRV)CsrServerInitialization();// 4. 禁用硬错误弹窗CsrpSetDefaultProcessHardErrorMode();// 5. 在会话 0 中标记为关键进程if(SessionId==0)RtlSetProcessIsCritical(TRUE);// 6. 主线程退出 —— CSRSS 通过 API 请求线程保持存活NtTerminateThread(NtCurrentThread(),STATUS_SUCCESS);}

_main在第 78 行调用CsrServerInitialization(),主线程在第 93 行退出。CSRSS 的生命周期由CsrApiRequestThread(LPC 监听线程)维持


2. CsrServerInitialization — 核心初始化

文件:[csrsrv/init.c#L1009](file:///d:/reactos/subsystems/csr/csrsrv/init.c#L1009)

这是 CSRSS 最核心的初始化函数,顺序执行 11 个步骤:

CsrServerInitialization() │ ├─ 1. 缓存系统基本信息 (SystemBasicInformation) │ ├─ 2. CsrHeap = RtlGetProcessHeap() │ ├─ 3. CsrSetProcessSecurity() ← 保护 CSRSS 进程 │ ├─ 4. CsrInitializeNtSessionList() ← 初始化 NT 会话列表 │ ├─ 5. CsrInitializeProcessStructure() ← 初始化根进程 │ ├─ 分配 CSR 根进程 (CsrRootProcess) │ ├─ 初始化进程锁 │ ├─ 初始化线程哈希表 (0x200 条目) │ └─ 初始化等待锁 │ ├─ 6. CsrParseServerCommandLine() ← ★ 解析注册表命令行 │ 从注册表读取: │ ├─ ObjectDirectory = \Windows │ ├─ SubSystemType = 0 (Windows) │ ├─ MaxRequestThreads = 期望线程数 │ ├─ SharedSection = 共享节大小 │ └─ ServerDll 条目 = 要加载的服务器 DLL │ ├─ basesrv:BaseServerDllInitialization,1 │ ├─ winsrv:UserServerDllInitialization,3 │ └─ winsrv:ConsoleServerDllInitialization,2 │ ├─ 7. CsrInitCsrRootProcess() ← 初始化每个 DLL 的进程数据 │ 对每个 ServerDll: │ ├─ LoadLibrary(ServerDll) │ ├─ 调用初始化入口点 → 注册 DispatchTable │ ├─ 分配每进程数据 │ └─ 调用 NewProcess 回调 │ ├─ ★ 8. CsrApiPortInitialize() ← ★ 创建 LPC API 端口 │ ├─ ★ 9. CsrSbApiPortInitialize() ← ★ 创建 SB 端口 (SMSS 回连) │ ├─ 10. SmConnectToSm() ← ★ 连接到 SMSS │ └─ 11. NtSetDefaultHardErrorPort(CsrApiPort) ← CSRSS 处理硬错误

3. CSR API 调度机制

3.1 双 LPC 端口架构

┌──────────────────┐ ┌──────────────────┐ │ CSRSS │ │ 客户端 │ │ │ │ (app.exe) │ │ \Windows\ApiPort│◄──LPC────┤ kernel32.dll │ │ (CsrApiPort) │ │ CsrClientCall..│ │ │ └──────────────────┘ │ \Windows\SbApiPo│◄──LPC────┤ SMSS │ │ (CsrSbApiPort) │ └──────────────────┘ └──────────────────┘
端口用途客户端
\Windows\ApiPort接收 Win32 API 调用所有 Win32 进程(通过 kernel32/ntdll)
\Windows\SbApiPort接收 SMSS 的 SB APISMSS

3.2 API 消息格式

文件:[csrmsg.h#L100](file:///d:/reactos/sdk/include/reactos/subsys/csr/csrmsg.h#L100)

typedefstruct_CSR_API_MESSAGE{PORT_MESSAGE Header;union{CSR_API_CONNECTINFO ConnectionInfo;struct{PCSR_CAPTURE_BUFFER CsrCaptureData;CSR_API_NUMBER ApiNumber;// ★ API 编号NTSTATUS Status;ULONG Reserved;union{CSR_CLIENT_CONNECT CsrClientConnect;ULONG_PTR ApiMessageData[39];// 数据填充}Data;};};}CSR_API_MESSAGE;

3.3 API 编号编码

文件:[csrmsg.h#L35](file:///d:/reactos/sdk/include/reactos/subsys/csr/csrmsg.h#L35)

// API 编号 = (ServerId << 16) | ApiId#defineCSR_CREATE_API_NUMBER(ServerId,ApiId)\(((ServerId)<<16)|(ApiId))#defineCSR_API_NUMBER_TO_SERVER_ID(ApiNumber)((ApiNumber)>>16)#defineCSR_API_NUMBER_TO_API_ID(ApiNumber)((ApiNumber)&0xFFFF)

编号空间分配

API 编号 (32 位): ┌─────────────────┬──────────────────────┐ │ ServerId (16) │ ApiId (16) │ ├─────────────────┼──────────────────────┤ │ 0 = CSRSRV │ ApiBase..ApiMax │ │ 1 = basesrv │ 0..31 │ │ 2 = consrv │ 512..(~110) │ │ 3 = usersrv │ 1024..(~10) │ └─────────────────┴──────────────────────┘
ServerIdDLLApiBaseAPI 数消息头文件
0CSRSRV (内置)05csrmsg.h
1basesrv032basemsg.h
2consrv512~110conmsg.h
3usersrv102410winmsg.h

3.4 CsrApiRequestThread — 核心 LPC 循环

文件:[csrsrv/api.c#L334](file:///d:/reactos/subsystems/csr/csrsrv/api.c#L334)

NTSTATUSCsrApiRequestThread(PVOID PortHandle){// 1. 连接到 User32 (循环直到成功)while(!CsrConnectedToUser)CsrConnectToUser();// 2. 主 LPC 循环while(TRUE){Status=NtReplyWaitReceivePort(PortHandle,&ClientContext,&ReplyMsg->h,&RequestMsg.h);switch(RequestMsg.h.u2.s2.Type){caseLPC_CONNECTION_REQUEST:CsrApiHandleConnectionRequest(...);break;caseLPC_CLIENT_DIED:caseLPC_PORT_CLOSED:// 清理 CSR 线程和进程CsrDestroyClientContext(...);break;caseLPC_EXCEPTION:// 终止进程break;caseLPC_ERROR_EVENT:// 硬错误处理: 轮询每个 ServerDll 的 HardErrorCallbackbreak;caseLPC_REQUEST:// ★ API 调用:ServerId=CSR_API_NUMBER_TO_SERVER_ID(RequestMsg.ApiNumber);ApiId=CSR_API_NUMBER_TO_API_ID(RequestMsg.ApiNumber)-ApiBase;ServerDll=CsrLoadedServerDll[ServerId];Status=ServerDll->DispatchTable[ApiId](&RequestMsg,&ReplyCode);// 通过客户端端口回复break;caseLPC_DATAGRAM:// 非 CSR 线程的 API 调用 (直接处理, 不回复)CsrApiHandleDatagram(...);break;}}}

4. 三台服务器 DLL

4.1 Base 服务器(basesrv)— ServerId 1

文件:[basesrv/init.c](file:///d:/reactos/subsystems/win/basesrv/init.c)

处理底层进程/线程管理和相关 Win32 操作:

API 编号功能函数
0CreateProcessBasepCreateProcess
1CreateThreadBasepCreateThread
2GetTempFileBasepGetTempFile
3ExitProcessBasepExitProcess
4DefineDosDeviceBasepDefineDosDevice
5GetComputerNameBasepGetComputerName
6SetComputerNameBasepSetComputerName
7SetUserProcessInfoBasepSetUserProcessInfo
8SxsCreateActivationContextBasepSxsCreateActivationContext

关键功能

  • 进程创建BasepCreateProcess通过 LPC 接收创建请求,验证参数,调用NtCreateUserProcess创建进程。这是kernel32!CreateProcess的服务器端实现。
  • DOS 设备映射BasepDefineDosDevice管理\??\下的符号链接(如\??\COM1)。
  • NLS 管理BasepNlsSetUserInfo设置用户 locale 信息。

4.2 控制台服务器(consrv)— ServerId 2

文件:[consrv/init.c](file:///d:/reactos/win32ss/user/winsrv/consrv/init.c)

处理控制台窗口相关操作,约 110 个 API:

API 编号功能函数
512AllocConsoleSrvAllocConsole
513FreeConsoleSrvFreeConsole
514CreateConsoleScreenBufferSrvCreateConsoleScreenBuffer
515GetConsoleModeSrvGetConsoleMode
516SetConsoleModeSrvSetConsoleMode
517ReadConsoleInputSrvReadConsoleInput
518WriteConsoleInputSrvWriteConsoleInput
519ReadConsoleOutputSrvReadConsoleOutput
520WriteConsoleOutputSrvWriteConsoleOutput
524FillConsoleOutputSrvFillConsoleOutput

4.3 用户服务器(usersrv)— ServerId 3

文件:[usersrv/init.c](file:///d:/reactos/win32ss/user/winsrv/usersrv/init.c)

处理桌面、会话和系统级操作:

API 编号功能函数
1024ExitWindowsExSrvExitWindowsEx
1025EndTaskSrvEndTask
1026LogonSrvLogon
1027RegisterServicesProcessSrvRegisterServicesProcess
1028ActivateDebuggerSrvActivateDebugger
1029GetThreadConsoleDesktopSrvGetThreadConsoleDesktop
1030DeviceEventSrvDeviceEvent
1031RegisterLogonProcessSrvRegisterLogonProcess
1032CreateSystemThreadsSrvCreateSystemThreads
1033RecordShutdownReasonSrvRecordShutdownReason

关键 API

  • SrvLogon— WINLOGON 登录完成后调用,通知 CSRSS 用户已登录
  • SrvCreateSystemThreads— 创建 RIT(原始输入线程)和桌面线程
  • SrvExitWindowsEx— 处理关机/重启/注销请求

UserClientConnect— 客户端连接回调:

// usersrv/init.c#L186NTSTATUSUserClientConnect(PCSR_PROCESS Process,PCSR_THREAD Thread){// 保存 CSR API 端口句柄CsrApiPort=...;// 通知内核模式 win32k: NtUserProcessConnectNtUserInitialize(CsrApiPort,...);returnSTATUS_SUCCESS;}

5. SB API 端口 — 与 SMSS 通信

5.1 CsrSbApiPort 创建

文件:[csrsrv/session.c](file:///d:/reactos/subsystems/csr/csrsrv/session.c)

CsrSbApiPortInitialize() └─ NtCreatePort(\Windows\SbApiPort) └─ RtlCreateUserThread(CsrSbApiRequestThread)

5.2 CsrSbApiRequestThread

接收来自 SMSS 的 SB API 调用:

PSB_API_HANDLER CsrSbDispatch[]={CsrSbCreateSession,// 创建新会话CsrSbTerminateSession,// 终止会话 (未实现)CsrSbForeignSessionComplete,// 外部会话完成 (未实现)CsrSbCreateProcess,// 创建进程 (未实现)};

5.3 CsrSbCreateSession — 创建新会话

文件:[csrsrv/session.c#L208](file:///d:/reactos/subsystems/csr/csrsrv/session.c#L208)

CsrSbCreateSession(SbCreateSessionMsg, ReplyMsg) │ ├─ SmpAllocateSessionId() → SmpNextSessionId++ ├─ 分配 CSR 进程 (CsrCreateProcess) ├─ 分配 CSR 线程 (CsrCreateThread) ├─ 设置异常端口 ├─ NtSetInformationProcess(ProcessHandle, SessionId) └─ 返回新会话 ID

6. 创建系统线程(RIT / 桌面线程)

文件:[usersrv/init.c#L113](file:///d:/reactos/win32ss/user/winsrv/usersrv/init.c#L113)

SrvCreateSystemThreads() ← CSR API 调用 └─ CsrExecServerThread(CreateSystemThreads, 0) └─ RtlCreateUserThread(NtCurrentProcess(), ...) └─ CreateSystemThreads() ← 新线程入口 └─ NtUserCallOneParam(0, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS) └─ [win32k.sys] ├─ 创建 RIT (Raw Input Thread) ├─ 创建桌面线程 └─ 创建鬼影窗口线程

CsrExecServerThread创建线程的调用链:

CsrExecServerThread(Routine, Parameter) [thredsup.c#L884] ├─ CsrCreateThread(RootProcess, &CsrThread) ← 分配 CSR 线程 ├─ RtlCreateUserThread(RootProcess, ... │ Routine, Parameter) ← 创建 NT 线程 ├─ 存入 CSR 线程信息 (句柄, ClientId) ├─ InsertTailList(线程列表) └─ 返回

7. 客户端调用路径

7.1 客户端 CsrClientCallServer

文件:[csrlib/connect.c#L364](file:///d:/reactos/subsystems/csr/csrlib/connect.c#L364)

app.exe → kernel32!CreateProcess() └─ ntdll!CsrClientCallServer() ├─ 填充 CSR_API_MESSAGE │ ├─ ApiNumber = CSR_CREATE_API_NUMBER(1, BasepCreateProcess) │ ├─ CsrCaptureData = CsrAllocateCaptureBuffer() │ ├─ CsrCaptureMessageBuffer(命令行参数等) │ └─ 计算 DataLength / TotalLength │ ├─ 转换捕获缓冲区的地址空间 │ (客户端地址 → 服务器地址 via PortMemoryDelta) │ ├─ NtRequestWaitReplyPort(CsrApiPort, &Message->h) │ → 阻塞等待 CSRSS 处理 │ ├─ 转换捕获缓冲区的地址空间回客户端视图 │ └─ 返回 CSRSS 的处理结果

7.2 进程间地址转换

共享内存段(SharedSection)在客户端和 CSRSS 之间共享。捕获缓冲区(CSR_CAPTURE_BUFFER)通过PortMemoryDelta(客户端地址 - 服务器地址)在两者间转换指针。

客户端地址空间: CSRSS 地址空间: ┌──────────────┐ ┌──────────────┐ │ SharedSection│ │ SharedSection│ ← 物理上相同的内存 │ (映射视图1) │ │ (映射视图2) │ └──────────────┘ └──────────────┘ PortMemoryDelta = View1_Base - View2_Base 服务器转换: ServerPtr = ClientPtr - PortMemoryDelta 客户端转换: ClientPtr = ServerPtr + PortMemoryDelta

8. 硬错误处理

文件:[usersrv/harderror.c#L1082](file:///d:/reactos/win32ss/user/winsrv/usersrv/harderror.c#L1082)

当内核调用NtRaiseHardError时,错误通过CsrApiPort发送到 CSRSS:

内核: NtRaiseHardError() └─ LPC 消息 → CSRSS CsrApiRequestThread └─ LPC_ERROR_EVENT 类型 └─ 轮询每个 ServerDll->HardErrorCallback └─ UserServerHardError() ├─ 从消息中捕获字符串参数 ├─ 格式化错误消息 (查找 ntdll 消息表) ├─ 弹窗显示 (MessageBox) └─ 返回用户响应 (重试/忽略/终止)

9. 完整架构图

用户模式 ┌──────────────────────────────────────────────────────────────────┐ │ │ │ ┌─────────┐ ┌─────────┐ ┌───────────┐ ┌──────────────┐ │ │ │ App.exe │ │ App.exe │ │ WINLOGON │ │ SMSS │ │ │ │ │ │ │ │ │ │ │ │ │ │ Create.. │ │ Alloc.. │ │ Logon │ │ \SmApiPort │ │ │ └────┬─────┘ └────┬─────┘ └─────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ │ │ kernel32.dll │ │ │ │ │ └── CsrClientCallServer │ │ │ │ │ │ │ │ │ │ LPC ──┼─────────────┼──────────────┼────────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ CSRSS │ │ │ │ │ │ │ │ CsrApiRequestThread() │ │ │ │ ├─ LPC_CONNECTION_REQUEST → CsrApiHandleConnectionReq │ │ │ │ ├─ LPC_REQUEST → 分发表 │ │ │ │ │ ├─ basesrv::DispatchTable[1] │ │ │ │ │ │ └─ ServerId=1, ApiId=BasepCreateProcess │ │ │ │ │ │ → BasepCreateProcess() │ │ │ │ │ │ → NtCreateUserProcess() │ │ │ │ │ │ │ │ │ │ │ ├─ consrv::DispatchTable[0] │ │ │ │ │ │ └─ ServerId=2, ApiId=ConsolepAllocConsole │ │ │ │ │ │ → SrvAllocConsole() │ │ │ │ │ │ │ │ │ │ │ └─ usersrv::DispatchTable[2] │ │ │ │ │ └─ ServerId=3, ApiId=UserpLogon │ │ │ │ │ → SrvLogon() │ │ │ │ │ │ │ │ │ ├─ LPC_ERROR_EVENT → UserServerHardError() │ │ │ │ │ → 弹窗 │ │ │ │ │ │ │ │ │ └─ LPC_CLIENT_DIED → CsrDestroyClientContext() │ │ │ │ │ │ │ │ CsrSbApiRequestThread() │ │ │ │ └─ CsrSbCreateSession() │ │ │ │ │ │ │ │ 服务器 DLL: │ │ │ │ ├─ CSRSRV (内置) │ │ │ │ ├─ basesrv.dll — 进程/线程/设备 │ │ │ │ ├─ consrv.dll — 控制台管理 │ │ │ │ └─ winsrv.dll — 桌面/系统(含usersrv+consrv) │ │ │ └───────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘

10. 关键设计要点

概念说明
原生模式启动CSRSS 是IMAGE_SUBSYSTEM_NATIVE,在 Win32 可用前启动
双 LPC 端口\Windows\ApiPort(客户端)+\Windows\SbApiPort(SMSS)
三级 API 编号(ServerId << 16) | ApiId,分发到 4 个服务器 DLL
捕获缓冲区通过CSR_CAPTURE_BUFFER+PortMemoryDelta跨进程编组指针
CSR 进程/线程对象CSRSRV 维护独立的CSR_PROCESS/CSR_THREAD结构管理客户端
硬错误处理CSRSS 通过NtSetDefaultHardErrorPort注册为系统硬错误处理器
系统线程创建CsrExecServerThread→ RtlCreateUserThread → win32k 创建 RIT/桌面
关键进程保护会话 0 的 CSRSS 标记为RtlSetProcessIsCritical(TRUE)
共享内存SharedSection在 CSRSS 和所有 Win32 进程间共享,用于快速数据交换
http://www.jsqmd.com/news/1216307/

相关文章:

  • 2026年上海杨浦区寻宠高手:如何找回走失的爱宠?
  • Agent 记忆系统的存储优化:向量检索与全文搜索的混合索引策略
  • Agent之Skill:dashi-ppt-skill的简介、安装和使用方法、案例应用之详细攻略
  • LangGraph 多用户并发:Thread 会话隔离 + Redis 持久化,彻底解决 Agent 上下文串话泄露
  • 2026年7月最新常州万国官方售后维修服务网点地址与客服电话 - 万国中国官方服务中心
  • 重庆本地四针盖土网批发采购选品实用指南 - 热点品牌推荐
  • 2026 年 7 月更新公告:江诗丹顿国内官方售后地址 热线,认准正规官方维修服务中心 - 江诗丹顿官方维修中心
  • 360 AI 研究院半年 6 篇顶会论文:真正值得看的,是“精准可控”如何落到产品里
  • 2026年7月最新西安积家官方售后客户服务热线与维修网点地址汇总 - 积家官方售后服务中心
  • 2026年企业抖音号运营公司选型:B端工业获客与服务商避坑指南
  • 出口订单怎么管理
  • 一篇读懂队列(Queue)————手撕队列,图文并茂+代码逐行精讲
  • 【JVM调优实战】13-经典收集器下-G1
  • ReactOS.exe 安装程序分析
  • 全栈 TypeScript 的编译性能优化:从 tsc 到 esbuild 的迁移与收益分析
  • 2026年通州靠谱的汽车改养护服务机构挑选实用指南 - 热点品牌推荐
  • EasyMarkets:经纪商平台综合实力的理性评估
  • 2026 年 7 月实时更新清单:百达翡丽官方维修服务中心,国内官方售后地址 热线核对表 - 百达翡丽官方服务中心
  • 天梭中国官方售后服务中心|服务热线及网点地址权威信息声明(2026年7月更新) - 天梭服务中心
  • 爱彼中国官方售后服务中心|官方电话和维修地址权威信息公告(2026年7月最新) - 爱彼中国官方服务中心
  • 7月18日更新,ChatGPT Plus、ChatGPT Pro 与 Codex:未来的软件开发(GPT5.6)
  • 2026年上海老弄堂里的秘密:一场寻宠之旅等你加入
  • Linux内核cgroup v2 CPU带宽控制机制:cpu.max、cpu.weight与CFS配额调度的精确调优
  • 翡翠资产配置的“隐形杀手”:我是如何帮客户拆解40%非必要成本的
  • WarcraftHelper:5分钟解决魔兽争霸III现代兼容性难题的终极方案
  • GPT-5.6提示词怎么写更有效?记住这4个要素
  • 广告归因数据对齐实战:从IP溯源看点击欺诈与AppsFlyer P360的匹配度优化
  • 宝珀官方售后服务中心电话和完整维修地址实地考察报告多信源验证(2026年7月最新) - 宝珀官方售后服务中心
  • 格拉苏蒂官方服务项目及价格查询|服务热线及全部网点地址权威信息通知(2026年7月最新) - 亨得利钟表维修中心
  • 积家中国官方售后服务中心|服务电话及全部网点地址权威信息通告(2026年7月最新) - 积家官方售后服务中心