A.2.4 SCSI Filter Driver’s Dispatch Routines

Like any other higher-level kernel-mode driver, a SCSI filter driver must have one or more Dispatch routines to handle every IRP_MJ_XXX  request for which the underlying SCSI class driver supplies a Dispatch entry point. Depending on the nature of its device, an SFD’s Dispatch entry point for any given request might do either of the following:

For requests that require no special handling, an SFD’s Dispatch routine usually calls IoGetNextIrpStackLocation with an input IRP, sets up the class driver’s I/O stack location and, then, calls IoCallDriver with pointers to the class driver’s device object and the IRP. Note that an SFD seldom sets its IoCompletion routine in IRPs that require no special handling both because a call to the IoCompletion routine is unnecessary and because it degrades I/O throughput for the SFD’s device(s).

For requests that do require special handling, the SFD can do the following:

  1. Create a new IRP with IoBuildDeviceIoControlRequest, IoAllocateIrp, IoBuildSynchronousFsdRequest, or IoBuildAsynchronousFsdRequest, usually specifying an I/O stack location for itself.

  2. Check the returned IRP pointer for NULL and return STATUS_INSUFFICIENT_RESOURCES if an IRP could not be allocated.

  3. If the driver-created IRP includes an I/O stack location for the SFD, call IoSetNextIrpStackLocation to set up the IRP stack location pointer. Then, call IoGetCurrentIrpStackLocation to get a pointer to its own I/O stack location in the driver-created IRP and set up it up with state to be used by its own IoCompletion routine.

  4. Call IoGetNextIrpStackLocation to get a pointer to the class driver’s I/O stack location in the driver-created IRP and set it up with the major function code IRP_MJ_SCSI and an SRB (see Sections A.1.4 through A.1.4.5).

  5. Translate data to be transferred to the device into a device-specific, nonstandard format if necessary.

  6. Call IoSetCompletionRoutine if the driver allocated any memory, such as memory for an SRB, SCSI request-sense buffer, MDL, and/or IRP with a call to IoAllocateIrp or IoBuildAsynchronousFsdRequest, or if the driver must translate data transferred from the device in a device-specific, nonstandard format.

  7. Pass the driver-created IRP to (and through) the class driver with IoCallDriver.

Like a SCSI class driver, an SFD might have SCSI-specific BuildSrb or SplitTransferRequest routines to be called from the driver’s Dispatch routine(s), or might implement the same functionality inline.

For more information about BuildSrb and SplitTransferRequest routines, see Sections A.1.4.4 and A.1.4.5. For more information about general requirements for Dispatch routines, see Chapter 6.