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.
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).
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 callsBus_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.
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.
!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