RegisterDeviceNotification and WdfDeviceCreateDeviceInterface

Hi all,

I have a driver that creates a raw pdo so that a user space app can connect it through.

Originally I have a piece of WDM code that used IoRegisterDeviceInterface with a custom GUID and I could register for arrival notifications on that GUID via RegisterDeviceNotification.

I now have written the same thing in WDF and I use WdfDeviceCreateDeviceInterface to do the registration part but apparently no arrival notification arrives on that GUID.

Is it supposed to work the way I’m expecting? Should I attempt to register the interface with IoRegisterDeviceInterface anyway?

Thank you in advance,
Marco.

It is supposed to work the way you are expecting. When are you creating the device interface on the raw PDO?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@laurenzano.it
Sent: Wednesday, October 13, 2010 12:00 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RegisterDeviceNotification and WdfDeviceCreateDeviceInterface

Hi all,

I have a driver that creates a raw pdo so that a user space app can connect it through.

Originally I have a piece of WDM code that used IoRegisterDeviceInterface with a custom GUID and I could register for arrival notifications on that GUID via RegisterDeviceNotification.

I now have written the same thing in WDF and I use WdfDeviceCreateDeviceInterface to do the registration part but apparently no arrival notification arrives on that GUID.

Is it supposed to work the way I’m expecting? Should I attempt to register the interface with IoRegisterDeviceInterface anyway?

Thank you in advance,
Marco.


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,

I create the PDO in the DeviceAdd handler.

I discovered new details about the problem though. The PDO gets actually created but only after the physical device generates at least one event.

The device is an HID device and the driver runs at USB level (not HID, for several reasons). The device initializes correctly and the creation of the raw pdo seems to happen correctly (since the code proceeds without failure) but simply doesn’t show up as available unless an event has gone through.

The main section of the driver uses the USB continuous reader to get messages from the device.

Thank you for your help,
Marco.

Just to add some information. I did some more observations in the attempt to understand the problem.

Apparently if nothing connects the raw pdo, after a first event, the pdo gets created and everything seems to work fine on both the USB flow and the raw pdo messaging.

If something attempts to connect the raw pdo upon its creation (provided to wait for one USB event first) the continuous reader stops working. It’s hard to tell what happens but it seems that really no IRPs get generated since not only the callback is never called but also I can’t see any activity if I use tools like the IRP tracker.

The IO target the continuous reader reads from is started and stopped in D0.

What could lock or stop the reader? what can I do to understand the its status?

Marco.

What do you mean by connects the raw pdo? And first event?

Are you synchronously blocking in any callbacks?

d

dent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@laurenzano.it
Sent: October 15, 2010 8:54 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] RegisterDeviceNotification and WdfDeviceCreateDeviceInterface

Just to add some information. I did some more observations in the attempt to understand the problem.

Apparently if nothing connects the raw pdo, after a first event, the pdo gets created and everything seems to work fine on both the USB flow and the raw pdo messaging.

If something attempts to connect the raw pdo upon its creation (provided to wait for one USB event first) the continuous reader stops working. It’s hard to tell what happens but it seems that really no IRPs get generated since not only the callback is never called but also I can’t see any activity if I use tools like the IRP tracker.

The IO target the continuous reader reads from is started and stopped in D0.

What could lock or stop the reader? what can I do to understand the its status?

Marco.


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

I use the raw pdo to provide a communication channel for a user space module. The module does a CreateFile and then enters a loop revolving around a blocking ReadFile. On the same handle another thread of the same module sends out some IOCTLs too.

By first event I mean USB activity tipically triggered by some user action on the device (like pressing a button). Apparently, when I plug in a device, the driver comes up (I can see traces in the kernel debugger) and the continuous reader is initialized. Also the PDO is created but apparently doesn’t “show up” in the sense that the user mode process doesn’t get any notification unless I actually trigger some USB report. Theoretically the raw pdo and the USB path are only loosely coupled by a ring buffer but, unless the driver is instructed to do so, no data is actually placed in that buffer. There is one spin lock that synchronizes the access to the ring buffer but I checked that and it seems fine and it would not really explain why the raw pdo is not available unless I create some event.

What is even weirder is that, after the raw pdo is “visible”, the user mode process opens it and sends a couple of IOCTLs which succeed. But from that moment on, the continuous reader won’t pick up anything anymore. I put a breakpoint into the callback for the reader and it’s really never called.
Also no activity is seen with the IRP tracer (at least on my driver).

Thanks for the help,
Marco.

Just to add some information:

I did some more experiments around this problem and I found that the issue is there regardless the raw pdo.

It has actually to do with the continuous reader or at least with a WdfIoTargetStart in D0Entry.

Here is what I had originally: set a handler for InternalIOctls that moves the interrupt transfer USBs into a manual queue (for later use). In preparehardware, I create a continuous reader. In D0Entry there’s a WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(filterExt->UsbPipe)) as per MS docs.
Well, if I do this and I start IRP tracker before the driver is loaded I see some PNP IRPs up to a start device, then I see some InternalIOCTLs originated by my driver (likely from the continuous reader) and then nothing else. Up to this point I haven’t touched the device and I don’t see any Internal IOCTL coming from the system and queued in the manual queue. If I then touch the device (it’s a HID device) the device somewhat “unlocks” and I can see another stream of PNP IRPs which I think complete the enumeration of the device. Only at that point I see some Internal IOCTLs from the system.
Most of the times, but not all the times, after this delayed enumeration, the driver doesn’t work. Apparently the reader doesn’t generate any URBs.

I then tried to remove the D0Entry handler all together. The continuous reader does get initialized, but never started. The D0Entry is left to its default handler in WDF. Well in that case, the enumeration process proceeds correctly and it’s not delayed. Therefore Internal IOCTLs from the system are correctly queued up without touching the device. Of course, with the reader disabled, I can’t read any activity from the device, but that’s expected.

So I suppose that it’s either that IoTargetStart in D0Entry or the Continuous reader that are causing the driver to lock.

At this point I’m pretty sure I’m doing something wrong but I can’t narrow down the problem. Does anybody have any insights on this?

Thank you,
Marco.

In case this may help somebody else, it seems that I fixed the problem.

Instead of starting the iotarget in the D0Entry handler, I do it in the InternalIOCtl handler that is called upon the first InternalIOCtl comes in. This can only happen if the device has gone through the complete initialization process.

I don’t know if this is expected or not and I will be testing it for some time but it seems to work.
I would really like to understand why it didn’t work before but at least this gets the job done apparently.

Marco.

It sounds like to me that something is blocking a callback in the initialization path. When you are in this state where the cont reader is stuck and not returning data, have you verified that your d0entry() is returinng back to kmdf and not infinitely blocking?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@laurenzano.it
Sent: Monday, October 18, 2010 11:19 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] RegisterDeviceNotification and WdfDeviceCreateDeviceInterface

In case this may help somebody else, it seems that I fixed the problem.

Instead of starting the iotarget in the D0Entry handler, I do it in the InternalIOCtl handler that is called upon the first InternalIOCtl comes in. This can only happen if the device has gone through the complete initialization process.

I don’t know if this is expected or not and I will be testing it for some time but it seems to work.
I would really like to understand why it didn’t work before but at least this gets the job done apparently.

Marco.


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

Actually yes I did. D0Entry is just one line of code that after that I have a debug trace just before exiting and I can see that.
From what I can see from the IRP tracker too, is that the continuous reader works (since I can see the IRPs sent down the stack generated by the driver) but the reader waiting for completion of its requests seems to prevent other requests from the system to come in.
All the queues are parallel BTW, so this is really weird.

I can reproduce the state pretty reliably, so I wonder, when the driver is in this wait state, I can freeze the system and inspect it. Is there anything that could be useful to understand what locks up and where?

Thanks!
Marco.

Are you the power policy owner for the stack? Are you also using power managed queues?

The usb cont reader doesn’t wait on anything, just sends async io down the stack and returns. The completion routine is called when the io completes.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@laurenzano.it
Sent: Monday, October 18, 2010 1:18 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] RegisterDeviceNotification and WdfDeviceCreateDeviceInterface

Actually yes I did. D0Entry is just one line of code that after that I have a debug trace just before exiting and I can see that.
From what I can see from the IRP tracker too, is that the continuous reader works (since I can see the IRPs sent down the stack generated by the driver) but the reader waiting for completion of its requests seems to prevent other requests from the system to come in.
All the queues are parallel BTW, so this is really weird.

I can reproduce the state pretty reliably, so I wonder, when the driver is in this wait state, I can freeze the system and inspect it. Is there anything that could be useful to understand what locks up and where?

Thanks!
Marco.


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

The driver is a filter driver and I don’t explicitly set any behaviour different than default.
So I suppose the driver is not PPO and therefore the queues are not power managed. Can that be a problem?

Hmmm… but you HAVE specifically set it as a filter (using WdfFdoSetFilter or whatever)??

Peter
OSR

Yes, of course. The DeviceAdd handler has a WdfFdoInitSetFilter, then sets callbacks for PrepareHardware, DeviceD0Entry, DeviceD0Exit and then WdfDeviceCreate…
What I meant but “don’t explicitly set” was that I don’t specify anything neither for the queues nor I set the driver as PPO.

I’ll like to stress the fact that the driver mostly works and by just moving the IoTargetStart from the D0Entry to when the first InternalIOCTL from the system comes in, the driver works like a charm.
It just seems that when IoTargetStart is in D0Entry, something waits for the completion of the URBs sent down by the cont reader before keeping on handling the other PNP IRPs (which are part of the enumeration process). The queues are configured as parallel dispatch and I made sure that no spin lock is held.

Thanks for you help!
Marco.

> It just seems that when IoTargetStart is in D0Entry

Just a wild guess: maybe SelfManagedIoInit is the place to init the IO target?


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com