IRP 处理流程

2023-10-28 02:38
文章标签 流程 处理 irp

本文主要是介绍IRP 处理流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文通过打开一个文件对象为例子,描述了一个带有两个I/O stack location的IRP的详细处理过程。当然一个IRP可以有多个I/O stack location,具体个数取决于将要处理该请求的驱动的层数。下图详细描述了驱动程序是如何通过使用I/O支持例程(IoXxx routines)来处理IRP以此来实现对相应文件的读写操作。




1:I/O管理器调用文件系统驱动(FSD)并把包含了子系统读/写请求的IRP传递给该驱动。 FSD访问IRP中的I/O stack location, 从而决定应该执行什么操作。


2:通过单此或者多次调用例程(IoAllocateIrp)来分配附加的IRP,FSD就可以把原始的请求分成几个小的请求(对于设备驱动不只一个的情况)。这些附加的IRP中的I/O stack location区域将会被下一级的驱动填充成零返回给FSD,正因为如此,FSD可以重复使用原始的IRP, 而不是向前面所讲的那样执行分配额外的IRP,并在这些IRP中创建针对下一层驱动的I/O stack location 并传送给下一层驱动。


3:对每一个驱动分配的IRP,如前面所述,FSD将调用I/O支持例程来注册一个由FSD提供的完成例程;在完成例程中,FSD可以判定下级驱动是否满足该请求,并且当下级驱动成功完成该IRP时释放该IRP。I/O管理器将调用FSD提供的完成例程来判断分配给驱动的IRP是成功完成了,还是完成了但有错误,或者是被取消了。上层驱动负责释放该驱动自己为下层驱动分配并设置的IRP。I/O管理器负责示释放它本身分配的并且被驱动完成的IRP。接下来,为了建立传递给下层驱动执行的请求,FSD将调用I/O支持例程(IoGetNextIrpStackLocation)来访问下层驱动的I/O stack location。(本例中,下一层驱动就是最后一层驱动)最后,FSD调用例程(IoCallDriver)将IRP传递给下一层驱动。


4:当IRP传递到下层驱动时,该驱动检查它对应的I/O stack location以此来判断自己在目标设备上该执行何种操作(由IRP_MJ_XXX之类的功能代码决定)。在指定的I/O stack location中已经把相应的目标设备通过设备对象抽象表征出来并出传递给本层驱动程序了。最底层的驱动可以做如下假设:I/O管理器把IRP转发给驱动的入口点,该入口点里面,驱动已经定义好了各种IRP_MJ_XXX操作(本例中是IRP_MJ_READ或者IRP_MJ_WRITE),而且上层的驱动已经对该请求的参数的有效性进行了检查。
如果没有上层驱动,那么底层驱动就要为针对IRP_MJ_XXX操作的参数的有效性进行检查,如果有效, 驱动程序通常调用I/O 支持例程来通知I/O管理器该层设备是将IRP挂起了,还是将IRP移入队列里等待,还是直接将IRP转发给由其他驱动提供的访问目标设备的驱动应用例程(此例中是一个物理或者逻辑设备: 磁盘或者分区)。

5: I/O管理器先判断驱动程序是否在忙于处理其他IRP,如果忙,则将IRP移入队列,并返回。否则,I/O管理器将把IRP转发给驱动提供的例程,该例程将在它所在的设备层发起I/O操作。

6:当设备中断发生时,驱动的中断服务例程(ISR)必须屏蔽相应中断并保存相关的上下文环境。然后,ISR将调用I/O支持例程(IoRequestDpc)将该IRP传递给由本层驱动提供的延时处理调用(DPC)例程中,以此使得该操作请求在比ISR低一级的硬件优先级下完成。

7:当驱动程序的DPC执行时,它使用上下文(由ISR中调用IoRequestDpc时传递下来)来完成I/O操作。 DPC调用相关的例程将下一个IRP(如果有的话)移出队列并将该IRP转发给由驱动提供的例程,这个例程开始在这个设备执行I/O操作。然后,DPC设置IRP中的I/O状态并调用例程IoCompleteRequest将它返回给I/O管理器。

8:I/O管理器把最底层的驱动程序的I/O stack location置零,然后调用文件系统已经注册好的完成例程(见步骤3)并把分配给FSD的IRP传递给文件系统驱动。该完成例程根据I/O状态(I/O status block)的结果来决定是重发该请求,还是更新原始请求保存的的内部状态信息,或者是释放分配给驱动的IRP。文件系统收集完所有分配给驱动的IRP中的状态信息,由此可以设置I/O的状态信息并结束原始IRP,当文件系统完成原始的IRP时,I/O管理器返回一个NTSTATUS的值给发起该I/O操作的原始请求者(子系统的原生函数)。


和上图描述的文件系统驱动一样,任何一个添加进驱动链表的新的驱动程序都可以实现下列功能:

●     在IRP中设置自己的完成例程。IoCompletion例程检查I/O status block来判断该IRP是被下一层的驱动成功完成了,还是被取消了, 或者是完成了但有错误. 完成例程还可以更新任何由驱动程序保存的IRP相关的状态, 也可以释放由驱动分配的任何操作相关的资源。另外,结束IRP之前,完成例程还可以延迟IRP的完成(通过告诉I/O管理器该IRP需要处理更多东西),并且可以在允许该IRP完成之前,向下一层驱动程序发送另外的请求。

●     在分配的IRP中可以创建下一层驱动对应的I/O stack location,并将请求发送给下一层驱动。

●     任何收到的IRP都可以通过在每一个IRP中添加针对下一层驱动的I/O stack location并调用IoCallDriver例程实现转发(值得注意的是: 针对主要功能代码为IRP_MJ_POWER,的IRP,驱动必须调用PoCallDriver例程才能转发)。

 

从上图我们可以知道,大部分驱动处理IRP是通过驱动提供的一组标准例程,但是处在驱动链中不同层的驱动必须有不同标准的例程。比如说,只有最底层的驱动可以处理来自物理设备的中断,所以只有最底层的驱动可以有ISR和DPC,ISR和DPC负责完成那些由中断驱动的I/O操作。从另一方面来说,因为最底层的驱动在收到来自设备的中断时就知道这些I/O操作已经完成,所以只有高层的驱动才有一个或者多个类似上文中提到的FSD的完成例程。


注:该文章英文原文出自msdn。



这篇关于IRP 处理流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/290128

相关文章

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

电脑提示xlstat4.dll丢失怎么修复? xlstat4.dll文件丢失处理办法

《电脑提示xlstat4.dll丢失怎么修复?xlstat4.dll文件丢失处理办法》长时间使用电脑,大家多少都会遇到类似dll文件丢失的情况,不过,解决这一问题其实并不复杂,下面我们就来看看xls... 在Windows操作系统中,xlstat4.dll是一个重要的动态链接库文件,通常用于支持各种应用程序

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1