Реализация процедуры отмены
Диспетчер ввода-вывода вызывает предоставленную драйвером подпрограмму 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 с удержанием спин-блокировки может привести к взаимоблокировкам.