I wanted to provide an update. I was mistaken on what I was seeing on the stack.
My driver is being called at IRP_MJ_DEVICE_CONTROL with IOCTL_SCSI_PASS_THROUGH_DIRECT but now I have a new problem.
a) My filter driver needs to handle disk reads in a particular manner.
So my driver filters out read operation code from the CDB. But the CDB operation code is always 0.
I was hoping that it would be SCSI reads of various types 6-byte, 12 byte 16 byte.
But it is always 0.
The system has 2 drives, one boot drive and one data drive.
For the controller that has the boot drive plugged to it, my filter driver never gets called at the above ioctl codes. Instead it only gets called at IRP_MJ_SCSI. Boot drives are treated specially by the driver and no processing is performed on boot drives
for the controller that has the data plugged in, initial SCSI operations are sent synchronously via the IRP_MJ_SCSI handler and then they are sent using the above ioctl codes (SCSI_PASS_THROUGH_DIRECT and SCSI_PASS_THROUGH).
Here is my processing for SCSI_PASS_THROUGH_DIRECT and SCSI_PASS_THROUGH IRP
I flag reads only if the CDB operation code matches one of the following values
8, 0x88, 0x28, 0xA8 (for various SCSI lengths).
These IRPs are treated specially by my driver. Everything else is just passed through
I did notice that sometimes I get 0xA1 operation code. This is a ATA_PASSTHROUGH operation code. What is the meaning of this operation code?. Otherwise I am getting 0 operation code all the time.
The reads and writes are happening just fine.
For now if the IRP is issued by a 32-bit process, I wanted to catch that to see if I was not handling that. I am never hitting this breakpoint.
Also, what dictates whether the disk driver uses IRP_MJ_SCSI or SCSI_PASS_THROUGH/SCSI_PASS_THROUGH_DIRECT to send CDB commands to the Storport driver?. is it some combination of Flags in the device Object of the underlying controller driver.
==========================================================Code==========================================
case IOCTL_SCSI_PASS_THROUGH:
case IOCTL_SCSI_PASS_THROUGH_DIRECT:
if (IoIs32bitProcess(Irp)) {
__debugbreak();
}
PUCHAR pDataBuffer = nullptr;
PCDB pcdb = nullptr;
ULONG dataTransferLength = 0;
UCHAR dataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
if (fcn == IOCTL_SCSI_PASS_THROUGH)
{
if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH))
break;
PSCSI_PASS_THROUGH pPT = static_cast<PSCSI_PASS_THROUGH>(Irp->AssociatedIrp.SystemBuffer);
pDataBuffer = (PUCHAR)(pPT) + pPT->DataBufferOffset;
pcdb = (PCDB)pPT->Cdb;
dataTransferLength = pPT->DataTransferLength;
dataIn = pPT->DataIn;
}
else
{
if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH_DIRECT))
break;
PSCSI_PASS_THROUGH_DIRECT pPTD = (PSCSI_PASS_THROUGH_DIRECT)Irp->AssociatedIrp.SystemBuffer;
pDataBuffer = (PUCHAR)pPTD->DataBuffer;
pcdb = (PCDB)(pPTD->Cdb);
dataTransferLength = pPTD->DataTransferLength;
dataIn = pPTD->DataIn;
}