Основы написания драйвера уровня ядра для ОС Windows 2000, XP и XP Embedded

Страница создана Гульнара Панина
 
ПРОДОЛЖИТЬ ЧТЕНИЕ
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
                         ДРАЙВЕРЫ

                         Основы написания
                         драйвера уровня ядра
                         для ОС Windows 2000,
                         XP и XP Embedded
                         Валерий Яковлев

                         Статья посвящена практическим аспектам написания драйверов уровня ядра
                         в операционных системах семейства NT — Windows 2000/XP (XP Embedded).
                         Для понимания работы подсистемы вводавывода, составляющим звеном которой
                         являются драйверы, дано краткое описание структурной организации ОС в целом.
                         Приводится рабочий пример простейшего драйвера уровня ядра.

     В ВЕДЕНИЕ                               2000/XP, поэтому дальнейшее изложе        ния ОС в целом. Это позволяет трезво
       Современный уровень аппаратных        ние материала касается именно этих         оценивать временн5ые возможности
     средств, используемых в автоматиза     ОС. Использование стандартных ОС           стандартных драйверов и при необхо
     ции, давно «размыл» чёткую границу      позволяет максимально использовать         димости получения лучших времен
     между компьютерами верхнего уровня      опыт программирования, накоплен           ны' х показателей проектируемой сис
     и контроллерами полевого уровня, с      ный специалистами, привыкшими ра          темы в целом написать свой, возмож
     точки зрения используемого систем      ботать со знакомым набором API             но менее функциональный, но более
     ного программного обеспечения. Ап      (Application Programming Interface —       быстрый драйвер. Тема драйверов дос
     паратные ресурсы современных конт      интерфейс прикладного программи           таточно обширна и не укладывается в
     роллеров позволяют использовать на      рования). В числе решаемых програм        рамки одной статьи, поэтому мы огра
     них не только оптимизированные к        мистами задач, кроме собственно на        ничимся минимально необходимым
     минимальным аппаратным требова         писания прикладной программы, мо          общим материалом по структуре
     ниям операционные системы, напри       жет возникнуть необходимость в на         Windows 2000/XP и затем решим при
     мер Windows CE .NET, но и стандарт     писании драйвера, например, если по        кладную задачу – напишем простей
     ные ОС класса Windows или Linux.        какимлибо причинам драйверы под           ший драйвер, осуществляющий доступ
     Кроме того, из встраиваемых, но более   ОС Windows не поставляются (напри         к регистрам платы, установленной в
     ресурсоёмких операционных систем,       мер, платы вводавывода в формате          слот ISA (пусть это будет модуль
     всё более активно применяющихся на      MicroPC фирмы Octagon Systems или          UNIOXX5 фирмы Fastwel). Выбор
     рынке автоматизации отечественной       Fastwel) или речь идёт о плате собст      устройства на шине ISA обусловлен
     промышленности, можно назвать           венной разработки. Несмотря на боль       более простой схемой программного
     Embedded Windows XP, общая струк       шое количество технической литера         взаимодействия с таким устройством,
     турная организация которой во           туры, посвящённой программирова           на самом деле это может быть и плата,
     многом схожа с организацией стан       нию в ОС Windows, проблемы написа         установленная в слот PCI, или любой
     дартного (офисного) варианта. Воз      ния драйверов практически не осве         другой системный ресурс, обращение
     можность «конструирования» разра       щаются. Безусловно, этот вопрос дос       к которому на уровне регистров запре
     ботчиком образа этой ОС из большого     таточно специфичен для программи          щено из программ режима пользовате
     числа компонентов не влияет на ос      стов общего плана, но для специали        ля. При этом усложняется алгоритм
     новные принципы общей организации       стов, работающих в сфере автоматиза       взаимодействия с устройством, но
     ОС в части затрагиваемых в этой ста    ции производства, эта тема представ       принцип доступа через порты ввода
     тье вопросов, поэтому рассматрива      ляет большой интерес. Даже если про       вывода остаётся. Драйвер напишем на
     емые здесь возможности написания        граммисту не придётся непосредствен       языке ассемблера, который наиболее
     драйверов уровня ядра применимы и       но заниматься написанием драйверов,        эффективно используется именно при
     для этой ОС. На текущий момент до      более глубокое понимание функцио          написании драйверов, где требования
     минирующее положение среди стан        нирования этой подсистемы ОС               к минимизации кода и, как следствие,
     дартных ОС Windows в сфере автома      Windows даст более чёткое представле      малое время исполнения объективно
68   тизации занимают ОС Windows             ние о возможностях функционирова          необходимы.

     www.cta.ru                                                                                                                СТА 2/2006

                                                                               © 2006, CTA Тел.: (495) 2340635 Факс: (495) 2321653 http://www.cta.ru
П Р О Г РА М М Н О Е О Б Е С П Е ЧЕ Н И Е / Д РА Й В Е Р Ы

Н ЕОБХОДИМЫЕИНСТРУМЕНТЫ
ПРОГРАММИРОВАНИЯ                                Процессы             Процессы               Пользовательские                Подсистемы
  Для решения поставленной задачи              поддержки             сервисов                 приложения                     окружения
используем пакет MASM32 v.8.2, а                системы
также комплект разработки драйверов
(Windows 2000 Driver Development Kit,
DDK), который можно бесплатно                                                    DLL всех систем
скачать с сайта Microsoft (www.micro
soft.com/ddk/). К сожалению, фирма                      Пользовательский
Microsoft пакет DDK для ОС Windows                      режим
XP не выкладывает для свободного                                                                                       Режим ядра
доступа, предлагая его получить по
почте на CDносителе. И хотя при
                                                     Исполнительная система
этом оплачивается только доставка,
                                                                                                       Поддержка
получение пакета затруднительно. В            Ядро          Драйверы устройств                       окон и графики
комплект DDK входят документация             Уровень абстрагирования от оборудования
(папка help), являющаяся наиболее
полным источником информации о
внутренних структурах данных и           Рис. 1. Упрощённая схема архитектуры Windows
внутрисистемных функциях исполь
зуемых драйверами устройств, вклю       К РАТКИЙОБЗОР                                     ством. Исполняемый код в пользова
чаемые файлы (*.inc) из папки inc,       АРХИТЕКТУРЫ W INDOWS                              тельском режиме имеет ограничения
примеры реализаций драйверов уст          В Windows 2000/XP существует чёт               на доступ к системным ресурсам, в ча
ройств (папка src), утилиты (папка       кое разграничение двух областей в                 стности, на прямой доступ к оборудо
tools). Главное, в DDK входит набор      оперативной памяти и режимов про                 ванию. Это связано с желанием обес
библиотечных файлов (*.lib), необхо     цессора для исполняемого кода: 1) об             печить более устойчивое функциони
димых при компоновке законченных         ласть исполняемого кода в непривиле              рование системы при наличии ошибок
драйверов и нашего простейшего           гированном режиме работы процессо                в программах пользователей. Надо
драйвера в том числе. В DDK есть два     ра (пользовательском режиме) для                  учитывать, что Windows проектирова
комплекта этих файлов — checked          приложений пользователя и части                   лась как многозадачная и многополь
build и free build, нам необходим free   компонентов ОС, и область исполняе               зовательская система, поэтому крах
build (папка libfre) для окончательной   мого кода операционной системы в                  одного приложения не должен приво
версии Windows, называемой свобод       привилегированном режиме процес                  дить к краху ОС и, следовательно, к
ным выпуском. Функции из библио         сора (режиме ядра). Под областью ис              краху других пользовательских прило
течных файлов (папка libchk) отла       полняемого кода надо понимать об                 жений, запущенных на исполнение в
дочной версии (checked build) отлича    ласти загрузки (диапазон адресов) в               этой системе. Приложения ОС и дру
ются более строгой проверкой оши        оперативной памяти вычислительной                 гие программы, исполняющиеся в ре
бок. Но, увы, не всё так хорошо для      системы. Windows 2000/XP — 32раз                жиме ядра, имеют полный доступ ко
прямого использования включаемых         рядная ОС (существующую 64бит                   всем ресурсам системы. Упрощённая
файлов, содержащих определения           овую версию этой ОС в данной статье               схема архитектуры Windows [2] приве
прототипов функций, а также необхо      не рассматриваем), и поэтому всем                 дена на рис. 1.
димых структур, символьных кон          приложениям доступно до 4 Гбайт ли                 Как уже отмечалось, в режиме поль
стант и макросов. Есть одна пробле      нейного адресного пространства. Ча               зователя функционируют не только
ма, заключающаяся в том, что все         ще всего в системе установлен сущест             прикладные программы пользователя,
описания в DDK даны из расчёта ис       венно меньший объём физической па                но и часть процессов самой ОС.
пользования языка С, в то время как      мяти, но тем не менее для работающих                К компонентам операционной сис
мы хотим воспользоваться «великим        программ это незаметно. Специаль                 темы, работающим в режиме пользова
и могучим» ассемблером. Если ещё         ные системные механизмы обеспечи                 теля, относятся:
есть утилиты, позволяющие автома        вают возможность виртуального при                ● некоторые процессы поддержки сис
тизировать получение incфайлов для      сутствия 4 Гбайт памяти в системе. Де              темы, например процесс обработки
имеющихся libфайлов, то формиро        ление 4 Гбайт виртуального (или не                  входа в систему (Winlogon);
вание incфайлов, содержащих струк      виртуального, если Вы можете себе это             ● процессы Windowsсервисов (о сер
туры и константы,— это в основном        позволить) адресного пространства                   висах поговорим чуть позже). В виде
ручной труд. Эту работу в необходи      между пользовательскими приложе                    сервисов оформлены как некоторые
мом объёме придётся проделать само      ниями и системными программами                      системные сервисы (например Task
стоятельно. Она не из категории твор    осуществляется поровну: первые                      Scheduler), так и отдельные компо
ческих, но в Интернете совершенно        2 Гбайт пользовательские, осталь                   ненты прикладных программ, на
бесплатно можно найти достаточно         ное — системное адресное простран                  пример Microsoft SQL Server, а также
полные версии конвертированных           ство. К ограничению свободы трудно                  некоторые драйверы;
для использования с ассемблером inc     привыкнуть, но, как и в наличии зако             ● пользовательские приложения. На
файлов, и таким образом можно на        нов в стране, в этом есть элемент веко             текущий момент они бывают шести
чать не с нуля [1].                      вой мудрости, накопленной человече                 типов: Win32, Win64 (в 64битовой                       69
СТА 2/2006                                                                                                                          www.cta.ru

                                                                                  © 2006, CTA Тел.: (495) 2340635 Факс: (495) 2321653 http://www.cta.ru
П Р О Г РА М М Н О Е О Б Е С П Е ЧЕ Н И Е / Д РА Й В Е Р Ы

          версии ОС), Windows 3.1, MSDOS,                 речь идёт только о файловой системе          В рамках обобщения понятия уст
          POSIX и OS/2;                                    ОС. На самом деле многие физиче           ройства в Windows существует понятие
        ● подсистемы окружения. Это часть                  ские устройства (например COM             класса устройств. Введение этого уров
          операционной системы (программ                  порты) представляются в системе            ня абстрагирования сопровождается
          ные оболочки), предоставляющая                   как файлы, и обращение к ним осу          неизбежным появлением типа драйве
          приложениям пользователя опреде                 ществляется посредством вызова             ров, отвечающих за обслуживание уст
          лённый для конкретной подсистемы                 функций, как к обычным файлам, но          ройств одного класса (например CD
          набор функций. Windows обеспечи                 со специфическими параметрами.             ROM), и драйверов, отвечающих за ре
          вает работу с тремя подсистемами                 Далее уже драйверы файловой систе         шение того или иного уровня взаимо
          окружения: Win32, POSIX и OS/2.                  мы, получившие запрос на вводвы          действия с конкретным оборудовани
          Windows 2000 поставляется с двумя                вод, определяют, о каком устройстве        ем. В рамках этого деления существуют
          подсистемами, а в Windows XP,                    идёт речь, и вызывают соответствую        драйверы:
          кроме Win32, не поставляются дру                щие физическому устройству драй           ● классов устройств;
          гие подсистемы окружения.                        веры следующего уровня;                    ● портдрайверы;
          К компонентам ОС, работающим в                 ● драйверы с поддержкой Plugand            ● минипортдрайверы.
        режиме ядра, относятся:                            Play (PnP) и ACPI (advanced configu         Драйверы устройств в ОС Windows
        ● исполнительная система, обеспечи                ration powermanagement interface —        могут работать как в режиме ядра, так и
          вающая базовыми сервисами в части                усовершенствованный интерфейс              в пользовательском режиме. К послед
          управления памятью, процессами и                 управления конфигурацией и энер           ним относятся:
          потоками, вводомвыводом и т.д.;                 гопотреблением);                           ● драйверы виртуальных устройств
        ● ядро, которое содержит обобщённый              ● драйверы, не поддерживающие спе             (VDD);
          набор функций ОС, скрывающий                     цификации PnP и ACPI (например             ● драйверы принтеров.
          различия между аппаратными плат                 драйверы      протоколов     TCP/IP,         Важнейшим компонентом испол
          формами (на разных этапах развития               IPX/SPX и т.д.), которые расширяют         нительной системы, отвечающим за
          ОС NT поддерживались не только                   функциональность системы, предо           связь с устройствами, является под
          процессоры Intel, но и MIPS, Alpha               ставляя доступ из режима пользова         система вводавывода. Построение
          AXP, Motorola PowerPC). Ядро пре                теля к системным сервисам и драй          подсистемы вводавывода, как и
          доставляет процедуры/функции и ба               верам режима ядра.                         других компонентов ОС Windows
          зовые объекты, используемые испол               В свою очередь, в каждой из катего        призвано обеспечить максимальную
          нительной системой и драйверами                рий есть группы драйверов, которые           устойчивость ОС в целом. Поэтому в
          для реализации структур и функций              различаются в зависимости от модели          соответствии с общей доктриной раз
          более высокого уровня. К таким                 устройства и места драйверов в цепоч        деления ответственности, связанной с
          функциям относятся планирование                ке обработки запроса на обслуживание         режимами работы в ОС Windows, при
          потоков, диспетчеризация прерыва              операций вводавывода.                       ложения пользователя не могут обра
          ний, синхронизация процессов и т.д.;             Начиная с Windows 2000, была введе        щаться к устройствам (читай — драй
        ● драйверы устройств;                            на поддержка PnP и энергосберегаю           верам) напрямую, а лишь через по
        ● уровень абстрагирования от оборудо            щих технологий (ACPI), что привело к         средников в лице диспетчеров. Неко
          вания (Hardware Abstraction Layer,             расширению модели драйверов, назы           торые компоненты подсистемы и дис
          HAL) — набор низкоуровневых                    ваемой Windows Driver Model (WDM);           петчеры, как, например, диспетчер
          функций (около 92), обеспечиваю               напомню, что речь идёт о линейке NT,         PlugandPlay, работают как в пользо
          щий стандартный интерфейс взаимо              модель драйверов WDM ранее реали            вательском режиме, так и в режиме
          действия с аппаратнозависимыми                зована в Windows 98 и Windows                ядра, но в целом вся подсистема и, в
          элементами для функций, вызывае               Millennium Edition. ОС Windows 2000 и        частности, её главный компонент —
          мых компонентами ядра, драйверов и             более поздние версии ОС линейки NT           диспетчер вводавывода работает в
          исполнительной системы, позволяю              поддерживают и так называемые уна           режиме ядра. В некотором промежу
          щий абстрагироваться от того, на ка           следованные драйверы (NT4), естест          точном положении (с точки зрения
          кой конкретно элементной базе (чи             венно, с некоторой потерей функцио          доступности из разных режимов) ока
          пе контроллера прерывания, кон                нальности.                                   зываются inf и catфайлы (хранят
          троллера ПДП) реализовано выпол                 Модель WDM предусматривает су             цифровые подписи, удостоверяющие
          нение доступа к шине, таймеру и т.д.;          ществование трёх типов драйверов:            аттестацию лаборатории Microsoft
        ● подсистема поддержки окон и гра               ● драйвер шины. Интересным момен            WHQL — Microsoft Windows Hardware
          фики.                                            том является то, что, в отличие от ОС      Quality Lab) и реестр. Диспетчер вво
          Драйверы устройств в Windows, в от              NT4, Windows 2000 и выше, позволя         давывода не только обеспечивает
        личие от DOS, для поддержки перено                ют реализовать поддержку новых ти         взаимосвязь между приложениями
        симости не обращаются к оборудова                 пов шин, не поддерживаемых самой           пользователя и драйверами устройств,
        нию напрямую, а используют функ                   ОС, не путём создания своего HAL           но также предоставляет общий для
        ции, предоставляемые HAL. Драйверы                 (DLL), а всего лишь добавлением            драйверов код, используемый при об
        устройств режима ядра делятся на                   своего драйвера шины. Это крайне           работке запросов, что существенно
        следующие основные категории:                      существенно для поставщиков                влияет на минимизацию кода самих
        ● драйверы файловой системы (напри                OEMоборудования;                          драйверов. Он также обеспечивает
          мер сетевые редиректоры и серверы).            ● функциональный драйвер;                    управление буферами запросов ввода
70        Не стоит понимать буквально, что               ● драйвер фильтра.                           вывода и при необходимости вызовы

        www.cta.ru                                                                                                                           СТА 2/2006

                                                                                             © 2006, CTA Тел.: (495) 2340635 Факс: (495) 2321653 http://www.cta.ru
П Р О Г РА М М Н О Е О Б Е С П Е ЧЕ Н И Е / Д РА Й В Е Р Ы

одним драйвером других драйверов
для организации обработки запроса                             Приложения                  Windows"
по цепочке. Упрощённая схема орга                            пользователя                сервисы
низации подсистемы вводавывода
[2] изображена на рис. 2. Подсистема
вводавывода Windows проектирова
лась с целью обеспечения максималь                                       Диспетчер PnP
                                             Приложения                                                     Устанавливаемые
                                                                          родительского
ной гибкости, как с точки зрения воз        пользователя                                                     компоненты
                                                                             режима
можности её расширения драйверами
специфических устройств, так и с
учётом поддержки максимального аб                                           Пользовательский
                                                                             режим                          INF", CAT"файлы,
страгирования устройств для при
                                                                                                                  реестр
кладных приложений. Важными мо                                                    Режим ядра
ментами обеспечения подобной
функциональности являются возмож
ности динамической загрузки (явной
                                                     Процедуры        Диспетчер         Диспетчер             Диспетчер
или на основе перечисления) и вы
                                                     WDM, WMI           PnP           электропитания        ввода"вывода
грузки драйверов, обобщённый вид
формируемых структур запросов на
вводвывод и диспетчеризация. Од                                                         Подсистема ввода"вывода
ним из инструментов регистрации,
запуска, останова и выгрузки драйве                                          Драйверы
ров служит механизм управления сер
висами.
                                                             Уровень абстрагирования от оборудования (HAL)
С ЕРВИСЫ
  Сервисы (Services), или службы, яв
ляются процессами, предоставляющи       Рис. 2. Компоненты подсистемы вводавывода
ми дополнительную функциональ
ность в системе, не зависящую от ин     ния сервисом функции из набора                 ный     раздел    в    ветке    реестра
терактивных действий пользователя.       SCMфункций. В основном SCPпри               HKEY_LOKAL_MACHINE\SYSTEM\
То есть это приложения, запускаемые      ложение предназначено для запуска,             CurrentControlSet\Service (основная
без учёта того, зарегистрировался ли в   останова и конфигурирования серви             информационная база SCM, или
системе какойлибо пользователь или      са, иногда это приложение расширяет            ServicesActive database), куда помеща
нет, и довольно часто запуск самого      политику управления сервисом по от            ется как параметр вновь созданного
сервиса происходит до момента появ      ношению к реализуемой SCM                     раздела реестра информация о месте
ления окна регистрации пользователя.     функции. В рамках ОС Windows суще             расположения на диске исполняемого
В части взаимодействия с системой        ствуют встроенные SCP, но для увели           файла соответствующего сервиса, его
сервисы используют «язык» Windows        чения возможностей конфигурирова              параметры при старте и конфигураци
API и функционально состоят из трёх      ния сервиса разработчик может напи            онные настройки (эти настройки по
компонентов:                             сать свою собственную программу                мещаются в подраздел Parameters соз
● Service application — сервисное при   SCP, возможно, даже не реализуя её             данного для сервиса раздела).
  ложение (или драйвер);                 как отдельное приложение, а встраи              SCM отвечает за загрузку как серви
● Service control program (SCP) —        вая её функции в основное приложе             сов, так и драйверов, поэтому не уди
  программа управления сервисом;         ние, использующее сервис. Сервис              вительно, что значения некоторых па
● Service Control Manager (SCM) —        ные приложения только косвенно                 раметров явным образом указывают на
  диспетчер управления сервисом.         взаимодействуют с SCP, изменяя свою            контекст текущего приложения. Об
  Весь необходимый API для реализа      статусную информацию в процессе                щий термин (Services), используемый
ции механизма диспетчеризации            выполнения команд от SCM. Перед                Microsoft для обозначения как служб,
(SCMфункции) сервисов сосредото        использованием SCMфункций SCP                 так и драйверов устройств (они дейст
чен в системной DLLбиблиотеке           необходимо установить канал связи с            вительно во многом схожи по стилю
Advapi32.dll (Advanced API).             SCM       (используется      функция           работы и характеру выполняемых
  Сервисное приложение — это драй       OpenSCManager). Важным моментом                функций), часто вызывает путаницу в
вер или обычное Windowsприложение       является то, что при установке любого          понимании программной документа
(чаще всего реализуемое как консоль     приложения, в рамках которого пред            ции. Наиболее важные для нашей при
ное приложение), имеющее дополни        полагается использование сервиса,              кладной задачи параметры созданного
тельный блок кода, обеспечивающий        необходимо предварительно заре                раздела реестра и их возможные значе
обработку команд от SCP и возврат        гистрировать сервис, вызвав функ              ния для драйверов и сервисов показа
ему определённой статусной инфор        цию CreateService (реализована в               ны в таблице 1.
мации.                                   Advapi32.dll). На основании парамет             На конечном этапе загрузки ОС
  SCP — стандартное Windowsпри         ров вызова этой функции SCM созда             системный процесс Winlogon (перед
ложение, использующее для управле       ёт для каждого сервиса индивидуаль            появлением диалогового окна с при                       71
СТА 2/2006                                                                                                                      www.cta.ru

                                                                              © 2006, CTA Тел.: (495) 2340635 Факс: (495) 2321653 http://www.cta.ru
П Р О Г РА М М Н О Е О Б Е С П Е ЧЕ Н И Е / Д РА Й В Е Р Ы

                                                                                                                                                        Таблица 1
                                      Основные параметры при регистрации сервиса/драйвера и их возможные значения

                 Параметр                 Значение                                                         Описание

                            SERVICE_BOOT_START            (0)     Драйвер загружается Ntldr или Osloader, то есть в период загрузки самой ОС
                            SERVICE_SYSTEM_START          (1)     Драйвер загружается после загрузки и инициализации драйверов со значением
         Start              SERVICE_AUTO_START            (2)     Драйвер или сервис запускается SCM автоматически после запуска SCMпроцесса (Services.exe)
                            SERVICE_DEMAND_START          (3)     Драйвер или сервис запускается SCM по требованию
                            SERVICE_DISABLED              (4)     Драйвер или сервис не загружается и не инициализируется
                            SERVICE_ERROR_IGNORE          (0)     Код ошибки, возвращаемый драйвером или сервисом, игнорируется
                            SERVICE_ERROR_NORMAL          (1)     Если драйвер или сервис возвращает код ошибки, выводится предупреждение
                                                                  Если драйвер или сервис возвращает ошибку и ещё не использовалась последняя удачная
         ErrorControl       SERVICE_ERROR_SEVERE          (2)     конфигурация, то используется последняя удачная конфигурация. Если используется
                                                                  именно она, то загрузка продолжается.
                                                                  Если драйвер или сервис возвращает ошибку и ещё не использовалась последняя удачная
                            SERVICE_ERROR_CRITICAL        (3)     конфигурация , то используется последняя удачная конфигурация. Если используется
                                                                  именно она, то выводится BSOD «Синий экран смерти».
                            SERVICE_KERNEL_DRIVER         (1)     Драйвер устройства режима ядра
         Type
                            SERVICE_FILE_SISTEM_DRIVER    (2)     Драйвер файловой системы
                                                                  Путь к исполняемому файлу драйвера или сервиса. По умолчанию файл ищется в папке
         ImagePath          Путь к исполняемому файлу
                                                                  %SystemRoot%\System32\Drivers
         DisplayName        Имя сервиса                           Имя сервиса. По умолчанию имя его раздела в реестре.

        глашением к регистрации) запускает               Прототип функции выглядит следую                     регистрация нашего драйвера путём
        SCM, который в созданной внутрен                щим образом:                                          вызова функции CreateService, прото
        ней базе данных сервисов SCM ищет                                                                      тип функции выглядит так:
        записи драйверов и сервисов с пара              OpenSCManager proto
        метром Start, имеющим значение                         lpMachineName:LPSTR,                            CreateService proto
        SERVICE_AUTO_START, и запускает                        lpDatabaseName:LPSTR,                                  hSCManager:HANDLE,
        их.                                                    wDesiredAccess:DWORD                                   lpServiceName:LPSTR,
          Далее рассмотрим пример реализа               lpMachineName                                                lpDisplayName:LPSTR,
        ции SCP на языке ассемблера                        Указатель на строку, завершающую                          dwDesiredAcces:DWORD,
        (листинг 1). Минимально необходимый                ся нулём, содержащую имя компью                           dwServiceType:DWORD,
        материал, позволяющий понять прави                тера. Устанавливая этот параметр в                         dwStartType:DWORD,
        ла и нотацию для оформления про                   NULL, мы устанавливаем связь с                             dwErrorControl:DWORD,
        грамм на этом языке, можно найти в [3].            локальным SCM (на этом компью                             lpBinaryPathName:LPSTR,
          Действия программы заключаются                   тере).                                                     lpLoadOrderGroup:LPSTR,
        в следующем. Устанавливается канал               lpDatabaseName                                               lpdwTagId:LPDWORD,
        связи с SCM. Если при установлении                 Указатель на строку, завершающую                          lpDependencies:LPSTR,
        канала связи происходит ошибка, вы                ся нулём, содержащую имя откры                            lpServiceStartName:LPSTR,
        водится сообщение “Attempt of                      ваемой базы. Устанавливая этот па                         lpPassword:LPSTR
        connection with SCM has failed!” и про            раметр в NULL, мы устанавливаем                     hSCManager
        грамма завершается. В случае уста                 связь с локальной, активной в теку                   Дескриптор базы данных SCM.
        новления канала регистрируем драй                 щий момент базой данных –                           lpServiceName
        вер. Если происходит ошибка регист                SERVICES_ACTIVE_DATABASE.                             Указатель на строку, завершающую
        рации, выводим соответствующее со               dwDesiredAccess                                         ся нулём, содержащую имя драйве
        общение “Attempt to register the driver            Права доступа, запрашиваемые при                      ра/сервиса. Длина до 256 символов.
        has failed!” и, закрыв дескриптор                  открытии канала. Могут быть сле                      Соответствует имени подраздела в
        SCM, завершаем программу. В случае                 дующие значения:                                      реестре.
        успеха регистрации драйвера запуска               SC_MANAGER_CONNECT (уста                           lpDisplayName
        ем драйвер, удаляем его, закрываем                 навливаются по умолчанию, пара                       Указатель на строку, завершающуюся
        дескриптор драйвера, закрываем                     метр 0);                                              нулём, содержащую экранное имя
        дескриптор SCM, завершаем про                     SC_MANAGER_CREATE_SERVICE                             драйвера/сервиса. Длина до 256 сим
        грамму. В этой программе драйвер за               (доступ для внесения в базу данных                    волов. Соответствует значению пара
        пускается один раз, и поэтому его                  записи о новом драйвере);                             метра DisplayName в реестре.
        действия носят характер, только под               SC_MANAGER_ALL_ACCESS                               dwDesiredAcces
        тверждающий факт его работы. Те                   (полный доступ).                                      Запрашиваемый тип доступа. Могут
        перь более подробно.                               Если эта функция возвращает не                        быть значения:
          Для вызова SCMфункций SCP дол                NULL (NULL говорит об ошибке), то                       SERVICE_ALL_ACCESS (полный
        жна установить канал связи с SCM, ис            мы получаем дескриптор активной                         доступ); SERVICE_START (доступ
72      пользуя функцию OpenSCManager.                   базы данных. Следующий шаг — это                        на запуск драйвера/сервиса);

        www.cta.ru                                                                                                                                    СТА 2/2006

                                                                                                      © 2006, CTA Тел.: (495) 2340635 Факс: (495) 2321653 http://www.cta.ru
П Р О Г РА М М Н О Е О Б Е С П Е ЧЕ Н И Е / Д РА Й В Е Р Ы

Листинг 1

 ; Пример простой программы управления сервисом (SCP)                   ; Регистрируем драйвер
                                                                             invoke CreateService, hSCManager, offset DrvName1, \
 .386                                                                        offset DispNameDrv, \
 .model flat, stdcall                                                        SERVICE_START + DELETE, SERVICE_KERNEL_DRIVER, \
 option casemap:none                                                         SERVICE_DEMAND_START, \
                                                                             SERVICE_ERROR_IGNORE, addr CardUNIODriverPath, \
 include D:\masm32\INCLUDE\kernel32.inc                                      NULL, NULL, NULL, NULL, NULL
 include D:\masm32\INCLUDE\user32.inc                                             .if eax != NULL
 include D:\masm32\INCLUDE\advapi32.inc                                               mov hService, eax
 include D:\masm32\INCLUDE\windows.inc                                  ; Запускаем драйвер
 includelib D:\masm32\LIB\kernel32.lib                                                invoke StartService, hService, 0, NULL
 includelib D:\masm32\LIB\user32.lib                                    ; Удаляем драйвер
 includelib D:\masm32\LIB\advapi32.lib                                                invoke DeleteService, hService
                                                                        ; Закрываем дескриптор драйвера
 .data                                                                                invoke CloseServiceHandle, hService
 hSCManager         dd 0                                                          .else
 hService           dd 0                                                ; Если не удалось зарегистрировать сервис, выводим об этом сообщение
 ALIGN               4                                                                invoke MessageBox, NULL, offset ErrMsg2, NULL,
 CardUNIODriverPath db "D:\masm32\BIN\CardUNIO.sys",0                     MB_ICONSTOP
 ALIGN               4                                                            .endif
 ErrMsg1            db "Attempt of connection with SCM has failed!",0   ; Закрываем канал связи с SCM
 ALIGN               4                                                            invoke CloseServiceHandle, hSCManager
 DrvName            db "CardUNIO.sys",0                                      .else
 ALIGN               4                                                  ; Сообщение в случае невозможности установить связь с SCM
 ErrMsg2            db "Attempt to register the driver has failed!",0        invoke MessageBox, NULL, offset ErrMsg1, NULL, MB_ICONSTOP
 ALIGN               4                                                       .endif
 DrvName1           db "CardUNIO",0
 ALIGN               4                                                       invoke ExitProcess, 0
 DispNameDrv        db "MyDriver",0
                                                                         start endp
 .code
  start proc                                                             end start

 ; Устанавливаем канал связи с SCM
      invoke OpenSCManager, NULL, NULL, SC_MANAGER_CREATE_SERVICE
      .if eax != NULL
           mov hSCManager, eax

  SERVICE_STOP (доступ на останов                 ся нулём, содержащую полный путь                 драйверов или групп разделяются од
  драйвера/сервиса); DELETE (доступ               к файлу загружаемого драйвера. Со               ним нулём. Если запуск драйвера не
  на удаление драйвера/сервиса из ба             ответствует значению параметра                   связан с предварительным запуском
  зы SCM).                                        ImagePath в реестре.                             других драйверов, значение NULL.
dwServiceType                                   lpLoadOrderGroup                                 lpServiceStartName
  Тип сервиса, в нашем случае                     Указатель на строку, завершающую                Указатель на строку, завершающую
  SERVICE_KERNEL_DRIVER.                          ся нулём, содержащую имя группы,                 ся нулём, содержащую имя учётной
  Соответствует значению параметра                в случае если загружаемый драйвер                записи (account), с правами которой
  TYPE в реестре.                                 является членом группы. В против                запускается текущий драйвер. В слу
dwStartType                                       ном случае значение NULL или ука                чае типа сервиса
  Тип запуска, в нашем случае                     затель на пустую строку.                         SERVICE_KERNEL_DRIVER пара
  SERVICE_DEMAND_START.                         lpdwTagId                                          метр содержит имя объекта драйве
  Соответствует значению параметра                Указатель на переменную, содержа                ра. Если используется имя объекта
  START в реестре.                                щую уникальное значение тега,                    драйвера, присвоенное подсистемой
dwErrorControl                                    идентифицирующее группу. В про                  вводавывода, то NULL.
  Характер контроля ошибок,                       тивном случае NULL.                            lpPassword
  в нашем случае                                lpDependencies                                     Указатель на строку, завершающуюся
  SERVICE_ERROR_IGNORE.                           Указатель на массив имен драйверов               нулём, содержащую пароль учётной
  Соответствует значению параметра                или групп драйверов, загрузка кото              записи, с правами которой запуска
  ErrorControl в реестре.                         рых должна быть осуществлена до за              ется текущий драйвер. В случае
lpBinaryPathName                                  пуска текущего драйвера. Массив за              SERVICE_KERNEL_DRIVER зна
  Указатель на строку, завершающую               канчивается двумя нулями, имена                  чение этого параметра игнорируется.                     73
СТА 2/2006                                                                                                                                www.cta.ru

                                                                                        © 2006, CTA Тел.: (495) 2340635 Факс: (495) 2321653 http://www.cta.ru
П Р О Г РА М М Н О Е О Б Е С П Е ЧЕ Н И Е / Д РА Й В Е Р Ы

          Остальные функции — StartService,                 менты. В нашем случае аргументы            теки. Надо сказать, что между драйве
        DeleteService и CloseServiceHandle —                отсутствуют, поэтому значение              рами и DLL очень много общего. По
        запускают, удаляют и закрывают                      NULL.                                      сле загрузки драйвера операционная
        дескриптор нашего драйвера. Далее                                                              система передаёт управление на его
        приводятся прототипы функций и                    DeleteService proto hService:HANDLE          точку входа. Предполагается, что вы
        описания их параметров.                           hService                                     полняемая функция программы, ко
                                                            Дескриптор удаляемой службы.               торой передано управление сразу по
        StartService proto                                                                             сле загрузки драйвера, — это инициа
               hService:HANDLE,                           CloseServiceHandle proto                     лизация структур и переменных, не
               dwNumServiceArgs:DWORD,                          hSCObject:HANDLE                       обходимых для дальнейшей работы
               lpServiceArgVectors:LPSTR                  hSCObject                                    драйвера, и отчёт перед ОС о выпол
        hService                                            Дескриптор закрываемого SCM,               ненной задаче (“DriverEntry is the first
          Дескриптор драйвера/сервиса.                      сервиса, драйвера.                         routine called after a driver is loaded, and
        dwNumServiceArgs                                                                               is responsible for initializing the
          Количество аргументов, передавае               П РОТОТИП ДРАЙВЕРА                           driver”, — читаем мы в MSDN). Точ
          мых сервису. Драйверу не передают              РЕЖИМА ЯДРА                                  кой входа является метка, указанная
          ся аргументы, поэтому значения                    Рассмотрим шаблон простейшего              после директивы End, то есть в нашем
          NULL.                                           драйвера (листинг 2).                        случае это EntryDriverUNIO (у Вашего
        lpServiceArgVectors                                 Не правда ли, если Вы знакомы с            драйвера может быть другое имя). В
          Указатель на массив указателей,                 динамически подключаемой библио             нашем примере после передачи управ
          ссылающихся на строки, завер                   текой (DLL) [3], то приведённый при         ления на точку входа происходит фор
          шающиеся нулём. В строках содер                мер во многом напомнит Вам структу          мирование перехода из 0 в 1 на одном
          жатся передаваемые службе аргу                 ру простейшей динамической библио           из выходов FPGA1платы UNIOXX5

        Листинг 2

         ; CardUNIO.asm                                                                   out dx,al
         .386                                                                             sti
         .model flat, stdcall                                                             invoke ShortDelay, MyDelay
         option casemap:none                                                              ; в регистрах маски каналы 0%23 на вывод
                                                                                          inc dx
         include D:\masm32\INCLUDE\DDK\wxp\ntddk.inc                                      mov al,0ffh
                                                                                          cli
         UNIO_FPGA1_BaseAdrr    equ 0a110h                                                out dx,al
         ; базовый адрес FPGA1 UNIOxx%5 при поставке                                      sti
                                                                                          invoke ShortDelay, MyDelay
         MyDelay                  equ 100h                                                xor al,al
         STATUS_IO_DEVICE_ERROR equ 0C0000185h                                            dec dx
                                                                                          ; в контрольном регистре устанавливаем BANK = 0
         .code                                                                            cli
         ShortDelay proc ValDelay:DWORD                                                   out dx,al
                      push cx                                                             sti
                      mov cx, ValDelay                                                    invoke ShortDelay, MyDelay
         @@delay:                                                                         inc dx
                      dec cx                                                              ; формируем импульс на 0%7 выходах
                      jnz @@delay                                                         Cli
                      pop cx                                                              Out dx,al
                      ret                                                                 invoke ShortDelay, MyDelay
                                                                                          mov al,0ffh
         ShortDelay endp                                                                  out dx,al
                                                                                          invoke ShortDelay, MyDelay
         EntryDriverUNIO proc DriverObject:PDRIVER_OBJECT, \                              xor al,al
           RegistryPath:PUNICODE_STRING                                                   out dx,al
                                                                                          ; возвращаем системе сообщение о неудачной
                       push cx                                                            ; инициализации драйвера
                       push dx                                                            mov eax, STATUS_IO_DEVICE_ERROR
                                                                                          pop dx
                       xor   al,al                                                        pop cx
                       inc   al                                                           ret
                       mov   dx, UNIO_FPGA1_BaseAdrr                         EntryDriverUNIO endp
                       ; в   контрольном регистре устанавливаем BANK = 1
74                     cli                                                   End EntryDriverUNIO

        www.cta.ru                                                                                                                            СТА 2/2006

                                                                                              © 2006, CTA Тел.: (495) 2340635 Факс: (495) 2321653 http://www.cta.ru
П Р О Г РА М М Н О Е О Б Е С П Е ЧЕ Н И Е / Д РА Й В Е Р Ы

(используется стандартная прошивка        нить загруженному драйверу, имен             драйвера. Файл будет выложен на сай
g00). Реальность отработки драйвера       но по этой причине ему и передаёт            те журнала «СТА».
можно наблюдать, подключив осцил         ся указатель на эту структуру. В на
лограф или светодиод к соответст         шем примере мы не занимались                  З АКЛЮЧЕНИЕ ,             ИЛИ
вующему выходу платы. Естественно,        этой работой, так как «не задержи            Ч ТО ВПЕРЕДИ
для визуализации работы драйвера          ваемся надолго». В полнофункцио                В статье изложен минимально необ
можно было обойтись и без платы,          нальном драйвере эту работу при              ходимый материал, для того чтобы
например, вывести какоелибо сооб        дётся проделать.                              обозначить основные направления
щение, или озвучить это событие на      RegistryPath                                    развития темы написания драйверов в
динамике ПК. Затем в регистр eax за      Указатель на структуру типа                   ОС Windows. Следующим шагом в соз
гружается возвращаемый параметр           UNICODE_STRING, содержащую                    дании полнофункционального драй
(STATUS_IO_DEVICE_ERROR), тем             указатель на UNICODEстроку, в                вера должно быть создание объекта
самым системе сообщают об ошибке.         которой содержится имя раздела в              «устройство» функцией IoCreateDevice
На этом работа (и «жизнь» ) драйвера      реестре с параметрами инициализа             в фазе инициализации драйвера (в
завершается. Так как текущий пример       ции драйвера.                                 рамках процедуры EntryDriverUNIO) и
является только шаблоном драйвера,        Надо особо подчеркнуть, что, в отли          достаточно полное изучение структу
какихлибо конструктивных действий      чие от пользовательского режима, в ре          ры DRIVER_OBJECT. Многие поля
в драйвере не производится. Код         жиме ядра ОС работает только со стро           структуры — это просто указатели на
ошибки выбран произвольно, его ис      ками типа UNICODE_STRING. Те                   процедуры обработки различных паке
пользование имело целью сообщить        перь несколько слов о компиляции и              тов запросов на вводвывод (IRP),
системе о том, что работа драйвера не   компоновке драйвера. Строка компи              формируемых диспетчером вводавы
может быть продолжена и его необхо     ляции достаточно традиционна и, если            вода на основании вызовов из прило
димо выгрузить, что операционная        мы работаем с masm32, выглядит сле             жений режима пользователя соответ
система и сделает. Но главного мы до   дующим образом:                                 ствующих функций или внутрисис
бились! Совершенно корректно, ис                                                       темных запросов. Нет необходимости
пользуя все «джентльменские» прави     ML /nologo /c /coff CardUNIO.asm                сразу пытаться реализовать все воз
ла поведения в ОС Windows, мы полу                                                     можные процедуры. Минимально не
чили полный доступ в святая свя          Опции компоновщика, естественно,              обходимые процедуры, обеспечиваю
тых — к системным ресурсам ОС,          отличаются от опций для стандартного            щие обработку IRP, формируются на
имея нулевой уровень привилегий для     исполняемого файла:                             основании вызовов приложением
исполняемого кода. Просто жуть бе                                                      пользователя функций CreateFile (от
рёт, если представить, что можно на    LINK /nologo /driver /base:0x1000               крытие созданного драйвером устрой
творить, бездумно воспользовавшись      /out:CardUNIO.sys /subsistem:native             ства) и DeviceIoControl (задание уст
открывшимися         возможностями.     CardUNIO.obj                                    ройству посредством драйвера опреде
Можно свободно читать и записывать                                                      лённых команд на выполнение). Учи
любые данные из внешних портов          /driver                                         тывая, что ОС Windows XP в любых её
операторами IN и OUT, что было так        Выходной файл – драйвер.                      ипостасях является одной из ведущих
привычно в DOS, записывать данные       /base:0x1000                                    операционных систем на рынке авто
в любые адреса памяти, но одним           Предопределённый адрес загрузки               матизации, есть смысл глубже изучить
неподходящим       оператором    или      драйвера.                                     вопрос строения этой ОС и овладеть
некорректным значением, записан        /out:CardUNIO.sys                               техникой написания драйверов для
ным в порт или операцию память,           Выходной файл драйвера должен                 неё. Удачи Вам! ●
можно получить «синий экран смер         иметь соответствующее расширение
ти» (BSOD) на Вашем мониторе.             (по умолчанию — .exe).                        Л ИТЕРАТУРА
Большие возможности прежде всего        /subsistem:native                               1. В. Пирогов. Ассемблер для Windows. —
предполагают и большую ответствен        Тип подсистемы, необходимый для                  3е изд. — СПб. : БХВПетербург, 2005.
ность. Вот уж где поговорка «Семь раз     работы выходного файла. Этого во             2. М. Руссинович, Д. Соломон. Внутреннее
отмерь, один раз отрежь!» очень акту     проса мы кратко касались в данной                устройство Microsoft Windows: Windows
альна.                                    статье, в части, посвящённой обзору              Server 2003, Windows XP, Windows 2000. —
  Рассмотрим прототип DriverEntry (у      архитектуры Windows. Напомню,                    4е изд. — М. : Русская Редакция, Питер,
нас это процедура EntryDriverUNIO).       что речь шла о существовании трёх                2005.
                                          подсистем окружения: Win32,                   3. Валерий Яковлев. Написание пользова
DriverEntry proto                         POSIX и OS/2. Параметр Native го                тельской DLL доступа к универсальному
      DriverObject:PDRIVER_OBJECT,        ворит о том, что нет необходимости               OPCсерверу Fastwel // Современные тех
      RegistryPath:PUNICODE_STRING        ни в одной из этих подсистем. Драй              нологии автоматизации. 2005. № 3.
DriverObject                              вер работает в «родной» или естест              С. 7481.
  Указатель на объект созданного          венной среде, то есть использует ба
  драйвера. Если говорить проще, то       зовый API самой ОС Windows.                   Автор — сотрудник фирмы
  речь идёт о структуре типа              К сожалению, в статье изза ограни           ПРОСОФТ
  DRIVER_OBJECT, описанной в            чений по объёму нет возможности при            Телефон: (812) 4480444
  файле NTDDK.h DDK. Часть полей        вести и прокомментировать листинг               Факс: (812) 4480339
  в этой структуре необходимо запол    ntddk.inc для создания простейшего              Email: info@spb.prosoft.ru                               75
СТА 2/2006                                                                                                                       www.cta.ru

                                                                               © 2006, CTA Тел.: (495) 2340635 Факс: (495) 2321653 http://www.cta.ru
Вы также можете почитать