wdm драйвера что это
990x.top
Простой компьютерный блог для души)
NVIDIA Virtual Audio Device (Wave Extensible) (WDM) — что это за драйвер? (nvvad64v.sys)
Приветствую. Каждая видеокарта способа воспроизводить картинку на экран — это ее главная задача. Геймерские — позволяют комфортно играть на высоких настройках. Но не все знают — некоторые могут воспроизводить и звук. Данную возможность обеспечивает интерфейс HDMI.
Разбираемся
NVIDIA Virtual Audio Device (Wave Extensible) (WDM) — драйвер для работы встроенного звукового контроллера видеокарты.
Видеокарта может выводить сигнал по кабелю HDMI, который поддерживает передачу не только видео, но и аудио сигнала. Другими словами — теоритически видеокарта может выполнять роль аудиокарты.
Сам аудиочип может быть фирмы Realtek (производитель огромного количества звуковых/сетевых чипов).
После установки дров напротив устройства в диспетчере может быть восклицательный знак. После перезагрузки должен исчезнуть.
Файл драйвера — nvvad64v.sys.
Фирменный мастер установки NVIDIA, который устанавливаем необходимые графические драйвера, в том числе и для HDMI.
High Definition Multimedia Interface (HDMI) — интерфейс передачи мультимедийных данных — видео с высоким разрешением, многоканальное аудио. Поддерживается защита от копирования High-Bandwidth Digital Content Protection (HDCP).
При установленном драйвере может не работать встроенная/внешняя звуковая карта
Иногда причина странных проблем/ошибок без видимых причин — некачественный кабель HDMI.
В теории касается не только видеокарт. Современные материнские платы часто содержат не только видеовыход DVI, но и HDMI — поэтому наличие устройства возможно даже без внешней видеокарты.
Вывод
1. Общие сведения о драйверах устройств в системе Windows.
Естественно, каждая операционная система имеет собственную архитектуру и свои особенности функционирования драйверов. Но практически во всех современных ОС можно выделить следующие особенности, характерные для работы подсистемы ввода-вывода:
• Фактически, пользовательские программы либо системные утилиты не могут напрямую обращаться к аппаратуре, используя порты ввода-вывода, DMA либо подобные низкоуровневые механизмы напрямую. Этот факт следует из самой идеологии защищенного режима современных ОС: все программы пользователя и часть ОС работают в 3-м кольце защиты компьютера (наименее привилегированном). При этом любая команда обращения к порту из данной программы может быть замаскирована и повлечет за собой аппаратное исключение (Exception). Напрямую к аппаратуре может обратится программа, работающая в самом приоритетном, 0-м кольце защиты.
• В настоящее время практически все устройства используют технологию автоматического распределения ресурсов (портов ввода-вывода, запросов на прерывания и т.п.) — Plug and Play (PnP). Когда новое устройство, например, та же звуковая карта, будет добавлена в систему, ей будут выделены те ресурсы, которые в данный момент свободны — незадействованные линии запросов на прерывание (IRQ), свободные адреса портов ввода-вывода. Поэтому драйвер изначально «не знает», какие именно адреса портов и IRQ ему будут выделены — эти данные будут различными для разных компьютеров. При этом задача распределения ресурсов ложится на ОС.
В ОС Windows, как и в большинстве современных ОС, драйвера управляют буквально всем: работой с аппаратурой, поддержкой файловых систем различных типов, сетевых протоколов и т.п. Это дает определенные преимущества и делает систему более гибкой: например, для того, чтобы ОС стала «понимать» другой сетевой протокол, нужно всего лишь установить соответствующий драйвер. 1.1 Система ввода-вывода в Windows.
На данный момент наиболее распространены два семейства ОС Windows: Windows NT, куда относятся Windows NT, 2000, XP, и Windows 9x (Win 95, 98, ME). При этом отмечается тенденция к отмиранию ветки 9х, хотя такие системы будут встречаться еще достаточно долго. Каждая ветка использует свою архитектуру ядра и подсистемы ввода-вывода. Поэтому естественно, написание драйверов для этих систем должно отличаться.
В Windows NT 4.0 появилась своя архитектура драйверов. Она ставила перед собой цели повышения устойчивости работы драйвера, переносимости с одной платформы на другую, поддержки многопроцессорности т.п. Вместе с тем архитектура драйверов Windows NT 4.0 была, что называется, «сырой» и недоработанной, хотя и очень перспективной. С выходом систем Win98 и Win2000 появилась новая архитектура драйверов — WDM (Windows Driver Model). Она развилась из архитектуры драйверов Windows NT 4.0 с небольшими изменениями. WDM – драйвера с равным успехом могут быть использованы как в Win 98, так и в Win 2000.
Система Win 98 состоит как бы из двух слоев: User Mode (режим пользователя) и Kernel Mode (режим ядра). В режиме пользователя функционируют пользовательские приложения. Они работают в 3-м кольце защиты; каждая программа работает в своем виртуальном адресном пространстве. Для каждого DOS или Windows–приложения создается своя виртуальная машина (Virtual Machine, VM), задачей которой является виртуализация аппаратуры компьютера для данного приложения. Т.е. каждое приложение считает, что вся оперативная память и все остальные аппаратные ресурсы принадлежат только ему и приложение может обратиться к ним в любой момент. Ядро ОС содержи диспетчер виртуальных машин (Virtual Machine Manager, VMM). Задача VMM — корректно разрешать конфликты, возникающие при доступе к ресурсам системы из разных VM. Ядро, VMМ, виртуальные машины и драйвера виртуальных устройств (Virtual Device Drivers), естественно, работают в режиме ядра (Kernel Mode).
Рис. 1. Подсистема ввода-вывода Win 98.
В Windows 98 обработка запросов на ввод-вывод от приложений DOS и от старых Win16–приложений отличается от обработки запросов новых Win32–приложений. Для DOS–приложений создается своя виртуальная машина (DOS virtual machine), Win 16 и Win32 — приложения используют виртуальную машину Windows (System Virtual Machine). Обычно, когда приложение запрашивает операцию ввода-вывода (например, вызывает функцию API ReadFile — чтение из файла), этот запрос поступает в одну из системных DLL (в нашем случае — kernel32.dll). Оттуда запрос на операцию с внешним устройством передается сразу системным драйверам. Такая организация запроса Приложение→dll→Драйвер получила наибольшее распространение.
Система Windows 2000 имеет другую архитектуру, отличную от Win98. Это обусловлено повышенными требованиями к надежности, защите и переносимости этой системы (теоретически, Win2000 — переносимая система, и существуют реализации Win2000 под системы Alpha, MIPS и др.). В настоящее время именно благодаря этим особенностям Win2000 завоевывает все большую популярность, поэтому стоит рассмотреть особенности ее архитектуры подробнее.
Рис. 2 — главные компоненты Windows2000.
Окружение Win2000 включает компоненты, которые работают в режиме пользователя (User mode) и в режиме ядра (Kernel mode). В режиме пользователя работают подсистема защиты, подсистема Win32-архитектуры (обеспечивает стандартные API — вызовы Windows), подсистема POSIX (обеспечение кроссплатформенности). В режиме ядра работают все основные компоненты системы: диспетчер ввода-вывода (I/O manager), диспетчер конфигурации (Configuration Manager), подсистема PnP, диспетчер управления энергопотреблением (Power Manager), диспетчер памяти (Memory Manager) и прочие жизненно необходимые службы. Драйвера в Win2000 включены в подсистему ввода-вывода. При этом драйвера тесно взаимодействуют практически со всеми компонентами ядра. Драйвера взаимодействуют с аппаратурой при помощи Hardware Abstraction Level, HAL (уровень абстракции аппаратуры). HAL — программный компонент ядра Win2000, который обеспечивает интерфейс ядра (в том числе и некоторых драйверов) с аппаратурой. Т.к. Win2000 – платформенно независимая система (уже сейчас есть версии Win2000 для процессоров Alpha и RISC), то HAL избавляет ядро от непосредственного общения с кэшем, прерываниями, шинами ввода-вывода и большинством прочих устройств, оставляя эту работу драйверам, специально написанным для данной системы. Таким образом, ядро системы представляется набором отдельных изолированных модулей с четко определенными внешними интерфейсами.
Все драйвера NT имеют множество стандартных методов драйвера, определенных системой, и, возможно, несколько специфических методов, определенных разработчиком. Драйвера Windows 2000 используют архитектуру WDM (Windows Driver Model). В Windows 2000 драйвера бывают следующих типов:
• Kernel mode drivers (драйверы режима ядра). Основной тип драйвера. Такие драйвера используются для решения общих задач: управление памятью, шинами, прерываниями, файловыми системами, устройствами хранения данных и т.п.
• Graphics drivers (драйверы видеокарт). Как правило, создаются одновременно с самой видеокартой. Очень сложны в написании, так как должны учитывать множество противоречивых требований и поддерживать множество стандартов. Скорее всего, вам не потребуется создавать ничего подобного.
• Multimedia drivers (мультимедиа-драйверы). Драйверы для :
• Аудиоустройств — считывание, воспроизведение и компрессия аудиоданных.
• устройств работы с видео — захват и компрессия видеоданных.
• позиционных устройств — джойстики, световые перья, планшеты и пр.
• Network drivers (сетевые драйвера) — работа с сетью и сетевыми протоколами на всех уровнях.
• Virtual DOS Drivers — драйверы для виртуальных машин MS-DOS. Постепенно переходят в раздел рудиментарных.
В свою очередь, существует три типа драйверов ядра, каждый тип имеет четко определенные структуру и функциональность.
• Device drivers (драйвера устройств), такие как драйвер клавиатуры или дисковый драйвер, напрямую общающийся с дисковым контроллером. Эти драйвера также называются драйверами низкого уровня, т. к. они находятся в самом низу цепочки драйверов Windows NT.
• Intermediate drivers (промежуточные драйвера), такие как драйвер виртуального или зеркального диска. Они используют драйверы устройств для обращения к аппаратуре.
• File system drivers (FSDs). Драйверы файловых систем, таких как FAT, NTFS, CDFS, для доступа к аппаратуре используют Intermediate drivers и Device drivers.
Драйвера Windows 2000 должны удовлетворять следующим требованиям:
• Переносимы с одной платформы на другую.
• Поддерживающие мультипроцессорные платформы.
• Поддерживать пакетный ввод-вывод с использванием I/O request packets (IRPs, запросы ввода-вывода).
• Поддерживать асинхронный ввод-вывод.
Система ввода-вывода Windows 2000 имеет следующие особенности:
• Менеджер ввода-вывода NT представляет интерфейс для всех kernel-mode драйверов, включая драйвера физических устройств, драйвера логических устройств и драйвера файловых систем.
• Операции ввода-вывода послойные. Это значит, что вызов, сделанный пользователем, проходит через несколько драйверов, генерируя несколько пакетов запросов на ввод-вывод и «по пути» обращаясь к необходимым драйверам. К примеру, когда приложение пытается открыть файл, подсистема ввода-вывода Windows делает запрос к драверу файловой системы; драйвер файловой системы обращается к промежуточному драйверу; и лишь промежуточный драйвер обращается непосредственно к винчестеру. Такая архитектура построения системы существенно повышает ее гибкость и снижает общую стоимость разработки.
• Разработчик драйвера обязан реализовать несколько стандартных функций, к которым будет обращаться диспетчер ввода-вывода (I/O manager).
Простейший 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. Прошу обратить внимание на комментарии, в частности на этот
Драйверная модель WDM
1.4 Драйверная модель WDM
WDM (Windows Driver Model) – новая модель архитектуры драйверов, предложенная Microsoft для Windows 2000, хотя эта архитектура развивалась, начиная с Windows 3.11, продолжая развиваться и в Windows 98 и Windows NT, но по-настоящему полной она стала только в Windows 2000.
С точки зрения WDM, существует три типа драйверов:
· Драйвер шины – драйвер, обслуживающий контроллер шины, адаптер, мост или любые другие устройства, имеющие дочерние устройства. Для каждого типа шины в операционной системе имеется свой драйвер;
· Функциональный драйвер – основной драйвер устройства, предоставляющий его функциональный интерфейс. Этот драйвер обязателен кроме тех случаев, когда ввод-вывод осуществляется драйвером шины или драйвером фильтров шины. Функциональный драйвер по определению обладает наиболее полной информацией о своем устройстве. Обычно только этот драйвер имеет доступ к специфическим регистрам устройства;
· Драйвер фильтра – драйвер, поддерживающий дополнительную функциональность устройства (или существующего драйвера) или изменяющий запросы ввода / вывода и ответы на них от других драйверов. Таких драйверов может быть несколько, хотя их присутствие необязательно. Они могут работать как на более высоком уровне, чем функциональный драйвер или драйвер шины, так и на более низком.
В среде WDM один драйвер не может контролировать все аспекты устройства: драйвер шины информирует диспетчера PnP об устройствах, подключенных к шине, в то время как функциональный драйвер управляет устройством.
1.4.1 Драйверные слои
Согласно перечисленным выше типам драйверов, существует три типа
объектов:
· Объекты физических устройств (PDO, Physical Device Object) – эти объекты создаются для каждого физически идентифицируемого элемента аппаратуры, подключенного к шине данных;
· Объекты функциональных устройств (FDO, Functional Device Object) – подразумевает единицу логической функциональности устройства;
· Объекты фильтров устройств (FiDO, Filter Device Object) – предоставляют дополнительную функциональность.
В Windows NT 5 последовательность загрузки драйверов устройств такая:
1. Во время загрузки операционной системы производится загрузка шинных драйверов для каждой известной системе шины (список шин создается при установке операционной системы и сохраняется в реестре);
2. Вызывается DriverEntry, а затем AddDevice для каждого шинного драйвера. В AddDevice создается FDO для драйвера системной шины. Затем на созданный FDO отправляется запрос IRP_MN_START_DEVICE;
3. Шинный драйвер составляет список всех устройств, подключенных к шине. Для каждого найденного устройства создается объект PDO;
4. На каждый PDO посылается запрос IRP_MN_QUERY_DEVICE_RELATION, в ответ на который шинный драйвер возвращает идентификаторы всех найденных устройств;
5. На эти PDO посылают запрос IRP_MN_QUERY_ID, в ответ на который драйвер системной шины сообщает идентификаторы этих устройств;
6. Получив идентификаторы, система пытается найти и загрузить драйверы устройств;
7. Найдя драйвер для устройств, система загружает его в память, вызывая его DriverEntry. Потом вызывается AddDevice, где создается FDO для устройства. Если устройств, управляемых этим драйвером, несколько, то AddDevice будет вызвана для каждого устройства. Если в реестре зарегистрированы дополнительные фильтры, то они также загружаются в память. Затем система посылает на FDO запрос IRP_MN_START_DEVICE;
8. Происходит посылка на FDO запроса IRP_MN_QUERY_DEVICE_RELATIONS. Если устройство само является шиной или держит на себе другие устройства, которыми само не управляет, то для устройства на нем повторяется вся последовательность действий, начиная с пункта 5.
Функция AddDevice, вызываемая для каждого FDO, вызывает IoCreateDevice и IoAttachDeviceToStack, обеспечивая построение стека устройств. Стек устройств обеспечивает прохождение запросов от пользовательских программ до аппаратного (нижнего) уровня драйверов (Рис. 1.4.1.1).
Рис. 1.4.1.1 Стек устройств
Из вышесказанного становится понятным, что разрабатываемый драйвер должен являться драйвером-фильтром нижнего уровня, связанным с клиентским драйвером USB‑накопителя. Необходимость работы с клиентским USB‑драйвером объясняется тем, что именно на этом уровне перехватываемая информация обладает требуемой структурированностью – передаются именно файлы, а не блоки информации (кадры или составленные из них транзакции), определяемые протоколом обмена по USB.
1.4.2 Точки входа WDM-драйвера
WDM‑драйверы отличаются от унаследованных драйверов тем, что должны содержать дополнительные точки входа для поддержки PnP, и, в целом, они более логичны по структуре. Приведем список точек входа и кратко охарактеризуем их назначение:
IN PDRIVER_OBJECT DriverObject, // указатель на объект драйвера
IN PUNICODE_STRING RegistryPath) // путь к подразделу регистра,
// относящегося к драйверу
Эта функция выполняется при загрузке драйвера операционной системой. В WDM‑драйверах на DriverEntry возложены обязанности по регистрации всех остальных точек входа драйвера.
IN PDRIVER_OBJECT DriverObject, // указатель на объект драйвера
IN PDEVICE_OBJECT PhysicalDeviceObject) // указатель на родительский PDO
В драйверах, поддерживающих PnP, через эту точку входа менеджер PnP посылает драйверу уведомление об обнаружении устройства, за которое должен отвечать драйвер. Функция AddDevice должна создать объект устройства с помощью вызова IoCreateDevice и при необходимости присоединить его к стеку устройств с помощью IoAttachDeviceToDeviceStack.
IN PDRIVER_OBJECT DriverObject) // указатель на объект драйвера
Вызывается при выгрузке драйвера. В этой функции должны осво
бождаться все затребованные драйвером ресурсы. Драйверы WDM‑модели
выполняют эти действия в обработчике запросов IRP_MJ_PNP с субкодом IRP_MN_REMOVE_DEVICE, то есть при удалении устройства из системы.
Следует выделить отдельный класс точек входа драйвера, которые предназначены для обработки IRP‑пакетов с различными кодами операций. Эти точки входа регистрируются при загрузке драйвера в функции DriverEntry. Регистрация производится путем заполнения элементов массива MajorFunction адресами диспетчеризуемых функций. Индексом в этом массиве являются коды IRP_MJ_XXX, то есть описанные числами типы пакетов IRP. Диспетчер ввода / вывода, ориентируясь на заполнение этого массива, вызывает нужные функции драйвера.
Поскольку для драйвера важны только адреса рабочих процедур, то все рабочие процедуры могут иметь совершенно произвольные имена.
Модель драйверов 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, и исправить количество портов ввода-вывода.
Драйверы фильтра, находящиеся на верхнем уровне, обычно предоставляют устройству какие-нибудь дополнительные свойства. Например, драйвер фильтра такого устройства, как клавиатура, находящийся на верхнем уровне, может навязывать дополнительные проверки безопасности.