Синхронизация отмены в подпрограммах драйверов, обрабатывающих IRPs
Все подпрограммы драйвера, которые отменяют или вызываются с помощью IRP, который находится в отменяемом состоянии, включая подпрограмму StartIo драйвера, должен выполнять следующие действия:
Вызов IoAcquireCancelSpinLock.
Убедитесь, что Irp равен DeviceObject-CurrentIrp>. В противном случае вызовите IoReleaseCancelSpinLock и контроль возврата.
Если они не совпадают, возможно, CurrentIrp был отменен в период с момента выпуска IoStartPacket блокировки спина отмены, и эта подпрограмма приобрела его.
Вызовите IoSetCancelRoutine с указателем NULL CancelRoutine, чтобы удалить IRP из состояния отмены.
Проверьте поле 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 в обоих этих подпрограммах драйверов, как уже описано.