バス ドライバーでのデバイスの削除
子デバイス (子 PDO) を削除するとき、親バス ドライバーは、デバイスを追加して起動するために実行したすべての操作を元に戻す必要があります。
バス ドライバーは、DispatchPnP ルーチンに次のようなプロシージャがある子デバイスを削除します。
ドライバーは、現在の FDO に対する以前の IRP_MN_SURPRISE_REMOVAL 要求を処理済みですか?
処理済みであれば、残りのクリーンアップを実行し、手順 4 に進みます。
通常、ドライバーは、デバイスの IRP_MN_SURPRI Standard Edition_REMOVAL 要求を処理したかどうかを示すフラグをデバイス拡張機能で管理します。
キューにあるすべての要求をドライバーで完了します。
バス ドライバーでその操作ができる場合は、デバイスの電源を切り、PoSetPowerState を呼び出して電源マネージャーに通知します。
バス ドライバーは、可能であれば、子デバイスの電源を切り、デバイスの電源状態の変化を電源マネージャーに通知します。 バス ドライバーは、IRP_MN_REMOVE_DEVICE 要求に応答してこの操作をします。デバイスの電源ポリシー所有者は、デバイスが削除されるときに IRP_MN_SET_POWER 要求を送信しません。 詳細については、「電源管理」を参照してください
バス ドライバーが BusRelations のIRP_MN_QUERY_DEVICE_RELATIONS 要求に対する最新の応答でこのデバイスを報告した場合、デバイスはマシン上に物理的にまだ存在しています。 この場合、バス ドライバーは次のように動作します。
デバイスが物理的に削除されるまで、デバイスの PDO を保持します。
>Irp-IoStatus.Status をSTATUS_SUCCESSに設定します。
IoCompleteRequest でIRP を完了します。
DispatchPnP ルーチンから返します。
バス ドライバーは、デバイスが物理的に削除されるまで、BusRelations の後続の列挙 IRP_MN_QUERY_DEVICE_RELATIONS で、このデバイスを報告し続けます。 PnP マネージャーは、列挙されたデバイスが追加されて起動されたかどうかを追跡します。
BusRelations の IRP_MN_QUERY_DEVICE_RELATIONS 要求に対するバス ドライバーの最新の応答にそのデバイスが含まれていない場合、バス ドライバーはそのデバイスがマシンから物理的に削除されたと見なします。 その場合、バス ドライバーは次のように動作します。
デバイス独自の割り当て、メモリ、イベントなどをクリーン アップします。
>Irp-IoStatus.Status をSTATUS_SUCCESSに設定します。
IoCompleteRequest でIRP を完了します。
IoDeleteDeviceで PDO を解放します。
そのデバイスが最新の BusRelations リストに掲載されていない場合、バス ドライバーは PDO を削除する必要があります。 ユーザーがデバイスをもう一度マシンに接続すると、バス ドライバーは、次の BusRelations クエリに応答して新しい PDO を作成する必要があります。 バス ドライバーがデバイスの新しいインスタンスに同じ PDO を再利用すると、マシンは正常に動作しません。
DispatchPnP ルーチンから返します。
PnP マネージャーがIRP_MN_REMOVE_DEVICE 要求を送信するときにそのデバイスがまだ残っていれば、バス ドライバーはその PDO を保持します。 後でそのデバイスがバスから物理的に削除されると、PnP マネージャーはもう 1 度 のIRP_MN_REMOVE_DEVICE を送信します。 後続の削除 IRP を受信すると、バス ドライバーは、そのデバイスの PDO を削除します。
バス ドライバーは、既に削除され、その PDO が削除対象としてマークされているデバイスの IRP_MN_REMOVE_DEVICE を処理できることとします。 このような IRP に対応して、バス ドライバーは IRP を成功させるか、STATUS_NO_SUCH_DEVICE を返すことができます。 一部のコンポーネントにオブジェクトへの参照が残っているため、バス ドライバーから IoDeleteDevice に以前に呼び出しをしたにもかかわらず、この場合、このデバイスの PDO はまだ削除されていません。 そのため、バス ドライバーは、2 番目の削除 IRP を処理しながら PDO にアクセスできます。 バス ドライバーは、この PDO の 2 回目の IoDeleteDevice を呼び出すことはできません。I/O システムは、その参照カウントが 0 になると、その PDO を削除します。
バス ドライバーは、そのデバイスのIRP_MN_REMOVE_DEVICE 要求を受け取るまで、その子デバイスのデータ構造体を削除しません。 バス ドライバーは、デバイスが削除されたことを検出し、IoInvalidateDeviceRelations を呼び出すかもしれませんが、PnP マネージャーが IRP_MN_REMOVE_DEVICE 要求を送信するまで、バス ドライバーはデバイスの PDO を削除することはできません。