Программирование драйверов Windows


Адресация и доступ к данным в IRP пакетах чтения/записи - часть 2


Когда обработка запроса ввода/вывода полностью завершена, клиентский буфер де-блокируется и удаляется из схемы распределения системной области памяти.

В том случае, если объект устройства, которому адресован IRР пакет, описан флагом DO_BUFFERED_IO, то драйвер должен взять адрес буферной области из поля IRP пакета AssociatedIrp.SystemBuffer. Данный адрес будет адресом в системном адресном пространстве. Диспетчер ввода/вывода выделяет этот буфер в нестраничной памяти после проверки на доступность предоставленного клиентом буфера. При запросе ввода данных (READ-запрос) Диспетчер ввода/вывода по окончании операции переносит данные из системного буфера в клиентский, а адрес клиентского буфера запоминается в поле IRP пакета UserBuffer. При запросе вывода данных (WRITE-запрос) в системный буфер переносятся данные из клиентского буфера (поле UserBuffer равно NULL). B обоих описанных выше случаях, предоставленные в IRP пакете адреса AssociatedIrp.SystemBuffer можно использовать в произвольном контексте в потоках режима ядра.

В том случае, если устройство не объявило признаков DO_DIRECT_IO или DO_BUFFERED_IO, то Диспетчер ввода/вывода не делает никаких особых действий, а просто помещает адрес буферной области, переданной ему инициатором запроса в поле IRP пакета UserBuffer. Оба поля Associate.SystemBuffer и MdlAddress устанавливаются равными NULL.

В последнем случае помещенный в пoлe UserBuffer виртуальный адрес является "нехорошим" адресом. В большинстве случаев инициатором обращения к драйверу является программный поток пользовательского режима. Соответственно, предоставленный им виртуальный адрес требует для своей корректной интерпретации контекст соответствующего пользовательского потока. Что, разумеется, исключает возможность использования такого адреса в произвольных контекстах режима ядра без предварительной подготовки (подготовки MDL списка и т.п.). Поэтому метод NEITHER можно рекомендовать только для драйверов самых верхних драйверных слоев.

Длина буфера во всех случаях передается в полях Parameters.Write.Length (при WRITE-запросах) или Parameters.Read.Length (при READ-запросах).




Начало  Назад  Вперед