12.1.2  Cancelable IRPs in Higher-Level Drivers without Cancel Routines

The designer of a higher-level NT driver can make no assumptions about whether or how existing lower-level NT drivers handle cancelable IRPs. As soon as any higher-level NT driver calls IoCallDriver with an IRP, it no longer “owns” that IRP and it can neither determine nor control whatever processing lower-level drivers are doing to satisfy that request.

However, any higher-level NT driver can set its IoCompletion routine in an IRP by calling IoSetCompletionRoutine before it calls IoCallDriver. Such a higher-level driver can determine whether any pending IRP is cancelled in a lower driver by calling IoSetCompletionRoutine with the InvokeOnCancel parameter set to TRUE before it passes the IRP on to lower drivers.

A higher-level NT driver can call IoCancelIrp with any pending IRP that the driver allocates. However, making this call does not guarantee that the given driver-allocated IRP will be completed with its I/O status block set to STATUS_CANCELLED. Such a higher-level driver that calls IoCancelIrp can check whether the given IRP was cancelled only in its IoCompletion routine so it must call IoSetCompletionRoutine with the InvokeOnCancel parameter set to TRUE before passing the IRP on to lower drivers. For more information about IoCompletion routines, see Chapter 13.

A higher-level NT driver should not call IoCancelIrp with an IRP that it did not allocate.