- Среда программирования драйверов под windows
- WinDDK-7 вот , что нужно для создания драйвера
- Далее просто пробуем написать простейший kernel драйвер
- Отладка
- Microsoft выложила бесплатный инструмент для написания драйверов Windows
- DMF – в помощь разработчикам драйверов
- О недостатках WDF
- Новый подход к разработке
- Программные средства от Microsoft
- Настройки проекта в Visual Studio 7 Net
- Компиляция и сборка драйвера утилитой Build пакета DDK
- Программа Depends
- Программа ReBase
- Программа ErrLook
- Программа GuidGen (UUIDGEN)
- Программа редактирования Системного Реестра
- Программа DeviceTree
- Программа DevCon
- Программа DevCtl
- Программы ChkInf и GenInf
- Программа Task Manager (Диспетчер Задач)
- Системный апплет «Производительность»
- Программное средство тестирования драйвера Driver Verifier
- Программное средство проверки логики функционирования PreFast
Среда программирования драйверов под windows
Ну вот мы и добрались до самого интересного — сейчас будем писать драйвер. Итак, приступим. Для удобства выполнения, всю последовательность действий по написанию драйвера я распишу по пунктам.
1. Создание директории проекта
Установив DDK, на Вашем компьютере в директории C:\WINDDK\2600.1106\ должны появиться файлы DDK. В этой директории создадим папку, в которой будут храниться наши проекты. Назовем ее, например, MyDrivers.
В папке MyDrivers создадим папку FirstDriver — тут будет находится наш первый проект драйвера.
2. Подготовка файлов проекта
В папке FirstDriver создайте пустой текстовый файл и переименуйте его под именем FirstDriver.c
При попытке переименовки со сменой расширения файла, появляется следующее предупреждение:
Не обращаем внимания на это предупреждение, и нажимаем Да. При этом наш файл примет вид:
Если же никакого предупреждения не было и переименованный файл так и остался текстовым с именем FirstDriver.c и расширением .txt, то в настройках своийств папки, которые можно найти в Пуск-> Настройка-> Панель управления-> Свойства паки уберите галочку напротив пункта «Скрывать расширения для зарегестрированных типов файлов». Попробуйте еще раз и все должно быть в порядке.
Теперь нам надо добавить еще два очень важных файла в наш проект, без которых драйвер нам не сделать. Они называются makefile и sources (обратите внимание, у них нет расширения). Их можно создать самим, но мы сделаем проще: скопируем готовые из какого либо примера проекта драйвера из DDK. Например, возьмем их из C:\WINDDK\2600.1106\src\general\cancel\sys\. Итак, копируем из указанной директории эти два файла и вставляем их в нашу папку проекта FirstDriver. Эти файлы управляют процессрм компиляции драйвера. Файл makefile оставляем без изменений, а вот sources надо подредактировать.
Открываем этот файл с помощью блокнота, и удаляем из него все что там есть и вставляем туда текст, представленный ниже. Сохранияем файл.
Первым параметром идет TARGETNAME, которому мы присвоили Port. Это значит, что когда DDK откомпилирует наш код и создаст драйвер, имя этого файла будет Port.sys Следующем параметром идет TARGETPATH, которому мы указали путь к папке нашего проекта. Если Вы устанавливали DDK в другое место, или создали пупку проекта в другой директории, здесь Вам надо это поправить на тот путь, который у Вас. Параметр TARGETTYPE пока оставлю без комментариев. В параметре SOURCES указываем, из каких файлов будет компилироваться драйвер. У нас это файл FirstDriver.c, вот мы его и указали.
Всю подготовительную работу мы сделали. Можно приступать к самой содержательной части — коду драйвера. Писать мы будем его на Си.
Еще раз напомню решаемую нами задачу: надо написать драйвер под Windows 2000, XP с помощью которого можно будет работать с портами компьютера (читать и писать данные) .
Рассмотрим код, представленный ниже. Серым цветом обозначены те участки кода, которые являются как бы шаблонными для большинства драйверов, а зеленым — код, который относится именно к нашему текущему драйверу.
Представленный код — есть код простейшего драйвера, который может только записать данные в порт и прочесть их от туда. Выглядит страшновато? Ни чего, в следующей статье будем разбираться с тем что в нем понаписано.
WinDDK-7 вот , что нужно для создания драйвера
У нас Windows 10-64.
Задача разработать например драйвер устройства под Windows.
Устанавливаем Windows Device Driver Kit 7 :
Скачиваем с офф.сайта microsoft ISO, разархивируем , запустим KitSetup.exe
Так выглядят в Панель управления\Программы\Программы и компоненты
Установлен у меня в C:\WinDDK\7600.16385.1
В C:\WinDDK\7600.16385.1\src много примеров исходных кодов.
Примечание : если у вас уже установлен Win Driver Kit 10 , то придется удалить.
Фишка в том , что сборку надо запускать через запуск сначала командного файла (который устанавливает переменные среды) :
см. Пуск->Windows Driver
Открывается консоль, где и надо ввести build (в каталоге вашего проекта). Процесс сборки выглядит примерно так:
Для x64 входим через C:\Windows\System32\cmd.exe /k C:\WinDDK\7600.16385.1\bin\setenv.bat C:\WinDDK\7600.16385.1\ fre x32-64
Windows 10 — надо сначала отключить проверку цифровой подписи (у меня срабатывает при нажатой SHIFT + клик Перезагрузка)
Отключаем.
Далее просто пробуем написать простейший kernel драйвер
На самом деле в дальнейшем в этой ветке сайта мы будем заниматься UMDF драйверами, но для проверки первого драйвера подвернулся пример driver.sys (kernel драйвер, драйвер уровня ядра)
Компилируем простейший драйвер (sys — кернел драйвер)
Для варианта сборки x86 пробуем зарегистрировать драйвер
Для варианта сборки amd64 получаем
Теперь по другому пробуем проверить запущен ли все-таки драйвер через программу OSR Driver Loader:
Получается драйвер все-таки запускается несмотря на ругань по поводу сертификата.
Смотрим например еще так :
Osr driver loader — прекрасно и сама регистрирует / запускает / останавливает / удаляет драйвер. Только не забывайте перезагружаться.
Отладка
У нас на сайте см. отдельный раздел по отладке драйверов.
Microsoft выложила бесплатный инструмент для написания драйверов Windows
DMF – в помощь разработчикам драйверов
Microsoft выпустила программную платформу (фреймворк) Driver Module Framework (DMF), призванную упростить процесс разработки структурированных WDF-драйверов (Windows Driver Frameworks) устройств для операционной системы Windows. Кроме того, по заявлению Microsoft, использование нового инструмента позволит программистам с легкостью повторно использовать собственный код в различных драйверах или делиться им с другими разработчиками.
DMF был создан командой Microsoft Devices специально для разработки драйверов устройств-трансформеров Surface и изначально предназначался только для внутреннего использования. Теперь же исходный код фреймворка опубликован на Github, популярном веб-сервисе для хостинга ИТ-проектов и их совместной разработки, под свободной лицензией MIT, и доступен всем желающим.
О недостатках WDF
Как правило, при написании драйверов устройств для Windows разработчики прибегают к помощи инструментария Windows Driver Frameworks (WDF), применение которого, в отличие от Windows Driver Model (WDM), более старого и «низкоуровнего» фреймворка, не требует от разработчика полного знакомства со множеством сложных технических нюансов для создания простейшего драйвера. Кроме того, WDF включает набор средств проверки готовой программы на наличие распространенных ошибок и позволяет выявить причины неправильного функционирования драйвера.
При разработке с применением WDF на плечи программиста ложится ответственность за реализацию механизмов коммуникации между отдельными модулями драйвера и их синхронизации с контекстом устройства в верном порядке и подходящее время, при этом избегая взаимных блокировок, что не всегда является тривиальной задачей. Контекст устройства (на схемах выделен зеленым цветом) в Windows – внутренняя структура, используемая для управления информацией об устройстве вывода. Приложения сперва направляют данные на вывод (например, на экран) в контекст устройства, и лишь потом Windows перенаправляет его содержимое непосредственно на устройство.
При необходимости повторного использования кода одного из модулей, программисту необходимо досконально разобраться в том, как именно модули взаимодействуют друг с другом, прежде чем извлекать нужный исходный код, что отнимает много времени и зачастую ведет к возникновению ошибок.
Новый подход к разработке
Фреймворк DMF позволяет создать тонкую «прослойку» между реализацией драйвера и WDF, которая связывает между собой все отдельные модули драйвера и клиентский код, грамотно организуя процесс их взаимодействия.
Кроме того, каждый отдельно взятый модуль получает собственную область в контексте устройства, которая доступна только ему, что снимает с программиста обязанность предусматривать механизмы поочередного доступа каждого модуля к контексту устройства.
Обратные вызовы WDF (на схеме окрашены в красный цвет) теперь также существуют независимо друг от друга в каждом модуле, а DMF отвечает за перехват, перенаправление вызовов к соответствующим модулям, а также возвращение результата обработки данных модулями.
Подобный подход позволяет рассматривать модуль драйвера как самостоятельную единицу, которую при необходимости можно легко отделить от остального кода и перенести в другой проект практически без изменений, будучи уверенным, что он окажется работоспособным.
Программные средства от Microsoft
Основным средством разработки является Microsoft Windows DDK, Device Driver Kit, — пакет разработки драйверов, включающий компилятор, редактор связей (линкер), заголовочные файлы, библиотеки, большой набор примеров (часть из которых является драйверами, реально работающими в операционной системе) и, разумеется, документацию. В состав пакета входит также отладчик WinDbg, позволяющий проводить интерактивную отладку драйвера на двухкомпьютерной конфигурации и при наличии файлов отладочных идентификаторов операционной системы WinDbg кроме того, позволяет просматривать файлы дампа (образа) памяти, полученного при фатальных сбоях операционной системы (так называемый crash dump file).
Следует особо отметить, что языком программирования, который используется в DDK является язык С, разумеется, допускающий вставки на языке ассемблер, который в былые времена был основным и единственным языком программирования драйверов.
В бесплатно распространяемом пакете DDK всегда отсутствовала интегрированная среда разработки. Поэтому программисты драйверов всегда были вынуждены подбирать для себя и средство редактирования исходного кода. Выбор был, практически, безальтернативен — пакет Visual С++ (теперь это Visual Studio 7 Net). При должной настройке этой среды процесс выявлений синтаксических ошибок существенно облегчается — неотъемлемое преимущество интегрированных сред программирования. Компилятор и редактор связей Visual Studio C++ создают нормальный бинарный код, вполне работоспособный при указании соответствующих опций (настроек) компиляции, однако эталоном следует считать бинарный код, получающийся при компиляции кода драйвера с использованием утилиты Build из состава пакета DDK. Разумеется, встроенный интерактивный отладчик Visual Studio и прилагаемая документация становятся для разработки драйвера совершенно бесполезными, поскольку не предназначены для работы с программным обеспечением для режима ядра.
Разработчику драйвера могут быть полезны некоторые вспомогательные программы, поставляемые теперь в составе Platform SDK, например утилита Depends, подробнее о которой будет сказано ниже.
Настройки проекта в Visual Studio 7 Net
Настройка проекта для компиляции и сборки драйвера режима ядра существенно отличаются от настроек, которые используются для работы с приложениями и динамическими библиотеками пользовательского режима. Ниже приводится точный текст файл Example.sln («sln» является сокращением от «solution»), который описывает проект драйвера Example, рассматриваемого в следующей главе.
Значительно более важным в проекте Example является файл Example.vcproj, который содержит конкретные значения настроек и описания используемых файлов. Точный текст Example.vcproj (файла настроек для компиляции и сборки простейшего не-WDM драйвера checked-версии в среде Visual Studio 7 Net) приводится ниже.
Приведенный выше текст переформатирован (для удобства чтения в формате книги), поэтому расположение слов несколько отличается от их размещения в оригинальных .vcproj файлах, генерируемых средой Visual Studio 7 Net. Значения строковых параметров AdditionalIncludeDirectories и PreprocessorDefinitions обязательно должны быть записаны в одну строку.
Следует отметить, что особую важность для компиляции имеют значения пара метров IgnoreStandardIncludePath (здесь он отменяет стандартные пути для обнаружения заголовочных файлов, которые явно заданы теперь в параметре AdditionalIncludeDirectories), AdditionalOptions и PreprocessOrDefinitions (значения которых рекомендуется повторить в точности), CallingConvention (здесь определяет __stdcall).
Из параметров сборки следует отметить параметры IgnoreAllDefaultLibraries (здесь он отменяет использование библиотек, назначаемых в Visual Studio по умолчанию), AdditionalLibraryDirectories и AdditionalDependencies (они определяют используемые библиотеки — в данном случае для сборки не-WDM драйвера под Windows 2000), BaseAddress (обязательно следует указать равным 0x10000) и «неприметный» коварный параметр SetChecksum (должен быть «TRUE»).
Все эти параметры можно настроить интерактивно и в самой интегрированной среде Visual Studio, однако, затем рекомендуется сравнить содержимое файла .vcproj с приведенным текстом, стараясь получить полное совпадение.
Компиляция и сборка драйвера утилитой Build пакета DDK
В том варианте, как поставляется пакет DDK, весьма просто использовать компилятор и редактор связей этого пакета. Для этого следует выбрать в меню запуска программ Пуск — Программы — . запуск соответствующей среды (по ряду причин наиболее предпочтителен выбор среды Window 2000, checked или free), в результате чего появится консольное окно, для которого уже (автоматически) будут должным образом установлены переменные окружения. В том случае, если у разработчика имеются файлы makefile, sources (описывающие процесс сборки данного конкретного драйвера), а пакет DDK установлен корректно, то необходимо лишь перейти в рабочую директорию проекта командой cd (для драйвера, рассматриваемого в следующей главе, это — директория C:\Example) и ввести команду build (см. рисунок 2.1). Разумеется, что в случае ошибок компиляции или сборки вывод будет содержать и их диагностику.
Рис. 2.1 Рабочее окно сборки драйвера под Windows 2000 DDK версии checked |
Программа Depends
Программа Depends предназначена для просмотра вызовов дополнительных библиотек. Программа Depends была создана в 1996 году и ранее поставлялась в составе Visual Studio 6. Теперь она является частью Platform SDK.
Скриншот (снимок экрана), представленный на рисунке 2.2, выполнен для просмотра дерева вызовов известного драйвера GiveIo.Sys. (Этот драйвер разблокирует доступ к портам ввода/вывода из приложений пользовательского режима при работе под Windows NT, используя при этом недокументированные возможности Windows.)
На приведенном рисунке видно, что драйвер обращается к функциям, экспортируемым NTOSKRNL.EXE, причем видно, что первыми (в порядке алфавита) являются вызовы IoCreateDevice, IoCreateSymbolicLink, IoDeleteDevice, IoDeleteSymbolicLink и др.
Программа может быть использована для просмотра вызовов, выполняемых из драйверов, исполняемых файлов (.exe файлов) и динамических библиотек. Программа работает и под Windows 98.
Рис. 2.2 Программа Depends для драйвера GiveIo |
Программа ReBase
Программа ReBase (консольное приложение) поставляется в составе Visual Studio и выполняет удаление отладочной информации из бинарных файлов, скомпилированных и собранных проектов, в нашем случае — из бинарных файлов драйверов (.sys файлов). Даже после сборки окончательной (релизной, free) версии драйвера при помощи программ DDK в нем еще остается некоторая отладочная информация (например, внутренние имена функций), которую программа ReBase может выделить и поместить в файл отладочных идентификаторов. Размер бинарного файла может уменьшиться при этом на четверть.
Ниже приведены примеры командной строки для запуска программы ReBase применительно к драйверу:
Во втором примере ключ -xa (расширение ключа -x из первого примера) задает удаление всей отладочной информации (с перемещением ее в файл с расширением .dbg). Директория, где будет размещен этот .dbg файл в первом примере — текущая (поскольку указана точка после -x), во втором — вложенная поддиректория .\dbgdir. Ключ -b указывает базовый адрес (для драйверов режима ядра всегда указывается значение 0x10000), ключ -l (эль) указывает файл протокола (log file), во втором примере файл protocol.
Более подробно с командами ReBase можно ознакомиться через сообщение, которое программа выведет по команде
Программа ErrLook
Программа ErrLook, поставляемая и в составе DDK и в составе Visual Studio, представляет собой декодер сообщений об ошибках. Полученный в приложениях пользовательского режима код ошибки (целое число) по вызову функции GetLastError несет мало информации для недостаточно квалифицированного пользователя. Получить по этому коду текстовое представления сообщения об ошибке можно с помощью специальных функций (при программировании приложения), либо подставив это число в программу ErrLook, как это показано на рисунке 2.3.
Рис. 2.3 Программа ErrLook |
Предположим, рабочая процедура драйвера возвратила управление Диспетчеру ввода/вывода, установив код завершения обработки пакета IRP равным STATUS_DEVICE_POWERED_OFF. В результате, если пользовательское приложение обратилось к драйверу с вызовом DeviceIoControl, но драйвером ответил отказом такого рода, то Диспетчер ввода/вывода передает приложению код ошибочного завершения вызова функции (для DeviceIoControl это 0) и устанавливает код ошибки (известный в документации MSDN под названием «system error code»). B свою очередь, пользовательское приложение может вызвать функцию GetLastError и в результате получит число 21 (которое и определил Диспетчер вода/вывода), что соответствует ошибке ERROR_NOT_READY — «The device is not ready». В примере, представленном на рисунке 2.3, программа ErrLook транслирует код 21 в текстовое сообщение, которое в русскоязычной версии Windows выдается в нижнем окошке на русском языке.
Следует обратить внимание, что, например, коду ошибки 21 (который выдается функцией GetLastError пользовательского режима в пользовательских приложениях) соответствует сразу несколько кодов завершения обработки IRP пакетов в драйвере:
- STATUS_DEVICE_NOT_CONNECTED
- STATUS_DEVICE_NOT_READY
- STATUS_DEVICE_OFF_LINE
- STATUS_DEVICE_POWER_FAILURE
- STATUS_DEVICE_POWERED_OFF
Эту особенность неоднозначного соответствия кодов ошибок в пользовательском режиме (system error code) и кодов завершения обработки запросов на ввод/вывод от Диспетчера BB (IRP запросов к драйверу) следует учитывать при выборе соответствующих значений STATUS_Xxx для достоверного информирования клиентов драйвера об ошибочных ситуациях.
Транслировать код ошибки в текстовую форму программно можно при помощи несложной функции, текст которой приведен ниже. Функция получает код ошибки (system error code, например, 21) и выводит текст, расшифровывающий это значение.
Программа GuidGen (UUIDGEN)
Программа GuidGen (UUIDGEN — ее консольная версия) выполняет генерацию 128 разрядного уникального ключа (GUID — глобально уникальный идентификатор), который может использоваться для регистрации интерфейса драйвера, в процессе инсталляции и т.п. Вероятность повторения данного значения весьма и весьма низка (хотя и не равна нулю), так что программа GuidGen является типовым инструментом для этих целей. Программа встречается во всех пакетах Microsoft.
Как показано на рисунке 2.4, программа создала GUID в формате, удобном для включения в текст на языке С. Нажав на кнопку «Сору» можно перенести его текст в буфер обмена и вставить в нужное место в тексте программы или драйвера.
Значения GUID можно встретить и в программах, работающих по технологии СОМ, и в Системном Реестре, где они часто используются как идентификаторы классов устройств или входят в состав имен параметров, описывающих устройства.
Рис. 2.4 Программа GuidGen |
Программа редактирования Системного Реестра
Программа, без которой не обойтись ни одному разработчику драйвера — программа редактирования Системного Реестра, которая запускается командой Пуск — Выполнить — regedit (в Windows 2000 — командой regedit32). Целостность информации, находящейся в Системном Реестре весьма важна для операционной системы. Поэтому проводить эксперименты над Реестром следует весьма осторожно, поскольку даже резервное копирование Реестра (а также защита отдельных разделов от какого бы то ни было редактирования) может не спасти от необходимости переустановки всей системы. Без достаточной необходимости не следует оставлять изменения, сделанные в Системном Реестре (рекомендуется возвращать его состояние к начальному, имевшему место до экспериментов).
Программа DeviceTree
В составе Windows DDK поставляется программа DeviceTree (рисунок 2.5), абсолютно незаменимая при самостоятельном изучении WDM модели, поскольку визуализирует представление о стеке драйверов (устройств) в операционной системе Windows.
Данная программа выполняет построение дерева устройств с двух точек зрения: с точки зрения принадлежности объектов устройств драйверам (режим D, рисунок 2.6) и с точки зрения взаимной подчиненности объектов устройств при выполнении операции перечисления устройств, enumeration process (режим P, рисунок 2.7). Программа позволяет отслеживать подчиненность объектов устройств в локальных стеках драйверов, их принадлежность драйверам, выявлять существующие фильтр-драйверы, устанавливать (выяснять) коды IPP пакетов, обслуживание которых объявил драйвер, и некоторую другую специфическую информацию.
Рис. 2.5 Заставка программы DeviceTree |
На рисунке 2.6 показан фрагмент дерева устройств на участке шинного драйвера PCI. 11 объектов устройств (за исключением безымянного нижнего) представляют созданные этим шинным драйвером физические объекты устройств (так называемые PDO) для всех имеющихся в системе реальных PCI устройств, включая мосты (PCI-PCI, PCI-ISA), контроллеры USB, AGP адаптер, аудио на материнской плате, PCI адаптер Ethernet и т.п.
Рис. 2.6 Шинный драйвер PCI и его объекты устройств |
Другой взгляд на этот же участок драйверного стека приведен на рисунке 2.7. Здесь показана взаимная подчиненность объектов устройств, возникающая в операционной системе при последовательно проводимой переписи устройств. Данное дерево отражает в своей структуре иерархию реальных устройств и очередность их обнаружения драйверами родительских устройств. Например, шинный драйвер PCI обнаруживает подключенные к шине устройства, что приводит к загрузке их драйверов, что, в свою очередь, приводит к обнаружению новых устройств, подключенных к ним — как в случае с шиной USB (ee контроллер является дочерним устройством шины PCI).
Программа DeviceTree является исследовательским инструментом, вносящим большое возмущение в работу системы, поэтому нередки случаи сбоя при некоторых ее операциях (наиболее часто — при выходе из программы).
Рис.2.7 Драйверный стек от ACPI драйвера до шинного драйвера PCI |
Программа DevCon
Консольное приложение DevCon из состава вспомогательных утилит пакета DDK позволяет запускать, останавливать драйверы и собирать информацию об отдельных устройствах или их группах. Например, по команде
(собрать информацию обо всех устройствах в стеке USB) данная утилита выводит в файл stack_usb.txt следующую информацию (немного изменен формат):
Программа DevCtl
Консольное приложение DevCtl из состава вспомогательных утилит пакета DDK проводит тестирование драйвера путем применения к нему наиболее употребительных вызовов ввода/вывода пользовательского режима, например NtCreateFile или DeviceIoControl. B процессе тестирования могут быть выявлены серьезные упущения в программировании драйвера, например, некорректная обработка неожиданных (для тестируемого драйвера) IOCTL запросов или запрос на получение данных, когда приложение указало заведомо малый размер буфера для получаемых данных.
В качестве указателя на тестируемый драйвер программе DevCtl следует передавать имя устройства (из числа тех, что видны в директории Device в рабочем окне программы WinObj, описание которой см. ниже). Более подробное описание программы DevCtl можно найти в DDK.
Программы ChkInf и GenInf
Программа ChkInf (точнее, скрипт для интерпретатора Perl) предназначена для проверки inf файлов, необходимых для выполнения установки драйвера в операционной системе, и подробно будет рассмотрена в главе 11.
Программа GenInf предназначена для генерации inf файлов в режиме вопросов и ответов (Wizard).
Программа Task Manager (Диспетчер Задач)
Не следует недооценивать значение использования стандартных системных средств в процессе получения нужных сведений о функционировании приложений, использующих драйверы. Всем известное системное программное средство Диспетчер Задач, вызываемый комбинацией клавиш Ctrl-Alt-Delete, позволяет оперативно получать сведения о работающих процессах (рисунок 2.8). Необходимо лишь в пункте меню «Вид» выбрать интересующие параметры для отображения. Хотя относятся они к приложениям пользовательского режима, могут дать косвенное представление и о работе вызываемых драйверов.
Закладка «Быстродействие» позволяет настроить отображение времени пребывания процесса в режиме ядра (в процентном отношении) — параметр «Вывод времени ядра» в пункте меню «Вид» для этой закладки. По этим показаниям можно оценить, какую часть времени работы приложения занимает обращение к драйверу.
Рис.2.8 Рабочее окно системного Диспетчера Задач |
Системный апплет «Производительность»
Более глубоко лежащим средством мониторинга системы и отдельных процессов и служб является апплет «Производительность» системной панели «Администрирование», вызываемой запускающей последовательностью Пуск — Настройка — Панель управления — Администрирование — Производительность.
Рабочее окно данного системного апплета показано на рисунке 2.9. По нажатию правой кнопки мышки появляется меню, допускающее добавление новых графиков в окно работающего апплета («Добавить счетчики»).Сочетание параметров, которые можно просматривать таким образом, настолько велико, что для их описания потребовалась бы отдельная глава. Для просмотра доступны параметры функционирования памяти, процессора, КЭШа, протоколов IP, TCP, UDP, отдельных процессов и сервисов, включая их отдельные потоки, — всего чуть менее полусотни информативных единиц. Для каждой такой единицы возможен просмотр достаточно большого набора счетчиков (как правило, не менее полутора десятков). Например, для процессора среди счетчиков, доступных для просмотра, можно назвать счетчики числа прерываний в секунду, процента времени бездействия, процента времени работы в пользовательском и привилегированном режимах, счетчика DPC процедур, поставленных в очередь, в секунду.
Краткие пояснения, касающиеся смысла указываемых счетчиков, можно получить при выборе счетчика по нажатию кнопки «Объяснение».
Рис. 2.9 Рабочее окно системного Диспетчера Задач |
Программное средство тестирования драйвера Driver Verifier
Программа Driver Verifier (последовательность старта Пуск — Программы — Development Kits — Windows DDK — Tools — Driver Verifier) проверяет драйвер на правильность выполнения следующих тестов:
- Операции с пулами памяти.
- Корректность уровней IRQL, на которых выполняется код драйвера.
- Обнаружение взаимоблокировок.
- Выполнение DMA операций.
- Стресс-тест (нехватка ресурсов).
- Нетипичные запросы к драйверу.
Проверка начинается после перезагрузки системы и при серьезных ошибках в драйвере может привести к необходимости переустановки системы. Поэтому не следует выполнять данные тесты на компьютере с ценными данными.
Программное средство проверки логики функционирования PreFast
Программа PreFast, появившаяся в составе пакета DDK Server 2003, предназначена для выявления ошибочных паттернов (шаблонов) программного кода на уровне исходного текста. Она запускается в качестве наблюдателя за процессом сборки или компиляции какого-либо программного кода и по завершении этого процесса сообщает о дополнительно замеченных ошибочных фрагментах кода (в случае ошибки собственно сборки или собственно компиляции программа PreFast в работу не вступает). Например, компиляция файла запускается под управлением PreFast следующей командной строкой:
Вторая строка при удачной компиляции покажет (если таковые имеются) логические ошибки в тексте, представленном в файле myfile.cpp.
Каковы логические ошибки, пропущенные компилятором и выявляемые программой PreFast? Например, в следующем фрагменте
программа PreFast выявит потенциально возможную утечку памяти, поскольку возможна ситуация, когда при втором неудачном выделении памяти, не будет освобождена первая, выделенная ранее. То есть произойдет утечка памяти.
На обнаружение такого типа логических ошибок, проявляющихся в пределах кода каждой отдельно взятой функции, и настроена программа PreFast. Количество выявляемых ошибочных паттернов на настоящий момент составляет более трех десятков.
Самым важным недостатком поставки PreFast в пакете DDK Server 2003 сборки 3790 (на данный момент) является то, что поставляемые настройки позволяют работать только с кодом пользовательского режима (хотя и это бывает нужно разработчику драйвера), поскольку распознает только имена функций типа malloc, sprintf и т.п. В режиме ядра, как будет показано позже, используются совершенно другие имена, которые, пока что, выходят за рамки настроек распознавания PreFast.