Отмена запросов ввода-вывода в UMDF
Предупреждение
UMDF 2 является последней версией UMDF и заменяет UMDF 1. Все новые драйверы UMDF должны быть написаны с помощью UMDF 2. Новые функции не добавляются в UMDF 1, а поддержка UMDF 1 в более новых версиях Windows 10 ограничена. Универсальные драйверы Windows должны использовать UMDF 2.
Архивные примеры UMDF 1 можно найти в Windows 11 версии 22H2 — обновление примеров драйверов за май 2022 г.
Дополнительные сведения см. в разделе начало работы с помощью UMDF.
Выполняющиеся операции ввода-вывода устройства (например, запрос на чтение нескольких блоков с диска) могут быть отменены приложением, системой или драйвером. Если операция ввода-вывода устройства отменена, диспетчер ввода-вывода пытается отменить все необработанные запросы ввода-вывода, связанные с операцией ввода-вывода. Драйверы устройства могут регистрироваться для получения уведомлений, когда диспетчер ввода-вывода пытается отменить запросы ввода-вывода, а драйверы могут отменять собственные запросы, завершив их с состоянием завершения HRESULT_FROM_WIN32 (ERROR_OPERATION_ABORTED).
Платформа обрабатывает некоторые действия по отмене для драйверов на основе платформы. Если операция ввода-вывода устройства отменена, платформа завершает с состоянием завершения HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED) следующие запросы ввода-вывода, связанные с отмененной операцией:
Недоставленные запросы ввода-вывода, которые платформа поместила в очередь ввода-вывода драйвера по умолчанию.
Недоставленные запросы ввода-вывода, которые платформа перенаправила в другую очередь, так как драйвер называется IWDFIoQueue::ConfigureRequestDispatching.
Так как платформа отменяет эти запросы, она не доставляет их драйверу.
После того как платформа доставляет драйверу запрос ввода-вывода, он принадлежит драйверу, и платформа не может отменить его. На этом этапе только драйвер может отменить запрос ввода-вывода, но платформа должна уведомить драйвер о том, что запрос должен быть отменен. Драйверы получают это уведомление, предоставляя функцию обратного вызова IRequestCallbackCancel::OnCancel .
Иногда драйвер получает запрос ввода-вывода из очереди ввода-вывода, но вместо обработки запроса драйвер повторно отправляет запрос в ту же или другую очередь ввода-вывода для последующей обработки. Например, платформа может доставлять запрос ввода-вывода одному из обработчиков запросов драйвера, а затем драйвер может вызвать IWDFIoRequest::ForwardToIoQueue , чтобы поместить запрос в другую очередь, или IWDFIoRequest2::Requeue , чтобы поместить запрос обратно в ту же очередь.
В таких случаях платформа может отменить запрос ввода-вывода, так как запрос находится в очереди ввода-вывода. Однако если драйвер зарегистрировал функцию обратного вызова для очереди ввода-вывода, в которой находится запрос, платформа вызывает функцию обратного вызова вместо отмены запроса при отмене связанной операции ввода-вывода. Если платформа вызывает функцию обратного вызова драйвера, драйвер должен отменить запрос.
Таким образом, при отмене операции ввода-вывода платформа всегда отменяет все связанные запросы ввода-вывода, которые никогда не были доставлены драйверу. Если драйвер получает запрос, а затем отправляет его в очередь, платформа отменит его (если запрос находится в очереди), если драйвер не предоставляет функцию обратного вызова для очереди ввода-вывода.
Вызов MarkCancelable
Драйвер может вызвать IWDFIoRequest::MarkCancelable для регистрации функции обратного вызова IRequestCallbackCancel::OnCancel . Если драйвер вызвал MarkCancelable и операция ввода-вывода, связанная с запросом, отменена, платформа вызывает функцию обратного вызова OnCancel драйвера, чтобы драйвер мог отменить запрос ввода-вывода.
Драйвер должен вызвать MarkCancelable , если он будет владеть запросом в течение относительно длительного времени. Например, драйверу может потребоваться дождаться ответа устройства или ждать, пока драйверы меньшего числа, чтобы выполнить набор запросов, созданных драйвером при получении одного запроса.
Если драйвер не вызывает MarkCancelable или если драйвер вызывает IWDFIoRequest::UnmarkCancelable после вызова MarkCancelable, драйвер не знает об отмене и поэтому обрабатывает запрос, как это обычно делается.
Вызов IsCanceled
Если драйвер не вызвал MarkCancelable для регистрации функции обратного вызова OnCancel , он может вызвать IWDFIoRequest2::IsCanceled , чтобы определить, пытается ли диспетчер ввода-вывода отменить запрос ввода-вывода. Если IsCanceled возвращает значение TRUE, драйвер должен отменить запрос.
Например, драйвер, получающий большой запрос на чтение или запись, который разбивается на несколько небольших запросов, может вызвать IsCanceled после того, как целевой объект ввода-вывода драйвера завершит каждый из небольших запросов, если драйвер не вызвал MarkCancelable для полученного запроса.
Отмена запроса
Отмена запроса ввода-вывода может включать в себя одно из следующих действий:
Остановка выполнения операции ввода-вывода.
Не пересылать запрос в целевой объект ввода-вывода.
Вызов IWDFIoRequest::CancelSentRequest для попытки отменить запрос, который драйвер ранее отправил в целевой объект ввода-вывода.
Если драйвер отменяет запрос ввода-вывода для объекта запроса, полученного драйвером от платформы, драйвер всегда должен завершить запрос, вызывая IWDFIoRequest::Complete или IWDFIoRequest::CompleteWithInformation с параметром CompletionStatus HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED). (Если драйвер вызвал IWDFDevice::CreateRequest для создания объекта запроса, драйвер вызывает IWDFObject::D eleteWdfObject вместо завершения запроса.)