网站建设备案流程图,wordpress 微博 主题,网站空间一般多大,ios开发者中心当一个应用程序调用函数去操作某个设备时#xff0c;比如调用createFile,deviceIOControl,等等时#xff0c;I/O管理器为此函数创建一个IRP数据结构对象和一个IRP_STACK_LOCATION数据结构对象数组。 #xff08;数组个数等于驱动程序堆栈上驱动的个数#xff09;。IRP对象中… 当一个应用程序调用函数去操作某个设备时比如调用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元素。