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

相关文章

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

使用Python处理CSV和Excel文件的操作方法

《使用Python处理CSV和Excel文件的操作方法》在数据分析、自动化和日常开发中,CSV和Excel文件是非常常见的数据存储格式,ython提供了强大的工具来读取、编辑和保存这两种文件,满足从基... 目录1. CSV 文件概述和处理方法1.1 CSV 文件格式的基本介绍1.2 使用 python 内

Python实现NLP的完整流程介绍

《Python实现NLP的完整流程介绍》这篇文章主要为大家详细介绍了Python实现NLP的完整流程,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 编程安装和导入必要的库2. 文本数据准备3. 文本预处理3.1 小写化3.2 分词(Tokenizatio

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

SpringBoot使用minio进行文件管理的流程步骤

《SpringBoot使用minio进行文件管理的流程步骤》MinIO是一个高性能的对象存储系统,兼容AmazonS3API,该软件设计用于处理非结构化数据,如图片、视频、日志文件以及备份数据等,本文... 目录一、拉取minio镜像二、创建配置文件和上传文件的目录三、启动容器四、浏览器登录 minio五、

MyBatis延迟加载的处理方案

《MyBatis延迟加载的处理方案》MyBatis支持延迟加载(LazyLoading),允许在需要数据时才从数据库加载,而不是在查询结果第一次返回时就立即加载所有数据,延迟加载的核心思想是,将关联对... 目录MyBATis如何处理延迟加载?延迟加载的原理1. 开启延迟加载2. 延迟加载的配置2.1 使用