Trouble sending SCSI IRP on Windows Vista

I have a lower filter driver on the HDD stack. I need to issue new
IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming IRP
request. My driver works well on W2k and XP but BSOD’s on Windows Vista
when I try to issue an IRP_MJ_SCSI via the IoBuildSynchronousFsdRequest.

Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from the
context of a IRP_MJ_SCSI handler) or do I have to use
IoBuildAsynchronousFsdRequest and mark the current IRP pending while I issue
my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never heard
otherwise) but a dev mentioned that I should use
IoBuildAsynchronousFsdRequest for Vista. I haven’t found any documentation
that supports his idea. Anybody konw one way or the other?

Thanks.

You can’t do synchronous I/O in an IRP_MJ_SCSI handler. Since it can be
invoked at dispatch level (and commonly is) you can only do asynch I/O.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Thursday, May 18, 2006 8:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trouble sending SCSI IRP on Windows Vista

I have a lower filter driver on the HDD stack. I need to issue new
IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
IRP request. My driver works well on W2k and XP but BSOD’s on Windows
Vista when I try to issue an IRP_MJ_SCSI via the
IoBuildSynchronousFsdRequest.

Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the context of a IRP_MJ_SCSI handler) or do I have to use
IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
heard
otherwise) but a dev mentioned that I should use
IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
documentation that supports his idea. Anybody konw one way or the
other?

Thanks.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Can you recommend any sample code in the DDK to show how to set an irp
pending and issue an async irp?

“Peter Wieland” wrote in message
news:xxxxx@ntdev…
You can’t do synchronous I/O in an IRP_MJ_SCSI handler. Since it can be
invoked at dispatch level (and commonly is) you can only do asynch I/O.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Thursday, May 18, 2006 8:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trouble sending SCSI IRP on Windows Vista

I have a lower filter driver on the HDD stack. I need to issue new
IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
IRP request. My driver works well on W2k and XP but BSOD’s on Windows
Vista when I try to issue an IRP_MJ_SCSI via the
IoBuildSynchronousFsdRequest.

Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the context of a IRP_MJ_SCSI handler) or do I have to use
IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
heard
otherwise) but a dev mentioned that I should use
IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
documentation that supports his idea. Anybody konw one way or the
other?

Thanks.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Use IoAllocateIrp to allocate an IRP, fill in the arguments for the
target driver, set a completion routine, and call the driver. Make sure
you specify the correct stack size, using the StackSize field of the
device object you intend to target.

PIRP Irp;
PIO_STACK_LOCATION Ios;

Irp = IoAllocateIrp(TargetDeviceObject->StackSize, FALSE);
if (Irp == NULL) { … }

// Set up call stack for next driver.
// This part completely depends on what kind of IRP you are submitting.
Ios = IoGetNextIrpStackLocation(Irp);
Ios->MajorFunction = IRP_MJ_DEVICE_CONTROL; // or whatever
Ios->MinorFunction = 0;
Ios->Parameters.DeviceIoControl.IoControlCode = …;
Ios->Parameters.DeviceIoControl.Xxx = etc.;
(fill in other parameter fields)

IoSetCompletionRoutine(Irp, MyIrpCompletionHandler);
Status = IoCallDriver(TargetDeviceObject, Irp);

Note: As the initiator of an IRP, you don’t set it pending. If anyone
sets it pending, it’s one of the drivers that processes the IRP, not the
initiator.

Also, you should not assume that the NTSTATUS value you get back from
IoCallDriver is the right value to return from your own IRP dispatch
routine.

You’ll also need to consider whether you need to use
IoSetCompletionRoutine or IoSetCompletionRoutineEx. The Ex version
handles a dangerous race condition for you (driver unload before I/O
completion routine returns to caller), but is not always necessary. In
this case, it probably *IS* necessary.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Friday, May 19, 2006 10:14 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Can you recommend any sample code in the DDK to show how to set an irp
pending and issue an async irp?

“Peter Wieland” wrote in message
news:xxxxx@ntdev…
You can’t do synchronous I/O in an IRP_MJ_SCSI handler. Since it can be
invoked at dispatch level (and commonly is) you can only do asynch I/O.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Thursday, May 18, 2006 8:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trouble sending SCSI IRP on Windows Vista

I have a lower filter driver on the HDD stack. I need to issue new
IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
IRP request. My driver works well on W2k and XP but BSOD’s on Windows
Vista when I try to issue an IRP_MJ_SCSI via the
IoBuildSynchronousFsdRequest.

Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the context of a IRP_MJ_SCSI handler) or do I have to use
IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
heard
otherwise) but a dev mentioned that I should use
IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
documentation that supports his idea. Anybody konw one way or the
other?

Thanks.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Note that IoSetCompletionRoutineEx can return !NT_SUCCESS and you must
check for failure and complete the original irp if you can’t set the
completion routine

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Arlie Davis
Sent: Friday, May 19, 2006 10:49 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Trouble sending SCSI IRP on Windows Vista

Use IoAllocateIrp to allocate an IRP, fill in the arguments for the
target driver, set a completion routine, and call the driver. Make sure
you specify the correct stack size, using the StackSize field of the
device object you intend to target.

PIRP Irp;
PIO_STACK_LOCATION Ios;

Irp = IoAllocateIrp(TargetDeviceObject->StackSize, FALSE);
if (Irp == NULL) { … }

// Set up call stack for next driver.
// This part completely depends on what kind of IRP you are submitting.
Ios = IoGetNextIrpStackLocation(Irp);
Ios->MajorFunction = IRP_MJ_DEVICE_CONTROL; // or whatever
Ios->MinorFunction = 0;
Ios->Parameters.DeviceIoControl.IoControlCode = …;
Ios->Parameters.DeviceIoControl.Xxx = etc.;
(fill in other parameter fields)

IoSetCompletionRoutine(Irp, MyIrpCompletionHandler);
Status = IoCallDriver(TargetDeviceObject, Irp);

Note: As the initiator of an IRP, you don’t set it pending. If anyone
sets it pending, it’s one of the drivers that processes the IRP, not the
initiator.

Also, you should not assume that the NTSTATUS value you get back from
IoCallDriver is the right value to return from your own IRP dispatch
routine.

You’ll also need to consider whether you need to use
IoSetCompletionRoutine or IoSetCompletionRoutineEx. The Ex version
handles a dangerous race condition for you (driver unload before I/O
completion routine returns to caller), but is not always necessary. In
this case, it probably *IS* necessary.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Friday, May 19, 2006 10:14 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Can you recommend any sample code in the DDK to show how to set an irp
pending and issue an async irp?

“Peter Wieland” wrote in message
news:xxxxx@ntdev…
You can’t do synchronous I/O in an IRP_MJ_SCSI handler. Since it can be
invoked at dispatch level (and commonly is) you can only do asynch I/O.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Thursday, May 18, 2006 8:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trouble sending SCSI IRP on Windows Vista

I have a lower filter driver on the HDD stack. I need to issue new
IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
IRP request. My driver works well on W2k and XP but BSOD’s on Windows
Vista when I try to issue an IRP_MJ_SCSI via the
IoBuildSynchronousFsdRequest.

Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the context of a IRP_MJ_SCSI handler) or do I have to use
IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
heard
otherwise) but a dev mentioned that I should use
IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
documentation that supports his idea. Anybody konw one way or the
other?

Thanks.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Great thanks. The only piece of this puzzle that I’m not able to visualize
is how to reset the original IRP that I set pending to “unpending” and have
the original IRP complete down to the lower drivers. Do I need to save the
original IRP from my handler in the context pointer that I send to my
completion routine so I can call IoCallDriver() from my completion routine?
That seems reasonable…just wonder if I’m over-simplifiing and creating a
poor design.

Thanks!

“Arlie Davis” wrote in message news:xxxxx@ntdev…
Use IoAllocateIrp to allocate an IRP, fill in the arguments for the
target driver, set a completion routine, and call the driver. Make sure
you specify the correct stack size, using the StackSize field of the
device object you intend to target.

PIRP Irp;
PIO_STACK_LOCATION Ios;

Irp = IoAllocateIrp(TargetDeviceObject->StackSize, FALSE);
if (Irp == NULL) { … }

// Set up call stack for next driver.
// This part completely depends on what kind of IRP you are submitting.
Ios = IoGetNextIrpStackLocation(Irp);
Ios->MajorFunction = IRP_MJ_DEVICE_CONTROL; // or whatever
Ios->MinorFunction = 0;
Ios->Parameters.DeviceIoControl.IoControlCode = …;
Ios->Parameters.DeviceIoControl.Xxx = etc.;
(fill in other parameter fields)

IoSetCompletionRoutine(Irp, MyIrpCompletionHandler);
Status = IoCallDriver(TargetDeviceObject, Irp);

Note: As the initiator of an IRP, you don’t set it pending. If anyone
sets it pending, it’s one of the drivers that processes the IRP, not the
initiator.

Also, you should not assume that the NTSTATUS value you get back from
IoCallDriver is the right value to return from your own IRP dispatch
routine.

You’ll also need to consider whether you need to use
IoSetCompletionRoutine or IoSetCompletionRoutineEx. The Ex version
handles a dangerous race condition for you (driver unload before I/O
completion routine returns to caller), but is not always necessary. In
this case, it probably IS necessary.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Friday, May 19, 2006 10:14 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Can you recommend any sample code in the DDK to show how to set an irp
pending and issue an async irp?

“Peter Wieland” wrote in message
news:xxxxx@ntdev…
You can’t do synchronous I/O in an IRP_MJ_SCSI handler. Since it can be
invoked at dispatch level (and commonly is) you can only do asynch I/O.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Thursday, May 18, 2006 8:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trouble sending SCSI IRP on Windows Vista

I have a lower filter driver on the HDD stack. I need to issue new
IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
IRP request. My driver works well on W2k and XP but BSOD’s on Windows
Vista when I try to issue an IRP_MJ_SCSI via the
IoBuildSynchronousFsdRequest.

Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the context of a IRP_MJ_SCSI handler) or do I have to use
IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
heard
otherwise) but a dev mentioned that I should use
IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
documentation that supports his idea. Anybody konw one way or the
other?

Thanks.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

> Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from the

context of a IRP_MJ_SCSI handler)

No. The thread context is not known there, and you can be on DISPATCH_LEVEL.

or do I have to use
IoBuildAsynchronousFsdRequest and

Yes, or IoAllocateIrp.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Once an irp is marked pending, there is no unmark. You either send it
down the stack or complete it later. In your scenario, saving the
original irp as the context for the completion routine and then
processing the original irp in the completion routine is the right thing
to do.

d

– I can spell, I just can’t type.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Friday, May 19, 2006 11:06 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Great thanks. The only piece of this puzzle that I’m not able to
visualize is how to reset the original IRP that I set pending to
“unpending” and have the original IRP complete down to the lower
drivers. Do I need to save the original IRP from my handler in the
context pointer that I send to my completion routine so I can call
IoCallDriver() from my completion routine?
That seems reasonable…just wonder if I’m over-simplifiing and creating
a poor design.

Thanks!

“Arlie Davis” wrote in message
news:xxxxx@ntdev…
Use IoAllocateIrp to allocate an IRP, fill in the arguments for the
target driver, set a completion routine, and call the driver. Make sure
you specify the correct stack size, using the StackSize field of the
device object you intend to target.

PIRP Irp;
PIO_STACK_LOCATION Ios;

Irp = IoAllocateIrp(TargetDeviceObject->StackSize, FALSE); if (Irp ==
NULL) { … }

// Set up call stack for next driver.
// This part completely depends on what kind of IRP you are submitting.
Ios = IoGetNextIrpStackLocation(Irp);
Ios->MajorFunction = IRP_MJ_DEVICE_CONTROL; // or whatever MinorFunction

Ios->= 0; Parameters.DeviceIoControl.IoControlCode = …;
Ios->Parameters.DeviceIoControl.Xxx = etc.;
(fill in other parameter fields)

IoSetCompletionRoutine(Irp, MyIrpCompletionHandler); Status =
IoCallDriver(TargetDeviceObject, Irp);

Note: As the initiator of an IRP, you don’t set it pending. If anyone
sets it pending, it’s one of the drivers that processes the IRP, not the
initiator.

Also, you should not assume that the NTSTATUS value you get back from
IoCallDriver is the right value to return from your own IRP dispatch
routine.

You’ll also need to consider whether you need to use
IoSetCompletionRoutine or IoSetCompletionRoutineEx. The Ex version
handles a dangerous race condition for you (driver unload before I/O
completion routine returns to caller), but is not always necessary. In
this case, it probably IS necessary.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Friday, May 19, 2006 10:14 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Can you recommend any sample code in the DDK to show how to set an irp
pending and issue an async irp?

“Peter Wieland” wrote in message
news:xxxxx@ntdev…
You can’t do synchronous I/O in an IRP_MJ_SCSI handler. Since it can be
invoked at dispatch level (and commonly is) you can only do asynch I/O.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Thursday, May 18, 2006 8:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trouble sending SCSI IRP on Windows Vista

I have a lower filter driver on the HDD stack. I need to issue new
IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
IRP request. My driver works well on W2k and XP but BSOD’s on Windows
Vista when I try to issue an IRP_MJ_SCSI via the
IoBuildSynchronousFsdRequest.

Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the context of a IRP_MJ_SCSI handler) or do I have to use
IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
heard
otherwise) but a dev mentioned that I should use
IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
documentation that supports his idea. Anybody konw one way or the
other?

Thanks.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

I’ve decided to create WorkItems from my IRP_MJ_SCSI dispatch handler to
issue new IRPs. This seems to work for a while until I eventually get a
bsod with one of the lovely looking stacks that doesn’t initially appear to
show anything obvious. Before I dig in and figure out this bsod I wanted to
know from you driver gurus if this is even a valid design. Here’s what I’m
doing:

  1. I receive an IRP_MJ_SCSI in my dispatch handler.
  2. In my dispatch handler I create a WorkItem with IoQueueWorkItem while
    saving the original IRP (as passed to my dispatch handler) in a context
    pointer which is sent to the WorkItem
  3. Finally, in my dispatch handler I set the IRP pending and return
    STATUS_PENDING
  4. Then, my WorkItem gets called and I issue some new irps to my lower
    driver then I complete the original IRP which was saved in the WorkItem
    context and exit the workitem function (I assume at this point the original
    IRP will be completed by the io manger)

Does this seem like a valid approach? I appreciate any input. Thanks!

Here’s how I complete the IRP within my workitem function:

VOID MyWorkItemCallback(PDEVICE_OBJECT DeviceObject, PVOID Context)
{
// get the original IRP saved from the dispatch

PIRP Irp = (PIRP)Context;

// do stuff at passive level here

// complete the original IRP saved from the MJ_SCSI dispatch
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

}

Here’s how I mark the irp pending in my SCSI dispatch handler:
NTSTATUS

DispatchScsi(

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp

)

{


// mark this irp as pending and let the work item complete the IRP after we
finish issueing our additional IRP’s

IoMarkIrpPending(Irp);

return STATUS_PENDING;

}

“Fred” wrote in message news:xxxxx@ntdev…
>I have a lower filter driver on the HDD stack. I need to issue new
>IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
>IRP request. My driver works well on W2k and XP but BSOD’s on Windows
>Vista when I try to issue an IRP_MJ_SCSI via the
>IoBuildSynchronousFsdRequest.
>
> Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from the
> context of a IRP_MJ_SCSI handler) or do I have to use
> IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
> issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
> heard otherwise) but a dev mentioned that I should use
> IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
> documentation that supports his idea. Anybody konw one way or the other?
>
> Thanks.
>
>

I have something to add to the below message of Arlie’s, namely the data
buffer management.
You must provide some data either to Irp->AssociatedIrp.SystemBuffer or to
Irp->MdlAddress (build and fill a MDL here).
More so, you must set Irp->RequestorMode. Namely, if the buffer is in user
mode, then set Irp->RequestorMode to UserMode, otherwise, to KernelMode.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: “Arlie Davis”
To: “Windows System Software Devs Interest List”
Sent: Friday, May 19, 2006 9:48 PM
Subject: RE: [ntdev] Trouble sending SCSI IRP on Windows Vista

Use IoAllocateIrp to allocate an IRP, fill in the arguments for the
target driver, set a completion routine, and call the driver. Make sure
you specify the correct stack size, using the StackSize field of the
device object you intend to target.

PIRP Irp;
PIO_STACK_LOCATION Ios;

Irp = IoAllocateIrp(TargetDeviceObject->StackSize, FALSE);
if (Irp == NULL) { … }

// Set up call stack for next driver.
// This part completely depends on what kind of IRP you are submitting.
Ios = IoGetNextIrpStackLocation(Irp);
Ios->MajorFunction = IRP_MJ_DEVICE_CONTROL; // or whatever
Ios->MinorFunction = 0;
Ios->Parameters.DeviceIoControl.IoControlCode = …;
Ios->Parameters.DeviceIoControl.Xxx = etc.;
(fill in other parameter fields)

IoSetCompletionRoutine(Irp, MyIrpCompletionHandler);
Status = IoCallDriver(TargetDeviceObject, Irp);

Note: As the initiator of an IRP, you don’t set it pending. If anyone
sets it pending, it’s one of the drivers that processes the IRP, not the
initiator.

Also, you should not assume that the NTSTATUS value you get back from
IoCallDriver is the right value to return from your own IRP dispatch
routine.

You’ll also need to consider whether you need to use
IoSetCompletionRoutine or IoSetCompletionRoutineEx. The Ex version
handles a dangerous race condition for you (driver unload before I/O
completion routine returns to caller), but is not always necessary. In
this case, it probably IS necessary.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Friday, May 19, 2006 10:14 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Can you recommend any sample code in the DDK to show how to set an irp
pending and issue an async irp?

“Peter Wieland” wrote in message
news:xxxxx@ntdev…
You can’t do synchronous I/O in an IRP_MJ_SCSI handler. Since it can be
invoked at dispatch level (and commonly is) you can only do asynch I/O.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Thursday, May 18, 2006 8:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trouble sending SCSI IRP on Windows Vista

I have a lower filter driver on the HDD stack. I need to issue new
IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
IRP request. My driver works well on W2k and XP but BSOD’s on Windows
Vista when I try to issue an IRP_MJ_SCSI via the
IoBuildSynchronousFsdRequest.

Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the context of a IRP_MJ_SCSI handler) or do I have to use
IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
heard
otherwise) but a dev mentioned that I should use
IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
documentation that supports his idea. Anybody konw one way or the
other?

Thanks.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

The completion routine of the “slave” IRP will call IoCompleteRequest on
the “master” IRP.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: “Fred”
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Friday, May 19, 2006 10:05 PM
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

> Great thanks. The only piece of this puzzle that I’m not able to visualize
> is how to reset the original IRP that I set pending to “unpending” and have
> the original IRP complete down to the lower drivers. Do I need to save the
> original IRP from my handler in the context pointer that I send to my
> completion routine so I can call IoCallDriver() from my completion routine?
> That seems reasonable…just wonder if I’m over-simplifiing and creating a
> poor design.
>
> Thanks!
>
>
> “Arlie Davis” wrote in message news:xxxxx@ntdev…
> Use IoAllocateIrp to allocate an IRP, fill in the arguments for the
> target driver, set a completion routine, and call the driver. Make sure
> you specify the correct stack size, using the StackSize field of the
> device object you intend to target.
>
>
> PIRP Irp;
> PIO_STACK_LOCATION Ios;
>
> Irp = IoAllocateIrp(TargetDeviceObject->StackSize, FALSE);
> if (Irp == NULL) { … }
>
> // Set up call stack for next driver.
> // This part completely depends on what kind of IRP you are submitting.
> Ios = IoGetNextIrpStackLocation(Irp);
> Ios->MajorFunction = IRP_MJ_DEVICE_CONTROL; // or whatever
> Ios->MinorFunction = 0;
> Ios->Parameters.DeviceIoControl.IoControlCode = …;
> Ios->Parameters.DeviceIoControl.Xxx = etc.;
> (fill in other parameter fields)
>
> IoSetCompletionRoutine(Irp, MyIrpCompletionHandler);
> Status = IoCallDriver(TargetDeviceObject, Irp);
>
>
> Note: As the initiator of an IRP, you don’t set it pending. If anyone
> sets it pending, it’s one of the drivers that processes the IRP, not the
> initiator.
>
> Also, you should not assume that the NTSTATUS value you get back from
> IoCallDriver is the right value to return from your own IRP dispatch
> routine.
>
> You’ll also need to consider whether you need to use
> IoSetCompletionRoutine or IoSetCompletionRoutineEx. The Ex version
> handles a dangerous race condition for you (driver unload before I/O
> completion routine returns to caller), but is not always necessary. In
> this case, it probably IS necessary.
>
> – arlie
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Fred
> Sent: Friday, May 19, 2006 10:14 AM
> To: Windows System Software Devs Interest List
> Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista
>
> Can you recommend any sample code in the DDK to show how to set an irp
> pending and issue an async irp?
>
> “Peter Wieland” wrote in message
> news:xxxxx@ntdev…
> You can’t do synchronous I/O in an IRP_MJ_SCSI handler. Since it can be
> invoked at dispatch level (and commonly is) you can only do asynch I/O.
>
> -p
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Fred
> Sent: Thursday, May 18, 2006 8:52 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] Trouble sending SCSI IRP on Windows Vista
>
> I have a lower filter driver on the HDD stack. I need to issue new
> IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
> IRP request. My driver works well on W2k and XP but BSOD’s on Windows
> Vista when I try to issue an IRP_MJ_SCSI via the
> IoBuildSynchronousFsdRequest.
>
> Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
> the context of a IRP_MJ_SCSI handler) or do I have to use
> IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
> issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
> heard
> otherwise) but a dev mentioned that I should use
> IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
> documentation that supports his idea. Anybody konw one way or the
> other?
>
> Thanks.
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Thanks for all the replies. I was able to get the WorkItem calls at passive
level working. I’m not sure if it was that last beer or the late hour but I
was calling IoCompleteRequest() instead of IoCallDriver() to pass down the
original IRP. But, hey, in my defense both calls do start with “IoC”
doink! LOL

As always, this is the best forum to bounce ideas around with some of the
great dev minds. Thanks!

“Fred” wrote in message news:xxxxx@ntdev…
>I have a lower filter driver on the HDD stack. I need to issue new
>IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each incoming
>IRP request. My driver works well on W2k and XP but BSOD’s on Windows
>Vista when I try to issue an IRP_MJ_SCSI via the
>IoBuildSynchronousFsdRequest.
>
> Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from the
> context of a IRP_MJ_SCSI handler) or do I have to use
> IoBuildAsynchronousFsdRequest and mark the current IRP pending while I
> issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay (never
> heard otherwise) but a dev mentioned that I should use
> IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
> documentation that supports his idea. Anybody konw one way or the other?
>
> Thanks.
>
>

I don’t think this will work for paging i/o. your work item can be
stuck behind other work items which are also doing paging i/o, in which
case you might deadlock and Mm will eventually bugcheck. Why do you
need to send the i/o from a work item? What you are doing that requires
passive level? Waiting for the i/o that you send to complete?

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Saturday, May 20, 2006 1:42 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Thanks for all the replies. I was able to get the WorkItem calls at
passive
level working. I’m not sure if it was that last beer or the late hour
but I
was calling IoCompleteRequest() instead of IoCallDriver() to pass down
the
original IRP. But, hey, in my defense both calls do start with “IoC”
doink! LOL

As always, this is the best forum to bounce ideas around with some of
the
great dev minds. Thanks!

“Fred” wrote in message news:xxxxx@ntdev…
>I have a lower filter driver on the HDD stack. I need to issue new
>IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each
incoming
>IRP request. My driver works well on W2k and XP but BSOD’s on Windows
>Vista when I try to issue an IRP_MJ_SCSI via the
>IoBuildSynchronousFsdRequest.
>
> Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the
> context of a IRP_MJ_SCSI handler) or do I have to use
> IoBuildAsynchronousFsdRequest and mark the current IRP pending while I

> issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay
(never
> heard otherwise) but a dev mentioned that I should use
> IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
> documentation that supports his idea. Anybody konw one way or the
other?
>
> Thanks.
>
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Yes, I need to block the incomming IRP, issue one or more of my own IRPs,
wait for my IRPs to complete, and then let the original IRP pass-through.
The passive level is used to send my IRPs and complete the original IRP.

“Doron Holan” wrote in message
news:xxxxx@ntdev…
I don’t think this will work for paging i/o. your work item can be
stuck behind other work items which are also doing paging i/o, in which
case you might deadlock and Mm will eventually bugcheck. Why do you
need to send the i/o from a work item? What you are doing that requires
passive level? Waiting for the i/o that you send to complete?

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Saturday, May 20, 2006 1:42 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Thanks for all the replies. I was able to get the WorkItem calls at
passive
level working. I’m not sure if it was that last beer or the late hour
but I
was calling IoCompleteRequest() instead of IoCallDriver() to pass down
the
original IRP. But, hey, in my defense both calls do start with “IoC”
doink! LOL

As always, this is the best forum to bounce ideas around with some of
the
great dev minds. Thanks!

“Fred” wrote in message news:xxxxx@ntdev…
>I have a lower filter driver on the HDD stack. I need to issue new
>IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each
incoming
>IRP request. My driver works well on W2k and XP but BSOD’s on Windows
>Vista when I try to issue an IRP_MJ_SCSI via the
>IoBuildSynchronousFsdRequest.
>
> Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the
> context of a IRP_MJ_SCSI handler) or do I have to use
> IoBuildAsynchronousFsdRequest and mark the current IRP pending while I

> issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay
(never
> heard otherwise) but a dev mentioned that I should use
> IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
> documentation that supports his idea. Anybody konw one way or the
other?
>
> Thanks.
>
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

You can do all of this asynchronously. You move to the next state in
your state machine the irp’s completion routine, where you either issue
new i/o or deal with the original i/o. unless you need to synchronously
wait on something, you are better of doing everything async.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Saturday, May 20, 2006 4:45 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Yes, I need to block the incomming IRP, issue one or more of my own
IRPs,
wait for my IRPs to complete, and then let the original IRP
pass-through.
The passive level is used to send my IRPs and complete the original IRP.

“Doron Holan” wrote in message
news:xxxxx@ntdev…
I don’t think this will work for paging i/o. your work item can be
stuck behind other work items which are also doing paging i/o, in which
case you might deadlock and Mm will eventually bugcheck. Why do you
need to send the i/o from a work item? What you are doing that requires
passive level? Waiting for the i/o that you send to complete?

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Saturday, May 20, 2006 1:42 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Thanks for all the replies. I was able to get the WorkItem calls at
passive
level working. I’m not sure if it was that last beer or the late hour
but I
was calling IoCompleteRequest() instead of IoCallDriver() to pass down
the
original IRP. But, hey, in my defense both calls do start with “IoC”
doink! LOL

As always, this is the best forum to bounce ideas around with some of
the
great dev minds. Thanks!

“Fred” wrote in message news:xxxxx@ntdev…
>I have a lower filter driver on the HDD stack. I need to issue new
>IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each
incoming
>IRP request. My driver works well on W2k and XP but BSOD’s on Windows
>Vista when I try to issue an IRP_MJ_SCSI via the
>IoBuildSynchronousFsdRequest.
>
> Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the
> context of a IRP_MJ_SCSI handler) or do I have to use
> IoBuildAsynchronousFsdRequest and mark the current IRP pending while I

> issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay
(never
> heard otherwise) but a dev mentioned that I should use
> IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
> documentation that supports his idea. Anybody konw one way or the
other?
>
> Thanks.
>
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

> 2. In my dispatch handler I create a WorkItem with IoQueueWorkItem while

saving the original IRP (as passed to my dispatch handler) in a context
pointer which is sent to the WorkItem
3. Finally, in my dispatch handler I set the IRP pending and return
STATUS_PENDING

First IoMarkIrpPending, then create a work item, then return STATUS_PENDING.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

This is very likely to fail at some point in the future when you aren’t
looking. As Doron points out, workitems can get blocked at which point
the entire system will back-up until the Memory Manager eventually
resets the system because it can’t make any forward progress.

Not to mention the fact that you’re going to be introducing
memory-allocation failure errors into an I/O path that needs to be able
to run even when memory isn’t available.

Doron wasn’t asking if you’re sending your I/O at passive level. He was
asking what it is your driver does that requires you to be at passive
level? Whatever it is, you’ll need to fix it if you’d like a functional
storage driver.

Just do the work asynchronously and you’ll be fine.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Saturday, May 20, 2006 4:45 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Yes, I need to block the incomming IRP, issue one or more of my own
IRPs, wait for my IRPs to complete, and then let the original IRP
pass-through.
The passive level is used to send my IRPs and complete the original IRP.

“Doron Holan” wrote in message
news:xxxxx@ntdev…
I don’t think this will work for paging i/o. your work item can be
stuck behind other work items which are also doing paging i/o, in which
case you might deadlock and Mm will eventually bugcheck. Why do you
need to send the i/o from a work item? What you are doing that requires
passive level? Waiting for the i/o that you send to complete?

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Fred
Sent: Saturday, May 20, 2006 1:42 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Trouble sending SCSI IRP on Windows Vista

Thanks for all the replies. I was able to get the WorkItem calls at
passive level working. I’m not sure if it was that last beer or the
late hour but I was calling IoCompleteRequest() instead of
IoCallDriver() to pass down the original IRP. But, hey, in my defense
both calls do start with “IoC”
doink! LOL

As always, this is the best forum to bounce ideas around with some of
the great dev minds. Thanks!

“Fred” wrote in message news:xxxxx@ntdev…
>I have a lower filter driver on the HDD stack. I need to issue new
>IRP_MJ_SCSI IRP’s downstream in my IRP_MJ_SCSI handler for each
incoming
>IRP request. My driver works well on W2k and XP but BSOD’s on Windows
>Vista when I try to issue an IRP_MJ_SCSI via the
>IoBuildSynchronousFsdRequest.
>
> Is it legal to issue a new IRP via IoBuildSynchronousFsdRequest (from
the
> context of a IRP_MJ_SCSI handler) or do I have to use
> IoBuildAsynchronousFsdRequest and mark the current IRP pending while I

> issue my new IRP? I assume IoBuildSynchronousFsdRequest is okay
(never
> heard otherwise) but a dev mentioned that I should use
> IoBuildAsynchronousFsdRequest for Vista. I haven’t found any
> documentation that supports his idea. Anybody konw one way or the
other?
>
> Thanks.
>
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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