The IoSetCompletionRoutine routine registers an IoCompletion routine, which will be called when the next-lower-level driver has completed the requested operation for the given IRP.
VOID IoSetCompletionRoutine( _In_ PIRP Irp, _In_opt_ PIO_COMPLETION_ROUTINE CompletionRoutine, _In_opt_ PVOID Context, _In_ BOOLEAN InvokeOnSuccess, _In_ BOOLEAN InvokeOnError, _In_ BOOLEAN InvokeOnCancel );
- Irp [in]
Pointer to the IRP that the driver is processing.
- CompletionRoutine [in, optional]
Specifies the entry point for the driver-supplied IoCompletion routine, which is called when the next-lower driver completes the packet.
- Context [in, optional]
Pointer to a driver-determined context to pass to the IoCompletion routine. Context information must be stored in nonpaged memory, because the IoCompletion routine is called at IRQL <= DISPATCH_LEVEL.
- InvokeOnSuccess [in]
Specifies whether the completion routine is called if the IRP is completed with a success status value in the IRP's IO_STATUS_BLOCK structure, based on results of the NT_SUCCESS macro (see Using NTSTATUS values).
- InvokeOnError [in]
Specifies whether the completion routine is called if the IRP is completed with a nonsuccess status value in the IRP's IO_STATUS_BLOCK structure.
- InvokeOnCancel [in]
Specifies whether the completion routine is called if a driver or the kernel has called IoCancelIrp to cancel the IRP.
Note Only a driver that can guarantee it will not be unloaded before its completion routine finishes can use IoSetCompletionRoutine. Otherwise, the driver must use IoSetCompletionRoutineEx, which prevents the driver from unloading until its completion routine executes.
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:
With a success status value
With a nonsuccess status value
By canceling 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 forestall the I/O manager's completion processing for the driver-allocated IRP.
Non-PnP drivers that might be unloaded before their IoCompletion routines run should use IoSetCompletionRoutineEx instead.
|Available starting with Windows 2000.|
DDI compliance rules
|CompleteRequest, CompleteRequestStatusCheck, CompletionRoutineRegistered, IoAllocateForward, IoAllocateIrpSignalEventInCompletion, IoAllocateIrpSignalEventInCompletion2, IoAllocateIrpSignalEventInCompletion3, IoAllocateIrpSignalEventInCompletionTimeout, IoBuildFsdForward, IoBuildFsdIrpSignalEventInCompletion, IoBuildFsdIrpSignalEventInCompletion2, IoBuildFsdIrpSignalEventInCompletion3, IoBuildFsdIrpSignalEventInCompletionTimeout, IoSetCompletionRoutineNonPnpDriver, LowerDriverReturn, MarkPower, MarkPowerDown, MarkQueryRelations, MarkStartDevice, PendedCompletedRequest, SignalEventInCompletion, SignalEventInCompletion2, SignalEventInCompletion3, StartDeviceWait, StartDeviceWait3, SetCompletionRoutineFromDispatch, IoFreeIrp|