EvtIoInCallerContext called infinitely

Hi all,

In my driver, I have a non power-managed queue to handle reads and ioctls. Ioctls use METHOD_NEITHER, so I intercept them with EvtIoInCallerContext (I followed the kmdf\nonpnp sample in WDK).
I also have a third-party application that opens a file handle and posts reads in separate thread.
In EvtDeviceD0Exit I call for WdfIoQueuePurge to cancel the posted reads, and here my problem starts: from that moment, I get the EvtIoInCallerContext called infinitely. In that function I check that the request is not an IOCTL, and read for WdfDeviceEnqueueRequest(device, request), which fails with STATUS_WDF_BUSY. Then I call for WdfRequestCompleteWithInformation(request, status, 0);
And this occurs in infinite loop, which causes my PC to freeze. If I change the code to return STATUS_CANCELLED instead of calling for WdfRequestCompleteWithInformation, I still get the same behavior - the callback is called non-stop.

If I remove the interception from the code, it works fine.

Do I miss here something? I thought that WDF should have it’s own interception function, which is called if I don’t define one. What should I implement in the function in order to cause it not to be called infinitely? Should I set something in WDF_REQUEST_PARAMETERS before completing the request?

Thanks,
S.

I am guessing your app is not reacting well to the error returned for the ioctl and just repeatedly sending in a tight loop.

d

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

-----Original Message-----
From: xxxxx@gmail.com
Sent: Tuesday, August 11, 2009 12:25 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] EvtIoInCallerContext called infinitely

Hi all,

In my driver, I have a non power-managed queue to handle reads and ioctls. Ioctls use METHOD_NEITHER, so I intercept them with EvtIoInCallerContext (I followed the kmdf\nonpnp sample in WDK).
I also have a third-party application that opens a file handle and posts reads in separate thread.
In EvtDeviceD0Exit I call for WdfIoQueuePurge to cancel the posted reads, and here my problem starts: from that moment, I get the EvtIoInCallerContext called infinitely. In that function I check that the request is not an IOCTL, and read for WdfDeviceEnqueueRequest(device, request), which fails with STATUS_WDF_BUSY. Then I call for WdfRequestCompleteWithInformation(request, status, 0);
And this occurs in infinite loop, which causes my PC to freeze. If I change the code to return STATUS_CANCELLED instead of calling for WdfRequestCompleteWithInformation, I still get the same behavior - the callback is called non-stop.

If I remove the interception from the code, it works fine.

Do I miss here something? I thought that WDF should have it’s own interception function, which is called if I don’t define one. What should I implement in the function in order to cause it not to be called infinitely? Should I set something in WDF_REQUEST_PARAMETERS before completing the request?

Thanks,
S.


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

Hi Doron,

Thank you for your reply.

I am guessing your app is not reacting well to the error returned for the ioctl and just repeatedly
sending in a tight loop.
My driver is a kind of usb-2-serial driver (it creates a COM port), and the problem also occurs with HyperTerminal. It occurs when I open a COM port and disconnect the device.
The problem doesn’t occur if I remove the intercept function (the EvtIoInCallerContext ). I guess that WDF has it’s own function, which is overwritten by mine. I’m looking for the difference between the functions. Is it possible that I should set/change something in WDF_REQUEST_PARAMETERS before I complete the request?

Thanks,
S.

There is no default in process callback. If you do not set one, kmdf pends the irp and puts it into a queue. By completing it synchronously in your callback you have diff behavior. My guess is that both apps gracefully handle a failed pended irp but not a failed synchronous irp. In you in caller context callback you try marking the irp pending using the wdm api, completing the request as you are now and returning status_pending to test the theory

d

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

-----Original Message-----
From: xxxxx@gmail.com
Sent: Tuesday, August 11, 2009 5:05 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] EvtIoInCallerContext called infinitely

Hi Doron,

Thank you for your reply.
> I am guessing your app is not reacting well to the error returned for the ioctl and just repeatedly
> sending in a tight loop.
My driver is a kind of usb-2-serial driver (it creates a COM port), and the problem also occurs with HyperTerminal. It occurs when I open a COM port and disconnect the device.
The problem doesn’t occur if I remove the intercept function (the EvtIoInCallerContext ). I guess that WDF has it’s own function, which is overwritten by mine. I’m looking for the difference between the functions. Is it possible that I should set/change something in WDF_REQUEST_PARAMETERS before I complete the request?

Thanks,
S.


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

My first question is why you are not using a power-managed queue. That’s
what they’re for. The framework will handle things for you.

(Two other little comments.)

  1. As with the other poster’s message that I just responded to, you should
    know that you don’t “cancel” I/O that you current own. You complete it.
    Cancellation happens in layers above the owner of the request. See my
    previous post today.

  2. Do you really want to fail requests in EvtDeviceD0Exit? That can happen
    when the machine is going to sleep. Most of the time, you only want to fail
    these requests when the driver is being torn down, and EvtDeviceD0Exit is a
    bad choice for that. Again, a power-managed queue would handle this for
    you.


Jake Oshins
Hyper-V I/O Architect
Windows Kernel Group

This post implies no warranties and confers no rights.


wrote in message news:xxxxx@ntdev…
> Hi all,
>
> In my driver, I have a non power-managed queue to handle reads and ioctls.
> Ioctls use METHOD_NEITHER, so I intercept them with EvtIoInCallerContext
> (I followed the kmdf\nonpnp sample in WDK).
> I also have a third-party application that opens a file handle and posts
> reads in separate thread.
> In EvtDeviceD0Exit I call for WdfIoQueuePurge to cancel the posted reads,
> and here my problem starts: from that moment, I get the
> EvtIoInCallerContext called infinitely. In that function I check that the
> request is not an IOCTL, and read for WdfDeviceEnqueueRequest(device,
> request), which fails with STATUS_WDF_BUSY. Then I call for
> WdfRequestCompleteWithInformation(request, status, 0);
> And this occurs in infinite loop, which causes my PC to freeze. If I
> change the code to return STATUS_CANCELLED instead of calling for
> WdfRequestCompleteWithInformation, I still get the same behavior - the
> callback is called non-stop.
>
> If I remove the interception from the code, it works fine.
>
> Do I miss here something? I thought that WDF should have it’s own
> interception function, which is called if I don’t define one. What should
> I implement in the function in order to cause it not to be called
> infinitely? Should I set something in WDF_REQUEST_PARAMETERS before
> completing the request?
>
> Thanks,
> S.
>

Hi All,

The way it worked for me with HyperTerminal is was to complete manually all pending IRPs with STATUS_CANCELLED, and then return STATUS_DEVICE_INVALID_STATE from EvtIoInCallerContext, without calling for WdfIoQueuePurge.

My first question is why you are not using a power-managed queue.
That’s the design of the driver, I can’t change it now.

As with the other poster’s message that I just responded to, you should know that you don’t “cancel”
I/O that you current own. You complete it.
I wanted to say that I complete it with STATUS_CANCELLED.

Do you really want to fail requests in EvtDeviceD0Exit? That can happen when the machine is
going to sleep. Most of the time, you only want to fail these requests when the driver is being torn
down, and EvtDeviceD0Exit is a bad choice for that.
Within EvtDeviceD0Exit, I check the target state for beign D3Final.

Thanks all for the input.
S.

STATUS_CANCELLED should realy only be used when the PIRP is canceled (i.e. your cancel routine is called or Irp->Cancel is a non zero value), it should not be used to indicate an invalid state.

D3Final is not only for being torn down, it is also for a pnp stop

d


From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] on behalf of xxxxx@gmail.com [xxxxx@gmail.com]
Sent: Monday, August 17, 2009 12:14 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] EvtIoInCallerContext called infinitely

Hi All,

The way it worked for me with HyperTerminal is was to complete manually all pending IRPs with STATUS_CANCELLED, and then return STATUS_DEVICE_INVALID_STATE from EvtIoInCallerContext, without calling for WdfIoQueuePurge.

My first question is why you are not using a power-managed queue.
That’s the design of the driver, I can’t change it now.

As with the other poster’s message that I just responded to, you should know that you don’t “cancel”
I/O that you current own. You complete it.
I wanted to say that I complete it with STATUS_CANCELLED.

Do you really want to fail requests in EvtDeviceD0Exit? That can happen when the machine is
going to sleep. Most of the time, you only want to fail these requests when the driver is being torn
down, and EvtDeviceD0Exit is a bad choice for that.
Within EvtDeviceD0Exit, I check the target state for beign D3Final.

Thanks all for the input.
S.


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