Verwenden von „Sperren entfernen“

Die Entfernen-Sperrroutinen bieten eine Möglichkeit, die Anzahl der ausstehenden E/A-Vorgänge auf einem Gerät nachzuverfolgen und zu bestimmen, wann es sicher ist, das Geräteobjekt eines Treibers zu trennen und zu löschen. Das System bietet diesen Routinen Treiberautoren als Alternative zur Implementierung ihres eigenen Tracking-Mechanismus.

Ein Treiber kann diesen Mechanismus für zwei Zwecke verwenden:

  1. Um sicherzustellen, dass die DispatchPnP-Routine des Treibers keine IRP_MN_REMOVE_DEVICE Anforderung abgeschlossen, während die Sperre gehalten wird (z. B. während eine andere Treiberroutine auf das Gerät zugreift).

  2. Um die Anzahl der Gründe zu ermitteln, warum der Treiber sein Geräteobjekt nicht löschen soll, und um ein Ereignis festzulegen, wenn diese Anzahl auf Null wechselt.

Um eine Entfernungssperre zu initialisieren, sollte ein Treiber eine IO_REMOVE_LOCK Struktur in seiner Geräteerweiterung zuordnen und dann IoInitializeRemoveLock aufrufen. Ein Treiber ruft In der Regel IoInitializeRemoveLock in seiner AddDevice-Routine auf, wenn der Treiber die restliche Geräteerweiterung für ein Geräteobjekt initialisiert.

Ihr Treiber muss IoAcquireRemoveLock jedes Mal aufrufen, wenn er einen E/A-Vorgang startet. Der Treiber muss IoReleaseRemoveLock jedes Mal aufrufen, wenn er einen E/A-Vorgang beendet. Ein Treiber kann die Sperre mehrmals erwerben. Die Entfernen-Sperrroutinen behalten eine Anzahl der ausstehenden Käufe der Sperre bei. Jeder Aufruf von IoAcquireRemoveLock erhöht die Anzahl, und IoReleaseRemoveLock erhöht die Anzahl.

Der Treiber sollte auch IoAcquireRemoveLock aufrufen, wenn er einen Verweis auf seinen Code übergibt (für Timer, DPCs, Rückrufe usw.). Der Treiber muss dann IoReleaseRemoveLock aufrufen, wenn das Ereignis zurückgegeben wurde.

Im Verteilercode für IRP_MN_REMOVE_DEVICE muss der Treiber die Sperre erneut abrufen und dann IoReleaseRemoveLockAndWait aufrufen. Diese Routine wird erst zurückgegeben, wenn alle ausstehenden Käufe der Sperre freigegeben wurden. Damit in die Warteschlange eingereihte E/A-Vorgänge abgeschlossen werden können, sollte jeder Treiber IoReleaseRemoveLockAndWait aufrufen, nachdem die IRP_MN_REMOVE_DEVICE Anforderung an den nächsten niedrigeren Treiber übergeben wurde, und bevor speicherfrei, IoDetachDevice aufgerufen oder IoDeleteDevice aufgerufen wird. Nachdem IoReleaseRemoveLockAndWait für eine bestimmte Remove-Sperre aufgerufen wurde, schlagen alle nachfolgenden Aufrufe von IoAcquireRemoveLock für dieselbe Remove-Sperre fehl.

Nachdem IoReleaseRemoveLockAndWait zurückgegeben wurde, sollte der Treiber das Gerät in einem Zustand betrachten, in dem es entfernt werden kann und keine E/A-Vorgänge ausführen kann. Daher darf der Treiber ioInitializeRemoveLock nicht aufrufen, um die Remove-Sperre erneut zu initialisieren. Verstoß gegen diese Regel, während der Treiber von der Treiberüberprüfung überprüft wird, führt zu einer Fehlerüberprüfung.

Da ein Treiber eine IO_REMOVE_LOCK Struktur in der Geräteerweiterung eines Geräteobjekts speichert, wird die Entfernungssperre gelöscht, wenn der Treiber die Geräteerweiterung löscht, während eine IRP_MN_REMOVE_DEVICE Anforderung verarbeitet wird.