Что такое wdm драйвер
Общие сведения о драйверах WDM Audio
Службы потоковой передачи ядра (KS) поддерживают обработку потоков данных в режиме ядра для аудио и других типов непрерывного носителя. По сути, поток проходит обработку, так как он проходит по пути к данным, содержащему некоторое количество обрабатывающих узлов. Набор связанных узлов объединяется в группу, образуя Фильтр KS, который представляет собой независимый блок функций потоковой обработки. Более сложные функции могут быть созданы с помощью модульного представления каскадом нескольких фильтров для формирования графа фильтра.
Типичная плата звукового адаптера может содержать звуковые устройства для воспроизведения волнового потока с помощью набора динамиков, преобразования звукового сигнала из микрофона в поток звукозаписи и синтезирования звука из потока MIDI. Драйвер адаптера может заключить каждое из этих звуковых устройств в фильтр KS, который предоставляется операционной системе. Операционная система подключает фильтры к другим фильтрам для формирования графов фильтров, обрабатывающих звуковые потоки от имени программ приложений.
Фильтры KS соединяются друг с другом через свои ПИН-коды. ПИН-код в фильтре аудио можно рассматривать как аудиоразъемы. Клиент создает экземпляр входного или выходного ПИН-кода для фильтра, когда клиенту требуется направить поток данных в этот фильтр или из него. В некоторых контекстах термин » ПИН-код » и » поток » могут быть взаимозаменяемы.
Выходной контакт вышестоящего фильтра соединен с входным закреплением подчиненного фильтра. Поток данных из выходного ПИН-кода должен иметь формат данных, который может принимать входной ПИН-код. Буферизация данных обычно требуется для смягчения несовпадений в скорости, с которой закрепление вывода создает данные, а входной ПИН-код использует их.
Фильтр KS реализуется как объект драйвера режима ядра, который инкапсулирует некоторое количество связанных функций обработки потока. Функциональность может быть реализована в программном обеспечении или оборудовании. В этой модели звуковой адаптер можно просмотреть как набор аппаратных устройств, а драйвер адаптера — для каждой из этих устройств в качестве отдельного фильтра.
Драйвер адаптера предоставляет набор фабрик фильтров для звуковой системы. Каждая фабрика фильтров поддерживает создание экземпляров фильтров определенного типа:
Если адаптер содержит одно или несколько устройств, которые похожи или идентичны, драйвер группирует фильтры для этих устройств вместе в одну фабрику фильтров.
Если адаптер содержит несколько типов устройств, эти устройства представляются несколькими различными фабриками фильтров.
Фильтр KS предоставляет набор фабрик закрепления для звуковой системы. Каждая фабрика закрепления может создавать экземпляры ПИН-кодов определенного типа. Если фильтр может предоставить один или несколько ПИН-кодов, одинаковых или одинаковых в функции, фильтр группирует эти контакты в одну фабрику. Например, фильтр, выполняющий микширование звука, может иметь одну фабрику закрепления, которая может создавать экземпляры одного выходного ПИН-кода и вторую фабрику закрепления, которая может создавать экземпляры нескольких входных ПИН-кодов.
службы KS создаются на основе WDM. Обратите внимание, что термин Фильтр KS должен отличаться от драйвера фильтратермина, который является другой концепцией WDM. Драйвер фильтра находится в стеке драйвера WDM и может перехватывать и изменять пакеты запросов ввода-вывода (IRP), распространяемые через стек. Драйверы фильтров верхнего и нижнего уровней располагаются выше и ниже драйвера функции соответственно. В этом разделе Фильтр терминов ссылается на фильтр KS, а не на драйвер фильтра, если не указано иное. Дополнительные сведения о драйверах фильтров см. в разделе Типы драйверов WDM.
В этом разделе рассматриваются следующие вопросы.
Обзор аудио драйверов WDM
аудио-драйверы WDM (WDM) используют компоненты потоковой передачи ядра (KS), которые работают в режиме ядра и являются частью операционной системы.
производители оборудования должны принять несколько решений по проектированию, прежде чем начинать разработку устройства аудио с использованием Windows.
Первое решение — необходимость разработки звукового устройства, для которого требуется пользовательский драйвер, предоставленный поставщиком. Windows содержит поддержку операционной системы для устройств PCI, USB и IEEE 1394, которые соответствуют рекомендациям по архитектуре Microsoft универсального аудио-архитектуры (UAA). Поставщику не требуется предоставлять пользовательский драйвер для устройства, совместимого с UAA.
Однако если требуется пользовательский звуковой драйвер, предоставленный поставщиком, поставщик должен выбрать, должен ли драйвер работать совместно с драйвером системы Портклс (Portcls.sys) или системным драйвером класса Австреам (Ks.sys). портклс и австреам являются частью Windows операционной системы. Портклс является верным выбором для большинства звуковых адаптеров. Дополнительные сведения о Портклс см. в разделе Введение в класс порта. Дополнительные сведения о Австреам см. в разделе Обзор австреам.
При проектировании пользовательского драйвера адаптера, использующего Портклс, устройства на аудио адаптере становятся доступными для приложений, использующих Ваверт. Дополнительные сведения см. в статье Введение в драйвер порта ваверт.
Два дополнительных решения предполагают, как представлять топологию адаптера и закреплять диапазоны данных в звуковых приложениях. Топология — это логическая карта путей к данным и управляющих узлов в цепи адаптеров. Диапазоны данных определяют форматы данных, которые устройства могут поддерживать в потоках Wave и MIDI. Оба решения влияют на то, как устройства звукового адаптера отображаются в приложениях.
При выполнении всех упомянутых выше решений поставщик оборудования должен оценить ценность улучшений производительности относительно затрат на их реализацию. другой вопрос заключается в том, можно ли выполнить определенное решение для работы с несколькими продуктами в семействе Windows. В этом разделе приводятся общие сведения об этих проблемах, а также ссылки на более подробную документацию по конкретным темам.
Различия между WDM и ВДФ
Модель WDM тесно связана с операционной системой. Драйверы напрямую взаимодействуют с операционной системой путем вызова подпрограмм системных служб и управления структурами операционных систем. Так как драйверы WDM являются доверенными компонентами режима ядра, система предоставляет ограниченные проверки входных драйверов.
в сравнении Windows модель платформы драйверов (вдф) посвящена требованиям драйвера, а библиотека платформы обрабатывает большинство взаимодействий с системой.
Платформа перехватывает запросы ввода-вывода, принимает при необходимости действия по умолчанию и вызывает обратные вызовы драйвера по мере необходимости. Модель ВДФ основана на объектах и управляется событиями. Объекты представляют общие конструкции драйверов, такие как устройство, блокировка или очередь. Драйвер инфраструктуры Kernel-Mode Driver Framework (КМДФ) или User-Mode Driver Framework (UMDF) содержит точку входа (DriverEntry), функции обратного вызова, связанные с событиями, необходимые для обслуживания устройства и поддержки операций ввода-вывода, а также любые дополнительные внутренние служебные функции, от которых зависит реализация.
В этом разделе описываются важные различия между WDM и ВДФ в следующих областях:
Структура драйвера
В драйвере WDM подпрограммы диспетчеризации ввода-вывода сопоставляются с определенными основными кодами IRP. Подпрограммы диспетчеризации получают IRP от диспетчера ввода-вывода, анализируют их и отвечают соответствующим образом.
В драйвере ВДФ Framework регистрирует собственные подпрограммы диспетчеризации, которые получают IRP от диспетчера ввода-вывода, анализируют их, а затем вызывают функции обратного вызова событий драйвера для их обработки. Функции обратного вызова событий обычно выполняют более конкретную задачу, чем общие подпрограммы ввода-вывода драйвера WDM.
Типичный драйвер ВДФ для устройства самонастраивающийся содержит:
Объекты устройств и роли драйверов
Драйверы WDM и ВДФ создают один или несколько объектов устройств. Каждый объект устройства представляет роль драйвера, предназначенную для запросов ввода-вывода. Объект физического устройства (PDO) представляет драйвер шины, объект функционального устройства (ФДО) представляет драйвер функции, а объект устройства фильтрации (Filter DO) представляет собой драйвер фильтра.
В драйверах WDM эти роли драйверов являются неявными, поэтому драйвер должен отследить, какую роль каждый объект устройства представляет, и отвечать на запросы IRP соответствующим образом.
Однако драйверы ВДФ явно указывают, представляет ли объект устройства PDO (только КМДФ), ФДО или Filter, и регистрировать обратные вызовы событий, относящиеся к этой роли. Например, ПДОС является целевым объектом запросов требований к ресурсам и запросов на извлечение устройств, тогда как фдос и Filter DOS не обрабатывают такие запросы.
Драйвер ВДФ настраивает каждый объект устройства для получения определенных типов запросов ввода-вывода. Платформа вызывает драйвер для обработки только запросов ввода-вывода и выполняет действие по умолчанию для всех остальных запросов. Если объект устройства представляет драйвер фильтра, платформа передает все остальные запросы следующему более низкому драйверу. Если объект устройства представляет шину или драйвер функции, платформа не сможет выполнить все остальные типы запросов.
Для самонастраивающийся и запросов питания платформа вызывает драйвер КМДФ или UMDF только для тех запросов, которые подходят для каждого объекта устройства — и в соответствующее время. Например, ФДО должен отвечать на определенные запросы после того, как базовый PDO уже ответил. В драйвере WDM ФДО должен установить подпрограмму завершения ввода-вывода, передать IRP в стек и обработать его после более низких драйверов. Драйвер ВДФ просто реализует соответствующую подпрограмму обратного вызова, и Платформа вызывает ее после завершения обработки более низкими драйверами.
Сведения о создании объектов устройств платформы см. в разделе Создание объекта устройства платформы.
Некоторые драйверы также обрабатывают определенные запросы ввода-вывода, которые не зависят от самонастраивающийся. Драйвер WDM создает DEVICE_OBJECT в качестве целевого объекта для таких запросов, но не прикрепляет его к стеку устройств самонастраивающийся. Чтобы добиться того же результата, драйвер КМДФ создает объект устройства управления. Некоторые драйверы на основе платформы используют объекты устройств управления для реализации механизмов ввода-вывода «сидебанд», чтобы они могли принимать определенные типы запросов ввода-вывода независимо от состояния устройства.
Модель объектов
ВДФ поддерживает согласованную объектную модель, в которой объекты непрозрачны для драйверов, предоставляют настраиваемые в драйверах области контекста и на которые ссылается handle. Объекты WDM являются объектами на уровне системы, доступными для драйверов и на которые ссылаются указатели. Драйвер, который повреждает объект WDM, может повредить всю систему. Повреждение объекта ВДФ не только усложняется, так как платформа проверяет данные, предоставляемые драйвером, но также вызывает проблемы на уровне системы гораздо реже.
Сведения о соглашении об именовании для объектов КМДФ см. в разделе архитектура ВДФ.
Платформа поддерживает счетчик ссылок для каждого объекта, что обеспечивает некоторый контроль над временем его существования. Дополнительные сведения см. в разделе жизненный цикл объекта платформы.
Несмотря на то, что многие объекты ВДФ соответствуют WDM-объектам, объекты ВДФ поддерживают функции, требующие дополнительного кода в драйвере WDM. Все объекты ВДФ поддерживают области контекста объекта, определяемые драйвером, чтобы драйвер мог хранить информацию, связанную с определенным экземпляром объекта, с самим объектом. Обычно объекты отслеживаниют состояние. Например, объекты ВДФКУЕУЕ — это не просто список запросов ввода-вывода; они поддерживают несколько типов диспетчеризации, автоматическую синхронизацию с самонастраивающийся и запрос отмены. Для объектов ВДФМЕМОРИ число ссылок, управляемых платформой, помогает предотвратить утечку памяти и преждевременный выпуск ресурсов.
Создание объектов
Драйверы ВДФ следуют регулярному шаблону для создания всех типов объектов:
Платформа определяет функции с именем WDF_Object_CONFIG_INIT для инициализации структур конфигурации, где объект представляет имя типа объекта. Функция WDF_OBJECT_ATTRIBUTES_INIT Инициализирует структуру WDF_OBJECT_ATTRIBUTES драйвера.
Область контекста объекта
Каждый экземпляр объекта может иметь одну или несколько областей контекста объекта. Область контекста объекта — это область хранения для данных, связанных с конкретным экземпляром, например объект события, выделенный драйвером. Драйвер определяет размер и расположение области контекста объекта. Для объекта устройства область контекста объекта эквивалентна расширению устройства WDM. Сведения об определении и инициализации области контекста см. в разделе пространство контекста объекта платформы.
Поддерживаемые типы IRP
вдф поддерживает подмножество Windows irp. Сводные сведения о типах основных WDM IRP и соответствующих функциях обратного вызова событий ВДФ см. в статье функции обратного вызова событий WDM IRP и ВДФ.
Даже если ваш драйвер получает IRP, отличный от перечисленных в таблице, его можно перенести в КМДФ. КМДФ предоставляет механизм, с помощью которого драйвер может получить «необработанные» WDM-IRP, но также использовать функции КМДФ для других типов IRP. Дополнительные сведения см. в разделе Обработка WDM IRP за пределами платформы.
Очереди ввода-вывода
Почти все драйверы помещаются в очередь запросов ввода-вывода. Драйверы WDM обычно используют один из следующих подходов:
Драйвер ВДФ создает объект очереди ВДФ (ВДФКУЕУЕ) для представления очереди ввода-вывода. Объект очереди ВДФ похож на отменяемую очередь, но предоставляет дополнительные возможности.
При переносе драйвера WDM в ВДФ можно использовать механизм очереди ВДФ независимо от механизма, используемого драйвером WDM. Дополнительные сведения об очередях см. в разделе объекты очереди платформы.
Синхронизация и параллелизм
Драйверы ВДФ имеют преимущество от встроенной поддержки синхронизации, которая недоступна для драйверов WDM. Хотя эта поддержка не означает, что драйвер может игнорировать параллелизм и синхронный доступ к данным, драйверы ВДФ, тем не менее, нуждаются в значительно меньшем количестве блокировок и меньше кода синхронизации, чем драйверы WDM.
Дополнительные сведения о возможностях синхронизации, предоставляемых платформой, см. в разделе методы синхронизации.
Установка драйвера
Как и драйверы WDM, драйверы КМДФ и UMDF устанавливаются с помощью INF-файлов. однако для установки драйвера вдф иногда требуется установщик платформы, поставляемый с комплектом драйверов Windows (WDK). Совместный установщик гарантирует наличие совместимой версии библиотеки Framework в целевой системе. Дополнительные сведения об установке см. в разделе Сборка и загрузка драйвера ВДФ.
Простейший WDM-драйвер
В данной статье описан процесс написания простейшего драйвера, который выводит скан-коды нажатых клавиш.
Также в данной статье описан процесс настройки рабочего места для написания драйверов.
Если Вам интересно, прошу под кат.
Подготовка стенда
Установка необходимого ПО для написания простейшего драйвера
Настройка рабочего места
Установка DDK
Установка предельно проста. Единственное на что необходимо обратить внимание — это диалог, в котором Вам предлагается выбрать компоненты, которые будут установлены. Настоятельно рекомендую отметить всю документацию и примеры.
Установка и настройка Microsoft® Visual Studio 2005
Установка и настройка DDKWizard
Установка необходимого ПО для запуска драйверов
Постановка задачи
Задача: написать драйвер, который будет выводить в дебаг скан-коды нажатых клавиш и их комбинаций.
Немного теории
IRP — это структура, которая используется драйверами для обмена данными.
Отличия между верхними и нижними фильтрующими драйверами
Через верхние фильтрующие драйверы проходят все запросы, а это значит, что они могут изменять и/или фильтровать информацию, идущую к функциональному драйверу, ну и далее, возможно, к устройству.
Пример использования верхних фильтрующих драйверов:
Фильтр-хук драйвер, который устанавливает свою хук-функцию для системного драйвера IpFilterDirver, для отслеживания и фильтрации траффика. Такие драйверы используются в брандмауэрах.
Через нижние фильтрующие драйверы проходит меньше запросов потому что большинство запросов выполняет и завершает функциональный драйвер.
Проблемы синхронизации
В драйвере, который мы будем писать, есть несколько «проблемных» секций. Для нашего драйвера вполне достаточно использования ассемблерных вставок:
Префикс lock позволяет безопасно выполнить идущую за ним команду. Она блокирует остальные процессоры, пока выполняется команда.
Экшен
Для начала необходимо включить заголовочные файлы «ntddk.h», «ntddkbd.h»
Также необходимо описать структуру DEVICE_EXTENSION
Объект pLowerDO это объект устройства, который находится ниже нас в стеке. Он нужен нам для того чтобы знать кому дальше отправлять IRP-пакеты.
Еще для работы нашего драйвера нам нужна переменная, в которой будет храниться количество не завершенных запросов.
Начнем с функции, которая является главной точкой входа нашего драйвера.
theDriverObject – объект драйвера, содержит указатели на все необходимые операционной системе функции, которые мы должны будем инициализировать.
ustrRegistryPath – имя раздела в реестре, где хранится информация о данном драйвере.
Для начала необходимо объявить и обнулить переменные:
Далее, как я и писал выше, нужно инициализировать указатели на функции
Функция DispatchRead будет обрабатывать запросы на чтение. Она будет вызываться, когда нажата или отпущена клавиша клавиатуры.
Функция DriverUnload вызывается, когда драйвер уже не нужен и его можно выгрузить из памяти, или когда пользователь сам выгружает драйвер. В данной функции должна производиться «зачистка», т.е. освобождаться ресурсы, которые использовались драйвером, завершаться все незавершенные запросы и т.д.
Функция DispatchThru это функция-заглушка. Все что она делает это передача IRP-пакета следующему драйверу (драйверу который находится под нашим в стеке, т.е. pLowerDO из DEVICE_EXTENSION ).
Далее мы вызываем нашу функцию, для создания и установки нашего устройства в стек устройств:
Эта функция создает объект устройства, настраивает его и включает в стек устройств поверх \\Device\\KeyboardClass0
pKeyboardDevice – это объект устройсва, которое мы должны создать.
Вызываем IoCreateDevice для создания нового устройства
Флаги, которые мы устанавливаем для нашего устройства, должны быть эквивалентными флагам устройства, поверх которого мы включаемся в стек.
Далее мы должны выполнить преобразования имени устройства, которое мы включаем в стек.
Функция IoAttachDevice внедряет наше устройство в стек. В pdx->pLowerDO будет храниться объект следующего (нижнего) устройства.
Далее разберем функцию DispatchRead с прототипом:
Данная функция будет вызываться операционной системой при нажатии или отпускании клавиши клавиатуры
Увеличиваем счетчик незавершенных запросов
Перед тем как передать запрос следующему драйверу мы должны настроить указатель стека для драйвера. IoCopyCurrentIrpStackLocationToNext копирует участок памяти, который принадлежит текущему драйверу, в область памяти следующего драйвера.
Когда запрос идет вниз по стеку в нем еще нет нужных нам данных, поэтому мы должны задать функцию, которая вызовется, когда запрос будет идти вверх по стеку с нужными нам данными.
где ReadCompletionRoutine наша функция.
Передаем IRP следующему драйверу:
Структура PKEYBOARD_INPUT_DATA используется для описания нажатой клавиши.
Проверяем, удачно завершен запрос или нет
Узнаем количество клавиш
И выводим каждую клавишу:
И не забываем уменьшать количество не обработанных запросов
Возвращаем статус запроса
Разберем функцию завершения работы. Прототип:
Извлекаем устройство из стека:
Проверяем есть незавершенные запросы или нет. Если мы выгрузим драйвер без этой проверки, при первом нажатии на клавишу после выгрузки будет БСоД.
Как запустить драйвер и просмотреть отладочную информацию
Для запуска драйвера я использовал утилиту KmdManager. Для просмотра отладочной информации использовалась утилита DbgView.
P. S. Статью писал давно, ещё на третьем курсе, сейчас уже почти ничего не помню. Но если есть вопросы, постараюсь ответить.
P. P. S. Прошу обратить внимание на комментарии, в частности на этот
Модель драйверов Windows (WDM)
В Windows 2000 была добавлена поддержка технологии Plug and Play, настроек электропитания и расширение модели драйверов Windows NT, названной моделью драйверов Windows (WDM). Windows 2000 и более поздние версии могут запускать драйверы, унаследованные у Windows NT 4, но, поскольку они не поддерживают технологию Plug and Play настройки электропитания, системы, запускающие эти драйверы, будут вынуждены ограничивать возможности в этих двух областях.
С точки зрения WDM, существуют драйверы трех типов:
Функциональный драйвер по определению является драйвером, который знает о конкретном устройстве практически все, и обычно он является единственным драйвером, обращающимся к специфическим регистрам устройства.
В среде окружения WDM все аспекты устройства контролируются не одним драйвером: драйвер шины занимается отправкой диспетчеру PnP отчетов об устройствах, подключенных к его шине, а функциональный драйвер управляет самим устройством.
В большинстве случаев драйверы фильтра, находящиеся на нижнем уровне, изменяют поведение устройства. Например, если устройство сообщает своему драйверу шины, что ему нужно 4 порта ввода-вывода, в то время как ему фактически нужно 16 портов ввода-вывода, функциональный драйвер фильтра для данного конкретного устройства может перехватить перечень аппаратных ресурсов, о котором драйвер шины сообщает диспетчеру PnP, и исправить количество портов ввода-вывода.
Драйверы фильтра, находящиеся на верхнем уровне, обычно предоставляют устройству какие-нибудь дополнительные свойства. Например, драйвер фильтра такого устройства, как клавиатура, находящийся на верхнем уровне, может навязывать дополнительные проверки безопасности.