SCSI_PASS_THROUGH_DIRECT, Filter, IRQL_NOT_LESS_OR_EQUAL

Perhaps I’m not following the process correctly, however I was hoping to get some insight from the list.

I’ve developed a very simple DiskClass Filter driver that properly recognizes SCSI_PASS_THROUGH_DIRECT (READ_6, READ_10, READ_16) commands sent to a specific disk.

I then set a completion routine, in that completion routine I perform the following:


PVOID Buffer;
size_t outLen=0;

Buffer = ReadIrp->AssociatedIrp.SystemBuffer;
outLen = SCSILoc->Parameters.DeviceIoControl.OutputBufferLength;
pSPTD = (PSCSI_PASS_THROUGH_DIRECT)Buffer;

At this point I have a SCSI_PASS_THROUGH_DIRECT structure pointer. Part of my filter driver is to modify the buffer containing the response data, therefore I have been accessing it as follows:

(unsigned char *)pSPTD->DataBuffer

and

pSPTD->DataBufferLength

However what I’m finding is on Windows 7 (32bit) this results in a IRQL_NOT_LESS_OR_EQUAL when I attempt to access the contents of pSPTD->DataBuffer.

After much research it appears I’m trying to access a buffer I’m not allowed to access at Dispatch level… Does SPTI require some additional steps since direct requests are user buffers? Is there a simple step I am missing? Or is there something more to this. Or perhaps my logic is flawed. Any suggestions greatly appreciated.

Thanks!

You have two problems here, first this is a user space buffer that has
not been locked into memory, and second the address you are using is for
a specific process and the completion routine runs in an arbitrary
process context that may not have that as a valid address. You are
going to have to lock the buffer on the way down, put the kernel address
away for later use (for instance in a context structure) then release
the buffer on completion.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@agilerm.net” wrote in message
news:xxxxx@ntdev:

> Perhaps I’m not following the process correctly, however I was hoping to get some insight from the list.
>
> I’ve developed a very simple DiskClass Filter driver that properly recognizes SCSI_PASS_THROUGH_DIRECT (READ_6, READ_10, READ_16) commands sent to a specific disk.
>
> I then set a completion routine, in that completion routine I perform the following:
>
> …
> PVOID Buffer;
> size_t outLen=0;
> …
> Buffer = ReadIrp->AssociatedIrp.SystemBuffer;
> outLen = SCSILoc->Parameters.DeviceIoControl.OutputBufferLength;
> pSPTD = (PSCSI_PASS_THROUGH_DIRECT)Buffer;
>
> At this point I have a SCSI_PASS_THROUGH_DIRECT structure pointer. Part of my filter driver is to modify the buffer containing the response data, therefore I have been accessing it as follows:
>
> (unsigned char *)pSPTD->DataBuffer
>
> and
>
> pSPTD->DataBufferLength
>
> However what I’m finding is on Windows 7 (32bit) this results in a IRQL_NOT_LESS_OR_EQUAL when I attempt to access the contents of pSPTD->DataBuffer.
>
> After much research it appears I’m trying to access a buffer I’m not allowed to access at Dispatch level… Does SPTI require some additional steps since direct requests are user buffers? Is there a simple step I am missing? Or is there something more to this. Or perhaps my logic is flawed. Any suggestions greatly appreciated.
>
> Thanks!

Thanks Don! I assume I should use MmProbeAndLockPages to probe and lock the buffer, then MmGetSystemAddressForMdlSafe to use them, and MmUnlockPages to unlock them?

Is there an additional step I’m missing?

Thanks!

mms

> Is there an additional step I’m missing?

You need to distinguish whether the pointer and thus the pass through structure itself is in the 32-bit or 64-bit form.

Thanks!

Is this related to the INT_PTR vs PVOID (32 bit vs 64 bit pointer) in the SCSI_PASS_THROUGH_DIRECT structure? I’m afraid I’m not following you completely, how would you recommend I distinguish the two?