Wdm integrated driver что это
Перейти к содержимому

Wdm integrated driver что это

  • автор:

Структура WDM драйвера и как работает ПК

Хочется представить хотя бы упрощенно общий принцип взаимодействия устройства с ПК. Мои рассуждения. Вот запускаем мы ПК. Счетчик команд главного процесcора равен 0. По этому адресу находится вход в программу BIOS. Уже на этом этапе нужно загружать драйвера системной шины, разных там портов, потом с помощью них сканируються все устройства, загружается таблица реестра, грузится сама ОС. Хотелось бы услышать как это работает на самом деле. Понимаю что это очень обширная тема, не надо посылать читать многочисленные тома, я хочу уловить только суть, чтобы потом подходить и изучать более подробные вопросы как бы глядя с высока.
И вот второе, что очень интересует, собственно по WDM драйверу, вот смотрю картинку иерархия обьектов устройств и драйверов. В самом низу находится драйвер шины — он управляет структурой ядра PDO, далее может быть фильтрующий драйвер, но считаем что его нет, а идет функциональный драйвер — и управляемая им структура FDO. Так вот. интересует — эти структуры заранее предопределены, то есть драйвером HOL. Я себе представляю это так. Есть материнская плата, в ней порты PCI, IDE, SATA и т д. Берем допустим PCI разьем — физически это всего n-ное количество выводов. Вся работа с ним производится через драйвер шины PCI. И вот ОС при загрузке описывает каждый порт и возможные для него функции через структуру PDO. Я так думаю эта структура представляет реальные PIN порта (его адреса), а также указатели — в которые мы можем поместить адреса функций для работы с портом. Эти функции определены в ядре, мы только выбираем что включить, что отключить, можем переопределять их.

Так вот эта структура PDO создается автоматически — вернее ее шаблон для конкретного разьема в момент подключения оборудования, а мы можем его конкретизировать с помощью драйвера шины, или можно полностью программировать PDO с ноля?
Обьект FDO — аналогично, что это? — то же что и PDO — только структура с более высокоуровневыми командами, которые выполняются через функции обьекта PDO?
Просветите, хотя бы в общих чертах.

Что такое wdm integrated driver

WDM works by channeling some of the work of the device driver into portions of
the code that are integrated into the operating system. These portions of code. This section describes the Windows Driver Model (WDM), and discusses types of
WDM drivers, device configuration, driver layering, and WDM versioning. Note: AMD Скачать ATI 690 Series Catalyst Software Suite v.10.2.
Производитель:ATI. Оборудование:ATI 690 Series. Название:WDM Integrated
Driver.

Windows Driver Model — Wikipedia, la enciclopedia libre

Драйверы для ATI 690 Series — Driver.ru

The official ATI Catalyst driver package is suitable for all desktop ATI graphics
need the full Catalyst Software Suite which includes the WDM Integrated Driver. Однако обычно более новый стандарт WDM Например, если TV-тюнер
использует VxD-драйвер, это. Note Drivers for versions of Windows NT-based operating systems before
Windows 2000 are not supported, and you should update these drivers. The
WDM. Windows driver model (WDM) es una estrategia de Microsoft para facilitar un
desarrollo simple de drivers para dispositivos compatibles Microsoft Windows 98,
.

Windows Driver Model — Wikipedia

Простейший WDM-драйвер / Хабрахабр

Описание:ATI Catalyst 9.7 for Windows Vista 64-bit, Windows 7 64-bit. Display
Driver ATI WDM Integrated Driver Catalyst Control Center (English Language. 1 июл 2012 В данной статье описан процесс написания простейшего драйвера, который
выводит скан-коды нажатых клавиш. Также в данной.

TweakGuides.com — ATI Catalyst Tweak Guide

Что такое WDM Driver

В хепле Windows Driver Development Kit написано следующее
Windows Driver Model (WDM) Defined
Any kernel-mode device driver that conforms to the Windows Driver Model (WDM) is called a WDM driver. WDM defines a unified approach to writing kernel-mode device drivers for all Windows operating systems.

Any device driver that will run on Windows 2000 and later operating systems must be a WDM driver. With a few special-case statements in the code, WDM drivers can be source-compatible across Windows 98, Windows Me and Windows 2000 and later operating systems. For more information, see Introduction to WDM.

If you are writing a new WDM driver, you should consider using Kernel-Mode Driver Framework (KMDF). KMDF interfaces are simpler to use than WDM interfaces. For more information about KMDF, see Getting Started with Kernel-Mode Driver Framework.

Wdm integrated driver что это

В продолжение предыдущего раздела хотелось бы отметить, что в конечном итоге, компания Microsoft разработала новую технологию — WDM (Windows Driver Model) — и вклю­чила ее в Windows 98 и Windows Me, наследников Windows 95. Кроме того, новая технология была включена в Windows 2000 и Windows ХР, наследников Windows NT 4.0 [7]. WDM предоставляла разработчикам драйверов доступ к практически полному диапазону технологий и интерфейсов, доступных для мира ядра Windows.

Вот теперь мы уже заговорили о таком понятии, как «драйверная модель» напрямую. Возможно, кому-то будет интересно узнать, что же это такое. Так вот, драйверная модель предоставляет собой абстрактный интерфейс для поддерж­ки устройств. Задача разработчиков драйверов как раз и состоит в реализации данного интерфейса, чтобы поддерживать конкретные требования аппаратного устройства. Выражаясь более простым языком, задачей драйвера является предоставление связи и контролирование взаимодействия между приложениями и устройством.

Я думаю, нет необходимости в подробностях объяснять, что представляет собой драйвер, как он «пишется», как выполняется под управлением операционной системы и проч., ибо это тема заслуживает отдельного доклада. Скажу лишь то, что драйвер представляет собой «контейнер» для функций, которые самостоятельно вызываются операционной системой в нужный момент (когда она сочтет нужным). Да-да, здесь нет ничего мистического. Другое дело, что драйверы обычно выполняются в доверенном пространстве ядра, хотя, в драйверной модели WDF драйверы UMDF выполняются в пользовательском режиме, но об этом мы еще поговорим.

Архитектура wdm

Ни для кого не секрет, что тема драйверов достаточно объемная и сложная, поэтому мы не будем уходить в «дебри» системного низкоуровнего программирования, а рассмотрим лишь в общих чертах особенности драйверных моделей. А для большей наглядности, рассмотрим архитектуру WDM на небольшом примере.

Допустим, програм­ме пользовательского режима потребовалось прочитать данные с устройства. Она вызывает функцию API ReadFile, к примеру. Модуль подсистемы — такой как KERNEL32.DLL — реализует вызов, передавая его к низ­коуровневой функции API NtReadFile [7]. Низкоуровневый API – довольно важная составляющая WDM да и архитектуры Windows в целом, но о нем чуть позже.

Такие функции, как, например, NtReadFile, является частью системного компонента, на­зываемого менеджером ввода/вывода (I/O Manager). Следует иметь ввиду, что в самой системе не существует конкретного исполняемого модуля с таким именем. Тем не менее, нам потребуется какое-то название для обозначения «облака» функций опера­ционной системы, окружающего драйвер.

В рассматриваемом примере с ReadFile функция NtReadFile создает IRP с основным кодом функ­ции IRP_MJ_READ. Дальнейшее может различаться в деталях, но чаще всего та­кие функции, как NtReadFile, возвращают управление вызывающей стороне поль­зовательского режима [7].

А теперь немного поводу низкоуровнего API. Низкоуровневый API представляет интерфейс, который позволяет «клиентским» приложениям обращаться к программам (в данном контексте — драйверам) режима ядра. Дело в том, что каждая точка входа данного API является тонкой оберткой для функции режима ядра. Все они проверяют свои параметры, предотвращая возможные дефекты безопас­ности. Сам вызов использует платформенно-зависимый интерфейс для передачи управления через границу пользовательского режима/режима ядра (например, инструкции ассемблера и т.п.). Функции низкоуровнего API работают в режиме ядра и обслуживают запросы приложений на обращение к устройству. Как правило, они создают структуру данных, называемую пакетом запроса ввода-вывода, или IRP (I/O Request Packet), и передают ее в точке входа некоторому драйверу устройства.

Для выполнения запроса IRP драйверу, в конечном счете, потребу­ется обратиться к своему устройству. Драйверы, хотя они и работают в режиме ядра и могут напрямую общаться с оборудованием, используют сред­ства прослойки HAL (Hardware Abstraction Layer) для обращения к оборудова­нию. Функции HAL используют платформенно-зависимую реализацию для выполнения операций. Закончив операцию ввода/вывода, драйвер завершает обработку IRP, вызывая соответствующую функцию режима ядра. Завершение является последним эта­пом обработки IRP и позволяет ожидающему приложению продолжить работу. Для большей наглядности рекомендую обратиться к рисунку 1.

Рисунок 1 – Принцип работы драйверов WDM

Вот, собственно, по такому принципу и работают драйверы WDM. Конечно, то, что мы рассмотрели, это, примерно, сотая часть архитектуры WDM и всего того, что с ней связано. Однако, в рамках статьи, надеюсь, вполне достаточно.

Итак, вот несколько ключевых особенностей драйверной модели WDM (по сравнению с предыдущей драйверной моделью – «драйвер виртуального устройства», применяемой в Windows 9x/ME)[2, 3, 5]:

Совместимость на уровне двоичных кодов между драйверами для Windows 98 и NТ;

Поддержка управления питанием (power management), что дает системе возможность осуществления энергосбережения путем выборочного отключения питания нескольких или всех устройств в системе;

Поддержка Plug and Play;

Поддержка «продвинутого» шинного управления (advanced bus management);

Единая обработка операций ввода/вывода посредством общей структуры данных — IRP (в Windows 98/Ме существовали серьезные различия в работе с дисками, коммуникационными портами, клавиатурами и т. д.).

Форум МИРа NVIDIA

Гость«Операционные системы Windows 98 SE и Windows 2000, равно как и их потомки, поддерживают новую модель драйверов, получившую название WDM (Windows Driver Model). Это – попытка реализовать полную поддержку Plug&Play и ACPI, то есть дать возможность загружать и выгружать драйверы «на ходу», без перезагрузки системы, подключать их в виде фильтров-расширений к стандартным драйверам Microsoft, более гибко управлять энергосбережением и конфигурацией устройств и т.п. WDM-драйверы хранятся в каталоге SYSTEM32/DRIVERS. В частности, интерфейсы нового поколения USB и IEEE-1394 (FireWire) работают только под управлением WDM-драйверов»

Простейший WDM-драйвер

В данной статье описан процесс написания простейшего драйвера, который выводит скан-коды нажатых клавиш.
Также в данной статье описан процесс настройки рабочего места для написания драйверов.
Если Вам интересно, прошу под кат.

Подготовка стенда
Установка необходимого ПО для написания простейшего драйвера
  1. Windows DDK (Driver Development Kit);
  2. VMware Workstation или Virtual Box;
  3. Windows XP;
  4. Visual Studio 2005;
  5. DDKWizard;
  6. KmdManager
  7. DebugView;
Настройка рабочего места
Установка DDK

Установка предельно проста. Единственное на что необходимо обратить внимание — это диалог, в котором Вам предлагается выбрать компоненты, которые будут установлены. Настоятельно рекомендую отметить всю документацию и примеры.

Установка и настройка Microsoft® Visual Studio 2005

Установка Microsoft® Visual Studio 2005 ничем не сложнее установки DDK. Если Вы будете использовать её только для написания драйверов, то когда инсталлятор спросит какие компоненты необходимо установить, выберите только Visual C++.
Далее можно установить Visual Assist X. С помощью этой программы (аддона) можно будет легко настроить подсказки для удобного написания драйверов.
После установки Visual Assist X в Visual Studio 2005 появится новое меню VAssistX. Далее в этом меню: Visual Assist X Options -> Projects -> C/C++ Directories -> Platform: Custom, Show Directories for: Stable include files . Нажимаем Ins или на иконку добавить новую директорию и в появившейся строке, если у вас Windows XP вписываем %WXPBASE%\inc\ddk\wxp .

Установка и настройка DDKWizard
  • Создать системные (рекомендуется) или пользовательские переменные со следующими именами и значением, которое соответствует пути к DDK
    Версия DDK Имя переменной Путь по умолчанию
    Windows XP DDK WXPBASE C:\WINDDK\2600
    Windows 2003 Server DDK WNETBASE C:\WINDDK\3790.1830
    Windows Vista/Windows 2008 Server WDK WLHBASE
    Windows 7/Windows 2008 Server R2 WDK W7BASE
Установка необходимого ПО для запуска драйверов
  • DebugView (link) — это утилитка, которая позволяет просматривать отладочный вывод как режима пользователя так и режима ядра.
  • KmdManager (link) — утилита динамической загрузки/выгрузки драйверов
Постановка задачи

Задача: написать драйвер, который будет выводить в дебаг скан-коды нажатых клавиш и их комбинаций.

Немного теории
  • драйверы классов;
  • минидрайверы;
  • функциональные драйверы;
  • фильтрующие драйверы.

Необязательно определять все возожные функции в своем драйвере, но он обязательно должен содержать DriverEntry и AddDevice .

IRP — это структура, которая используется драйверами для обмена данными.

  • верхние фильтрующие драйверы;
  • нижние фильтрующие драйверы.
Отличия между верхними и нижними фильтрующими драйверами

Через верхние фильтрующие драйверы проходят все запросы, а это значит, что они могут изменять и/или фильтровать информацию, идущую к функциональному драйверу, ну и далее, возможно, к устройству.
Пример использования верхних фильтрующих драйверов:
Фильтр-хук драйвер, который устанавливает свою хук-функцию для системного драйвера IpFilterDirver, для отслеживания и фильтрации траффика. Такие драйверы используются в брандмауэрах.

Через нижние фильтрующие драйверы проходит меньше запросов потому что большинство запросов выполняет и завершает функциональный драйвер.

Проблемы синхронизации

В драйвере, который мы будем писать, есть несколько «проблемных» секций. Для нашего драйвера вполне достаточно использования ассемблерных вставок:

Префикс lock позволяет безопасно выполнить идущую за ним команду. Она блокирует остальные процессоры, пока выполняется команда.

Экшен

Для начала необходимо включить заголовочные файлы «ntddk.h», «ntddkbd.h»

Также необходимо описать структуру DEVICE_EXTENSION

Объект pLowerDO это объект устройства, который находится ниже нас в стеке. Он нужен нам для того чтобы знать кому дальше отправлять IRP-пакеты.
Еще для работы нашего драйвера нам нужна переменная, в которой будет храниться количество не завершенных запросов.

Начнем с функции, которая является главной точкой входа нашего драйвера.

theDriverObject – объект драйвера, содержит указатели на все необходимые операционной системе функции, которые мы должны будем инициализировать.
ustrRegistryPath – имя раздела в реестре, где хранится информация о данном драйвере.
Для начала необходимо объявить и обнулить переменные:

Далее, как я и писал выше, нужно инициализировать указатели на функции

Функция DispatchRead будет обрабатывать запросы на чтение. Она будет вызываться, когда нажата или отпущена клавиша клавиатуры.
Функция DriverUnload вызывается, когда драйвер уже не нужен и его можно выгрузить из памяти, или когда пользователь сам выгружает драйвер. В данной функции должна производиться «зачистка», т.е. освобождаться ресурсы, которые использовались драйвером, завершаться все незавершенные запросы и т.д.
Функция DispatchThru это функция-заглушка. Все что она делает это передача IRP-пакета следующему драйверу (драйверу который находится под нашим в стеке, т.е. pLowerDO из DEVICE_EXTENSION ).
Далее мы вызываем нашу функцию, для создания и установки нашего устройства в стек устройств:

Эту функцию я опишу чуть ниже.
Возвращаем status , в котором, если функция InstallFilter завершилась удачей, хранится значение STATUS_SUCCESS .
Переходим к функции InstallFilter . Вот её прототип:

Эта функция создает объект устройства, настраивает его и включает в стек устройств поверх \\Device\\KeyboardClass0

pKeyboardDevice – это объект устройсва, которое мы должны создать.
Вызываем IoCreateDevice для создания нового устройства

  • Первый аргумент это объект драйвера, который мы получили как параметр функции InstallFilter. Он передается в IoCreateDevice для того чтобы установить связь между нашим драйвером и новым устройством.
  • Третий параметр это имя устройства
  • Четвертый параметр это тип устройства
  • Пятый параметр это флаги, которые обычно устанавливаются для запоминающих устройств.
  • Шестой параметр описывает можно ли открывать манипуляторы устройства в количестве больше одного. Если FALSE можно открыть только один манипулятор. Иначе можно открыть любое количество манипуляторов.
  • Седьмой параметр это память, в которой будем сохранен созданный объект устройства.

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

Функция IoAttachDevice внедряет наше устройство в стек. В pdx->pLowerDO будет храниться объект следующего (нижнего) устройства.

Далее разберем функцию DispatchRead с прототипом:

Данная функция будет вызываться операционной системой при нажатии или отпускании клавиши клавиатуры
Увеличиваем счетчик незавершенных запросов

Перед тем как передать запрос следующему драйверу мы должны настроить указатель стека для драйвера. IoCopyCurrentIrpStackLocationToNext копирует участок памяти, который принадлежит текущему драйверу, в область памяти следующего драйвера.
Когда запрос идет вниз по стеку в нем еще нет нужных нам данных, поэтому мы должны задать функцию, которая вызовется, когда запрос будет идти вверх по стеку с нужными нам данными.

где ReadCompletionRoutine наша функция.
Передаем IRP следующему драйверу:

Теперь разберем функцию, которая будет вызываться каждый раз при завершении IRP . Прототип:

Структура PKEYBOARD_INPUT_DATA используется для описания нажатой клавиши.

Проверяем, удачно завершен запрос или нет

Чтобы достать структуру KEYBOARD_INPUT_DATA нужно обратиться к системному буферу IRP -пакета.

Узнаем количество клавиш

И выводим каждую клавишу:

И не забываем уменьшать количество не обработанных запросов

Возвращаем статус запроса

Разберем функцию завершения работы. Прототип:

Извлекаем устройство из стека:

Проверяем есть незавершенные запросы или нет. Если мы выгрузим драйвер без этой проверки, при первом нажатии на клавишу после выгрузки будет БСоД.

Как запустить драйвер и просмотреть отладочную информацию

Для запуска драйвера я использовал утилиту KmdManager. Для просмотра отладочной информации использовалась утилита DbgView.

P. S. Статью писал давно, ещё на третьем курсе, сейчас уже почти ничего не помню. Но если есть вопросы, постараюсь ответить.
P. P. S. Прошу обратить внимание на комментарии, в частности на этот

Windows Driver Model

Windows Driver Model (WDM) – фреймворк для драйверов устройств (также известен как Win32 Driver Model и Windows NT Driver Model), был введен в Windows 98 и Windows 2000 для замены устаревшего VxD, который использовался в старых версиях Windows таких как Windows 95 и Windows 3.1.

Содержание

Обзор

Microsoft Windows Driver Model определяет унифицированную модель драйвера для операционных систем Windows 98, Windows 2000 и старше, стандартизируя требования и уменьшая количество кода, необходимое для написания драйвера. В соответствии с концепцией WDM, драйверы могут быть бинарно совместимы. Так, например, драйвер для платформы x86, написанный для Windows 98 может подойти и к Windows Me, и к Windows 2000, и даже к Windows Vista. WDM-драйвера спроектированы для прямой совместимости, поэтому такой драйвер может быть запущен на более поздней версии Windows, чем та, для которой он был изначально написан. Но это также означает, что драйвер не сможет использовать новые возможности новой версии WDM-фреймворка. WDM-драйвера, главным образом, обратно не совместимы. Это означает, что нет никаких гарантий, что такой драйвер запустится на версии Windows, более старой чем та, для которой он был написан. Например, Windows XP может использовать драйвер, написанный для Windows 2000, но этот драйвер не может использовать новые возможности, добавленные в Windows XP. Однако, драйвер, написанный для Windows XP, может работать в Windows 2000, а может и не работать.

WDM-драйверы взаимодействуют друг с другом через пакеты запроса ввода — вывода (IRPs).

Технология WDM была разработана для увеличения функциональности и облегчения написания драйверов для Windows. Хотя WDM в основном был разработан для бинарной совместимости и совместимости на уровне исходного кода между Windows 98 и Windows 2000, зачастую это не всегда ожидаемо и поэтому специфические драйвера разрабатываются для каждой операционной системы отдельно.

WDM драйвера предназначены в общем для расширения стандартных возможностеи основного драйвера.

VxD, WDM и Windows 98

Операционные системы, основанные на Windows 98 (Windows 98, Windows 98 Second Edition и Windows Me), могут использовать оба стандарта драйверов — WDM и VxD. Обе модели драйверов могут предоставлять уникальные и различные возможности для одного и того же устройства. Однако, обычно более новый стандарт WDM предоставляет больше возможностей. Например, если TV-тюнер использует VxD-драйвер, это позволяет захватывать изображение разрешением 384 x 288 пикселей. Тот же TV-тюнер с драйвером WDM может захватывать изображение разрешением 768 x 576 пикселей.

Критика

Windows Driver Model, даже несмотря на значительные улучшения по сравнению с предшествующими ему VxD и Windows NT driver model, критикуется разработчиками драйверов [1], в основном по следующим причинам:

  • WDM слишком сложен для изучения.
  • Сложное взаимодействие с событиями управления питанием и Plug and Play. Это приводит ко множеству ситуаций, когда компьютеры, управляемые Windows, не могут перейти в спящий режим или правильно выйти из него из-за ошибок в коде драйвера.
  • Отмену ввода/вывода практически невозможно правильно определить.
  • Для каждого драйвера требуются тысячи строк сопровождающего кода.
  • Нет поддержки для написания «чистых» драйверов пользовательского режима.

Было также много проблем из-за качества документации и примеров, предоставляемых Microsoft.

Из-за этих проблем Microsoft выпустила новый фреймворк, заменяющий WDM, названный Windows Driver Foundation, который включает в себя Kernel-Mode Driver Framework (KMDF) и User-Mode Driver Framework (UMDF). Windows Vista поддерживает оба стандарта: и WDM, и новый Windows Driver Foundation. KMDF также доступен для скачивания для Windows XP и даже Windows 2000, в то время, как UMDF доступен начиная только с Windows XP.

Что такое WDM Driver

В хепле Windows Driver Development Kit написано следующее
Windows Driver Model (WDM) Defined
Any kernel-mode device driver that conforms to the Windows Driver Model (WDM) is called a WDM driver. WDM defines a unified approach to writing kernel-mode device drivers for all Windows operating systems.

Any device driver that will run on Windows 2000 and later operating systems must be a WDM driver. With a few special-case statements in the code, WDM drivers can be source-compatible across Windows 98, Windows Me and Windows 2000 and later operating systems. For more information, see Introduction to WDM.

If you are writing a new WDM driver, you should consider using Kernel-Mode Driver Framework (KMDF). KMDF interfaces are simpler to use than WDM interfaces. For more information about KMDF, see Getting Started with Kernel-Mode Driver Framework.

Что такое wdm integrated driver

WDM works by channeling some of the work of the device driver into portions of
the code that are integrated into the operating system. These portions of code. This section describes the Windows Driver Model (WDM), and discusses types of
WDM drivers, device configuration, driver layering, and WDM versioning. Note: AMD Скачать ATI 690 Series Catalyst Software Suite v.10.2.
Производитель:ATI. Оборудование:ATI 690 Series. Название:WDM Integrated
Driver.

Windows Driver Model — Wikipedia, la enciclopedia libre

Драйверы для ATI 690 Series — Driver.ru

The official ATI Catalyst driver package is suitable for all desktop ATI graphics
need the full Catalyst Software Suite which includes the WDM Integrated Driver. Однако обычно более новый стандарт WDM Например, если TV-тюнер
использует VxD-драйвер, это. Note Drivers for versions of Windows NT-based operating systems before
Windows 2000 are not supported, and you should update these drivers. The
WDM. Windows driver model (WDM) es una estrategia de Microsoft para facilitar un
desarrollo simple de drivers para dispositivos compatibles Microsoft Windows 98,
.

Windows Driver Model — Wikipedia

Простейший WDM-драйвер / Хабрахабр

Описание:ATI Catalyst 9.7 for Windows Vista 64-bit, Windows 7 64-bit. Display
Driver ATI WDM Integrated Driver Catalyst Control Center (English Language. 1 июл 2012 В данной статье описан процесс написания простейшего драйвера, который
выводит скан-коды нажатых клавиш. Также в данной.

TweakGuides.com — ATI Catalyst Tweak Guide

Wdm integrated driver что это

В продолжение предыдущего раздела хотелось бы отметить, что в конечном итоге, компания Microsoft разработала новую технологию — WDM (Windows Driver Model) — и вклю­чила ее в Windows 98 и Windows Me, наследников Windows 95. Кроме того, новая технология была включена в Windows 2000 и Windows ХР, наследников Windows NT 4.0 [7]. WDM предоставляла разработчикам драйверов доступ к практически полному диапазону технологий и интерфейсов, доступных для мира ядра Windows.

Вот теперь мы уже заговорили о таком понятии, как «драйверная модель» напрямую. Возможно, кому-то будет интересно узнать, что же это такое. Так вот, драйверная модель предоставляет собой абстрактный интерфейс для поддерж­ки устройств. Задача разработчиков драйверов как раз и состоит в реализации данного интерфейса, чтобы поддерживать конкретные требования аппаратного устройства. Выражаясь более простым языком, задачей драйвера является предоставление связи и контролирование взаимодействия между приложениями и устройством.

Я думаю, нет необходимости в подробностях объяснять, что представляет собой драйвер, как он «пишется», как выполняется под управлением операционной системы и проч., ибо это тема заслуживает отдельного доклада. Скажу лишь то, что драйвер представляет собой «контейнер» для функций, которые самостоятельно вызываются операционной системой в нужный момент (когда она сочтет нужным). Да-да, здесь нет ничего мистического. Другое дело, что драйверы обычно выполняются в доверенном пространстве ядра, хотя, в драйверной модели WDF драйверы UMDF выполняются в пользовательском режиме, но об этом мы еще поговорим.

Архитектура wdm

Ни для кого не секрет, что тема драйверов достаточно объемная и сложная, поэтому мы не будем уходить в «дебри» системного низкоуровнего программирования, а рассмотрим лишь в общих чертах особенности драйверных моделей. А для большей наглядности, рассмотрим архитектуру WDM на небольшом примере.

Допустим, програм­ме пользовательского режима потребовалось прочитать данные с устройства. Она вызывает функцию API ReadFile, к примеру. Модуль подсистемы — такой как KERNEL32.DLL — реализует вызов, передавая его к низ­коуровневой функции API NtReadFile [7]. Низкоуровневый API – довольно важная составляющая WDM да и архитектуры Windows в целом, но о нем чуть позже.

Такие функции, как, например, NtReadFile, является частью системного компонента, на­зываемого менеджером ввода/вывода (I/O Manager). Следует иметь ввиду, что в самой системе не существует конкретного исполняемого модуля с таким именем. Тем не менее, нам потребуется какое-то название для обозначения «облака» функций опера­ционной системы, окружающего драйвер.

В рассматриваемом примере с ReadFile функция NtReadFile создает IRP с основным кодом функ­ции IRP_MJ_READ. Дальнейшее может различаться в деталях, но чаще всего та­кие функции, как NtReadFile, возвращают управление вызывающей стороне поль­зовательского режима [7].

А теперь немного поводу низкоуровнего API. Низкоуровневый API представляет интерфейс, который позволяет «клиентским» приложениям обращаться к программам (в данном контексте — драйверам) режима ядра. Дело в том, что каждая точка входа данного API является тонкой оберткой для функции режима ядра. Все они проверяют свои параметры, предотвращая возможные дефекты безопас­ности. Сам вызов использует платформенно-зависимый интерфейс для передачи управления через границу пользовательского режима/режима ядра (например, инструкции ассемблера и т.п.). Функции низкоуровнего API работают в режиме ядра и обслуживают запросы приложений на обращение к устройству. Как правило, они создают структуру данных, называемую пакетом запроса ввода-вывода, или IRP (I/O Request Packet), и передают ее в точке входа некоторому драйверу устройства.

Для выполнения запроса IRP драйверу, в конечном счете, потребу­ется обратиться к своему устройству. Драйверы, хотя они и работают в режиме ядра и могут напрямую общаться с оборудованием, используют сред­ства прослойки HAL (Hardware Abstraction Layer) для обращения к оборудова­нию. Функции HAL используют платформенно-зависимую реализацию для выполнения операций. Закончив операцию ввода/вывода, драйвер завершает обработку IRP, вызывая соответствующую функцию режима ядра. Завершение является последним эта­пом обработки IRP и позволяет ожидающему приложению продолжить работу. Для большей наглядности рекомендую обратиться к рисунку 1.

Рисунок 1 – Принцип работы драйверов WDM

Вот, собственно, по такому принципу и работают драйверы WDM. Конечно, то, что мы рассмотрели, это, примерно, сотая часть архитектуры WDM и всего того, что с ней связано. Однако, в рамках статьи, надеюсь, вполне достаточно.

Итак, вот несколько ключевых особенностей драйверной модели WDM (по сравнению с предыдущей драйверной моделью – «драйвер виртуального устройства», применяемой в Windows 9x/ME)[2, 3, 5]:

Совместимость на уровне двоичных кодов между драйверами для Windows 98 и NТ;

Поддержка управления питанием (power management), что дает системе возможность осуществления энергосбережения путем выборочного отключения питания нескольких или всех устройств в системе;

Поддержка Plug and Play;

Поддержка «продвинутого» шинного управления (advanced bus management);

Единая обработка операций ввода/вывода посредством общей структуры данных — IRP (в Windows 98/Ме существовали серьезные различия в работе с дисками, коммуникационными портами, клавиатурами и т. д.).

Форум МИРа NVIDIA

Гость«Операционные системы Windows 98 SE и Windows 2000, равно как и их потомки, поддерживают новую модель драйверов, получившую название WDM (Windows Driver Model). Это – попытка реализовать полную поддержку Plug&Play и ACPI, то есть дать возможность загружать и выгружать драйверы «на ходу», без перезагрузки системы, подключать их в виде фильтров-расширений к стандартным драйверам Microsoft, более гибко управлять энергосбережением и конфигурацией устройств и т.п. WDM-драйверы хранятся в каталоге SYSTEM32/DRIVERS. В частности, интерфейсы нового поколения USB и IEEE-1394 (FireWire) работают только под управлением WDM-драйверов»

Простейший WDM-драйвер

В данной статье описан процесс написания простейшего драйвера, который выводит скан-коды нажатых клавиш.
Также в данной статье описан процесс настройки рабочего места для написания драйверов.
Если Вам интересно, прошу под кат.

Подготовка стенда
Установка необходимого ПО для написания простейшего драйвера
  1. Windows DDK (Driver Development Kit);
  2. VMware Workstation или Virtual Box;
  3. Windows XP;
  4. Visual Studio 2005;
  5. DDKWizard;
  6. KmdManager
  7. DebugView;
Настройка рабочего места
Установка DDK

Установка предельно проста. Единственное на что необходимо обратить внимание — это диалог, в котором Вам предлагается выбрать компоненты, которые будут установлены. Настоятельно рекомендую отметить всю документацию и примеры.

Установка и настройка Microsoft® Visual Studio 2005

Установка Microsoft® Visual Studio 2005 ничем не сложнее установки DDK. Если Вы будете использовать её только для написания драйверов, то когда инсталлятор спросит какие компоненты необходимо установить, выберите только Visual C++.
Далее можно установить Visual Assist X. С помощью этой программы (аддона) можно будет легко настроить подсказки для удобного написания драйверов.
После установки Visual Assist X в Visual Studio 2005 появится новое меню VAssistX. Далее в этом меню: Visual Assist X Options -> Projects -> C/C++ Directories -> Platform: Custom, Show Directories for: Stable include files . Нажимаем Ins или на иконку добавить новую директорию и в появившейся строке, если у вас Windows XP вписываем %WXPBASE%\inc\ddk\wxp .

Установка и настройка DDKWizard
  • Создать системные (рекомендуется) или пользовательские переменные со следующими именами и значением, которое соответствует пути к DDK
    Версия DDK Имя переменной Путь по умолчанию
    Windows XP DDK WXPBASE C:\WINDDK\2600
    Windows 2003 Server DDK WNETBASE C:\WINDDK\3790.1830
    Windows Vista/Windows 2008 Server WDK WLHBASE
    Windows 7/Windows 2008 Server R2 WDK W7BASE
Установка необходимого ПО для запуска драйверов
  • DebugView (link) — это утилитка, которая позволяет просматривать отладочный вывод как режима пользователя так и режима ядра.
  • KmdManager (link) — утилита динамической загрузки/выгрузки драйверов
Постановка задачи

Задача: написать драйвер, который будет выводить в дебаг скан-коды нажатых клавиш и их комбинаций.

Немного теории
  • драйверы классов;
  • минидрайверы;
  • функциональные драйверы;
  • фильтрующие драйверы.

Необязательно определять все возожные функции в своем драйвере, но он обязательно должен содержать DriverEntry и AddDevice .

IRP — это структура, которая используется драйверами для обмена данными.

  • верхние фильтрующие драйверы;
  • нижние фильтрующие драйверы.
Отличия между верхними и нижними фильтрующими драйверами

Через верхние фильтрующие драйверы проходят все запросы, а это значит, что они могут изменять и/или фильтровать информацию, идущую к функциональному драйверу, ну и далее, возможно, к устройству.
Пример использования верхних фильтрующих драйверов:
Фильтр-хук драйвер, который устанавливает свою хук-функцию для системного драйвера IpFilterDirver, для отслеживания и фильтрации траффика. Такие драйверы используются в брандмауэрах.

Через нижние фильтрующие драйверы проходит меньше запросов потому что большинство запросов выполняет и завершает функциональный драйвер.

Проблемы синхронизации

В драйвере, который мы будем писать, есть несколько «проблемных» секций. Для нашего драйвера вполне достаточно использования ассемблерных вставок:

Префикс lock позволяет безопасно выполнить идущую за ним команду. Она блокирует остальные процессоры, пока выполняется команда.

Экшен

Для начала необходимо включить заголовочные файлы «ntddk.h», «ntddkbd.h»

Также необходимо описать структуру DEVICE_EXTENSION

Объект pLowerDO это объект устройства, который находится ниже нас в стеке. Он нужен нам для того чтобы знать кому дальше отправлять IRP-пакеты.
Еще для работы нашего драйвера нам нужна переменная, в которой будет храниться количество не завершенных запросов.

Начнем с функции, которая является главной точкой входа нашего драйвера.

theDriverObject – объект драйвера, содержит указатели на все необходимые операционной системе функции, которые мы должны будем инициализировать.
ustrRegistryPath – имя раздела в реестре, где хранится информация о данном драйвере.
Для начала необходимо объявить и обнулить переменные:

Далее, как я и писал выше, нужно инициализировать указатели на функции

Функция DispatchRead будет обрабатывать запросы на чтение. Она будет вызываться, когда нажата или отпущена клавиша клавиатуры.
Функция DriverUnload вызывается, когда драйвер уже не нужен и его можно выгрузить из памяти, или когда пользователь сам выгружает драйвер. В данной функции должна производиться «зачистка», т.е. освобождаться ресурсы, которые использовались драйвером, завершаться все незавершенные запросы и т.д.
Функция DispatchThru это функция-заглушка. Все что она делает это передача IRP-пакета следующему драйверу (драйверу который находится под нашим в стеке, т.е. pLowerDO из DEVICE_EXTENSION ).
Далее мы вызываем нашу функцию, для создания и установки нашего устройства в стек устройств:

Эту функцию я опишу чуть ниже.
Возвращаем status , в котором, если функция InstallFilter завершилась удачей, хранится значение STATUS_SUCCESS .
Переходим к функции InstallFilter . Вот её прототип:

Эта функция создает объект устройства, настраивает его и включает в стек устройств поверх \\Device\\KeyboardClass0

pKeyboardDevice – это объект устройсва, которое мы должны создать.
Вызываем IoCreateDevice для создания нового устройства

  • Первый аргумент это объект драйвера, который мы получили как параметр функции InstallFilter. Он передается в IoCreateDevice для того чтобы установить связь между нашим драйвером и новым устройством.
  • Третий параметр это имя устройства
  • Четвертый параметр это тип устройства
  • Пятый параметр это флаги, которые обычно устанавливаются для запоминающих устройств.
  • Шестой параметр описывает можно ли открывать манипуляторы устройства в количестве больше одного. Если FALSE можно открыть только один манипулятор. Иначе можно открыть любое количество манипуляторов.
  • Седьмой параметр это память, в которой будем сохранен созданный объект устройства.

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

Функция IoAttachDevice внедряет наше устройство в стек. В pdx->pLowerDO будет храниться объект следующего (нижнего) устройства.

Далее разберем функцию DispatchRead с прототипом:

Данная функция будет вызываться операционной системой при нажатии или отпускании клавиши клавиатуры
Увеличиваем счетчик незавершенных запросов

Перед тем как передать запрос следующему драйверу мы должны настроить указатель стека для драйвера. IoCopyCurrentIrpStackLocationToNext копирует участок памяти, который принадлежит текущему драйверу, в область памяти следующего драйвера.
Когда запрос идет вниз по стеку в нем еще нет нужных нам данных, поэтому мы должны задать функцию, которая вызовется, когда запрос будет идти вверх по стеку с нужными нам данными.

где ReadCompletionRoutine наша функция.
Передаем IRP следующему драйверу:

Теперь разберем функцию, которая будет вызываться каждый раз при завершении IRP . Прототип:

Структура PKEYBOARD_INPUT_DATA используется для описания нажатой клавиши.

Проверяем, удачно завершен запрос или нет

Чтобы достать структуру KEYBOARD_INPUT_DATA нужно обратиться к системному буферу IRP -пакета.

Узнаем количество клавиш

И выводим каждую клавишу:

И не забываем уменьшать количество не обработанных запросов

Возвращаем статус запроса

Разберем функцию завершения работы. Прототип:

Извлекаем устройство из стека:

Проверяем есть незавершенные запросы или нет. Если мы выгрузим драйвер без этой проверки, при первом нажатии на клавишу после выгрузки будет БСоД.

Как запустить драйвер и просмотреть отладочную информацию

Для запуска драйвера я использовал утилиту KmdManager. Для просмотра отладочной информации использовалась утилита DbgView.

P. S. Статью писал давно, ещё на третьем курсе, сейчас уже почти ничего не помню. Но если есть вопросы, постараюсь ответить.
P. P. S. Прошу обратить внимание на комментарии, в частности на этот

Windows Driver Model

Windows Driver Model (WDM) – фреймворк для драйверов устройств (также известен как Win32 Driver Model и Windows NT Driver Model), был введен в Windows 98 и Windows 2000 для замены устаревшего VxD, который использовался в старых версиях Windows таких как Windows 95 и Windows 3.1.

Содержание

Обзор

Microsoft Windows Driver Model определяет унифицированную модель драйвера для операционных систем Windows 98, Windows 2000 и старше, стандартизируя требования и уменьшая количество кода, необходимое для написания драйвера. В соответствии с концепцией WDM, драйверы могут быть бинарно совместимы. Так, например, драйвер для платформы x86, написанный для Windows 98 может подойти и к Windows Me, и к Windows 2000, и даже к Windows Vista. WDM-драйвера спроектированы для прямой совместимости, поэтому такой драйвер может быть запущен на более поздней версии Windows, чем та, для которой он был изначально написан. Но это также означает, что драйвер не сможет использовать новые возможности новой версии WDM-фреймворка. WDM-драйвера, главным образом, обратно не совместимы. Это означает, что нет никаких гарантий, что такой драйвер запустится на версии Windows, более старой чем та, для которой он был написан. Например, Windows XP может использовать драйвер, написанный для Windows 2000, но этот драйвер не может использовать новые возможности, добавленные в Windows XP. Однако, драйвер, написанный для Windows XP, может работать в Windows 2000, а может и не работать.

WDM-драйверы взаимодействуют друг с другом через пакеты запроса ввода — вывода (IRPs).

Технология WDM была разработана для увеличения функциональности и облегчения написания драйверов для Windows. Хотя WDM в основном был разработан для бинарной совместимости и совместимости на уровне исходного кода между Windows 98 и Windows 2000, зачастую это не всегда ожидаемо и поэтому специфические драйвера разрабатываются для каждой операционной системы отдельно.

WDM драйвера предназначены в общем для расширения стандартных возможностеи основного драйвера.

VxD, WDM и Windows 98

Операционные системы, основанные на Windows 98 (Windows 98, Windows 98 Second Edition и Windows Me), могут использовать оба стандарта драйверов — WDM и VxD. Обе модели драйверов могут предоставлять уникальные и различные возможности для одного и того же устройства. Однако, обычно более новый стандарт WDM предоставляет больше возможностей. Например, если TV-тюнер использует VxD-драйвер, это позволяет захватывать изображение разрешением 384 x 288 пикселей. Тот же TV-тюнер с драйвером WDM может захватывать изображение разрешением 768 x 576 пикселей.

Критика

Windows Driver Model, даже несмотря на значительные улучшения по сравнению с предшествующими ему VxD и Windows NT driver model, критикуется разработчиками драйверов [1], в основном по следующим причинам:

  • WDM слишком сложен для изучения.
  • Сложное взаимодействие с событиями управления питанием и Plug and Play. Это приводит ко множеству ситуаций, когда компьютеры, управляемые Windows, не могут перейти в спящий режим или правильно выйти из него из-за ошибок в коде драйвера.
  • Отмену ввода/вывода практически невозможно правильно определить.
  • Для каждого драйвера требуются тысячи строк сопровождающего кода.
  • Нет поддержки для написания «чистых» драйверов пользовательского режима.

Было также много проблем из-за качества документации и примеров, предоставляемых Microsoft.

Из-за этих проблем Microsoft выпустила новый фреймворк, заменяющий WDM, названный Windows Driver Foundation, который включает в себя Kernel-Mode Driver Framework (KMDF) и User-Mode Driver Framework (UMDF). Windows Vista поддерживает оба стандарта: и WDM, и новый Windows Driver Foundation. KMDF также доступен для скачивания для Windows XP и даже Windows 2000, в то время, как UMDF доступен начиная только с Windows XP.

Структура WDM драйвера и как работает ПК

Хочется представить хотя бы упрощенно общий принцип взаимодействия устройства с ПК. Мои рассуждения. Вот запускаем мы ПК. Счетчик команд главного процесcора равен 0. По этому адресу находится вход в программу BIOS. Уже на этом этапе нужно загружать драйвера системной шины, разных там портов, потом с помощью них сканируються все устройства, загружается таблица реестра, грузится сама ОС. Хотелось бы услышать как это работает на самом деле. Понимаю что это очень обширная тема, не надо посылать читать многочисленные тома, я хочу уловить только суть, чтобы потом подходить и изучать более подробные вопросы как бы глядя с высока.
И вот второе, что очень интересует, собственно по WDM драйверу, вот смотрю картинку иерархия обьектов устройств и драйверов. В самом низу находится драйвер шины — он управляет структурой ядра PDO, далее может быть фильтрующий драйвер, но считаем что его нет, а идет функциональный драйвер — и управляемая им структура FDO. Так вот. интересует — эти структуры заранее предопределены, то есть драйвером HOL. Я себе представляю это так. Есть материнская плата, в ней порты PCI, IDE, SATA и т д. Берем допустим PCI разьем — физически это всего n-ное количество выводов. Вся работа с ним производится через драйвер шины PCI. И вот ОС при загрузке описывает каждый порт и возможные для него функции через структуру PDO. Я так думаю эта структура представляет реальные PIN порта (его адреса), а также указатели — в которые мы можем поместить адреса функций для работы с портом. Эти функции определены в ядре, мы только выбираем что включить, что отключить, можем переопределять их.

Так вот эта структура PDO создается автоматически — вернее ее шаблон для конкретного разьема в момент подключения оборудования, а мы можем его конкретизировать с помощью драйвера шины, или можно полностью программировать PDO с ноля?
Обьект FDO — аналогично, что это? — то же что и PDO — только структура с более высокоуровневыми командами, которые выполняются через функции обьекта PDO?
Просветите, хотя бы в общих чертах.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *