Periodic read requests

Dear,

I’d like to generate Read requests periodically from a filter driver in order to update a buffer. Could you tell me what’s the best way to setup a timer, and what’s the classic way to build read requests.

What I tried is the following (no timer for the moment) :

Creating the memory once in DeviceAdd :

KdPrint((“Creating memory”));
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = device;
WdfMemoryCreate(&attributes, NonPagedPool, 0, 21, &mem, NULL);

And creating read requests using :

WDFREQUEST rawRequest;
WDFIOTARGET rawIoTarget;

KdPrint((“Getting target.”));
rawIoTarget = WdfDeviceGetIoTarget(rawDevice);

KdPrint((“Creating raw read request.”));
WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, rawIoTarget, &rawRequest);

KdPrint((“Formating raw read request.”));
WdfIoTargetFormatRequestForRead(rawIoTarget, rawRequest, mem, NULL, 0);

KdPrint((“Sending raw read request.”));
FilterForwardRequestWithCompletionRoutine(rawRequest, rawIoTarget);

I’m doing some treatment in the completion routine, directly on “mem” which is a global (I read somewhere I couldn’t use WdfRequestRetrieveOutputMemory in case I’m creating the request myself).

buffer = WdfMemoryGetBuffer(mem, &buffer_size);

WdfRequestComplete(Request, CompletionParams->IoStatus.Status);

I end up with a bluescreen when calling WdfRequestComplete.

Any idea ? is this the correct way to do this ?
What about the timer ?

Regards,

xxxxx@gmail.com wrote:

I’d like to generate Read requests periodically from a filter driver in order to update a buffer. Could you tell me what’s the best way to setup a timer, and what’s the classic way to build read requests.

What I tried is the following (no timer for the moment) :

And creating read requests using :

I’m doing some treatment in the completion routine, directly on “mem” which is a global (I read somewhere I couldn’t use WdfRequestRetrieveOutputMemory in case I’m creating the request myself).

But you can certainly create a context structure for your request, and
store the memory buffer there. On the other hand, if there is only one
such buffer for your whole driver, it could also go in your device context.

buffer = WdfMemoryGetBuffer(mem, &buffer_size);

WdfRequestComplete(Request, CompletionParams->IoStatus.Status);

I end up with a bluescreen when calling WdfRequestComplete.

You only need to complete requests that you receive from elsewhere.
When you create a request, you must not complete it. (See the doc page
for WdfRequestCreate.) By the time it gets back to you, it’s life is
already over. Just delete it. There is no one waiting above you to
process the request, and the blue screen probably came from the
framework desperately trying to find someone who cares about it.

What about the timer ?

What about it? Have you already ready about WdfTimerCreate?


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

tim answered the lower level implementation issues. what do you mean by a period read? do you really mean send a read on a specific interval (like every 100 ms)? or do you really mean that you always want a read pending at the lower level and when it completes, you send it back down so there is still a read pending?

d

I’m more interested in always having a read pending to always have the latest data from the device. So I guess I’ll just need to send a new read request just after completion, right ? Is there any problem doing that from the completion routine ?

Thanks you two for your explanations, it’s’obvious now that i shouldn’t try to complete it.

Regards,

xxxxx@gmail.com wrote:

I’m more interested in always having a read pending to always have the latest data from the device. So I guess I’ll just need to send a new read request just after completion, right ? Is there any problem doing that from the completion routine ?

No. What bus is your device on? If your read requests complete
instantly, you could easily flood a CPU this way. This kind of
“continuous reader” is commonly used in USB, because the USB scheduling
provides the pacing.


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

It will be used on a hid usb custom interface. Thanks again for your help. I’ll test that tomorrow morning and I’ll let you know if anything goes wrong.

Regards,

what you want to do is

  1. create the WDFREQUEST and associated WDFMEMORYY in AddDevice. parent the request and memory objects to the WDFDEVICE
  2. when you want to start sending the request (probably in self managed io init and restart), format it, and send it
  3. in the completion routine, process the data, reuse the request (WdfRequestReuse), reformat it and send it down again
  4. you will want to stop the sending of the request (cancel it, do not resend in the completion routine) when powering down (most likely in self managed io stop)

d

Thank you for your help.

Doron, it’s precisely what I want to do, but it seems that when sending the read request myself after a call to “reuse”, it completes immediately, but it shouldn’t because my hardware answers only when new data is available (and it’s not the case).

Any idea what might cause this behavior ?

To precise my last post :
In the completion routine, the request status is 0xC0000061.

Found that this status is :

0xC0000061
STATUS_PRIVILEGE_NOT_HELD

A required privilege is not held by the client.

Can’t find what could cause such a problem. Would you mind pointing the resource that will help me in solving this issue ?

Regards,

Problem solved thanks to this thread (thanks Doron):
http://www.osronline.com/showthread.cfm?link=193441

IoGetNextIrpStackLocation(WdfRequestWdmGetIrp(mouseRequest))->FileObject =
IoGetCurrentIrpStackLocation(WdfRequestWdmGetIrp(originalRequest))->FileObject;

Regards,

This fixed the problem because I was sending my own request from an IoRead evt, however, I’m trying to move the “starting point” to the self managed io init as you advised me, and I also end up having the same STATUS_PRIVILEGE_NOT_HELD in the completion routine.

For the moment I’m working on the mouse HID interface, just the same thing related in the post I mentioned above.

Could you explain me how I could manage these “FileCreate” in order to have the following behavior.

  • Starting my sort of continuous reader from self managed io init (that’s the point I’m failing to implement).
  • Have a buffer filled in the completion routine then resend a new read request.
  • From the completion routine, check if any IoRead is pending (data requested from a user software) and complete them.

I’m able to do that if a user software sends at least one read request, in order to start reading in loop, but I’d like to do have the loop running even if no user software requested data.

Thanks for your help.

xxxxx@gmail.com wrote:

Could you explain me how I could manage these “FileCreate” in order to have the following behavior.

  • Starting my sort of continuous reader from self managed io init (that’s the point I’m failing to implement).
  • Have a buffer filled in the completion routine then resend a new read request.
  • From the completion routine, check if any IoRead is pending (data requested from a user software) and complete them.

I’m able to do that if a user software sends at least one read request, in order to start reading in loop, but I’d like to do have the loop running even if no user software requested data.

That’s fine. You could submit your first read during the EvtFileCreate
callback, or even during one of the power-on callbacks.


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

power own callbacks will not work, they are too early, they are also invoked on start. but if you need the file object for sending your reads, i still say you are in the wrong level of the stack. you should be a hid custom hid miniport, not a lower filter below mouhid. a custom hid miniport will be sending its period reads down the stack and those reads will not require a file object

d