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


Синхронизация отмены в подпрограммах драйверов, обрабатывающих IRPs

Все подпрограммы драйвера, которые отменяют или вызываются с помощью IRP, который находится в отменяемом состоянии, включая подпрограмму StartIo драйвера, должен выполнять следующие действия:

  1. Вызов IoAcquireCancelSpinLock.

  2. Убедитесь, что Irp равен DeviceObject-CurrentIrp>. В противном случае вызовите IoReleaseCancelSpinLock и контроль возврата.

    Если они не совпадают, возможно, CurrentIrp был отменен в период с момента выпуска IoStartPacket блокировки спина отмены, и эта подпрограмма приобрела его.

  3. Вызовите IoSetCancelRoutine с указателем NULL CancelRoutine, чтобы удалить IRP из состояния отмены.

  4. Проверьте поле Irp-Cancel>, чтобы определить, следует ли отменить IRP или начать обработку запроса ввода-вывода.

    Если для Irp-Cancel> задано значение TRUE, сделайте следующее:

    • Вызов IoReleaseCancelSpinLock.

    • Задайте для состояния Irp-IoStatus.Status> значение STATUS_CANCELLED.

    • Задайте для Irp-IoStatus.Information> значение 0.

    • Вызовите IoStartNextPacket (в подпрограмме StartIo), чтобы запустить следующий пакет.

    • Вызов IoCompleteRequest с приоритетом повышения IO_NO_INCREMENT для завершения IRP.

    Если для Irp-Cancel> задано значение FALSE, вызовите IoReleaseCancelSpinLock и запустите запрошенную обработку запроса ввода-вывода или передайте IRP следующему нижнему драйверу по мере необходимости.

Драйверы, управляющие собственными очередями IRP, а не с помощью очереди устройств, предоставленной диспетчером ввода-вывода, не нужно получать блокировку отмены при вызове IoSetCancelRoutine. Однако эти драйверы должны проверить указатель подпрограммы Отмены, который возвращает IoSetCancelRoutine, чтобы определить, уже запущена ли подпрограмма отмены.

В любом драйвере, обрабатывающего отменяемые irPs, каждая подпрограмма драйвера, обрабатывающая IRP до того, как базовое устройство было запрограммировано для запрошенной операции ввода-вывода, должно проверить состояние отмены всех входящих IRP. В частности, драйвер устройства высокого уровня с подпрограммами StartIo и ControllerControl должен обрабатывать входящие irPs в обоих этих подпрограммах драйверов, как уже описано.