内核函数IoGetTopLevelIrp的说明

看一眼这玩意的官方说明:

IoGetTopLevelIrp 例程返回当前线程的 TopLevelIrp 字段的值。

IoGetTopLevelIrp 可以返回 NULL、任意特定于文件系统的值 (如指向当前 IRP) 的指针,或下表中列出的标志之一。

如果当前线程在文件系统上方没有资源, IoGetTopLevelIrp 将返回 NULL

如果文件系统是当前线程的顶级组件, IoGetTopLevelIrp 将返回指向当前 IRP 的指针。

如果文件系统以外的组件是当前线程的顶级组件, IoGetTopLevelIrp 将返回以下标志之一:

展开表

标志含义
FSRTL_FSP_TOP_LEVEL_IRP这是递归调用。
FSRTL_CACHE_TOP_LEVEL_IRP缓存管理器是当前线程的顶级组件。
FSRTL_MOD_WRITE_TOP_LEVEL_IRP修改后的页面编写器是当前线程的顶级组件。
FSRTL_FAST_IO_TOP_LEVEL_IRP缓存管理器是当前线程的顶级组件,当前线程位于快速 I/O 路径中。

 官方的解释对于初次使用这个API 的同学来说非常不好理解,简单理解就是:

如果IoGetTopLevelIrp 返回null,那么这个IRP就是用户模式触发的文件操作,这里的用户模式不是指Ring3应用层的概念,既可以是Ring3层的操作,也可以是用户写的Ring0内核驱动进行ZwCreateFile等的文件操作,反正不是系统内部自己的行为。

有什么用呢?注意,这个API 在MiniFilter文件过滤器开发中用的比较多,目的就是判定一个IRP操作是不是用户发起的,或者用来判断这个IRP是不是MiniFilter发起的循环重入,用法如下:

FLT_PREOP_CALLBACK_STATUS PreOperationCallback(PFLT_CALLBACK_DATA Data)
 {
    // 若为分页I/O或非用户模式产生的IRP,直接跳过处理
    if ((Data->Iopb->IrpFlags & IRP_PAGING_IO) || IoGetTopLevelIrp()) 
    {
        return FLT_PREOP_SUCCESS_NO_CALLBACK; 
    }

    // 处理用户模式触发的IRP,继续其他逻辑操作


    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值