1
votes

I'm studying Microsoft Toaster sample code from WDK7, and I find a subtle problem.

Now trying the compiled drivers(WDM busenum and WDM featured1) on Windows 7.

As guided by README, enum -p 1 adds a toaster device, then, I open device manager(devmgmt), find the device, Uninstall it.

Uninstall toaster device from devmgmt.msc

This will destroy the toaster devnode(I believe); we can see that ToasterDevice01 node now disappears from Device Manager. !devnode 0 1 shows that the toaster devnode still exists, with State=DeviceNodeUninitialized (0x301), Previous State=DeviceNodeRemoved (0x312).

Then, I execute enum -p 1 trying to add the device again. But I got error 0x57(ERROR_INVALID_PARAMETER).

enum -p 1 , got 0x57 error

I debug the source code and identify the reason: buspdo.c does not distinguish between devmgmt's Disable and Uninstall operation. His code logic is:

  • If toaster gets surprise-removed(enum -u 1), it calls Bus_DestroyPdo() which is correct behavior.
  • If toaster gets Disabled from devmgmt, it does not call Bus_DestroyPdo(), which is also correct.

The problem is, when an end-user executes Uninstall from devmgmt, it follows the Disable path. Something bad now happens: Windows removes the toaster devnode, but toaster bus driver does not destroy the corresponding PDO, so, when next time user execute enum -p 1, the toaster bus driver Bus_PlugInDevice() blames that the toaster device with SerialNo==1 already exists and hence fail the user request.

enter image description here

BTW: Toaster's KMDF version exhibits similar problem(only static-enumeration version tried today)

Now my question is clear: How can I distinguish from Disable and Uninstall, shall I do it in bus driver or child device driver? Answer for KMDF version is also welcome.

1
Is the devnode really destroyed? I think it still may exist since the PDO exists (the PDO contains a reference to coresponding devnode). Does the sample behave the same way when you disable and then enable the the device via Device Manager.Martin Drab
Please tell me a way(like some stock utility) that is able to check whether a devnode exists, thank you.Jimm Chen
I don't know about any tool able to do this. You can use my tool (github.com/MartinDrab/VrtuleTree/releases) to check whether the PDO is present after the uninstall (github.com/MartinDrab/VrtuleTree/releases - File -> Create snapshot and look for the \Driver\<toasterbusname>). The kernel seems to delete the devnode structure when deleting the PDO.Martin Drab
Thank you. I checked with your tool and DevTreeView from OSR; they both show the PDO for toaster child still exists, and I find out WinDBG !devnode 0 1 shows that the devnode still exists too. So, I have to set aside this problem and wait for a chance to solve it later.Jimm Chen

1 Answers

0
votes

Now I can make a conclusion. Our client driver can NOT distinguish between Disable and Uninstall from Device Manager. This is Microsoft's design.

To make the distinguishment, we need the help from application layer. Provide a CoInstaller for the child device, and, when the CoInstaller gets DIF_REMOVE notification(this results from devmgmt doing Uninstall), send an custom IOCTL(e.g. IOCTL_UNPLUG_MY_CHILD) to the kernel driver so that kernel driver unplug corresponding child.