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


Реализация процедуры отмены

Диспетчер ввода-вывода вызывает предоставленную драйвером подпрограмму Cancel с входным IRP для отмены и указателем DeviceObject , который представляет целевое устройство для запроса ввода-вывода.

IRP может быть тем, что подпрограмма DispatchReadWrite драйвера помещается в очередь так же, как текущее приложение Win32 закрывается пользователем. IRP также может быть тем, который драйвер более высокого уровня явно отменял в зависимости от характера базового устройства.

При вызове подпрограммы Отмена входной IRP может уже быть CurrentIrp в целевом объекте устройства или уже находиться в очереди устройства, связанной с объектом целевого устройства, если драйвер имеет подпрограмму StartIo . Если у драйвера нет подпрограммы StartIo , IRP может находиться во внутренней очереди irPs, управляемой драйвером, при вызове процедуры Отмены . В любом случае, прежде чем диспетчер операций ввода-вывода вызовет подпрограмму Отмена для входящего IRP, диспетчер операций ввода-вывода устанавливает для элемента Cancel в этом IRP значение TRUE , а для элемента CancelRoutine в IRP — значение NULL.

Подпрограмма Отмена для master IRP с соответствующими irP отвечает за вызов IoCancelIrp для отмены связанных irp.

Все процедуры отмены должны соответствовать следующим рекомендациям:

  • Вызовите IoReleaseCancelSpinLock , чтобы освободить блокировку отмены вращения системы.

  • Задайте для элемента Status блока состояния ввода-вывода значение STATUS_CANCELLED, а для элемента Information задайте нулевое значение.

  • Завершите указанную IRP, вызвав IoCompleteRequest.

  • Так как подпрограмма Отмена всегда вызывается с удерживаемой блокировкой спина отмены, эта подпрограмма не должна вызывать IoAcquireCancelSpinLock , если она не вызывает IoReleaseCancelSpinLock .

  • Подпрограмма отмены не может удерживать системную блокировку отмены спина при возврате управления. То есть каждая подпрограмма отмены должна вызывать IoReleaseCancelSpinLock по крайней мере один раз, прежде чем она вернет управление.

  • Если она вызывает IoAcquireCancelSpinLock, подпрограмма Отмена должна как можно быстрее выполнить обратный вызов IoReleaseCancelSpinLock .

  • Никогда не вызывайте IoCompleteRequest с IRP при удержании спин-блокировки. Попытка завершить IRP с удержанием спин-блокировки может привести к взаимоблокировкам.