IRP和IO_STACK_LOCATION

当一个应用程序调用函数去操作某个设备时,比如调用createFile,deviceIOControl,等等时,I/O管理器为此函数创建一个IRP数据结构对象和一个IRP_STACK_LOCATION数据结构对象数组。

(数组个数等于驱动程序堆栈上驱动的个数)。IRP对象中的数据成员是已经被填充好了的,其中有一个CurrentLocation是当前IRP_STACK_LOCATION堆栈单元的索引,Tail.Overlay.CurrentStackLocation

是当前IRP_STACK_LOCATION单元的指针。

一开始的时候,它当然是指向IRP_STACK_LOCATION数组的第一个元素。

这调用某个驱动程序的分发函数时,IRP作为参数传给了该分发函数,这样,该函数就可以访问IRP中的Tail.Overlay.CurrentStackLocation, 这样就可以访问IRP_STACK_LOCATION的

成员了(当然我们不需要直接这样做,而是调用IoGetCurrentStackLocation来实现)。因为OS并不会为我们初始化IRP_STACK_LOCATION数组中的每一个对象,所以初始化下一层驱动要使用的IRP_STACK_LOCATION就由它的上一层驱动来完成。要初始化它们,首先要找到它们,方法是调用IoGetNextStackLocation(它内部实现只是将CurrentStackLocation++),得到下一个IRP_STACK_LOCATION

对象指针。然后为其赋值。然后调用IOCALLDRIVER().

理解的关键点是:

一 OS为我们生成IRP,IPR_STACK_LOCATION数组,注意,是个数组。IRP中的CurrentStackLocation指向IRP_STACK_LOCATION中的某一个元素。

二 OS 并不会为我们填充好IRP_STACK_LOCATION数组,每一个元素是由上一层驱动负责填充的。

三 IRP_STACK_LOCATION数组,它们的元素之间不需要指针联系。

四 OS只负责把IRP包给最上层的驱动程序,至于如何向下层,就是驱动程序自己的事情了。所以下层对就的那些IRP_STACK_LOCATION,完全由上层驱动函数负责填充,OS不管。

 

驱动程序如何填充一层驱动需要用的IRP_STACK_LOCATION呢?

可以通过调用IoGetNextIrpStackLocation调用得到。其实该函数内部就是返回CurrentStackLocation加1而已。对数组值加1,当然就是得到数组的下一个值了。

这样就可以对它进行赋值了。然后调用IoCallDriver(),IoCallDriver()会将irp包中的CurrentStackLocation值加1,然后调用那个DRIVER.

 

如果下一层的驱动需要的IRP_STACK_LOCATION和本层驱动的一样,则可以直接调用IoSkipCurrentIrpStackLocation或IoCopyCurrentIrpStackLocationToNext.

IoSkipCurrentIrpStackLocation将CurrentStackLocation减1. 正好与IoCallDriver的加1抵消。所以相当于下层驱动和本层驱动用的是同一个IRP_STACK_LOCATIN元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值