Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
(Please excuse the recycled bits. The 7-month-old is still absorbing most of my blogging time (along with sleeping time, dating time, playing time, cleaning time, working time, etc...))
A question came up on the ntdev mailing list about why there are "so many" ways to send an I/O request to a SCSI driver.
In matter of fact there are two - IRP_MJ_SCSI and IOCTL_SCSI_PASS_THROUGH (and it's direct mapped variant).
IRP_MJ_SCSI == IRP_MJ_INTERNAL_DEVICE_CONTROL. This is easily determined by looking at the headers. No SCSI shouldn't have its own IRP MJ code, and no it shouldn't reuse a number from an existing one. But it's been that way since I joined MS (and I tried to change it once ... not possible without breaking everyone doing storage) and so we all just have to live with it. Someone decided we needed a MJ code for SCSI requests. I suspect IRP_MJ_INTERNAL_DEVICE_CONTROL was reused to avoid the cost of an additional PVOID per driver object (which at the time would have been an issue).
IOCTL_SCSI_EXECUTE_* is set in the stack ___location for an IRP_MJ_SCSI to (a) allow someone handling IRP_MJ_INTERNAL_DEVICE_CONTROL to differentiate between the two and (b) to provide some indicator of which direction the SRB is transferring data. Its use isn't particularly consistent ... I think of it as more of a debugging aid but I see that some of our drivers (like the RAMDISK driver) use it to decide if the SRB in question is a read/write type command or one of those strange SCSI commands like REQUEST_SENSE which require more complex emulation. I think using the CDB code would have been a much better idea.
IRP_MJ_SCSI comes with an SRB.
IOCTL_SCSI_PASS_THROUGH and IOCTL_SCSI_PASS_THROUGH_DIRECT are to send SCSI requests from user-mode. They come with SCSI_PASS_THROUGH/SCSI_PASS_THROUGH_DIRECT structures so as not to expose SRB to user-mode and so as to avoid validating SRBs which might come from user-mode (besides, how is a user mode component going to provide a value like OriginalIrp).
IOCTL_SCSI_PASS_THROUGH is a buffered operation, while IOCTL_SCSI_PASS_THROUGH_DIRECT direct maps the data transfer. They're separate control codes because they are - I suppose a flag in the PASS_THROUGH structure could have contained the transfer mode ... would that make you happier?
So there are two ways to send a SCSI request. One for kernel-mode components (IRP_MJ_SCSI) and one for user-mode components (IOCTL_SCSI_PASS_THROUGH[_DIRECT]). If you want to convert a pass-through command to a IRP_MJ_SCSI command it's pretty straight-forward to make an SRB and send it down.
-p
Comments
Anonymous
May 30, 2008
(Please excuse the recycled bits.  The 7-month-old is still absorbing most of my blogging time (along with sleeping time, dating time, playing time, cleaning time, working time, etc...)) A question came up on the ntdev mailing list about whyAnonymous
June 05, 2008
(Please excuse the recycled bits.  The 7-month-old is still absorbing most of my blogging time (along with sleeping time, dating time, playing time, cleaning time, working time, etc...)) A question came up on the ntdev mailing list about why