Определение пользовательских типов ошибок
Драйверы могут указывать собственные типы ошибок и сообщения об ошибках. Чтобы определить настраиваемое сообщение об ошибке, сначала необходимо определить новое значение IO_ERR_XXXX, чтобы указать в качестве члена ErrorCode записи журнала ошибок. Просмотр событий использует значение IO_ERR_XXXX для поиска сообщения об ошибке драйвера.
Чтобы поддерживать пользовательские сообщения об ошибках в драйвере, выполните следующие действия.
Создайте текстовый файл сообщения, указывающий настраиваемое значение IO_ERR_XXXX и соответствующие сообщения об ошибках. Дополнительные сведения см. в разделе "Создание текстового файла сообщения об ошибке".
Скомпилируйте текстовый файл сообщения об ошибке в ресурс и подключите ресурс к изображению драйвера. Дополнительные сведения см. в разделе "Компиляция текстового файла сообщения об ошибке".
Зарегистрируйте образ драйвера как содержащий сообщения об ошибках. Дополнительные сведения см. в разделе "Регистрация в качестве источника сообщений об ошибках".
Создание текстового файла сообщения об ошибке
Определение пользовательских значений IO_ERR_XXXX и сопоставлений шаблонов сообщений об ошибке присоединяются в качестве ресурса таблицы сообщений к изображению драйвера. Вы можете описать сообщения для драйвера в текстовом файле сообщения (который имеет расширение имени MC-файла).
Текстовый файл сообщения состоит из двух разделов: раздела заголовка и раздела сообщения. Раздел заголовка позволяет объявлять символьные имена числовых значений, а раздел сообщения задает значения IO_ERR_XXXX и шаблоны сообщений об ошибках.
Пример текстового файла сообщения см. в файле Serlog.mc в примере серийного драйвера, доступном на сайте GitHub.
Раздел заголовка
Раздел заголовка должен содержать следующую строку:
MessageIdTypedef=NTSTATUS
Это гарантирует, что тип значений IO_ERR_XXX, созданных компилятором сообщений, объявлен NTSTATUS.
Другие директивы, отображаемые в разделе заголовка, определяют символьные значения, используемые вместо числовых значений в разделе сообщения.
Директивы SeverityNames и FacilityNames определяют символьные значения для полей серьезности и объектов значений NTSTATUS. Директивы имеют ключевое слово формы ( значения ), где значения состоят из одной или нескольких инструкций значения имени = формы: header_name, разделенных пробелами. Параметр name — это имя, которое используется для указания числового значения в текстовом файле сообщения, а header_name — это имя этого значения, объявленного в файле заголовка C, созданном компилятором сообщений. Предложение : header_name является необязательным.
Ниже приведен пример объявления заголовков символьных имен для кодов серьезности:
SeverityNames = (
Success = 0x0:STATUS_SEVERITY_SUCCESS
Informational = 0x1:STATUS_SEVERITY_INFORMATIONAL
Warning = 0x2:STATUS_SEVERITY_WARNING
Error = 0x3:STATUS_SEVERITY_ERROR
)
Директива LanguageNames определяет символьные значения для идентификаторов языкового стандарта (LCID). Директива состоит из формы LanguageNames = (значения), где значения состоят из одной или нескольких инструкций формы language_name = lcid: langfile, разделенных пробелами. Параметр language_name — это имя, используемое вместо lcid в текстовом файле сообщения, а имя файла — уникальное имя файла (без расширения). Когда компилятор сообщений создает скрипт ресурса из текстового файла сообщения, он сохраняет все строковые ресурсы для этого языка в файле с именем langfile.bin.
Раздел сообщения
Каждое определение сообщения начинается с определения настраиваемого значения IO_ERR_XXX, используемого драйвером для сообщения об этой конкретной ошибке. Значение IO_ERR_XXX определяется рядом пар значений ключевых слов = . Возможные ключевые слова и их смысл приведены следующим образом.
Ключевое слово | Значение |
---|---|
MessageId |
Поле кода нового значения IO_ERR_XXXX. |
Уровень серьезности |
Поле серьезности нового значения IO_ERR_XXXX. Указанное значение должно быть одним из символьных имен, определенных директивой заголовка SeverityNames . |
Средство |
Поле объекта нового значения IO_ERR_XXXX. Указанное значение должно быть одним из символьных имен, определенных директивой заголовка FacilityNames . |
Символьные имена |
Символьное имя нового значения IO_ERR_XXXX . Компилятор сообщений создает файл заголовка C, содержащий объявление #define имени в качестве соответствующего значения NTSTATUS. Драйвер использует это имя при указании типа ошибки. |
Первое ключевое слово всегда должно быть MessageId.
Остальная часть определения сообщения состоит из одной или нескольких локализованных версий сообщения об ошибке. Каждая версия имеет форму:
Language=language_name
localized_message
Значение language_name , которое должно быть одним из символьных имен, определенных директивой заголовка LanguageNames , указывает язык текста сообщения. Локализованный текст сообщения состоит из строки Юникода. Все внедренные строки формы "%n" будут рассматриваться как шаблоны, которые Просмотр событий заменит при регистрации ошибки. Строка "%1" заменяется именем объекта устройства драйвера, а "%2" по "%n" заменяются любыми строками вставки, предоставляемыми драйвером.
Определение сообщения завершается одним периодом в строке.
Если вы определяете пользовательские сообщения об ошибках, не следует использовать строки вставки, если это не необходимо. Строки вставки нельзя локализовать, поэтому их следует использовать для строк, которые являются независимыми от языка, например чисел или имен файлов. Большинство драйверов не используют строки вставки.
Компиляция текстового файла сообщения об ошибке
Используйте компилятор сообщений (mc.exe), чтобы скомпилировать текстовый файл сообщения в файл скрипта ресурса (который имеет расширение ИМЕНИ RC-файла). Команда формы
mc filename.mc
Вызывает компилятор сообщений для создания следующих файлов:
filename.h— файл заголовка, содержащий объявления каждого пользовательского значения IO_ERR_XXXX в имени файла.mc.
filename.rc, скрипт ресурса.
Один файл для каждого языка, который отображается в текстовом файле сообщения. Каждый из этих файлов хранит все ресурсы строки сообщения об ошибке для одного языка. Файл для каждого языка называется langfile.bin, где langfile — это значение, указанное для языка в директиве LanguageNames текстового файла сообщения.
Дополнительные сведения о компиляторе сообщений можно найти в пакете SDK для Microsoft Windows.
Компилятор ресурсов преобразует скрипт ресурса в файл ресурсов, который можно подключить к образу драйвера. Если вы используете служебную программу сборки для сборки драйвера, вы можете убедиться, что скрипт ресурсов преобразуется в файл ресурсов и подключен к образу драйвера, просто включив имя скрипта ресурса в переменную SOURCES для драйвера. Дополнительные сведения о компиляторе ресурсов см. в документации по пакету SDK для Windows. Сведения об использовании служебной программы сборки для сборки драйвера см. в разделе "Создание драйвера".