返回STATUS_MORE_PROCESSING_REQUIRED的2种形式
一种是自己申请IRP
第二种是自身是过滤驱动(IRP是上层组件下发的,所以IRP不能只在我们驱动的函数这里(像第一种情况那样就释放)就消失了
第一种:
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
if (Irp->UserEvent)
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
if (Irp->MdlAddress)
{
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
xxfun()
{
allocate irp()
IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
iocalldriver()
if pending
waitfor pending
done!
}
===================
第二种
NTSTATUS
DispatchRoutine_2(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
KEVENT event;
NTSTATUS status;
KeInitializeEvent(&event, NotificationEvent, FALSE);
//
// You are setting completion routine, so you must copy
// current stack location to the next. You cannot skip a location
// here.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
CompletionRoutine_2,
&event,
TRUE,
TRUE,
TRUE
);
status = IoCallDriver(TopOfDeviceStack, Irp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Executive, // WaitReason
KernelMode, // must be Kernelmode to prevent the stack getting paged out
FALSE,
NULL // indefinite wait
);
status = Irp->IoStatus.Status;
}
// <---- Do your own work here.
//
// Because you stopped the completion of the IRP in the CompletionRoutine
// by returning STATUS_MORE_PROCESSING_REQUIRED, you must call
// IoCompleteRequest here.
//
IoCompleteRequest (Irp, IO_NO_INCREMENT);//注意要在这里complete
return status;
}
NTSTATUS
CompletionRoutine_2(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
if (Irp->PendingReturned == TRUE) {
//
// You will set the event only if the lower driver has returned
// STATUS_PENDING earlier. This optimization removes the need to
// call KeSetEvent unnecessarily and improves performance because the
// system does not have to acquire an internal lock.
//
KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
注意:这里也不需要调用 IoMarkIrpPending( Irp );,IoMarkIrpPending是为了把SL_PENDING_RETURNED标志一直往上传,最终的可能就是设置PendingReturned,
PendingReturned 标志就是要告诉IO在完成IRP的时候,这个IO是异步完成的,但由于我们在这里返回STATUS_MORE_PROCESSING_REQUIRED,并且DispatchRoutine_2 waitfor了,这样在DispatchRoutine_2调用IoCompleteRequest 完成IRP的时候,这个IO其实就变成同步完成了,这样当然就不要上报这个标志了
}
// This is the only status you can return.
return STATUS_MORE_PROCESSING_REQUIRED;
}

浙公网安备 33010602011771号