IRPs and I/O Cancellation

·Change in Spin Lock Usage and Return Value for IoSetCancelRoutine

If a driver manages its own queue(s) of IRPs, it does not need to hold the cancel spin lock when calling IoSetCancelRoutine. IoSetCancelRoutine now uses an interlocked exchange intrinsic to set the address of a cancel routine in an IRP as an atomic operation. Drivers that manage their own queues should move calls to IoSetCancelRoutine out of code holding the cancel spin lock, to reduce contention for the spin lock and possibly improve performance.

If a driver uses the I/O-manager-supplied device queue in the device object and uses the IoStart..Packet..routines, then the driver must still hold the system cancel spin lock when calling IoSetCancelRoutine.

IoSetCancelRoutine now returns the previous value of
Irp->CancelRoutine, which is of type PDRIVER_CANCEL.

·Optional Additional Pointers in IRP When Not Using the Device Queue

If a driver is not using the DeviceQueueEntry field in the IRP, it can use that field to store up to four pointers. The driver can use those pointers for any purpose as long as it owns the IRP. For example, one pointer could point to the listhead for the queue in which the IRP resides. The definition of that field in the IRP has been expanded as follows:

    union {

        KDEVICE_QUEUE_ENTRY DeviceQueueEntry;

        struct {

            PVOID DriverContext[4];

        };

    };