Verwenden von Sperren entfernen

Die Entfernungssperrroutinen bieten eine Möglichkeit, die Anzahl der ausstehenden E/A-Vorgänge auf einem Gerät nachzuverfolgen und zu bestimmen, wann das Geräteobjekt eines Treibers sicher getrennt und gelöscht werden kann. Das System stellt diese Routinen für Treiberautoren als Alternative zur Implementierung eines eigenen Nachverfolgungsmechanismus bereit.

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 zählen, warum der Treiber sein Geräteobjekt nicht löschen sollte, und um ein Ereignis festzulegen, wenn diese Anzahl auf 0 geht.

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 den Rest der 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 abrufen. Die Entfernensperrroutinen behalten eine Zählung der ausstehenden Käufe der Sperre bei. Jeder Aufruf von IoAcquireRemoveLock erhöht die Anzahl, und IoReleaseRemoveLock verringert die Anzahl.

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

In seinem Dispatchcode für IRP_MN_REMOVE_DEVICE muss der Treiber die Sperre erneut abrufen und dann IoReleaseRemoveLockAndWait aufrufen. Diese Routine kehrt erst wieder zurück, wenn alle ausstehenden Übernahmen der Sperre freigegeben wurden. Damit E/A-Vorgänge in der Warteschlange abgeschlossen werden können, sollte jeder Treiber IoReleaseRemoveLockAndWait aufrufen, nachdem er die IRP_MN_REMOVE_DEVICE Anforderung an den nächstniedrigen Treiber übergibt und bevor er Arbeitsspeicher freigibt, IoDetachDevice aufruft oder IoDeleteDevice aufruft. Nachdem IoReleaseRemoveLockAndWait für eine bestimmte Entfernungssperre aufgerufen wurde, schlagen alle nachfolgenden Aufrufe von IoAcquireRemoveLock für dieselbe Remove-Sperre fehl.

Nachdem IoReleaseRemoveLockAndWait zurückgegeben wurde, sollte der Treiber berücksichtigen, dass sich das Gerät in einem Zustand befindet, in dem es zum Entfernen bereit ist und keine E/A-Vorgänge ausführen kann. Daher darf der Treiber IoInitializeRemoveLock nicht aufrufen, um die Entfernungssperre erneut zu initialisieren. Ein Verstoß gegen diese Regel, während der Treiber von Driver Verifier ü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 beim Verarbeiten einer IRP_MN_REMOVE_DEVICE Anforderung löscht.