首页
社区
课程
招聘
[求助]bulkusb中的读写例程中返回STATUS_PENDING后,再没做处理,为什么?
发表于: 2013-1-29 18:44 4669

[求助]bulkusb中的读写例程中返回STATUS_PENDING后,再没做处理,为什么?

2013-1-29 18:44
4669
在DDk的bulkusb的读写中将irp转发给pdo后,直接返回status_pending了而没有再对该irp做结束处理,这样的代码不是有问题吗?
先将读写例程和完成例程简化如下:
NTSTATUS
BulkUsb_DispatchReadWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
//初始化变量,构建mdl,创建urb,设置下层io栈等等
...
//设置完成例程
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)BulkUsb_ReadWriteCompletion, rwContext, TRUE,TRUE,TRUE);
//阻塞irp
IoMarkIrpPending(Irp);
//将irp转发到下层usb总线驱动
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,Irp);
//返回挂起状态
return STATUS_PENDING
}

通过设置完成例程,可将大传输量拆分为多次传输得以完成。现假设在传输字节很少,以至于一次就可完成传输的情况下,完成例程可简化如下:
NTSTATUS  
BulkUsb_ReadWriteCompletion(  
    IN PDEVICE_OBJECT DeviceObject,  
    IN PIRP           Irp,  
    IN PVOID          Context  
    )  
{
ntStatus = Irp->IoStatus.Status;
Irp->IoStatus.Information = rwContext->Numxfer;
return ntStatus;
}

这样就有疑问:
读写例程中将irp挂起后,转发给下层处理,并直接返回status_pending,后续应该还有对irp的处理啊?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 1370
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
请求斑竹、各路高手帮忙解释一下啊
2013-1-29 20:14
0
雪    币: 83
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
百度进来的。。不是挖坟啊。。最近一直在弄rootkit。。简单说一下吧。。

STATUS_PENDING 状态会最终返回到I/O管理器,I/O管理器收到了STATUS_PENDING后会wait一个事件。这个过程是没有问题的。最底层的驱动会跟硬件进行交互,当完成了全部IRP的内容后,会最后调用一个IoCompleteRequest的函数来做收尾的工作,这个函数会从下向上遍历设备栈,然后依次调用每个设备栈的完成例程,代码中是BulkUsb_ReadWriteCompletion函数。
其中很重要的是IO_STACK_LOCATION里control域的SL_PENDING_RETURNED标志,如果SL_PENDING_RETURNED为1,IoCompleteRequest函数在遍历的过程中会把SL_PENDING_RETURNED标志的值从下到上传递到最顶层的驱动里(SL_PENDING_RETURNED设置为1由IoMarkIrpPending函数完成),而最关键的是IoCompleteRequest函数会根据最顶层的SL_PENDING_RETURNED值来通过APC的方式通知I/O管理器结束等待。不然I/O管理器会一直等待。

所以
1)return STATUS_PENDING前一定要调用IoMarkIrpPending,这样就不会导致I/O管理器一直等待下去。
2)虽然派遣函数返回了STATUS_PENDING,但是因为设置了完成例程,IRP结束后,还是会有一个执行代买的机会。

简单的描述了一下,省略了很多细节,比如设备栈是否设置了完成例程,IoCompleteRequest会有不同处理。比如同步异步等等。。
2013-9-13 11:47
0
游客
登录 | 注册 方可回帖
返回
//