Поделиться через


Можно ли настроить DoTraceMessage?

Да, вы можете написать собственную версию макроса DoTraceMessage . DoTraceMessage создает сообщение трассировки.

Пример драйвера TraceDrv содержит пример методов, описанных в этом разделе. TraceDrv доступен в репозитории примеров драйверов Windows на сайте GitHub.

DoTraceMessage: версия по умолчанию

По умолчанию макрос DoTraceMessage имеет следующий формат:

DoTraceMessage(Flag,"Message",MessageVariables...);

В этой версии по умолчанию Flag представляет флаги трассировки, которые являются условиями, при которых создается сообщение. MessageVariables содержит разделенный запятыми список переменных, которые определяются драйвером и отображаются в сообщении трассировки. Переменные MessageVariables форматируются с помощью элементов printf . Препроцессор WPP создает директиву компилятора из макроса DoTraceMessage. Этот макрос добавляет сведения об определении сообщения и сведения о форматировании в PDB-файл, созданный для поставщика трассировки, например драйвер в режиме ядра или приложение в пользовательском режиме.

Макрос DoTraceMessage логически разворачивается на следующие элементы:

PRE macro // If defined
If (WPP_CHECK_INIT && Flag is enabled) {
 ....Call WmiTraceMessage;
}
POST macro // If defined

Рассмотрим следующий пример кода.

DoTraceMessage(ERROR, "IOCTL = %d", ControlCode);

Этот вызов создает сообщение трассировки, если включен флаг ERROR. Сообщение имеет значение "IOCTL=%d", а MessageVariables — значение ControlCode.

Если определены макросы предварительного и post-ведения журнала, они также будут развернуты. Макросы PRE и POST поддерживаются в операционных системах Microsoft Windows 2000 и более поздних версий. Чтобы использовать макросы, необходимо создать драйвер с помощью WDK. Если вы создаете драйвер с помощью более ранней версии пакета средств разработки драйверов Windows (DDK), функции PRE и POST недоступны, а макросы не будут выполняться как часть инструкции трассировки. Сборка драйвера с использованием более ранней версии Windows DDK может не привести к прерыванию сборки, но код не будет работать должным образом.

DoTraceMessage: общий формат

Ниже приведен общий формат допустимой функции сообщений трассировки.

FunctionName(Conditions...,"Message",MessageVariables...);

Параметры, которые появляются перед сообщением, интерпретируются как условия. Параметры, которые появляются после сообщения, интерпретируются как переменные сообщения.

Условия — это разделенный запятыми список значений. Сообщение трассировки создается, только если выполняются все условия. Можно указать любое условие, которое поддерживается в коде.

Пример: MyTrace

Ниже приведен пример функции трассировки. В этом примере добавляются условия для уровня трассировки и подкомпонента поставщика, создающего сообщение трассировки.

MyDoTrace(Level, Flag, Subcomponent,"Message",MessageVariables...);

Пример:

MyDoTrace(TRACE_LEVEL_ERROR, VERBOSE, Network,"IOCTL = %d", ControlCode);

Уровень трассировки — это стандартный уровень, определенный в Evntrace.h, общедоступном файле заголовка, который находится в подкаталоге Include WDK.

#define TRACE_LEVEL_NONE        0   // Tracing is not on
#define TRACE_LEVEL_FATAL       1   // Abnormal exit or termination
#define TRACE_LEVEL_ERROR       2   // Severe errors that need logging
#define TRACE_LEVEL_WARNING     3   // Warnings such as allocation failure
#define TRACE_LEVEL_INFORMATION 4   // Includes non-error cases(for example, Entry-Exit)
#define TRACE_LEVEL_VERBOSE     5   // Detailed traces from intermediate steps
#define TRACE_LEVEL_RESERVED6   6
#define TRACE_LEVEL_RESERVED7   7
#define TRACE_LEVEL_RESERVED8   8
#define TRACE_LEVEL_RESERVED9   9

Создание пользовательской функции трассировки

Чтобы создать пользовательскую функцию трассировки, выполните следующие действия.

  • Написание альтернативных версий макросов, поддерживающих макрос DoTraceMessage.

  • Добавьте параметр -func в инструкцию RUN_WPP, которая вызывает препроцессор WPP.

Написание пользовательских макросов

Чтобы создать пользовательскую функцию трассировки, которая изменяет условия сообщения трассировки (параметры, отображаемые перед сообщением), необходимо написать альтернативные версии макросов, поддерживающих функции трассировки, WPP_LEVEL_ENABLED и WPP_LEVEL_LOGGER.

  • WPP_LEVEL_ENABLED (Флаги) определяет, включено ли ведение журнала с указанным значением флага. Возвращает значение TRUE или FALSE.

  • WPP_LEVEL_LOGGER (Флаги) находит сеанс трассировки, для которого включен поставщик, и возвращает дескриптор сеансу трассировки.

Например, если вы хотите включить уровень трассировки, в дополнение к флагам, в качестве условия определите новый макрос WPP_LEVEL_ENABLED, включающий уровень трассировки. Определение нового макроса можно основывать на макросе по умолчанию, как показано в следующем примере кода.

#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >=lvl

Как правило, макрос WPP_LEVEL_LOGGER не затрагивается. В таких случаях можно определить новый макрос как макрос по умолчанию. Пример:

#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags)

Однако в некоторых случаях необходимо изменить макрос LOGGER. Например, может потребоваться написать функцию трассировки, которая зависит только от уровня трассировки, а не от флагов.

В следующем примере кода значение флагов в макросе заменяется фиктивным значением. При объявлении определения GUID элемента управления флаги не определены.

#define WPP_CONTROL_GUIDS \
   WPP_DEFINE_CONTROL_GUID(CtlGuid,(a044090f,3d9d,48cf,b7ee,9fb114702dc1),  \
        WPP_DEFINE_BIT(DUMMY))
#define WPP_LEVEL_LOGGER(lvl) (WPP_CONTROL(WPP_BIT_ ## DUMMY).Logger)

Добавление функции в WPP

Чтобы добавить пользовательскую функцию трассировки в WPP, добавьте параметр -func в оператор RUN_WPP с объявлением функции, как показано в следующем примере кода.

RUN_WPP=$(SOURCES) -km -func:DoTraceLevelMessage(LEVEL,FLAGS,MSG,...)

Примечание Не следует указывать параметр -km в директиве RUN_WPP для приложений пользовательского режима или библиотек динамической компоновки (DLL).

Полный список необязательных параметров для RUN_WPP см. в разделе Препроцессор WPP.