Передача данных от приложения к драйверу. Асинхронная обработка.
Код пользовательского уровня не может напрямую вызвать код режима ядра. Для этого существуют специальные прерывания. Одним из них является прерывание 2Е – вызов системного сервиса. Диспетчер ввода/вывода обрабатывает вызовы системных сервисов специальным образом (см. рис. 9). В своем обработчике системного сервиса он создает специальный запрос ввода/вывода IRP и передает его на обработку некоторому объекту-устройству, после чего работа обработчика может завершиться, но обработка IRP при этом может быть не закончена.
Рис. 9.Обработка вызовов системных сервисов Диспетчером ввода/вывода
Модель ввода/вывода, предусматривающая завершение функции ввода/вывода до завершения запроса ввода/вывода называется асинхронным вводом/выводом. Асинхронный ввод/вывод позволяет программе запросить выполнение операции ввода/вывода, после чего продолжать выполнение другой операции, пока устройство не закончит пересылку данных. Система ввода/вывода автоматически уведомляет программу о завершении операции ввода/вывода.
Модель ввода/вывода, обеспечиваемая Диспетчером ввода/вывода, асинхронна всегда, хотя этот факт может быть скрыт функциями подсистемы окружения. Например, так происходит в случае функции CreateFile(). Эта функция не является асинхронной, хотя пользуется асинхронной функцией NtCreateFile().
При асинхронном вводе/выводе более поздний по времени запрос ввода/вывода может быть закончен до завершения более ранних запросов.
Вызов прерывания и переключение процессора в режим ядра не влияют на текущий контекст памяти. Из этого следует, что при обработке вызова системного сервиса и Диспетчер памяти, и соответствующая точка входа драйвера работают в контексте памяти процессора – инициатора запроса ввода/вывода.
В случае, когда устройство обрабатывает запрос ввода/вывода сразу при его поступлении, диспетчеру ввода/вывода не требуется переключение контекста памяти для уведомления процесса о завершении запроса.
В случае, когда устройство отложило запрос в очередь запросов, в тот момент, когда подошла очередь запроса на обработку, контекст памяти будет неизвестен – случайный контекст памяти. При этом диспетчеру ввода/вывода понадобится механизм уведомления нужного процесса о завершении запроса ввода/вывода. Таким механизмом является механизм Асинхронного Вызова Процедуры (Asynchronous procedure call, АРС). Вкратце он состоит в том, что прикладная программа предоставляет диспетчеру ввода/вывода адрес функции, которая должна быть вызвана при завершении запроса ввода/вывода. При запросе АРС диспетчер ввода/вывода указывает этот адрес и поток, в котором должна быть вызвана эта функция. АРС запрашивается с помощью генерации специального прерывания на уровне IRQL равном APC_LEVEL. Запрос АРС откладывается в очередь АРС и будет выполнен, когда управление получит нужный поток и текущий уровень IRQL будет меньше APC_LEVEL.