ReactOS 0.4.16-dev-1946-g52006dd
tracing.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 Tracing.cpp
8
9Abstract:
10
11 This module implements tracing for the driver frameworks
12
13Author:
14
15
16
17Environment:
18
19 Kernel mode only
20
21Revision History:
22
23
24
25
26
27--*/
28
29#include "fxcorepch.hpp"
30
31// We use DoTraceMessage
32extern "C" {
33// #include "tracing.tmh"
34}
35
36#include <initguid.h>
37#include "fxifr.h" // shared struct between IFR and debug ext.
38#include "fxifrkm.h" // kernel mode only IFR definitions
39
40
41//=============================================================================
42//
43//=============================================================================
44
48 VOID
49 )
50
51/*++
52
53Routine Description:
54
55 This routine initializes the frameworks tracing.
56
57 It must be called early on in the frameworks DriverEntry
58 initialization.
59
60Arguments:
61
62 None
63
64Returns:
65
66 NTSTATUS code
67
68--*/
69{
70 //
71 // Initialize the tracing package: Vista or later
72 //
74
75 return STATUS_SUCCESS;
76}
77
78VOID
80 VOID
81 )
82/*++
83
84Routine Description:
85 This routine uninitializes the frameworks tracing. It must be called just
86 before DriverUnload
87
88Arguments:
89 None
90
91Returns:
92 None
93
94--*/
95{
96 //
97 // Vista and later
98 //
100}
101
105 __in TRACEHANDLE LoggerHandle,
106 __in ULONG MessageFlags,
107 __in LPGUID MessageGuid,
109 __in ...
110 )
111{
113 va_list va;
114
116
117#pragma prefast(suppress:__WARNING_BUFFER_OVERFLOW, "Recommneded by EndClean");
118#ifndef __REACTOS__
119 status = WmiTraceMessageVa(LoggerHandle,
120 MessageFlags,
121 MessageGuid,
123 va);
124#endif
125 va_end(va);
126
127 return status;
128}
129
130
131//-----------------------------------------------------------------------------
132// Subcomponents for the In-Flight Recorder follow.
133//-----------------------------------------------------------------------------
134
135ULONG
137 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
139 )
140/*++
141
142Routine Description:
143 Checks to see if the service has overriden the default number of pages that
144 are in the IFR.
145
146Arguments:
147 RegistryPath - path to the service
148
149Return Value:
150 The size of the IFR to create in bytes (not pages!)
151
152 --*/
153{
154 FxAutoRegKey service, parameters;
157 ULONG numPages;
158
159 //
160 // This is the value used in case of any error while retrieving 'LogPages'
161 // from the registry.
162 //
163 numPages = FxIFRMinLogPages;
164
165 //
166 // External representation of the IFR is the "LogPages", so use that term when
167 // overriding the size via the registry.
168 //
169 DECLARE_CONST_UNICODE_STRING(parametersPath, L"Parameters\\Wdf");
170 DECLARE_CONST_UNICODE_STRING(valueName, L"LogPages");
171
175 NULL,
176 NULL);
177
178 status = ZwOpenKey(&service.m_Key, KEY_READ, &oa);
179 if (!NT_SUCCESS(status)) {
180 goto defaultValues;
181 }
182
184 (PUNICODE_STRING)&parametersPath,
186 service.m_Key,
187 NULL);
188
189 status = ZwOpenKey(&parameters.m_Key, KEY_READ, &oa);
190
191 if (!NT_SUCCESS(status)) {
192 goto defaultValues;
193 }
194
195 status = FxRegKey::_QueryULong(parameters.m_Key, &valueName, &numPages);
196 if (!NT_SUCCESS(status)) {
197 goto defaultValues;
198 }
199
200 if (numPages == 0) {
201 numPages = FxIFRMinLogPages;
202 }
203
204defaultValues:
205 //
206 // Use FxIFRAvgLogPages if user specifies greater than FxIFRMaxLogPages and if
207 // Verifier flag is on and so is Verbose flag.
208 //
209 if (numPages > FxIFRMaxLogPages) {
210 if (FxDriverGlobals->FxVerifierOn && FxDriverGlobals->FxVerboseOn) {
211 numPages = FxIFRAvgLogPages;
212 }
213 else {
214 numPages = FxIFRMinLogPages;
215 }
216 }
217
218 return numPages * PAGE_SIZE;
219}
220
221VOID
223 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
226 )
227/*++
228
229Routine Description:
230
231 This routine initialize the In-Flight Recorder (IFR).
232
233 The default log size is set by WDF_IFR_LOG_SIZE and currently
234 is 4096 (one x86 page).
235 This routine should be called very early in driver initialization
236 to allow the capture of all significant events.
237
238--*/
239{
241 ULONG size;
242
244
246
247 //
248 // Return early if IFR is disabled.
249 //
251 ASSERT(FxDriverGlobals->WdfLogHeader == NULL);
252 return;
253 }
254
255 if (FxDriverGlobals == NULL || FxDriverGlobals->WdfLogHeader != NULL) {
256 return;
257 }
258
259 size = FxIFRGetSize(FxDriverGlobals, RegistryPath);
260
262 size,
264 if (pHeader == NULL) {
265 return;
266 }
267
269
270 //
271 // Initialize the header.
272 // Base will be where the IFR records are placed.
273 // WPP_ThisDir_CTLGUID_FrameworksTraceGuid
274 //
275 RtlCopyMemory(&pHeader->Guid, (PVOID) &WdfTraceGuid, sizeof(GUID));
276
277 pHeader->Base = (PUCHAR) &pHeader[1];
278 pHeader->Size = size - sizeof(WDF_IFR_HEADER);
279
280 pHeader->Offset.u.s.Current = 0;
281 pHeader->Offset.u.s.Previous = 0;
282 RtlStringCchCopyA(pHeader->DriverName, WDF_IFR_HEADER_NAME_LEN, FxDriverGlobals->Public.DriverName);
283
284 FxDriverGlobals->WdfLogHeader = pHeader;
285
287 "FxIFR logging started" );
288
289 if (size > FxIFRMinLogSize) {
291 FxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDRIVER,
292 "FxIFR has been started with a size override: size 0x%x bytes, "
293 "# Pages %d. An extended IFR size may not be written to a minidump!",
295 }
296}
297
298VOID
300 __in PFX_DRIVER_GLOBALS FxDriverGlobals
301 )
302/*++
303
304Routine Description:
305
306 This routine stops the In-Flight Recorder (IFR).
307
308 It should be called as late in the driver teardown as possible
309 to allow for the capture of all significant events.
310
311--*/
312{
313 //
314 // Return early if IFR is disabled.
315 //
317 ASSERT(FxDriverGlobals->WdfLogHeader == NULL);
318 return;
319 }
320
321 if (FxDriverGlobals == NULL || FxDriverGlobals->WdfLogHeader == NULL) {
322 return;
323 }
324
325 //
326 // Free the Log buffer.
327 //
328 ExFreePoolWithTag( FxDriverGlobals->WdfLogHeader, WDF_IFR_LOG_TAG );
329 FxDriverGlobals->WdfLogHeader = NULL;
330}
331
335 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
336 __in UCHAR MessageLevel,
337 __in ULONG MessageFlags,
338 __in LPGUID MessageGuid,
340 __in ...
341 )
342/*++
343
344Routine Description:
345
346 This routine is the main In-Flight Recorder (IFR) routine.
347
348 It captures a WPP message to the IFR log.
349 The IFR is always running, e.g. not WPP logger is necessary
350 to start logging.
351
352Arguments:
353
354 MessageLevel - The WPP message level for this event
355 MessageFlags - The WPP message flags for this event (see trace GUID)
356 MessageGuid - The tracewpp generated guid for module emitting this event.
357 MessageNumber - The tracewpp generated message number within
358 the emitting module.
359 ... - Variable arguments associates with the emitted message.
360
361Returns:
362
363 NTSTATUS
364
365--*/
366{
367 size_t size;
370
371 UNREFERENCED_PARAMETER( MessageLevel );
372 UNREFERENCED_PARAMETER( MessageFlags );
373
374 //
375 // Return early if IFR is disabled.
376 //
378 ASSERT(FxDriverGlobals->WdfLogHeader == NULL);
379 return STATUS_SUCCESS;
380 }
381
382 if ( FxDriverGlobals->WdfLogHeader == NULL) {
383 return STATUS_UNSUCCESSFUL;
384 }
385
386 //
387 // Determine the number bytes to follow header
388 //
389 size = 0; // For Count of Bytes
390
391 //
392 // Determine how much log space is needed for this
393 // trace record's data.
394 //
395 {
396 va_list ap;
397 size_t argLen;
398
400#pragma prefast(suppress: __WARNING_BUFFER_OVERFLOW, "Recommneded by EndClean");
401 while ((va_arg(ap, PVOID)) != NULL) {
402
403 argLen = va_arg(ap, size_t);
404
405 if (argLen > 0) {
406
407 if (argLen > FxIFRMaxMessageSize) {
408 goto drop_message;
409 }
410 size += (USHORT) argLen;
411 }
412 }
413
414 va_end(ap);
415
416 //
417 // NOTE: The final size must be 32-bit (ULONG) aligned.
418 // This is necessary for IA64 to prevent Alignment Faults.
419 //
420 size += (size % sizeof(ULONG)) ? sizeof(ULONG) - (size % sizeof(ULONG)) : 0;
421
423 goto drop_message;
424 }
425 }
426
427 size += sizeof(WDF_IFR_RECORD);
428
429 //
430 // Allocate log space of the calculated size
431 //
432 {
433 WDF_IFR_OFFSET offsetRet;
434 WDF_IFR_OFFSET offsetCur;
435 WDF_IFR_OFFSET offsetNew;
436 USHORT usSize = (USHORT) size; // for a prefast artifact.
437
438 header = (PWDF_IFR_HEADER) FxDriverGlobals->WdfLogHeader;
439
440 FxVerifyLogHeader(FxDriverGlobals, header);
441
442 offsetRet.u.AsLONG = header->Offset.u.AsLONG;
443 offsetNew.u.AsLONG = offsetRet.u.s.Current;
444
445 do {
446 offsetCur.u.AsLONG = offsetRet.u.AsLONG;
447
448 if (&header->Base[header->Size] < &header->Base[offsetCur.u.s.Current+size]) {
449
450 offsetNew.u.s.Current = 0;
451 offsetNew.u.s.Previous = offsetRet.u.s.Previous;
452
453 offsetRet.u.AsLONG =
454 InterlockedCompareExchange( &header->Offset.u.AsLONG,
455 offsetNew.u.AsLONG,
456 offsetCur.u.AsLONG );
457
458 if (offsetCur.u.AsLONG != offsetRet.u.AsLONG) {
459 continue;
460 } else {
461 offsetNew.u.s.Current = offsetCur.u.s.Current + usSize;
462 offsetNew.u.s.Previous = offsetRet.u.s.Current;
463 }
464 } else {
465
466 offsetNew.u.s.Current = offsetCur.u.s.Current + usSize;
467 offsetNew.u.s.Previous = offsetCur.u.s.Current;
468 }
469
470 offsetRet.u.AsLONG =
471 InterlockedCompareExchange( &header->Offset.u.AsLONG,
472 offsetNew.u.AsLONG,
473 offsetCur.u.AsLONG );
474
475 } while (offsetCur.u.AsLONG != offsetRet.u.AsLONG);
476
477 record = (PWDF_IFR_RECORD) &header->Base[offsetRet.u.s.Current];
478
479 // RtlZeroMemory( record, sizeof(WDF_IFR_RECORD) );
480
481 //
482 // Build record (fill all fields!)
483 //
484 record->Signature = FxIFRRecordSignature;
485 record->Length = (USHORT) size;
486 record->PrevOffset = (USHORT) offsetRet.u.s.Previous;
487 record->MessageNumber = MessageNumber;
488 record->Sequence = InterlockedIncrement( &header->Sequence );
489 record->MessageGuid = *MessageGuid;
490 }
491
492 //
493 // Move variable part of data into log.
494 //
495 {
496 va_list ap;
497 size_t argLen;
499 PUCHAR argsData;
500
501 argsData = (UCHAR*) &record[1];
502
504
505 while ((source = va_arg(ap, PVOID)) != NULL) {
506
507 argLen = va_arg(ap, size_t);
508
509 if (argLen > 0) {
510
511 RtlCopyMemory( argsData, source, argLen );
512 argsData += argLen;
513 }
514 }
515
516 va_end(ap);
517 }
518
519 FxVerifyLogHeader(FxDriverGlobals, header);
520
521 return STATUS_SUCCESS;
522
523 {
524 //
525 // Increment sequence number to indicate dropped message
526 //
527drop_message:
528 header = (PWDF_IFR_HEADER) FxDriverGlobals->WdfLogHeader;
529 InterlockedIncrement( &header->Sequence );
530 return STATUS_UNSUCCESSFUL;
531 }
532}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
#define __in
Definition: dbghelp.h:35
#define TRACINGDRIVER
Definition: dbgtrace.h:68
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define L(x)
Definition: resources.c:13
#define WPP_INIT_TRACING(a, b)
Definition: kdebugprint.h:56
#define WPP_CLEANUP(a)
Definition: kdebugprint.h:57
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NonPagedPool
Definition: env_spec_w32.h:307
ULONG64 TRACEHANDLE
Definition: evntrace.h:40
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
#define WDF_IFR_LOG_TAG
Definition: fxifr.h:88
struct _WDF_IFR_HEADER * PWDF_IFR_HEADER
struct _WDF_IFR_RECORD WDF_IFR_RECORD
#define WDF_IFR_RECORD_SIGNATURE
Definition: fxifr.h:109
struct _WDF_IFR_HEADER WDF_IFR_HEADER
struct _WDF_IFR_RECORD * PWDF_IFR_RECORD
#define WDF_IFR_HEADER_NAME_LEN
Definition: fxifr.h:42
@ FxIFRMaxLogPages
Definition: fxifrkm.h:20
@ FxIFRMinLogPages
Definition: fxifrkm.h:19
@ FxIFRMinLogSize
Definition: fxifrkm.h:23
@ FxIFRAvgLogPages
Definition: fxifrkm.h:21
@ FxIFRMaxMessageSize
Definition: fxifrkm.h:27
@ FxIFRRecordSignature
Definition: fxifrkm.h:29
__inline VOID FxVerifyLogHeader(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_IFR_HEADER Header)
Definition: fxifrkm.h:49
GLsizeiptr size
Definition: glext.h:5919
FxContextHeader * pHeader
Definition: handleapi.cpp:604
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InterlockedCompareExchange
Definition: interlocked.h:119
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define KEY_READ
Definition: nt_native.h:1026
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
NTSTATUS NTAPI WmiTraceMessageVa(IN TRACEHANDLE LoggerHandle, IN ULONG MessageFlags, IN LPGUID MessageGuid, IN USHORT MessageNumber, IN va_list MessageArgList)
Definition: wmi.c:368
NTSTRSAFEAPI RtlStringCchCopyA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:110
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
struct _WDF_IFR_OFFSET::@5054::@5055 s
union _WDF_IFR_OFFSET::@5054 u
LONG AsLONG
Definition: fxifr.h:83
Definition: ps.c:97
_Must_inspect_result_ NTSTATUS FxIFR(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in UCHAR MessageLevel, __in ULONG MessageFlags, __in LPGUID MessageGuid, __in USHORT MessageNumber, __in ...)
Definition: tracing.cpp:334
_Must_inspect_result_ NTSTATUS FxWmiTraceMessage(__in TRACEHANDLE LoggerHandle, __in ULONG MessageFlags, __in LPGUID MessageGuid, __in USHORT MessageNumber, __in ...)
Definition: tracing.cpp:104
ULONG FxIFRGetSize(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PCUNICODE_STRING RegistryPath)
Definition: tracing.cpp:136
VOID FxIFRStart(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PCUNICODE_STRING RegistryPath, __in MdDriverObject DriverObject)
Definition: tracing.cpp:222
VOID TraceUninitialize(VOID)
Definition: tracing.cpp:79
VOID FxIFRStop(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: tracing.cpp:299
_Must_inspect_result_ NTSTATUS FxTraceInitialize(VOID)
Definition: tracing.cpp:47
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define WDFCASSERT(c)
Definition: wdfassert.h:93
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
_Must_inspect_result_ typedef _In_ ULONG _In_ ULONG MessageNumber
Definition: iotypes.h:4307
unsigned char UCHAR
Definition: xmlstorage.h:181