To claim a SCSI device, a class driver either calls a ClaimDevice routine or implements the same functionality in its DriverEntry routine. A ClaimDevice routine sets up an SRB for the target device (designated by PathId, TargetId, and Lun in the SRB) with the Function value SRB_FUNCTION_CLAIM_DEVICE.
The ClaimDevice routine allocates an IRP with IoBuildDeviceIoControlRequest, setting up the port driver’s I/O stack location with the I/O control code IOCTL_SCSI_EXECUTE_NONE and a pointer to the SRB at Parameters.Scsi.Srb. ClaimDevice also must set up an event object so it can wait on the completion of the IRP. Then, it sends the IRP on to the port driver with IoCallDriver.
On return from a successful call to the system port driver, the ClaimDevice routine checks the SRB’s DataBuffer for a nonNULL pointer to the port driver’s device object for the HBA.
The class driver must store such a returned pointer in the device extension of its own device object that represents the newly claimed device. The class driver must use this HBA-specific device object pointer in all subsequent requests that the class driver sends down to the port-miniport driver pair.
A ClaimDevice routine can serve double duty as a routine to be called from a class driver’s Unload routine by also sending SRBs with the Function value SRB_FUNCTION_RELEASE_DEVICE. If the class driver can be unloaded, its Unload or ClaimDevice routine must dereference the pointer to the HBA-specific device object by calling ObDereferenceObject.