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.
NTSTATUS (*PIO_COMPLETION_ROUTINE)( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context );
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:
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.
IO_STACK_LOCATION, IoAllocateIrp, IoBuildAsynchronousFsdRequest, IRP, IoBuildPartialMdl, IoFreeIrp