Wednesday, May 2, 2012

IRP三种操作


IRP的操作
通常状态下派遣函数调用IoCompleteRequest 结束当前IRP请求
但在一些情况下可能要挂起irp 内核函数IoMarkIrpPending 挂起IRP并返回 STATUS_PENDING ,对于ring3级的请求会返回False 这时用GetLastError会发现错误码是ERROR_IO_PENDING 表明当前操作被挂起。为了最终要结束所有的IRP请求,我们需要保存被挂起的IRP,并在最后进行处理(IRP_MJ_CLEANUP
还有一种情况是取消IRP的请求IoSetCancelRoutinePIRP pIrp PDRIVER_CANCEL CancelRoutine);参数1 需要取消的IRP;参数2 :回调函数地址,需要同步执行的。
流程:在某个派遣函数A中挂起IRP 并且设置返回为STATUS_PENDING,同时需要设置取消例程,也就是回调函数。此回调函数需要同步执行,其可以在ring3级显示调用(CancelIo(hDevice) hDcvice为操作的句柄内核函数可以调用IoCancelIrp(IN pIrp) ),也可以不需要调用,程序关闭设备时会自动调用CancelIo系统调用IoCancelIrp时自动会获得自旋锁,以进行同步,所以在回调函数完成时记得释放自旋锁(IoReleaseCancelSpinLock,否则会导致系统崩溃,另外此cancel自旋锁是全局自旋锁,所有驱动都会使用,所以不宜长时间占用。

No comments:

Post a Comment