上一个文章讲了StartIo的基本用法(http://blog.csdn.net/zj510/article/details/8230071),其中调用IoStartPacket的时候传了一个取消例程进去。如:
IoStartPacket(fdo, Irp, 0, HelloWDMOnCancelIRP);
参考MSDN上的参数说明:
第四个参数是一个Cancel routine(取消例程)的入口地址。取消例程有什么用呢?MSDN上是这么说的,http://msdn.microsoft.com/en-us/library/windows/hardware/ff540742(v=vs.85).aspx
当caller提交了一个请求之后,还可以取消这个请求。当然前提是请求还没有被执行。
这里有几点需要注意:
1. 用过IoStartPacket()和IoSetCancelRoutine()可以注册取消例程。
2. I/O管理器会先调用IoAcquireCancelSpinLock获取自旋锁,然后再调用驱动的取消例程,那么在取消例程里面一定要调用IoReleaseCancelSpinLock来释放自旋锁。
3. 取消例程运行在DISPATCH_LEVEL irql(因为调用了IoAcquireCancelSpinLock),直到取消例程调用IoReleaseCancelSpinLock。取消例程需要传递Irp->CancelIrql给IoReleaseCancelSpinLock。其中,对于Irp->CancelIrql,MSDN是这么描述的:
CancelIrqlContains the IRQL at which a driver is running when