当PnP管理器检测到硬件时,它首先参考注册表以了解有哪些过滤器驱动程序将管理该硬件。如果必要(某些驱动程序可能因为其它硬件的需要已经被系统装入)它将装入这些驱动程序,并调用它们的AddDevice函数。最后AddDevice函数创建设备对象并连入设备堆栈。此后,PnP管理器将为所有设备驱动程序分配I/O资源。 一旦资源分配确定,PnP管理器通过向每个设备发送一个带IRP_MN_START_DEVICE副功能码的PnP请求来通知设备。通常过滤器驱动程序对这个IRP不感兴趣,所以它们使用DefaultPnpHandler方式把请求向下传。而功能驱动程序正好相反,它需要在这个IRP上做大量工作,包括分配并配置额外的软件资源以及为设备操作做准备。这个工作需要在PASSIVE_LEVEL级上进行,并在低层驱动程序处理完该IRP后完成。 在PnP处理函数中分发IRP_ MN_START_DEVICE这个PnP给函数PnpStartDeviceHandler(fdo,Irp)处理; switch( MinorFunction) NTSTATUS PnpStartDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp) 在PnpStartDeviceHandler处理函数中我们可以看到有一个ForwardIrpAndWait函数,这个函数是 为了在下传IRP_MN_START_DEVICE请求后再获得控制,派遣例程需要等待一个内核事件,该事件最终由低层驱动程序对IRP的完成操作来通知。因此,写了这一个辅助函数来执行这个前进和等待机制,该函数原形如下:
1 KeInitializeEvent(event, EventType, initialstate)这个函数的解释如下: event是事件对象的地址。EventType是一个枚举值,可以为NotificationEvent或SynchronizationEvent。通知事件(notification event)有这样的特性,当它进入信号态后,它将一直处于信号态直到你明确地把它重置为非信号态。此外,当通知事件进入信号态后,所有在该事件上等待的线程都被释放。这与用户模式中的手动重置事件相似。而对于同步事件(synchronization event),只要有一个线程被释放,该事件就被重置为非信号态。这又与用户模式中的自动重置事件相同。而KeWaitXxx函数在同步事件对象上执行的附加动作就是把它重置为非信号态。最后的参数是布尔量,为TRUE表示事件的初始状态为信号态,为FALSE表示事件的初始状态为非信号态。 我们创建一个内核事件对象。KeInitializeEvent必须在PASSIVE_LEVEL级上被调用。幸运的是,PnP请求总是在PASSIVE_LEVEL上发送,所以正好符合这种需求。事件对象本身必须占用非分页内存。另外,在大多数情况下,你也可以认为执行堆栈也是非分页的。 2 由于我们要安装一个完成例程,所以必须向下一层驱动程序复制堆栈参数。 3 指定一个完成例程以便我们能知道下层驱动程序何时完成该IRP。我们应该等待完成操作发生,所以必须确保我们的完成例程被调用。这就是为什么我把三个标志参数都指定为TRUE,它们指出我们希望在IRP正常完成、遇到错误、被取消这三种情况下都调用OnRequestComplete。完成例程的上下文参数是event对象的地址。 4 IoCallDriver调用下一层驱动程序,可以是一个低层过滤器驱动程序或是PDO驱动程序本身。PDO驱动程序将执行某些处理,或者是立即完成该请求,或者返回STATUS_PENDING。 5 如果IoCallDriver返回STATUS_PENDING,我们都将调用KeWaitForSingleObject在我们以前建立的内核事件上永远等待。当下层驱动程序完成该IRP并把事件置成信号态时,我们的完成例程将再次获得控制。 6 这里,我们捕获IRP的最终状态并返回给我们的调用者。 一旦我们调用了IoCallDriver,我们就放弃了IRP的控制权,直到某些运行在任意线程上下文中的代码调用 IoCompleteRequest通知该IRP完成,IoCompleteRequest将调用我们的完成例程。完成例程特别简单:
2. 通过返回STATUS_MORE_PROCESSING_REQUIRED,我们停止了I/O堆栈的回卷处理。此时,上层过滤器驱动程序安装的任何完成例程都得不到调用,并且I/O管理器将停止在该IRP上的工作。这种情形就象根本没有调用过IoCompleteRequest一样,当然,某些已经调用过的低级完成例程除外。在这一时刻,该IRP将处于一个中间状态,但我们的ForwardAndWait例程将再次获得该IRP的所有权。
|
|
来自: tuohuang0303 > 《我的图书馆》