Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
203
Добавлен:
20.02.2016
Размер:
95.23 Кб
Скачать

Лекция №9. Многоуровневая модель драйверов. Уровневые драйвера и драйвера-фильтры. [9.1] Понимание многоуровневой модели драйверов

На лекции 7 в разделе [7.1] “Подсистема в/в и её характеристики” в качестве одной из характеристик подсистемы в/в упоминалась ее многоуровневость. Что это такое?

NT позволяет выстраивать драйвера в соответствии с некоторой функциональной иерархией. При этом, например, одни драйвера имеют своей единственной целью обмен данными с некоторым физическим устройством. Что это за данные и что с ними делать, такие драйвера не знают. Другие драйвера выполняют обработку данных, но не знают в точности, как эти данные получены и как будут отправлены. Такая концепция разделения полномочий драйверов носит название многоуровневой (или послойной) модели драйверов (layered driver model), а сами драйвера – уровневыми драйверами (layered drivers).

В NT 4 концепция многоуровневых драйверов занимает важное место, но ее использование не является обязательным требованием.

В NT 2000 все драйвера, считающиеся родными, будут уровневыми (для того, чтобы драйвер считался родным для W2K, он должен как минимум поддерживать управление питанием, а для этого он должен быть уровневым). Большинство драйверов, которые в NT4 мы считали монолитными, в NT 2000 будут по своей сути уровневыми.

Будем выделять следующие типы драйверов:

  • Драйвера, представляющие некоторый уровень в многоуровневой архитектуре. Далее именно эти драйвера мы будем называть уровневыми драйверами.

  • Драйвера-фильтры

  • Драйвера файловой системы (File System Driver - FSD)

  • Мини-драйвера(mini-driver)

Для каждого типа драйверов существует свой протокол реализации многоуровневой структуры. Мы рассмотрим только уровневые драйвера и драйвера-фильтры.

[9.2] Реализация уровневых драйверов

Стек драйверов обычно создается самими драйверами. Корректное создание стека зависит от правильной последовательности и момента загрузки каждого драйвера из стека. Первыми должны грузиться драйвера самого нижнего уровня и т.д.

При рассмотрении организации стека драйверов необходимо понимание трех моментов:

  1. Объединение драйверов в стек

  2. Обработка запросов IRP стеком

  3. Освобождение драйверов стека

IoGetDeviceObjectPointer(), возвращающая указатель на именованный объект-устройство драйвера нижележащего уровня, и IoCallDriver(), посылающая драйверу нижележащего уровня пакет IRP.

[9.2.1] Объединение драйверов в стек и освобождение драйверов стека

Для объединения драйверов в стек обычно используется функция IoGetDeviceObjectPointer(). Функция вызывается драйвером вышележащего уровня для получения указателя на объект-устройство драйвера нижележащего уровня по его имени.

Функция имеет следующий прототип:

NTSTATUS IoGetDeviceObjectPointer(

IN PUNICODE_STRING ObjectName,

IN ACCESS_MASK DesiredAccess,

OUT PFILE_OBJECT FileObject,

OUT PDEVICE_OBJECT DeviceObjct);

ObjectName: Имя требуемого Объекта-устройство.

DesiredAccess: Требуемый доступ к указанному Объекту-устройство.

FileObject: Указатель на Объект-файл, который будет использоваться для обращения к устройству.

DeviceObject: Указатель на Объект-устройство с именем ObjectName.

Прототип функции IoGetDeviceObjectPointer().

Функция IoGetDeviceObjectPointer() принимает имя Объекта-устройство, и возвращает указатель на Объект-устройство с этим именем. Функция работает, посылая запрос CREATE на названное устройство. Этот запрос будет неудачным, если никакого устройства по имени ObjectName не существует, или вызывающая программа не может предоставить доступ, указанный в параметре DesiredAccess. Если запрос CREATE успешен, создается Объект-файл, что увеличивает счетчик ссылок Объекта-устройство, с которым связан Объект-файл. Затем Диспетчер в/в искусственно увеличивает счетчик ссылок на Объект-файл на единицу, и посылает на устройство запрос CLOSE. В результате всего этого процесса, Объект-устройство (чей указатель возвращен в DeviceObject) не может быть удален, пока не обнулится счетчик ссылок соответствующего ему Объекта-файл. Таким образом, Объект-устройство нижнего уровня не может быть удален, в то время как драйвер вышележащего уровня имеет указатель на него.

Выделим из всего вышесказанного, что функция предусматривает в качестве выходного параметра указатель на Объект-файл специально для того, чтобы при выгрузке стека драйверов освободить устройство нижележащего уровня. Это должно быть сделано в функции Unload драйвера вышележащего уровня с помощью вызова функции ObDereferenceObject( FileObject ).

После получения указателя на объект-устройство драйвера нижележащего уровня, драйвер вышележащего уровня должен установить корректное значение полей Characteristics, StackSize, Flags и AlignmentRequirement своего объекта-устройство. Поля Characteristics, Flags и AlignmentRequirement объектов-устройств всех драйверов в стеке должны совпадать, а значение поля StackSize вышележащего устройства должно быть на 1 больше значения этого поля у нижележащего устройства.

Соседние файлы в папке Лабы по драйверам