Minifilter中文件清空保存触发什么回调?为何PreWrite回调未触发
清空文件操作不触发IRP_MJ_WRITE的原因
- 你遇到的是Windows文件系统的标准行为:将文件大小置0的截断操作,本质是通过
IRP_MJ_SET_INFORMATION请求完成,而非IRP_MJ_WRITE请求,因此不会触发你注册的PreWrite回调。 - 绝大多数编辑器的「全选清空+保存」逻辑,会先调用
SetEndOfFileWin32 API将文件尾偏移设置为0,直接丢弃所有原有内容,该操作没有实际的数据写入动作,不会走写入请求路径。 - 部分编辑器会采用「创建临时文件写入新内容→删除原文件→重命名临时文件为原文件名」的逻辑实现保存,该场景下的原文件清空效果是通过
FileDispositionInformation类的IRP_MJ_SET_INFORMATION请求实现,同样不会触发IRP_MJ_WRITE。
拦截清空文件操作的实现方案
你需要注册IRP_MJ_SET_INFORMATION的Pre回调,在回调中完成判断和拦截:
- 首先校验请求的信息类是否为
FileEndOfFileInformation - 取出请求附带的
FILE_END_OF_FILE_INFORMATION结构体,读取EndOfFile.QuadPart值,若该值为0即表示目标是将文件截断为0字节,匹配你要拦截的场景 - 确认是需要拦截的操作后,直接在Pre回调中返回
STATUS_ACCESS_DENIED即可终止操作,可根据需求增加进程、文件路径的白名单逻辑 - 建议同步覆盖
FileAllocationInformation信息类的校验,部分应用会通过修改文件分配大小为0的方式实现文件清空,避免漏拦截。
新手常见概念遗漏
- 很多Minifilter开发新手只会优先关注读写请求,忽略了
IRP_MJ_SET_INFORMATION是覆盖绝大多数文件元操作的核心请求:修改文件大小、重命名、修改权限、标记删除、修改创建/修改时间等操作全部走该请求路径,这部分是文件系统过滤驱动的核心覆盖场景。 - 调试阶段可以在Pre回调中打印所有接收到的IRP主功能号和副功能号,直观匹配不同用户操作对应的内核请求类型,能快速定位需要拦截的回调点。
内容的提问来源于stack exchange,提问作者kran
相关产品推荐
相关产品推荐

