Where should I create PDOs in KMDF USB bus driver?

I recently failed the Plug and Play rebalance test in DTM on my USB generic parent.

On XP, the failure mode is an outright blue screen. The WinDbg output says PNP_DETECTED_FATAL_ERROR and claims that I created a duplicate PDO in my driver.

The process inside my driver looks like this:

  1. DriverEntry
  2. EvtDeviceAdd
  3. EvtDevicePrepareHardware(), which parses the device’s config descriptor, and then creates several PDOs based on the contents.

Apparently, my problem was assuming that prepare-hardware would only be called once during the lifetime of the driver, or perhaps assukming that my PDOs would have been destroyed by KMDF at this point if I ever got a callback here a second time.

So my question is – what’s the best way to deal with this? Where’s the safest/sanest place to create my PDOs such that this doesn’t occur?

Or, should I register an EvtDeviceReleaseHardware() callback where I destroy the child PDOs manually?

Do not destroy the PDOs on ReleaseHW(). That means that all of your child stacks disappear on resource rebalance. Not very nice ;(. If you need a one time init for a device when it is started, use EvtDeviceSelftManagedIoInit. Otherwise, you can track a tiny bit of state and just return from PrepareHW() on the 2…Nth time on the FDO.

d

Okay, thanks. That leaves me with one last problem (well, I hope).

In my USB modem function driver sitting on top of my generic parent, I create a DOS symbolic link to my device (“COM4”). I do this inside EvtDevicePrepareHardware() also.

Of course, when this gets hit the second time, I get “could not create symbolic link – 0xC0000010”, and so I fail PrepareHardware, which PNPDTEST in turn translates as me failing IRP_MN_START_DEVICE, and thus the test fails.

Now, I’m wondering if it’s safe to move my DOS symbolic link creation to EvtDeviceSelfManagedIoInit(). After the rebalance, would the link still be valid?

Or, would you recommend that I create a ReleaseHardware() callback, and use it to destroy the DOS symbolic link?

Create the symbolic link in your modem FDO’s AddDevice routine. The difference between the sym link and the PDO enumeration is that the symlink does not require hw access, while the PDO enumeration does.

d

That’s just what I did (adding the symbolic link in AddDevice) – thanks. The fakemodem sample has it in AddDevice too. Somehow it migrated into PrepareHardware in my driver.

IoRegisterDeviceInterface - AddDevice time
IoSetDeviceInterfaceState(TRUE) - MN_START_DEVICE time

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

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Tuesday, February 13, 2007 10:21 PM
Subject: RE:[ntdev] Where should I create PDOs in KMDF USB bus driver?

> That’s just what I did (adding the symbolic link in AddDevice) – thanks.
The fakemodem sample has it in AddDevice too. Somehow it migrated into
PrepareHardware in my driver.
>
> —
> 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

Doron Holan wrote:

Create the symbolic link in your modem FDO’s AddDevice routine. The
difference between the sym link and the PDO enumeration is that the
symlink does not require hw access, while the PDO enumeration does.

Just to follow up on this topic with one more question.

Would you consider failure of WdfDeviceCreateSymbolicLink() during EvtDeviceAdd to be a condition for banging out the device?

Consider the situation where the driver cannot create, say, \DosDevices\COM4, because there is some sort of COM port conflict or other local configuration issue on the machine.

Technically, you could still bring up the device and talk to it through the modem device interface (which appears to be what TAPI does, since I can open my modem in Hyperterminal (by FriendlyName only) without registering the COM port symbolic link).

However, the KMDF fakemodem sample fails out if symbolic link creation fails, which is the pattern I followed. What do you think?

Looking a little further into this, both the WDM and KMDF serial samples in the WDK seem to fail out completely if the DOS symbolic name cannot be created (KMDF in EvtDeviceAdd, WDM in the IRP_MN_START_DEVICE handler). And in both cases the device interface creation follows (does not precede) the DOS symbolic creation, although I suppose that doesn’t matter.

However, if I write an in-use COM port name (such as “COM1”) into my device’s Enum key, and then bring up usbser.sys for my device, I can still talk to it (through the device interface/TAPI only).

Is it safe to assume, then, that the WDM and KMDF serial drivers differ from usbser.sys in this respect? And that to emulate usbser.sys, I shouldn’t fail add-device or bang out if my symbolic link creation fails?

Yes, they differ. You can easily ignore the failure to create a symbolic link and still succeed when creating the device interface. You will have to field the support calls either way i guess (!'ed out or no !, but not accessible to some applications which rely on the DOS name)

d