Отмена запросов ввода-вывода

Выполняющиеся операции ввода-вывода устройства (например, запрос на чтение нескольких блоков с диска) могут быть отменены приложением, системой или драйвером. Если операция ввода-вывода устройства отменена, диспетчер ввода-вывода пытается отменить все необработанные запросы ввода-вывода, связанные с операцией ввода-вывода. Драйверы устройства могут зарегистрироваться, чтобы получать уведомления о попытке диспетчера ввода-вывода отменить запросы ввода-вывода, а драйверы могут отменить собственные запросы, выполнив их с состоянием завершения STATUS_CANCELLED.

Платформа обрабатывает некоторые операции отмены для драйверов на основе платформы. Если операция ввода-вывода устройства отменена, платформа выполняет следующие запросы ввода-вывода (с состоянием завершения STATUS_CANCELLED), связанные с отмененной операцией:

  • Недоставленные запросы ввода-вывода, которые платформа поместила в очередь ввода-вывода драйвера по умолчанию.

  • Недоставленные запросы ввода-вывода, которые платформа перенаправила в другую очередь, так как драйвер называется WdfDeviceConfigureRequestDispatching.

Так как платформа отменяет эти запросы, она не доставляет их драйверу.

После того как платформа доставляет драйверу запрос ввода-вывода, драйверу принадлежит запрос, и платформа не может его отменить. На этом этапе только драйвер может отменить запрос ввода-вывода, но платформа должна уведомить драйвер об отмене запроса. Драйверы получают это уведомление, предоставляя функцию обратного вызова EvtRequestCancel .

Иногда драйвер получает запрос ввода-вывода из очереди ввода-вывода, но вместо обработки запроса драйвер повторно отправляет запрос в ту же или другую очередь ввода-вывода для последующей обработки. Примеры такой ситуации:

  • Платформа доставляет запрос ввода-вывода одному из обработчиков запросов драйвера, а затем драйвер вызывает либо WdfRequestForwardToIoQueue (или WdfRequestForwardToParentDeviceIoQueue), чтобы поместить запрос в другую очередь, либо WdfRequestRequeue , чтобы поместить запрос обратно в ту же очередь.

  • Платформа доставляет запрос ввода-вывода функции обратного вызова EvtIoInCallerContext драйвера, драйвер вызывает WdfDeviceEnqueueRequest , чтобы передать запрос обратно в платформу, и платформа впоследствии помещает запрос в одну из очередей ввода-вывода драйвера.

В таких случаях платформа может отменить запрос ввода-вывода, так как запрос находится в очереди ввода-вывода. Однако если драйвер зарегистрировал функцию обратного вызова EvtIoCanceledOnQueue для очереди ввода-вывода, в которой находится запрос, платформа вызывает функцию обратного вызова вместо отмены запроса при отмене связанной операции ввода-вывода. Если платформа вызывает функцию обратного вызова EvtIoCanceledOnQueue драйвера, драйвер должен завершить запрос.

Таким образом, при отмене операции ввода-вывода платформа всегда отменяет все связанные запросы ввода-вывода, которые никогда не были доставлены драйверу. Если драйвер получает запрос, а затем повторно отправляет его в очередь, платформа отменит запрос (если запрос находится в очереди), если драйвер не предоставляет функцию обратного вызова EvtIoCanceledOnQueue для очереди ввода-вывода.

Вызов WdfRequestMarkCancelable или WdfRequestMarkCancelableEx

Драйвер может вызвать WdfRequestMarkCancelable или WdfRequestMarkCancelableEx для регистрации функции обратного вызова EvtRequestCancel . Если драйвер вызвал WdfRequestMarkCancelable или WdfRequestMarkCancelableEx и операция ввода-вывода, связанная с запросом, отменена, платформа вызывает функцию обратного вызова EvtRequestCancel драйвера, чтобы драйвер мог отменить запрос ввода-вывода.

Драйвер должен вызывать WdfRequestMarkCancelable или WdfRequestMarkCancelableEx , если он будет владеть запросом в течение относительно длительного времени. Например, драйверу может потребоваться дождаться ответа устройства или ждать, пока более низкие драйверы завершат набор запросов, созданных драйвером при получении одного запроса.

Если драйвер не вызывает WdfRequestMarkCancelable или WdfRequestMarkCancelableEx или если драйвер вызывает WdfRequestUnmarkCancelable после вызова WdfRequestMarkCancelable или WdfRequestMarkCancelableEx, драйвер не знает об отмене и, следовательно, обрабатывает запрос, как это обычно.

Вызов WdfRequestIsCanceled

Если драйвер не вызывал функцию обратного вызова EvtRequestCancelable или WdfRequestMarkCancelableEx, он может вызвать WdfRequestIsCancel, чтобы определить, пытался ли диспетчер операций ввода-вывода отменить запрос ввода-вывода. Если WdfRequestIsCanceled возвращает значение TRUE , а драйвер является владельцем запроса, драйвер должен отменить запрос. Если драйвер не владеет запросом, он не должен вызывать WdfRequestIsCanceled.

Драйвер, который не вызывал WdfRequestMarkCancelable или WdfRequestMarkCancelableEx , может вызвать WdfRequestIsCanceled в следующих случаях:

  • Драйвер, ожидающий прерываний устройства, может вызывать WdfRequestIsCanceled из функции обратного вызова EvtInterruptDpc .

  • Драйвер, который опрашивает свое устройство, может вызвать WdfRequestIsCanceled из потока опроса.

  • Драйвер, который разбивает транзакцию DMA на несколько небольших передач, может вызывать WdfRequestIsCanceled после завершения каждой передачи.

  • Драйвер, который получает большой запрос на чтение или запись, который разбивается на несколько небольших запросов, может вызвать WdfRequestIsCanceled после того, как целевой объект ввода-вывода драйвера завершит каждый из небольших запросов, если драйвер не вызвал WdfRequestMarkCancelable или WdfRequestMarkCancelableEx для полученного запроса.

Отмена запроса

Отмена запроса ввода-вывода может включать одно из следующих действий:

  • Остановка выполнения операции ввода-вывода.

  • Не пересылать запрос в целевой объект ввода-вывода.

  • Вызов WdfRequestCancelSentRequest , чтобы попытаться отменить запрос, который драйвер ранее отправил в целевой объект ввода-вывода.

Если драйвер отменяет запрос ввода-вывода для объекта запроса, полученного драйвером от платформы, драйвер всегда должен завершить запрос, вызывая WdfRequestComplete, WdfRequestCompleteWithInformation или WdfRequestCompleteWithPriorityBoost с параметром Status STATUS_CANCELLED. (Если драйвер вызвал WdfRequestCreate для создания объекта запроса, драйвер вызывает WdfObjectDelete вместо завершения запроса.)

Синхронизация отмены

Сведения о синхронизации кода, отменяющего запросы ввода-вывода, см. в разделе: