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

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

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

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

Подпрограмма Отмена для основного IRP, у которого есть связанные IRP, отвечает за вызов IoCancelIrp для отмены этих связанных IRP.

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

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

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

  • Выполните указанный IRP путем вызова IoCompleteRequest.

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

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

  • Если он вызывает IoAcquireCancelSpinLock, процедура Cancel должна вызвать функцию IoReleaseCancelSpinLock как можно быстрее.

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