Методы отправки для запросов ввода-вывода
Когда драйвер вызывает WdfIoQueueCreate для создания очереди ввода-вывода, он задает метод отправки для очереди. Фреймворк предоставляет три метода диспетчеризации: последовательный, параллельныйи ручной. Драйвер может указать любой из этих методов диспетчеризации для любой очереди ввода-вывода, включая очередь ввода-вывода устройства по умолчанию .
Драйвер задает метод отправки очереди, указав WDF_IO_QUEUE_DISPATCH_TYPEтипизированное значение в структуре WDF_IO_QUEUE_CONFIG очереди.
Пример использования каждого метода диспетчеризации см. в разделе Пример использования очередей ввода-вывода.
последовательная диспетчеризация
Если драйвер или устройство могут обрабатывать только один запрос ввода-вывода из очереди за раз, следует настроить очереди ввода-вывода устройства для использования последовательной диспетчеризации, также известной как синхронная диспетчеризация. С помощью этого типа отправки платформа отправляет запросы драйверу по одному за раз. Фреймворк не обрабатывает следующий запрос, пока драйвер не завершит, не отменитили не повторно поставит предыдущий запрос.
После того как платформа отправляет запрос одному из обработчиков запросов драйвера, драйвер обрабатывает запрос. Если драйвер перенаправит запрос на общий целевой объект ввода-вывода , он обычно вызывает один из его синхронных методов. Дополнительные сведения об этих методах см. в Синхронная отправка запросов ввода-вывода. Драйвер должен в конечном итоге завершить или отменить каждый запрос, полученный из очереди ввода-вывода.
Драйвер, настроивший очередь ввода-вывода для последовательной отправки, может вызывать WdfIoQueueRetrieveNextRequest или WdfIoQueueRetrieveRequestByFileObject для получения другого запроса из очереди до завершения или отмены последнего полученного запроса. Это может быть полезно сделать в функциональном драйвере, чтобы драйвер мог инициировать следующую аппаратную операцию, пока функция обратного вызова драйвера EvtInterruptDpc продолжает обрабатывать данные от предыдущей операции с аппаратным обеспечением.
Если вы создаете несколько очередей ввода-вывода и настраиваете их для последовательной отправки, платформа отправляет запросы из каждой очереди последовательно, но очереди выполняются параллельно. Если драйвер или устройство могут обрабатывать только один запрос в любое время, необходимо использовать одну очередь ввода-вывода с функцией обратного вызова EvtIoDefault.
Параллельная Диспетчеризация
Если драйвер и устройство могут одновременно обрабатывать несколько запросов ввода-вывода, можно настроить очереди ввода-вывода устройства для использования параллельной отправки, чтобы драйвер может обрабатывать запросы асинхронно. Этот метод диспетчеризации также называется асинхронная диспетчеризация.
Если драйвер настраивает очередь ввода-вывода для использования параллельной отправки, платформа отправляет запросы ввода-вывода драйверу, как только они доступны в очереди. Результатом является то, что драйвер может одновременно обрабатывать несколько запросов.
Каждый раз, когда один из обработчиков запросов драйвера получает запрос, драйвер должен обработать запрос, а затем завершить запроса. Если драйвер перенаправит запрос на общий целевой объект ввода-вывода , он обычно вызывает один из его асинхронных методов. Дополнительные сведения об этих методах см. в асинхронной отправке запросов ввода-вывода. Драйвер должен в конечном итоге завершить или отменить каждый запрос, полученный из очереди ввода-вывода.
Драйвер, использующий параллельную диспетчеризацию, может вызывать WdfIoQueueStop или WdfIoQueueStopSynchronous, чтобы временно остановить очередь, а затем вызвать WdfIoQueueStart для перезапуска очереди.
Ручной режим отправки
Если вы хотите, чтобы драйвер имел полный контроль над управлением запросами ввода-вывода, можно настроить очередь ввода-вывода устройства для использования ручной отправки, что означает, что фреймворк не передает запросы драйверу, если драйвер явно не запрашивает запрос.
Чтобы получить запрос из ручной очереди, драйвер может вызывать WdfIoQueueRetrieveNextRequest или WdfIoQueueRetrieveRequestByFileObject в цикле, который опрашивает очередь. Кроме того, драйвер может вызывать WdfIoQueueReadyNotify для регистрации функции обратного вызова, которую платформа будет вызывать, когда один или несколько запросов доступны в очереди. После вызова функции обратного вызова драйвер может вызывать WdfIoQueueRetrieveNextRequest или WdfIoQueueRetrieveRequestByFileObject в цикле для получения запросов.
Когда драйвер получает запрос из очереди, он должен обработать запрос. Драйвер должен в конечном итоге завершить или отменить каждый запрос.