Bus driver child re-enumeration problems

When my bus driver got first created, all the child are enumerated. When
I’m deleting one of the child and that I’m doing a scan for hardware change
after in the device manager, Windows did’nt restart the deleted child. The
functional device of my bus driver is always sending the same PDO list to
the plug and play manager (in response of a IRP_MN_QUERY_DEVICE_RELATIONS).
I must delete and restart my bus driver at each time to be able to restart
one of the deleted child and this is very annoying. Why deleted child(s)
are never restarted after a scan for hardware change in the device
manager.


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Hi,

IoInvalidateDeviceRelations()?

Regards,
Anton

On 01/07/02, “xxxxx@matrox.com” wrote:

When my bus driver got first created, all the child are enumerated. When
I’m deleting one of the child and that I’m doing a scan for hardware change
after in the device manager, Windows did’nt restart the deleted child. The
functional device of my bus driver is always sending the same PDO list to
the plug and play manager (in response of a IRP_MN_QUERY_DEVICE_RELATIONS).
I must delete and restart my bus driver at each time to be able to restart
one of the deleted child and this is very annoying. Why deleted child(s)
are never restarted after a scan for hardware change in the device
manager.


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

On 01/07/02, “xxxxx@matrox.com” wrote:

When my bus driver got first created, all the child are enumerated. When
I’m deleting one of the child and that I’m doing a scan for hardware change
after in the device manager, Windows did’nt restart the deleted child. The
functional device of my bus driver is always sending the same PDO list to
the plug and play manager (in response of a IRP_MN_QUERY_DEVICE_RELATIONS).
I must delete and restart my bus driver at each time to be able to restart
one of the deleted child and this is very annoying. Why deleted child(s)
are never restarted after a scan for hardware change in the device
manager.

In order for Windows to restart the child, it has to think the child is
new. You can’t just keep reporting the child to the Pnp manager via
IRP_MN_QUERY_DEVICE_RELATIONS and change state in your driver and expect
the Pnp manager to pick up on the fact that the child went away and came
back. You need to report the child as removed in response to
IRP_MN_QUERY_DEVICE_RELATIONS by not including it in the PDO list at some
point after the child is intended for removal. This will also cause a
surprise remove IRP to come down that child’s device stack. Then, sometime
later report the child again in response to another
IRP_MN_QUERY_DEVICE_RELATIONS IRP and the Pnp manager will see it as just
arriving and will look for a driver to create an FDO again. You can cause
an IRP_MN_QUERY_DEVICE_RELATIONS IRP to be sent to the bus driver’s FDO at
anytime by calling IoInvalidateDeviceRelations with BusRelations type.

Bill McKenzie


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> When my bus driver got first created, all the child are enumerated. When

I’m deleting one of the child and that I’m doing a scan for hardware change
after in the device manager, Windows did’nt restart the deleted child. The
functional device of my bus driver is always sending the same PDO list to
the plug and play manager (in response of a IRP_MN_QUERY_DEVICE_RELATIONS).

A cite from the documentation:

"If the bus driver reported this device in its most recent response to an IRP_MN_QUERY_DEVICE_RELATIONS request for BusRelations,
the device is still physically present on the machine. In this case, the bus driver:
a… Retains the PDO for the device until the device has been physically removed.
b… Sets Irp->IoStatus.Status to STATUS_SUCCESS.
c… Completes the IRP with IoCompleteRequest.
d… Returns from the DispatchPnP routine "
End of cite.

You must not call IoDeleteDevice in your REMOVE path if the PDO was reported to PnP in device relations. Such a “REMOVE with a PDO
still in relations” is sent by “disable” or “update driver” from Device Manager, and they must not kill a PDO, they must retain the
PDO (and thus devnode) to be displayed as “disabled” in Device Manager tree and then re-activated by START. Only the real device
disappear (no longer on the bus) must kill the PDO.

The correct way to handle removes is:

  • maintain the “killed” and “reported in relations” flags in the PDO.
  • in device disappear path (real disappear of yours, not the REMOVE path, your bus driver’s path which is called if the child does
    no longer exist) - mark the device as “killed” and call IoInvalidateDeviceRelations. Killed PDOs are not reported in relations.
  • in MN_QUERY_RELATIONS path:
  • mark all PDOs as not “reported in relations”
  • then assemble a PDO pointer array, and do not include “killed” PDOs there.
  • then mark all PDOs in a pointer array as “reported in relations”.
  • complete
  • in MN_REMOVE_DEVICE path (a part of, see the documentation for more details):
  • if the device is “reported in relations”
    // This is a REMOVE request initiated by the Device Manager “disable” or “update
    // driver” features
  • complete
  • else
    // This REMOVE request is due to device really disappeared from the relations
  • delete the PDO
  • complete

Note that you must not have this in surprise removal case (SURPRISE_REMOVAL before REMOVE. SURPRISE_REMOVAL is sent by PnP if the
device disappeared from the relations without the user-initiated action in the Device Manager - “disable” or “update driver”). Just
delete the PDO in this case.

Also note that failed START causes REMOVE. In this case, the PDO must not be deleted too, this is automatically handled by the “do
not delete PDOs reported in relations” rule.

For instance - I have buggy Adaptec/Roxio drivers from EasyCD Creator. They are both upper and lower filters to the CD/DVD-ROM
devnodes.
The bug is that after awakening from hibernate, they usually fail START due to some strange reasons. In this case, the CD/DVD-ROM
devnode is dead. Even the “Advanced Properties” (DVD) tab is not displayed, the CD also has no drive letter. There is also no device
interface symlinks to it.
Nevertheless, the devnode (created by atapi.sys) is still there, regardless of START failure. It is not deleted on REMOVE followed
the failed START, and the REMOVE really was there since it deleted the symlinks.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

I did several test with the toaster bus example of the DDK. The “killed”
and “in relations” flags are represented in these examples by the “Present”
and “ReportedMissing” flags. When a toaster device is deleted from the
device manager, the Present flag is never set to false (this flag is only
set to false if the device is ejected). Because of that, the device is
still enumerated in the QUERY_DEVICE_RELATIONS because the device is still
present:

if(pdoData->Present) {
relations->Objects[prevcount] = pdoData->Self;
ObReferenceObject (pdoData->Self);
prevcount++;
} else {
pdoData->ReportedMissing = TRUE;
}

So the plug and play manager always receive the same PDO list for each
QUERY_DEVICE_RELATIONS. If a “scan for hardware change” is executed in the
device manager, the deleted toaster is re-detected even if we always
reported it in the PDO array of pointers. For which reason it’s working in
this case??


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Ah, I misunderstood you question. Well, if the child device is disabled in
device manager then when it is reenabled, you should get a start in that
FDO driver. If the driver is uninstalled, then if you scan for hardware
changes in device manager it should be reenumerated causing the found new
hardware wizard or the driver to be reloaded for the device provided the
PDO is still being reported by the bus driver. Are you not seeing that
happen? Are you sure your child device’s FDO driver unloaded from memory
when the remove happened?

Bill M.

I did several test with the toaster bus example of the DDK. The “killed”
and “in relations” flags are represented in these examples by the “Present”
and “ReportedMissing” flags. When a toaster device is deleted from the
device manager, the Present flag is never set to false (this flag is only
set to false if the device is ejected). Because of that, the device is
still enumerated in the QUERY_DEVICE_RELATIONS because the device is still
present:

if(pdoData->Present) {
relations->Objects[prevcount] = pdoData->Self;
ObReferenceObject (pdoData->Self);
prevcount++;
} else {
pdoData->ReportedMissing = TRUE;
}

So the plug and play manager always receive the same PDO list for each
QUERY_DEVICE_RELATIONS. If a “scan for hardware change” is executed in the
device manager, the deleted toaster is re-detected even if we always
reported it in the PDO array of pointers. For which reason it’s working in
this case??


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

What I’m seing here is that at each time that I delete a child device in
the device manager, the child device’s FDO unload function is called (so
the driver is unloaded). When a rescan from the device manager, my bus
driver is still reporting the PDO of the deleted child but the driver is
never restarted(the hardware wizard never start).


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

This is absolutely correct, nothing strange in it.

Max

----- Original Message -----
From:
To: “NT Developers Interest List”
Sent: Wednesday, January 09, 2002 11:25 AM
Subject: [ntdev] Re: Bus driver child re-enumeration problems

> What I’m seing here is that at each time that I delete a child device in
> the device manager, the child device’s FDO unload function is called (so
> the driver is unloaded). When a rescan from the device manager, my bus
> driver is still reporting the PDO of the deleted child but the driver is
> never restarted(the hardware wizard never start).
>
> —
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
>


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

No this is not correct, the hardware wizard is supposed to popup a dialog
to re-install the deleted driver. I tested it with the toaster bus of the
DDK and it works but with my bus driver, it does’nt popup.


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Even though your child FDO driver’s unload was called, are you sure the
device object was truly done away with. I would run WinObj, or DevView and
make sure that the device object truly went away for that device. Sounds
like you are ending up in limbo somehow.

Bill M.

On 01/11/02, “xxxxx@matrox.com” wrote:

No this is not correct, the hardware wizard is supposed to popup a dialog
to re-install the deleted driver. I tested it with the toaster bus of the
DDK and it works but with my bus driver, it does’nt popup.


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com