Поделиться через


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

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

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

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

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

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

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

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

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

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

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