Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Если драйвер не использует буферизованного или прямого ввода-вывода, диспетчер операций ввода-вывода передает исходные виртуальные адреса пространства пользователя в IRPs, которые он отправляет драйверу. Для безопасного доступа к этим буферам драйвер должен выполняться в контексте вызывающего потока. Как правило, только драйверы высокого уровня, такие как FSD, могут использовать этот метод для доступа к буферам.
Промежуточный или самый низкий уровень драйвера не всегда может соответствовать этому условию. Например, если запрос потока ожидает завершения запроса ввода-вывода или если драйвер более высокого уровня находится на уровне промежуточного или нижнего уровня драйвера, подпрограммы драйвера нижнего уровня вряд ли будут вызываться в контексте запрашивающего потока.
Диспетчер операций ввода-вывода определяет, что операция ввода-вывода не использует буферизованного и прямого ввода-вывода следующим образом:
Для запросов IRP_MJ_READ и IRP_MJ_WRITE ни DO_BUFFERED_IO, ни DO_DIRECT_IO не установлены в элементе Flags структуры DEVICE_OBJECT. Дополнительные сведения см. в инициализации объекта устройства.
Для запросов IRP_MJ_DEVICE_CONTROL и IRP_MJ_INTERNAL_DEVICE_CONTROL значение кода IOCTL содержит METHOD_NEITHER в качестве значения TransferType в значении IOCTL. Дополнительные сведения см. в разделе Определение кодов управления ввода-вывода.
Когда драйвер получает IRP, указывающий операцию ввода-вывода без использования ни буферизованного, ни прямого ввода-вывода, он должен выполнять следующие действия:
Проверьте правильность диапазона адресов буфера пользователя и убедитесь, что предоставлен соответствующий доступ на чтение или запись, используя вспомогательные процедуры ProbeForRead и ProbeForWrite. Драйвер должен заключить свои обращения к диапазону адресов буфера в предоставленный им обработчик исключений, чтобы поток пользователя не мог изменить права доступа к буферу, пока драйвер обращается к памяти. Если проба вызывает исключение, драйвер должен вернуть ошибку. Драйвер должен вызывать эти подпрограммы в контексте потока, который сделал запрос ввода-вывода; таким образом, только драйвер более высокого уровня может выполнять эту задачу.
Управление буферами и операциями памяти одним из следующих способов:
- Выполняйте собственные операции двойной буферизации, как это делает диспетчер операций ввода-вывода для драйверов, использующих буферизованный ввод-вывод. Дополнительные сведения см. в разделе Использование буферизованного ввода-вывода.
- Создайте собственные MDLs и зафиксируйте буфер, вызвав вспомогательные функции диспетчера памяти, так как это делает менеджер ввода-вывода для драйверов, использующих прямой ввод-вывод. Дополнительные сведения см. в "Использование прямого ввода-вывода".
- Выполните все необходимые операции в буфере пользователя непосредственно в контексте вызывающего потока. Драйвер должен упаковать доступ к буферу в обработчике исключений, предоставленном драйвером, если поток пользователя изменяет права доступа к буферу или данным в буфере, пока драйвер обращается к памяти. Для получения дополнительной информации см. Обработка исключений.
В действительности драйвер должен выбирать на основе каждого IRP, делать ли буферированные операции ввода-вывода, прямые операции ввода-вывода или операции ввода-вывода в контексте вызывающего потока, и он должен обрабатывать все исключения, которые могут возникать в контексте потока в пользовательском режиме. Драйвер должен управлять собственным доступом к буферу пользователя, операциями двойного буферизации и сопоставлениями памяти, а не разрешать диспетчеру ввода-вывода обрабатывать эти операции для драйвера.