Можно ли настроить 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.