现在的驱动大多都是分层的,既然是分层驱动,那么调用下层驱动就无可避免。调用下层驱动可以分为同步和异步两种。
1. 下层驱动同步完成irp,那么IoCallDriver返回的时候irp已经完成了。
2. 下层驱动异步完成irp,那么IoCallDriver返回的时候irp还没有完成,irp的状态是pending。
针对第二种情况,因为IoCallDriver直接返回了,那么过滤驱动怎么知道下层驱动什么时候完成了irp呢?哈哈,该轮到完成例程出场了。
使用完成例程需要2个步骤:
1. 增加一个完成例程,原型如下:
NTSTATUS MyIoCompletion(IN PDEVICE_OBJECT fdo, IN PIRP irp, IN PVOID context)
2. 在调用下层驱动前,调用IoSetCompletionRoutine,如:
IoSetCompletionRoutine(Irp, MyIoCompletion, NULL, TRUE, TRUE, TRUE);
将前面的例子http://blog.csdn.net/zj510/article/details/8332658,稍作改动,改动的是过滤驱动。
增加一个完成例程
NTSTATUS MyIoCompletion(IN PDEVICE_OBJECT fdo, IN PIRP irp, IN PVOID context)
{
KdPrint(("Enter MyIoCompletion\n"));
if(irp->PendingReturned)
{
IoMarkIrpPending(irp);
}
KdPrint(("Leave MyIoCompletion\n"));
return STATUS_SUCCESS;
}
这个函数啥也没做,就打2个log。
设置完成例程
NTSTATUS HelloWDMIOControl(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
KdPrint