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


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

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

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

  1. Чтобы убедиться, что диспетчера диспетчера подпрограмма не завершит запрос 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.