CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD Issue (code 38) (repost with some changes)

Hello.

I had posted on this issue before, but that just before the list was down for a period of time early this April.
(old post: http://www.osronline.com/showThread.cfm?link=288600)

As I have a bit more information now, I will repost.

I have a strange problem which appears only on Windows 10 (1703/1709 tested), and never on Windows 7 or Windows 8. I have a bus driver (WDM- which I maintain, and did not write from scratch) which enumerates one AVSTREAM child (audio/MIDI). In certain cases, I see the code CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD listed for the parent bus driver in the SETUPAPI logfile (and in the device manager).

There is a FAQ for debugging this:
“Debugging a Failed Driver Unload”
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-a-failed-driver-unload

After a few debug sessions, I have found out that the OBJECT_HEADER of the PDO created by my bus driver has a PointerCount > 0 after the device has been unplugged (HandleCount is 0), resulting in the bus device driver instance being pinned in memory (its unload routine was called), and no other instance being able to load thereafter.

I can usually duplicate the issue as follows:

a) Plug in device.

b) Open application, which opens a handle to the AVSTREAM child.

c) Unplug the device with the application still open. I note that my bus driver receives (for the affected PDO) surprise removal, but not removal, which is expected, as the application does not close its handle.

d) Replug the device, while keeping the application open.

e) Close the application (bus driver receives remove for the old PDO, and IoDeleteDevice is called on it).

f) Unplug and replug the device, and periodically the symptom in the device manager appears (code 38). When this issue occurs, I see using the debugger that the original child PDO has a PointerCount > 0 (HandleCount is 0).

Now following the “Debugging a Failed Driver Unload” link above, I have the kernel stacks of each reference/dereference case on the PDO when the issue was reproduced. I do not see a point where I have an unbalanced reference/dereference with my driver as the origin of both. The obvious unbalanced cases where my bus driver is involved are the IRP_MN_QUERY_DEVICE_RELATIONS TargetDeviceRelation/BusRelations paths, where my bus driver returns a referenced device. I have never received a TargetDeviceRelation/BusRelations request for this PDO after the device has been unplugged in step c) above, so at that point, all outstanding references to this PDO for the QDR/TargetDeviceRelation case ultimately lie in the KS layer, and all outstanding relations to this PDO for the QDR/BusRelations case ultimately lie in the PnP layer.

On to the truly desperate: I have found that adding a long delay in the child’s AddDevice routine when there is another device departing in parallel causes this issue to no longer manifest itself. This is not a solution in any way, and I would like to know how I could address the cause of this issue.

Could anyone see how I might have provoked this situation, or have an idea what might be the cause, or offer any advice?

Thank you,
Philip Lukidis