Использование удаления блокировок

Процедуры удаления блокировки позволяют отслеживать количество невыполненных операций ввода-вывода на устройстве и определять, когда безопасно отсоединять и удалять объект устройства драйвера. Система предоставляет эти процедуры авторам драйверов в качестве альтернативы реализации собственного механизма отслеживания.

Драйвер может использовать этот механизм для двух целей:

  1. Чтобы гарантировать, что подпрограмма DispatchPnP драйвера не завершит запрос IRP_MN_REMOVE_DEVICE во время блокировки (например, когда другая подпрограмма драйвера обращается к устройству).

  2. Для подсчета количества причин, по которым драйвер не должен удалять свой объект устройства, а также для установки события, когда это число равно нулю.

Чтобы инициализировать блокировку, драйвер должен выделить IO_REMOVE_LOCK структуру в расширении устройства , а затем вызвать IoInitializeRemoveLock. Драйвер обычно вызывает IoInitializeRemoveLock в своей процедуре AddDevice , когда драйвер инициализирует остальную часть расширения устройства для объекта устройства.

Драйвер должен вызывать IoAcquireRemoveLock при каждом запуске операции ввода-вывода. Драйвер должен вызывать IoReleaseRemoveLock при каждом завершении операции ввода-вывода. Драйвер может получить блокировку несколько раз. Процедуры удаления блокировки поддерживают количество непогашенных приобретений блокировки. Каждый вызов IoAcquireRemoveLock увеличивает число, а IoReleaseRemoveLock уменьшает счетчик.

Драйвер также должен вызывать IoAcquireRemoveLock , когда он передает ссылку на свой код (для таймеров, DPC, обратных вызовов и т. д.). Затем драйвер должен вызвать IoReleaseRemoveLock , когда событие возвращается.

В коде диспетчеризации для IRP_MN_REMOVE_DEVICE драйвер должен получить блокировку еще раз, а затем вызвать IoReleaseRemoveLockAndWait. Эта процедура не возвращается до тех пор, пока не будут освобождены все непогашенные приобретения блокировки. Чтобы разрешить выполнение операций ввода-вывода в очереди, каждый драйвер должен вызывать IoReleaseRemoveLockAndWaitпослепередачи IRP_MN_REMOVE_DEVICE запроса следующему драйверу и перед освобождением памяти вызывает IoDetachDevice или ioDeleteDevice. После вызова IoReleaseRemoveLockAndWait для определенной блокировки удаления все последующие вызовы IoAcquireRemoveLock для той же блокировки удаления завершатся ошибкой.

После возврата IoReleaseRemoveLockAndWait драйвер должен считать, что устройство находится в состоянии, в котором оно готово к удалению и не может выполнять операции ввода-вывода. Поэтому драйвер не должен вызывать IoInitializeRemoveLock для повторной инициализации блокировки удаления. Нарушение этого правила при проверке драйвера с помощью средства проверки драйверов приведет к ошибке проверка.

Так как драйвер сохраняет структуру IO_REMOVE_LOCK в расширении устройства объекта устройства, блокировка удаления удаляется, когда драйвер удаляет расширение устройства при обработке запроса IRP_MN_REMOVE_DEVICE .