Modifying/Adding IO_STACK_LOCATION

Hi everyone,
I’m writing a USB filter driver and am trying to modify/append some of the data in the SRB. I am currently creating a new IO_STACK_LOCATION and trying to use WdfRequestWdmFormatUsingStackLocation but the driver crashes (I don’t have useful debug information at the time, sorry). I copy all of the unchanged data from the current IO_STACK_LOCATION. Any suggestions would be most helpful! Thanks.

~Jamey

Post your code

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: xxxxx@gmail.com
Sent: Wednesday, August 26, 2009 6:18 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Modifying/Adding IO_STACK_LOCATION

Hi everyone,
I’m writing a USB filter driver and am trying to modify/append some of the data in the SRB. I am currently creating a new IO_STACK_LOCATION and trying to use WdfRequestWdmFormatUsingStackLocation but the driver crashes (I don’t have useful debug information at the time, sorry). I copy all of the unchanged data from the current IO_STACK_LOCATION. Any suggestions would be most helpful! Thanks.

~Jamey


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

VOID
WdfFltrInternalDeviceControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
) {
WDFFLTR_REQUEST requestEntry;
PWDFFLTR_DEVICE_CONTROL_REQUEST deviceControlRequest;
PIRP deviceControlIrp;
PIO_STACK_LOCATION deviceIoStackLocation;
USHORT srbSize = 0;
UCHAR cdbCommand = 0;
WDF_REQUEST_SEND_OPTIONS options;
PDEVICE_CONTEXT devCont;
NTSTATUS status;

deviceControlIrp = WdfRequestWdmGetIrp(Request);

deviceIoStackLocation = IoGetCurrentIrpStackLocation(deviceControlIrp);
srbSize = deviceIoStackLocation->Parameters.Scsi.Srb->Length;
cdbCommand = deviceIoStackLocation->Parameters.Scsi.Srb->Cdb[0];

if((INT)cdbCommand == 42)
{
RtlZeroMemory(&stack, sizeof(stack));
stack.MajorFunction = deviceIoStackLocation->MajorFunction;
stack.MinorFunction = deviceIoStackLocation->MinorFunction;
RtlCopyMemory(&stack.Flags, &deviceIoStackLocation->Flags, sizeof(UCHAR));
RtlCopyMemory(&stack.Control, &deviceIoStackLocation->Control, sizeof(UCHAR));
RtlCopyMemory(&stack.Parameters.Scsi.Srb, &deviceIoStackLocation->Parameters.Scsi.Srb, sizeof(SCSI_REQUEST_BLOCK));
RtlFillMemory(&stack.Parameters.Scsi.key, sizeof(UCHAR), ‘#’);
RtlCopyMemory(&stack.DeviceObject, deviceIoStackLocation->DeviceObject, sizeof(PDEVICE_OBJECT));
RtlCopyMemory(&stack.FileObject, deviceIoStackLocation->FileObject, sizeof(PFILE_OBJECT));

devCont = WdfFltrGetDeviceContext(WdfIoQueueGetDevice(Queue));
ASSERT(IS_DEVICE_CONTEXT(devCont));
WdfRequestWdmFormatUsingStackLocation(Request, (IO_STACK_LOCATION*)&stack);
WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

if(!WdfRequestSend(Request, devCont->TArgetToSendRequestsTo, &options))
{
status = WdfRequestGetStatus(Request);
WdfRequestComplete(Request, status);
}

return;
}

This is missing the declaration and initialization of the variable “stack”, which it seems to me is rather central to what you’re trying to accomplish.

Is there some reason you’re not just using the I/O Stack Location in the incoming IRP? The only field I see you changing is “Parameters.Scsi.key”

Peter
OSR

Sorry I missed that line it was:
IO_STACK_LOCATION_WKEY stack;

I modified the orginal IO_STACK_LOCATION struct to include the Scsi parameter to include the key variable. This is why I’m not using the original stack location. If there is an easy way to add this to the existing one that would be much better. Thanks

~Jamey

Try this

deviceControlIrp = WdfRequestWdmGetIrp(Request);
IoCopyCurrentIrpStackLocationToNext(deviceControlIrp);

nextIoStackLocation = IoGetNextIrpStackLocation(deviceControlIrp);
nextIoStackLocation->… Key =…;

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: xxxxx@gmail.com
Sent: Wednesday, August 26, 2009 7:43 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Modifying/Adding IO_STACK_LOCATION

Sorry I missed that line it was:
IO_STACK_LOCATION_WKEY stack;

I modified the orginal IO_STACK_LOCATION struct to include the Scsi parameter to include the key variable. This is why I’m not using the original stack location. If there is an easy way to add this to the existing one that would be much better. Thanks

~Jamey


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Huh??

IO_STACK_LOCATION is defined by the system. You can’t change it’s layout.

Or, are you saying that you “modified the oritinal IO_STACK_LOCATION struct to” define an existing field to be NAMED “Key”? In which case… which field are you using??

Peter
OSR

I basically copied the IO_STACK_LOCATION struct and added the key field to it (I renamed it as well). This is basically the whole problem. I want add data to the IRP that I’m filtering but I want to add it in a specific spot so that my USB device picks it up.

See my previous post: “IO_STACK_LOCATION is defined by the system. You can’t change it’s layout.”

Please describe the problem you’re trying to solve… not the errors you’ve encountered in your attempt to solve it. It’s very likely that we can tell you how to solve your root problem once you’ve told us what it is.

Here. I’ll start you post for you:

“I have a filter driver in the USB stack, the purpose of which is to control and send additional information to my USB device (which is a specific model of a generic device supported by a standard Windows in-box driver). On receiving a xxxxxxx request, I want to yyyyyyyy. What’s the best way for me to do that, without modifying the standard Windows in-box drivers?”

Peter
OSR

James Drennan wrote:

I basically copied the IO_STACK_LOCATION struct and added the
key field to it (I renamed it as well).

Again, where’s Anton?? This guy is attempting to resize built-in structs???

xxxxx@gmail.com wrote:

VOID
WdfFltrInternalDeviceControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
) {
WDFFLTR_REQUEST requestEntry;
PWDFFLTR_DEVICE_CONTROL_REQUEST deviceControlRequest;
PIRP deviceControlIrp;
PIO_STACK_LOCATION deviceIoStackLocation;
USHORT srbSize = 0;
UCHAR cdbCommand = 0;
WDF_REQUEST_SEND_OPTIONS options;
PDEVICE_CONTEXT devCont;
NTSTATUS status;

deviceControlIrp = WdfRequestWdmGetIrp(Request);

deviceIoStackLocation = IoGetCurrentIrpStackLocation(deviceControlIrp);
srbSize = deviceIoStackLocation->Parameters.Scsi.Srb->Length;
cdbCommand = deviceIoStackLocation->Parameters.Scsi.Srb->Cdb[0];

if((INT)cdbCommand == 42)
{
RtlZeroMemory(&stack, sizeof(stack));

Where is stack defined?

stack.MajorFunction = deviceIoStackLocation->MajorFunction;
stack.MinorFunction = deviceIoStackLocation->MinorFunction;
RtlCopyMemory(&stack.Flags, &deviceIoStackLocation->Flags, sizeof(UCHAR));
RtlCopyMemory(&stack.Control, &deviceIoStackLocation->Control, sizeof(UCHAR));
RtlCopyMemory(&stack.Parameters.Scsi.Srb, &deviceIoStackLocation->Parameters.Scsi.Srb, sizeof(SCSI_REQUEST_BLOCK));
RtlFillMemory(&stack.Parameters.Scsi.key, sizeof(UCHAR), ‘#’);
RtlCopyMemory(&stack.DeviceObject, deviceIoStackLocation->DeviceObject, sizeof(PDEVICE_OBJECT));
RtlCopyMemory(&stack.FileObject, deviceIoStackLocation->FileObject, sizeof(PFILE_OBJECT));

I’m always fascinated to see code like this. What led you do it this
way, instead of:
stack.Flags = deviceIoStackLocation->Flags;
stack.Control = deviceIoStackLocation->Control;
stack.Parameters.Scsi.key = ‘#’;
stack.DeviceObject = deviceIoLocation->DeviceObject;
stack.FileObject = deviceIoLocation=>FileObject;

It’s amazing to me to think of incurring the overhead of a call to
RtlCopyMemory in lieu of moving one byte inline.

Or even:
stack = *deviceIoLocation;

As a side note, the Scsi part of the union in the IO_STACK_LOCATION only
uses one dword. Therefore, you could store your “key” in
Parameters.Others.Argument2, 3, or 4, without taking the dangerous step
of redefining the struct.

Or, if you must;

#define ScsiKey Others.Argument2

stack.Parameters.ScsiKey = ‘#’;


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim I tried it the way you have it (sans Rtl) originally but thought maybe the incoming IRP was off limits to direct access (I guess I was wrong).
If I were to put my “key” in the Parameters.Others.Argument2 would it show up or be transferred right behind the last part of the original Scsi srb? Thanks for the post!

~Jamey

xxxxx@gmail.com wrote:

Tim I tried it the way you have it (sans Rtl) originally but thought maybe the incoming IRP was off limits to direct access (I guess I was wrong).
If I were to put my “key” in the Parameters.Others.Argument2 would it show up or be transferred right behind the last part of the original Scsi srb? Thanks for the post!

Your code doesn’t touch the SRB. You’re just changing the IRP. The IRP
has a POINTER to the SRB, and your key (I presume) follows that pointer
in the IRP. It won’t affect the SRB itself.

If you want to add a field to the SRB, I think you have to allocate your
own memory (as sizeof(SRB)+4), copy the SRB into it, add your appendage,
and put that pointer in the IRP.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

As with so many similar questions, it’s not clear what the OP wants to accomplish.

OP: We can’t intelligently advise you if you won’t tell us what problem you’re trying to solve. Until you do that, everything else you get here (from me or from Tim) is purely a guess.

Peter
OSR

> Again, where’s Anton?? This guy is attempting to resize built-in structs???

Well, normally I just skip any thread that mentions WDF. However, now I see how much I miss, at least in terms of entertainment…

Anton Bassov

The goal is to add a byte(s) of data after the Srb (more specifically a byte or multiple bytes following the scsi cdb command block) on read/write requests that come down the USB stack. Does this clear up what I’m attempting to do? If not please let me know how I can clarify.

I have yet to try some of the above suggestions due to time but I appreciate them. I don’t believe I’m trying to resize built-in structs…I tried creating my own from the built-in ones and adding to them.

~Jamey

That doesn’t clear up much. How was modifying IRP stack locations
going to help with this?

Ignoring that, what has motivated you to try to redefine yet another
standard data structure, namely scsi request blocks?

You are engaged in a standard behavior here of posting your solutions
that don’t work to an unnamed problem. Try starting from the
beginning.

Having given you another useless lecture, did you notice that the Cdb
field is sized for 16 bytes? I have no idea what you are actually
doing, but if you only support 10 byte scsi commands for read and
write then you have 6 extra bytes there to mess with.

It is still the wrong approach.

Mark Roddy

On Thu, Aug 27, 2009 at 11:37 PM, wrote:
> The goal is to add a byte(s) of data after the Srb (more specifically a byte or multiple bytes following the scsi cdb command block) on read/write requests that come down the USB stack. ?Does this clear up what I’m attempting to do? ?If not please let me know how I can clarify.
>
> I have yet to try some of the above suggestions due to time but I appreciate them. ?I don’t believe I’m trying to resize built-in structs…I tried creating my own from the built-in ones and adding to them.
>
> ~Jamey
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

No. Seriously.

If we’re going to provide you meaningful help, you really need to go back and read what I said to you yesterday at about this time.

Don’t worry about the suggestions. Though we’re TRYing to help you, we’re all just guessing at what you’re trying to accomplish.

PLEASE: Tell us what the ROOT problem is that you’re trying to solve. “The goal is to add a byte(s) of data after the Srb” sounds like a SOLUTION you’re attempting. After all, simply adding a byte of data after the SRB in and of itself doesn’t cause anything to happen. Why “after the SRB”? Why not IN the SRB? When you add it, who’s supposed to know it’s there and interpret it?

You’re sort of posting “Please help me, the wings keep falling off my pig”… and we’re asking “ahhh… OK… why are you trying to put wings on a pig in the first place?”

Peter
OSR

xxxxx@gmail.com wrote:

The goal is to add a byte(s) of data after the Srb (more specifically a byte or multiple bytes following the scsi cdb command block) on read/write requests that come down the USB stack. Does this clear up what I’m attempting to do? If not please let me know how I can clarify.

I have yet to try some of the above suggestions due to time but I appreciate them. I don’t believe I’m trying to resize built-in structs…I tried creating my own from the built-in ones and adding to them.

Yes, but you modified the wrong one. If you want to add a byte to the
SRB, it doesn’t help to modify the IO_STACK_LOCATION.

If you want to add one byte to an SRB, you need to allocate a new SRB
one byte longer than the usual one and copy. So:

SCSI_REQUEST_BLOCK* pSrbNew = ExAllocatePool( NonPagedPool,
sizeof(SRB) + 1 );
*pSrbNew = *pOriginalSrb;
unsigned char * pMyExtension = (unsigned char *)(pSrbNew+1);
*pMyExtension = ‘#’;

Now you can replace the SRB in the IO_STACK_LOCATION with your pSrbNew.
You probably want to remember the address of the original SRB somewhere,
in case you need to return any fields. You also need to free the one
you allocated during your completion routine.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.