デバイスを停止する要求の処理
デバイスのドライバーがデバイスの停止を求める前に、PnP マネージャーがデバイスの停止が適切かどうかを確認する状況としては、次の 2 つがあります。
ユーザーが新しいデバイスをプラグインし、新しいデバイスを受け入れるために PnP マネージャーがシステムのハードウェア リソースを再配布する必要がある。
ユーザーがデバイスの取り外しを指示した。
ドライバーがこれらの状況を処理できる方法は複数あります。
デバイスが特別なファイルをサポートしているためドライバーが WdfDeviceSetSpecialFileSupport を呼び出す場合、および特別なファイルがデバイス上で開いている場合、フレームワークはデバイスの停止を許可しません。
比較的短時間にわたって一時的にすべてが停止するのを防止するために、ドライバーは WdfDeviceSetStaticStopRemove を呼び出すことができます。
それぞれの停止の指示を個別に評価および処理するために、ドライバーは EvtDeviceQueryStop コークバック関数と EvtDeviceQueryRemove コークバック関数を提供できます。
デバイスが特別なファイルをサポートしていない場合、およびデバイスを停止または取り外してもデバイスまたはドライバーに問題が発生しない場合、ドライバーは EvtDeviceQueryStop コールバック関数および EvtDeviceQueryRemove コールバック関数を提供せず、WdfDeviceSetStaticStopRemove を呼び出しません。この場合、PnP マネージャーは常に、最初にドライバーを停止可能かどうかをチェックせずにデバイスを停止します。
リソースの再配布
場合によっては、PnP マネージャーがシステムのハードウェア リソースを再配布する必要があります。通常、この再配布は、新しいデバイスがプラグインされたことをバス ドライバーが報告し、その新しいデバイスがリソースに割り当て済みになっている必要がある場合に実行されます。デバイスは、リソースの再割り当てを行う前に停止する必要があります。
ビジー状態のデバイスが PnP マネージャーによって停止される場合があることをドライバーで防止する必要があるときに、ドライバーは EvtDeviceQueryStop コールバック関数を提供できます。ドライバーの EvtDeviceQueryStop コールバック関数がエラー状態の値を返した場合、PnP マネージャーはデバイスを停止しません。
ドライバーがデバイスを安全に停止できると判断した場合、コールバック関数は STATUS_SUCCESS を返します。デバイスのいずれのドライバーによっても停止が防止されない場合、PnP マネージャーは一時的にデバイスを停止します。
PnP マネージャーがデバイスを停止してリソースを再配布するときに、フレームワークがドライバーのイベント コールバック関数を呼び出す順序については、「PnP マネージャーによるシステム リソースの再配布」を参照してください。
ユーザーによるデバイスの取り外しまたは無効化
ユーザーは一部のデバイスを取り外したり無効にしたりできます。次に例を示します。
ドライバーがデバイスの WDF_DEVICE_PNP_CAPABILITIES 構造体の Removable メンバーを設定している (かつ、SurpriseRemovalOK メンバーを設定していない) 場合、ユーザーは Unplug プログラムまたは Eject Hardware プログラムを実行して、デバイスの取り外しまたは取り出しを行うことができます。
ドライバーがデバイスの WDF_DEVICE_STATE 構造体の NotDisableable メンバーを設定していない場合、ユーザーはデバイス マネージャーを使用してデバイスを無効にできます。
これらの場合、PnP マネージャーは、ユーザーが取り外す前にデバイスの停止を試みます。
ビジー状態のデバイスが取り外される場合があることをドライバーで防止する必要があるときに、ドライバーは EvtDeviceQueryRemove コールバック関数を提供できます。いずれかのドライバーの EvtDeviceQueryRemove コールバック関数がエラー状態の値を返した場合、PnP マネージャーはデバイスを停止しません。
ドライバーがユーザーによるデバイスの取り外しが安全と判断した場合、コールバック関数は STATUS_SUCCESS を返します。デバイスのいずれのドライバーによっても取り外しが防止されない場合、PnP マネージャーはデバイスを停止します。
取り外しのためにデバイスを停止するときに、フレームワークがドライバーのイベント コールバック関数を呼び出す順序については、「ユーザーによるデバイスの取り外し」を参照してください。