An IRP remains pending in upper driver, which was seen as successful in next lower driver

Hi All,

I am working on writing functional and upper filter WDM drivers for a
particular device on Windows 2k. The stack of drivers is used to connect
to the device and upload a file from it (beside other things).

A snapshot of code in the upper filter driver, which interacts with the
functional driver….

While (ReadMoreData == TRUE)
{
.
.
pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
MyUSBDriverDevice, MyBuffer, MY_USB_BUFFER_SIZE, &MyStartingOffset,
&MyReadEvent, &MyIoStatusBlock);

PIO_STACK_LOCATION nextStack;
nextStack = IoGetNextIrpStackLocation(pIrp);
nextStack->MajorFunction = IRP_MJ_READ;
nextStack->FileObject = pMyFileObject;
nextStack->FileObject->FsContext =MyUsbPipeInformation[1];
status = IoCallDriver(MyUSBDriverDevice, pIrp);

ResetEvent(MyReadEvent);
KeWaitForSingleObject(&MyReadEvent, &status, Executive, KernelMode,
FALSE, &MyDelay);

// note that theres is no completion routine as the Irp is synchjronous

if((pIrp->IoStatus->Status==0)
{
// success… hence read the data from Irp and send it to the application
}else
{
// continue the next iteraion
}
.
.

}

The problem scenario

It is observed by the application using this driver stack that sometimes
a packet of data is missing randomly.

On further investigation we found that the functional driver receives an
IRP with status (pIrp->IoStatus->Status) ‘successful’ for each and every
packet read from the device. This was verified with the help of the
sequence number carried by each packet. So we can conclude that the
functional driver receives all the packets read from the device.

For some packets ( which are reported missing by the application), the
IRP containing that packet has status ‘successful’ in the functional
driver, but the status of the same IRP is seen as ‘pending’ in the upper
filter driver.

As the upper filter driver sees the status of the Irp pending even after
waiting on the event associated with the IRP, it assumes that there is
nothing to be read and goes on to the next iteration to try and read from
the device, loosing a packet in the process.

This happens roughly 2 out of 5 times the application asks to upload a
file form the device. Sometimes up to 2-3 packets (out of about 400
packets) are reported missing.

HELP!!

Could somebody explain why the pIrp->IoStatus->Status differs for the
same Irp in two immediate drivers (even after using an event for
serialization)?

Rahul Jethlia wrote:

Could somebody explain why the pIrp->IoStatus->Status differs for the
same Irp in two immediate drivers (even after using an event for
serialization)?

Well, given that driverA directly calls driverB with IoCallDriver and
there are no intervening drivers, if you’re seeing a different
IoStatus.Status in the IRP sent from driverA to driverB, and driverB has
calle3d IoCompleteRequest on an IRP, only the following things can be true:

  1. DriverB changed the contents of IoStatus.Status after it has called
    IoCompleteRequest

  2. Another driver, (such as DriverA) has changed the contents of
    IoStatus.Status after DriverB has called IoCompleteRequest

  3. The IRP is being improperly serialized between the two drivers, and
    is being re-used after driverB calls IoCompleteRequest (this is clearly
    a specific case of item 2, above, but worthy of mention as it’s the most
    likely scenario).

Soooooo… Have you tracked these errant IRPs down and tried to observe
the problem using OSR’s (free) IRPTracker utility? If not, that’s your
first job.

Peter
OSR

A few problems:

  1. you reset the event after calling IoCallDriver. Since IoCallDriver
    can set the event immediately, you can potentially clear the event and
    wait forever. You should reset before the call to IoCallDriver

  2. once the event is set (ie the irp has completed), pIrp has been
    freed. You need to use MyIoStatusBlock.Status to get the returned
    status.

  3. when comparing the status, you should use NT_SUCCESSS(…), not ==
    0, since there are many NTSTATUS return values which indicate success
    which are not STATUS_SUCCESS.

  4. when formatting the next stack location, you don’t need to set
    MajorFunction, the IoBuild call did that for you. Also, I don’t
    understand you setting the FsContext field in the fileobject every time.
    Usually this is set by the owner of the fileobject in the stack during
    IRP_MJ_CREATE.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Rahul Jethlia
Sent: Tuesday, January 04, 2005 2:22 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] An IRP remains pending in upper driver, which was seen
as successful in next lower driver

Hi All,

I am working on writing functional and upper filter WDM drivers for a
particular device on Windows 2k. The stack of drivers is used to connect

to the device and upload a file from it (beside other things).

A snapshot of code in the upper filter driver, which interacts with the
functional driver…

While (ReadMoreData == TRUE)
{
.
.
pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
MyUSBDriverDevice, MyBuffer, MY_USB_BUFFER_SIZE, &MyStartingOffset,
&MyReadEvent, &MyIoStatusBlock);

PIO_STACK_LOCATION nextStack;
nextStack = IoGetNextIrpStackLocation(pIrp);
nextStack->MajorFunction = IRP_MJ_READ;
nextStack->FileObject = pMyFileObject;
nextStack->FileObject->FsContext =MyUsbPipeInformation[1];
status = IoCallDriver(MyUSBDriverDevice, pIrp);

ResetEvent(MyReadEvent);
KeWaitForSingleObject(&MyReadEvent, &status, Executive,
KernelMode,
FALSE, &MyDelay);

// note that theres is no completion routine as the Irp is synchjronous

if((pIrp->IoStatus->Status==0)
{
// success… hence read the data from Irp and send it to the
application
}else
{
// continue the next iteraion
}
.
.

}

The problem scenario

It is observed by the application using this driver stack that sometimes

a packet of data is missing randomly.

On further investigation we found that the functional driver receives an

IRP with status (pIrp->IoStatus->Status) ‘successful’ for each and every

packet read from the device. This was verified with the help of the
sequence number carried by each packet. So we can conclude that the
functional driver receives all the packets read from the device.

For some packets ( which are reported missing by the application), the
IRP containing that packet has status ‘successful’ in the functional
driver, but the status of the same IRP is seen as ‘pending’ in the upper

filter driver.

As the upper filter driver sees the status of the Irp pending even after

waiting on the event associated with the IRP, it assumes that there is
nothing to be read and goes on to the next iteration to try and read
from
the device, loosing a packet in the process.

This happens roughly 2 out of 5 times the application asks to upload a
file form the device. Sometimes up to 2-3 packets (out of about 400
packets) are reported missing.

HELP!!

Could somebody explain why the pIrp->IoStatus->Status differs for the
same Irp in two immediate drivers (even after using an event for
serialization)?


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

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The following is doomed to fail:

if((pIrp->IoStatus->Status==0)

DriverVerifier uses its own successful statuses to catch this very bug in
code. If you run with DriverVerifier this if test will fail. NT_SUCCESS()
is how you should check for success as Doron mentioned.


Bill McKenzie
Software Engineer - Prism 802.11 Wireless Solutions
Conexant Systems, Inc.

“Rahul Jethlia” wrote in message
news:xxxxx@ntdev…
> Hi All,
>
> I am working on writing functional and upper filter WDM drivers for a
> particular device on Windows 2k. The stack of drivers is used to connect
> to the device and upload a file from it (beside other things).
>
> A snapshot of code in the upper filter driver, which interacts with the
> functional driver…
>
> While (ReadMoreData == TRUE)
> {
> .
> .
> pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
> MyUSBDriverDevice, MyBuffer, MY_USB_BUFFER_SIZE, &MyStartingOffset,
> &MyReadEvent, &MyIoStatusBlock);
>
> PIO_STACK_LOCATION nextStack;
> nextStack = IoGetNextIrpStackLocation(pIrp);
> nextStack->MajorFunction = IRP_MJ_READ;
> nextStack->FileObject = pMyFileObject;
> nextStack->FileObject->FsContext =MyUsbPipeInformation[1];
> status = IoCallDriver(MyUSBDriverDevice, pIrp);
>
> ResetEvent(MyReadEvent);
> KeWaitForSingleObject(&MyReadEvent, &status, Executive, KernelMode,
> FALSE, &MyDelay);
>
> // note that theres is no completion routine as the Irp is synchjronous
>
> if((pIrp->IoStatus->Status==0)
> {
> // success. hence read the data from Irp and send it to the application
> }else
> {
> // continue the next iteraion
> }
> .
> .
>
> }
>
>
> The problem scenario
>
> It is observed by the application using this driver stack that sometimes
> a packet of data is missing randomly.
>
> On further investigation we found that the functional driver receives an
> IRP with status (pIrp->IoStatus->Status) ‘successful’ for each and every
> packet read from the device. This was verified with the help of the
> sequence number carried by each packet. So we can conclude that the
> functional driver receives all the packets read from the device.
>
> For some packets ( which are reported missing by the application), the
> IRP containing that packet has status ‘successful’ in the functional
> driver, but the status of the same IRP is seen as ‘pending’ in the upper
> filter driver.
>
> As the upper filter driver sees the status of the Irp pending even after
> waiting on the event associated with the IRP, it assumes that there is
> nothing to be read and goes on to the next iteration to try and read from
> the device, loosing a packet in the process.
>
> This happens roughly 2 out of 5 times the application asks to upload a
> file form the device. Sometimes up to 2-3 packets (out of about 400
> packets) are reported missing.
>
>
> HELP!!
>
> Could somebody explain why the pIrp->IoStatus->Status differs for the
> same Irp in two immediate drivers (even after using an event for
> serialization)?
>
>
>