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:
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.
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.
> 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 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?