次の方法で共有


ドライバーによって割り当てられたリソースの解放

ドライバーによるレジストリの使用方法、システム オブジェクトのセットアップ方法、そのデバイス拡張機能、コントローラー拡張機能、またはドライバーによって割り当てられた非ページ プールのリソースの詳細はドライバーによって異なります。 ただし、どの Unload ルーチンでも、ドライバーが段階的に使用しているリソースを解放する必要があります。

どのドライバーの Unload ルーチンでも、リソースを解放するときは、その前に他のドライバー ルーチンが現在そのリソースを使用していないか、あるいは近々そのリソースを使用する予定がないかを確認する必要があります。

一般に、Unload ルーチンは、次の段階ですべてのドライバー割り当てリソースを解放します。

  1. ドライバーがまだ行っていない場合は、可能であれば、任意の物理デバイスの割り込みを無効にし、割り込みが無効になったらすぐに IoDisconnectInterrupt を呼び出します。

  2. Unload ルーチンで解放される予定のリソースを他のドライバー ルーチンが参照できないことを確認します。

    たとえば、ドライバーの IoTimer ルーチンが特定のデバイス オブジェクトに対して現在有効になっている場合、Unload ルーチンは IoStopTimer を呼び出す必要があります。 どのドライバーのディスパッチャー オブジェクトの記憶域を解放するときも、事前に、そのドライバーのディスパッチャー オブジェクトを待機しているスレッドがないことを確認し、そのタイマー オブジェクトが CustomTimerDpc ルーチンの呼び出しのキューに登録されていないことを確認する必要があります。 ISR でキュー待ちになっている可能性がある CustomDpc ルーチンがある場合は、KeRemoveQueueDpc を呼び出す必要があります。

    ドライバーが IoQueueWorkItem を呼び出す場合、作業項目が完了していることを確認する必要があります。 IoQueueWorkItem は、関連付けられているデバイス オブジェクトの参照を取り出します。このような参照が残っている場合、ドライバーはアンロードできません。

    ドライバーが PsCreateSystemThread を呼び出す場合は、ドライバーがアンロードされる前にスレッド自体が PsTerminateSystemThread を呼び出すことができるように、Unload ルーチンで、ドライバーが作成したスレッドを実行する必要もあります。 ドライバーによって作成されたシステム スレッドは、ZwCloseを、PsCreateSystemThread によって返された ThreadHandle とともに呼び出して、ドライバーで解放することはできません。

  3. ドライバーが割り当てたデバイス固有のリソースをすべて解放します。 これを行うには、以下のシステム サポート ルーチンを呼び出す必要があります。

  4. DriverEntry ルーチンまたは Reinitialize ルーチンでデバイス オブジェクトのデバイス拡張またはコントローラー オブジェクトのコントローラー拡張にセットアップしたシステム オブジェクトとリソースを (どれか作成した場合は) 解放します。 特に、ドライバーでは、デバイス オブジェクト (IoDeleteDevice) またはコントローラー オブジェクト (IoDeleteController) の削除を試みる前に、次の操作を行う必要があります。

  5. DriverEntry ルーチンまたは Reinitialize ルーチンがドライバーの物理デバイスのために要求したハードウェア リソースが \Registry\Machine\Hardware\ResourceMap ツリーの下にあれば解放します。

  6. DriverEntry ルーチンまたは Reinitialize ルーチンがレジストリで \Registry..\DeviceMap ツリーの下に保存したデバイスの名前を削除します。

ドライバーが、デバイス、システム、およびハードウェア リソースを解放すると、「デバイス オブジェクトとコントローラー オブジェクトの解放」にあるようにドライバーはそのデバイス オブジェクトとコントローラー オブジェクトを削除できます。