VOID
IoSetCompletionRoutine(
IN PIRP Irp,
IN PIO_COMPLETION_ROUTINE CompletionRoutine,
IN PVOID Context,
IN BOOLEAN InvokeOnSuccess,
IN BOOLEAN InvokeOnError,
IN BOOLEAN InvokeOnCancel
);
IoSetCompletionRoutine registers an IoCompletion routine to be called when the next-lower-level driver has completed the requested operation for the given IRP.
Parameters
Irp
Points to the IRP that the driver wants to track.
CompletionRoutine
Specifies the entry point for the driver-supplied IoCompletion routine to be called when the next-lower driver completes the packet. This routine is declared as follows:
NTSTATUS
(*PIO_COMPLETION_ROUTINE)(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
Context
Points to a driver-determined context to pass to the IoCompletion routine.
InvokeOnSuccess
Specifies whether the completion routine is called if the IRP is completed with STATUS_SUCCESS in the I/O status block.
InvokeOnError
Specifies whether the completion routine is called if the IRP is completed with an error STATUS_XXX in the I/O status block.
InvokeOnCancel
Specifies whether the completion routine is called if the IRP is completed with STATUS_CANCELLED set in the I/O status block.
Comments
This routine sets the transfer address of the IoCompletion routine in the given IRP. The lowest-level driver in a chain of layered drivers cannot call this routine.
IoSetCompletionRoutine registers the specified routine to be called when the next-lower-level driver has completed the requested operation in any or all of the following ways:
·Successfully
·With an error
·Canceled the IRP
Usually, the I/O status block is set by the underlying device driver. It is read but not altered by any higher-level drivers’ IoCompletion routines.
Higher-level drivers that allocate IRP’s with IoAllocateIrp or IoBuildAsynchronousFsdRequest must call this routine with all InvokeOnXxx parameters set to TRUE before passing the driver-allocated IRP to IoCallDriver. When the IoCompletion routine is called with such an IRP, it must free the driver-allocated IRP and any other resources that the driver set up for the request, such as MDLs with IoBuildPartialMdl. Such a driver should return STATUS_MORE_PROCESSING_REQUIRED when it calls IoFreeIrp to forstall the I/O Manager’s completion processing for the driver-allocated IRP.
Callers of IoSetCompletionRoutine must be running at IRQL <= DISPATCH_LEVEL.
See Also
IO_STACK_LOCATION, IoAllocateIrp, IoBuildAsynchronousFsdRequest, IRP, IoBuildPartialMdl, IoFreeIrp