使用ReadDirectoryChangesExW确定Windows文件变更关联用户及会话0异常问题
文件系统变更关联用户及会话0异常问题解答
一、会话0输出异常的原因
会话0是Windows系统预留的服务会话,所有系统服务默认运行在这个会话中,它并非用户交互式会话,因此会出现以下情况:
- 针对交互式会话设计的WTS查询参数(如
WTSInitialProgram、WTSApplicationName)对会话0无效,调用WTSQuerySessionInformationW时自然返回错误87(参数不正确)。 - 该会话没有关联的登录用户账户,所以
WTSUserName、WTSDomainName等用户相关字段为空。 WTSConnectState返回乱码是因为直接读取了枚举值的原始字节,未做转译处理,实际会话0的状态就是WTS_STATE::Disconnected(非交互式断开状态)。GetShellProcessName返回explorer.exe只是读取了系统默认的壳程序配置,但会话0不会启动桌面壳程序,这个结果没有实际意义。
二、将FILE_NOTIFY_EXTENDED_INFORMATION变更关联到Windows用户的方案
1. 通过文件ID追踪进程与用户
- 利用
FILE_NOTIFY_EXTENDED_INFORMATION中的FileId,调用OpenFileById打开目标文件获取句柄(需确保进程有足够权限)。 - 通过
GetProcessIdFromHandle获取最后操作该文件的进程ID。 - 用
OpenProcess打开进程,再调用GetTokenInformation获取进程的用户令牌,解析令牌中的TokenUser信息得到用户名和域。 - 注意:若文件已被关闭,
OpenFileById可能失败,需结合其他方式补充处理。
2. 基于ETW事件关联进程与用户
- 订阅Windows内核的ETW事件:
Microsoft-Windows-Kernel-File(捕获文件操作事件)和Microsoft-Windows-Kernel-Process(捕获进程用户信息)。 - 文件操作事件中包含进程ID,进程事件中包含该进程对应的用户身份信息,通过进程ID关联两者,即可定位文件变更的操作用户。
- 这种方式可靠性更高,能覆盖文件被关闭后的场景,但需要实现ETW事件的订阅、解析和关联逻辑。
3. 多会话场景下的进程-用户映射
- 用
WTSEnumerateSessions枚举所有系统会话,对每个会话调用WTSQueryUserToken获取会话的用户令牌。 - 枚举系统中所有进程(
EnumProcesses),通过ProcessIdToSessionId判断进程所属会话,建立进程ID到用户的映射表。 - 收到文件变更事件后,找到对应的进程ID,再通过映射表关联到所属用户。此方案可兼容RDP多会话场景,同时需注意会话0中的系统服务进程属于SYSTEM用户。
内容的提问来源于stack exchange,提问作者Dean Knight
相关产品推荐
相关产品推荐

