-
-
[旧帖]
[原创]IRP完成的几种常见错误
0.00雪花
-
发表于:
2010-4-2 12:30
2684
-
[旧帖] [原创]IRP完成的几种常见错误
0.00雪花
直接上代码。
第一种:
NTSTATUS DispatchSomething(PDEVICE_OBJECT fidp, PIRP irp)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fido->DevcieExtension;
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp, CompletionRoutine, ...);
NTSTATUS status = IoCallDriver(pdx->LowerDevice, irp);
if (STATUS_PENDING == status)
{
IoMarkIrpPending(Irp)
}
return status;
}
这种情况貌似很正确,当下层返回STATUS_PENDING的时候标记一下
其实错就错在当返回STATUS_PENDING的时候这个IRP可能已经完成了,这时候千万不要碰IRP了。
第二种:
NTSTATUS DispatchSomething(PDEVICE_OBJECT fido, PIRP irp)
{
PDEVICE_EXTENSION pdx = fido->DeviceExtension;
IoMarkIrpPending(irp);
IoCopyCurrrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp, TopDriverCompleteRoutine, ...);
return IoCallDriver(pdx->LowrDevice, irp);
}
同样,看起来没什么问题,大不了我先标记一下吧。
这里的问题在于IoMarkIrpPending和STATUS_PENDING必须配对使用,这里是标记了要Pending,但是函数却有可能返回了别的值。
第三种:
NTSTATUS DeispatchSomething(PDEVCIE_OBJECT fido, PIRP irp)
{
PDEVICE_EXTENSION pdx = fido->DeviceExtenson;
KEVENT event;
KeInitializeEvent(&event, NotificaionEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp, CompletionRoutine, &event, TRUE,TRUE,TRUE);
IoCallDriver(pdx->LowerDeviceObject, irp);
KeWaitForSingleObject(&event, ...);
Irp->IoStatus.Status = status;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS CompletionRoutine(PDEVICE_OBJECT fido, PIRP irp, PVOID pev)
{
if (Irp->PendingReturned)
{
IoMarkIrpPending(irp);
}
KeSetEvent((PKEVENT)pev, IO_NO_CREMENT, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
这个是在完成例程中标记的,如果下层异步完成,则标记,看起来没错,其实也犯了和前一个一样的错误。
第四种:
VOID SomeFunction()
{
PIRP irp = IoBuildAsynchronousFsdRequest(...);
IoSetCompleteRoutine(irp, MyCompleteRoutine, ...);
IoCallDriver(...);
}
NTSTATUS MyCompletionRoutine(PDEVCIE_OBJECT junk, PIRP irp, PVOID context)
{
if (Irp->PendingReturned)
{
IoMarkIrpPending(irp);
}
IoFreeIrp(irp);
return STATUS_MORE_PROCESISING_REQUIRED;
}
这种方式为自己构造IRP,然后传递给下层处理。
该情况的错误在于自己构造的IRP没有当前栈,所以也无法调用IoMarkIrpPending
在实际代码编写中一定要注意避免上述几种错误
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!