1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
|
/*++
Copyright (c) Microsoft Corporation. All Rights Reserved
Abstract:
WPP Macro definitions.
Author:
Travis Martin (TravM)
--*/
//
// Helpful macros
//
#ifndef WIDEN2
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#endif
//
// WPP definitions. Listed below is a set of WPP Trace macros. The comments
// between "//begin_wpp config" and "//end_wpp" are used by the WPP pre-processor
// to create the *.tmh files
//
#define PROXIMITY_COMMON_TRACE L"Microsoft\\Windows\\ProximityCommon"
#ifndef TRACE_CONTROL_GUID
#define TRACE_CONTROL_GUID (93bfc19b, a967, 4339, a3e6, 3a4cc30681d1)
#endif
#define WPP_CONTROL_GUIDS \
WPP_DEFINE_CONTROL_GUID(PROXIMITY, TRACE_CONTROL_GUID, \
WPP_DEFINE_BIT(EntryExit) \
WPP_DEFINE_BIT(AllocFree) \
WPP_DEFINE_BIT(Info) \
WPP_DEFINE_BIT(Warning) \
WPP_DEFINE_BIT(Error) \
\
WPP_DEFINE_BIT(NoisyEntryExit) \
WPP_DEFINE_BIT(NoisyAllocFree) \
WPP_DEFINE_BIT(NoisyInfo) \
WPP_DEFINE_BIT(NoisyWarning))
//
// Used for trace messages indentation
//
const char __indentSpacer[] =
" "
" "
" "
" "
" "
" ";
#define INDENT_STR(indent) \
(__indentSpacer + ((sizeof(__indentSpacer) >= (indent)*5) ? (sizeof(__indentSpacer)-2-(indent)*5) : 0))
//---------------------------------------------------------------------------
// Stores a pointer to current tracing context
//---------------------------------------------------------------------------
extern DWORD __g_tracingTlsSlot;
//---------------------------------------------------------------------------
// This macro declares the global variable that will store TLS index for the
// tracing context pointer.
//---------------------------------------------------------------------------
#define DECLARE_TRACING_TLS DWORD __g_tracingTlsSlot = TLS_OUT_OF_INDEXES
//---------------------------------------------------------------------------
// To be used only within non-WDTF EXE init routines or by the Tracer.
//---------------------------------------------------------------------------
inline bool TracingTlsInitialize()
{
if (__g_tracingTlsSlot == TLS_OUT_OF_INDEXES)
{
__g_tracingTlsSlot = TlsAlloc();
if (__g_tracingTlsSlot == TLS_OUT_OF_INDEXES)
{
// Return error: cannot allocate TLS slot
return false;
}
}
return true;
}
//---------------------------------------------------------------------------
// To be used only within non-WDTF EXE exit routines or by the Tracer.
//---------------------------------------------------------------------------
inline void TracingTlsFree()
{
if (__g_tracingTlsSlot != TLS_OUT_OF_INDEXES)
{
TlsFree(__g_tracingTlsSlot);
__g_tracingTlsSlot = TLS_OUT_OF_INDEXES;
}
}
namespace TracingInternal
{
//---------------------------------------------------------------------------
// Used for storing current tracing context within a TLS slot
//---------------------------------------------------------------------------
struct TracingContext
{
ULONG CallDepth; // Current depth of internal calls
DWORD Context; // A context value (used to correlate scenarios that cross-threads)
};
//---------------------------------------------------------------------------
// Auto-incrementing and decrementing variable
//---------------------------------------------------------------------------
class AutoStackDepth
{
public:
__forceinline AutoStackDepth(ULONG *pCallDepth)
: _pCallDepth(pCallDepth)
{
WUDF_SAMPLE_DRIVER_ASSERT(_pCallDepth);
if (_pCallDepth)
{
++*_pCallDepth;
}
}
__forceinline ~AutoStackDepth()
{
if (_pCallDepth)
{
--*_pCallDepth;
}
}
private:
AutoStackDepth(AutoStackDepth& rh);
const AutoStackDepth& operator =(AutoStackDepth& rh);
private:
ULONG* _pCallDepth;
};
//---------------------------------------------------------------------------
// Sets new value to a variable but saves old value and restores it on
// destrutcion
//---------------------------------------------------------------------------
template <class T>
class AutoRestoredValue
{
public:
__forceinline AutoRestoredValue(T* pVar, T newVal)
: _pVar(pVar)
, _oldVal()
{
WUDF_SAMPLE_DRIVER_ASSERT(_pVar);
if (_pVar)
{
_oldVal = *_pVar;
*_pVar = newVal;
}
}
__forceinline ~AutoRestoredValue()
{
if (_pVar)
{
*_pVar = _oldVal;
}
}
private:
AutoRestoredValue(AutoRestoredValue& rh);
const AutoRestoredValue& operator =(AutoRestoredValue& rh);
private:
T* _pVar;
T _oldVal;
};
//---------------------------------------------------------------------------
// Auto-pointer stored in TLS
//---------------------------------------------------------------------------
template <class Pointee>
class AutoTlsPtr
{
public:
__forceinline AutoTlsPtr()
: _dwSlotIndex(TLS_OUT_OF_INDEXES)
{
}
__forceinline ~AutoTlsPtr()
{
if (_dwSlotIndex != TLS_OUT_OF_INDEXES)
{
LPVOID pCtx = TlsGetValue(_dwSlotIndex);
if (pCtx)
{
TlsSetValue(_dwSlotIndex, NULL);
}
}
}
__forceinline Attach(Pointee* pCtx, DWORD dwSlotIndex)
{
_dwSlotIndex = dwSlotIndex;
TlsSetValue(_dwSlotIndex, pCtx);
}
private:
DWORD _dwSlotIndex;
};
}
//---------------------------------------------------------------------------
// This macro should be used at entry point of all functions with tracing.
// It reads from a Tracing context structure stored in the TLS.
// If the slot contains a NULL a new TracingContext is used. An object
// is created that increments CallDepth and auto-decrements it on function exit.
//---------------------------------------------------------------------------
#define USE_DEFAULT_TRACING_CONTEXT \
TracingInternal::TracingContext* __pCtx = (TracingInternal::TracingContext*)TlsGetValue(__g_tracingTlsSlot); \
TracingInternal::AutoTlsPtr<TracingInternal::TracingContext> __autoTlsPtr; \
TracingInternal::TracingContext __ctx; \
if (__pCtx == NULL) \
{ \
__pCtx = &__ctx; \
__pCtx->CallDepth = 0; \
__autoTlsPtr.Attach(__pCtx, __g_tracingTlsSlot); \
} \
TracingInternal::AutoStackDepth __autoStackDepth(&__pCtx->CallDepth);
//MACRO: MethodEntry
//
//begin_wpp config
//USEPREFIX (MethodEntry, "%!STDPREFIX!%s-->this(%p):%!FUNC!(", INDENT_STR(__pCtx->CallDepth), this);
//FUNC MethodEntry{ENTRYLEVEL=EntryExit}(MSG, ...);
//USESUFFIX (MethodEntry, ")");
//end_wpp
#define WPP_ENTRYLEVEL_ENABLED(LEVEL) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_ENTRYLEVEL_LOGGER(LEVEL) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_ENTRYLEVEL_PRE(LEVEL) USE_DEFAULT_TRACING_CONTEXT;
//MACRO: MethodReturn
//
//begin_wpp config
//USEPREFIX (MethodReturn, "%!STDPREFIX!%s<--this(%p):%!FUNC!(): ", INDENT_STR(__pCtx->CallDepth), this);
//FUNC MethodReturn{RETURNLEVEL=EntryExit}(RET, MSG, ...);
//end_wpp
#define WPP_RETURNLEVEL_RET_ENABLED(LEVEL, Ret) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_RETURNLEVEL_RET_LOGGER(LEVEL, Ret) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_RETURNLEVEL_RET_POST(LEVEL, Ret) ;return Ret;
//MACRO: MethodReturnHR
//
//begin_wpp config
//USEPREFIX (MethodReturnHR, "%!STDPREFIX!%s<--this(%p):%!FUNC!(): %!HRESULT!", INDENT_STR(__pCtx->CallDepth), this, __hr);
//FUNC MethodReturnHR{RETURNHRLEVEL=EntryExit}(HR);
//end_wpp
#define WPP_RETURNHRLEVEL_HR_ENABLED(LEVEL, hr) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_RETURNHRLEVEL_HR_LOGGER(LEVEL, hr) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_RETURNHRLEVEL_HR_PRE(LEVEL, hr) { \
HRESULT __hr = hr;
#define WPP_RETURNHRLEVEL_HR_POST(LEVEL, hr) /*TraceMessage()*/; \
return __hr; \
}
//MACRO: MethodReturnVoid
//
//begin_wpp config
//USEPREFIX (MethodReturnVoid, "%!STDPREFIX!%s<--this(%p):%!FUNC!()", INDENT_STR(__pCtx->CallDepth), this);
//FUNC MethodReturnVoid{RETURNVOIDLEVEL=EntryExit}(...);
//end_wpp
#define WPP_RETURNVOIDLEVEL_ENABLED(LEVEL) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_RETURNVOIDLEVEL_LOGGER(LEVEL) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_RETURNVOIDLEVEL_POST(LEVEL) ;return;
//MACRO: MethodReturnBool
//
//begin_wpp config
//USEPREFIX (MethodReturnBool, "%!STDPREFIX!%s<--this(%p):%!FUNC!(): %!bool!", INDENT_STR(__pCtx->CallDepth), this, __bRet);
//FUNC MethodReturnBool{RETURNBOOLLEVEL=EntryExit}(BOOLRETVAL);
//end_wpp
#define WPP_RETURNBOOLLEVEL_BOOLRETVAL_ENABLED(LEVEL, bRet) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_RETURNBOOLLEVEL_BOOLRETVAL_LOGGER(LEVEL, bRet) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_RETURNBOOLLEVEL_BOOLRETVAL_PRE(LEVEL, bRet) { \
bool __bRet = (bRet ? true : false);
#define WPP_RETURNBOOLLEVEL_BOOLRETVAL_POST(LEVEL, bRet) /*TraceMessage()*/; \
return __bRet; \
}
//MACRO: MethodReturnPtr
//
//begin_wpp config
//USEPREFIX (MethodReturnPtr, "%!STDPREFIX!%s<--this(%p):%!FUNC!(): %p", INDENT_STR(__pCtx->CallDepth), this, __ptrRetVal);
//FUNC MethodReturnPtr{RETURNPTRLEVEL=EntryExit}(TYPE, PRET);
//end_wpp
#define WPP_RETURNPTRLEVEL_TYPE_PRET_ENABLED(LEVEL, Type, pRet) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_RETURNPTRLEVEL_TYPE_PRET_LOGGER(LEVEL, Type, pRet) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_RETURNPTRLEVEL_TYPE_PRET_PRE(LEVEL, Type, pRet) { \
Type __pRet = pRet;
#define WPP_RETURNPTRLEVEL_TYPE_PRET_POST(LEVEL, Type, pRet) /*TraceMessage()*/; \
return __pRet; \
}
//MACRO: MethodReturnIfNull
//
//begin_wpp config
//USEPREFIX (MethodReturnIfNull, "%!STDPREFIX!%s<-this(%p):%!FUNC!(): E_POINTER %s=NULL, bailing out!", INDENT_STR(__pCtx->CallDepth), this, #PTR);
//FUNC MethodReturnIfNull{METHOD_POINTER_LEVEL=EntryExit}(PTR);
//end_wpp
#define WPP_METHOD_POINTER_LEVEL_PTR_ENABLED(LEVEL, PTR) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_METHOD_POINTER_LEVEL_PTR_LOGGER(LEVEL, PTR) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_METHOD_POINTER_LEVEL_PTR_PRE(LEVEL, PTR) if ((PTR) == NULL) \
{
#define WPP_METHOD_POINTER_LEVEL_PTR_POST(LEVEL, PTR) /*TraceMessage()*/; \
return E_POINTER; \
}
//MACRO: FunctionEntry
//
//begin_wpp config
//USEPREFIX (FunctionEntry, "%!STDPREFIX!%s-->%!FUNC!(", INDENT_STR(__pCtx->CallDepth));
//FUNC FunctionEntry{FUNCENTRYLEVEL=EntryExit}(MSG, ...);
//USESUFFIX (FunctionEntry, ")");
//end_wpp
#define WPP_FUNCENTRYLEVEL_ENABLED(LEVEL) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_FUNCENTRYLEVEL_LOGGER(LEVEL) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_FUNCENTRYLEVEL_PRE(LEVEL) USE_DEFAULT_TRACING_CONTEXT;
//MACRO: FunctionReturn
//
//begin_wpp config
//USEPREFIX (FunctionReturn, "%!STDPREFIX!%s<--%!FUNC!(): ", INDENT_STR(__pCtx->CallDepth));
//FUNC FunctionReturn{FUNCRETURNLEVEL=EntryExit}(RET, MSG, ...);
//end_wpp
#define WPP_FUNCRETURNLEVEL_RET_ENABLED(LEVEL, Ret) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_FUNCRETURNLEVEL_RET_LOGGER(LEVEL, Ret) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_FUNCRETURNLEVEL_RET_POST(LEVEL, Ret) ;return Ret;
//MACRO: FunctionReturnHR
//
//begin_wpp config
//USEPREFIX (FunctionReturnHR, "%!STDPREFIX!%s<--%!FUNC!(): %!HRESULT!", INDENT_STR(__pCtx->CallDepth), __hr);
//FUNC FunctionReturnHR{FUNCRETURNHRLEVEL=EntryExit}(HR);
//end_wpp
#define WPP_FUNCRETURNHRLEVEL_HR_ENABLED(LEVEL, hr) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_FUNCRETURNHRLEVEL_HR_LOGGER(LEVEL, hr) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_FUNCRETURNHRLEVEL_HR_PRE(LEVEL, hr) { \
HRESULT __hr = hr;
#define WPP_FUNCRETURNHRLEVEL_HR_POST(LEVEL, hr) /*TraceMessage()*/; \
return __hr; \
}
//MACRO: FunctionReturnVoid
//
//begin_wpp config
//USEPREFIX (FunctionReturnVoid, "%!STDPREFIX!%s<--%!FUNC!()", INDENT_STR(__pCtx->CallDepth));
//FUNC FunctionReturnVoid{FUNCRETURNLEVELVOID=EntryExit}(...);
//end_wpp
#define WPP_FUNCRETURNLEVELVOID_ENABLED(LEVEL) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_FUNCRETURNLEVELVOID_LOGGER(LEVEL) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_FUNCRETURNLEVELVOID_POST(LEVEL) ;return;
//MACRO: FunctionReturnBool
//
//begin_wpp config
//USEPREFIX (FunctionReturnBool, "%!STDPREFIX!%s<--%!FUNC!(): %!bool!", INDENT_STR(__pCtx->CallDepth), __bRet);
//FUNC FunctionReturnBool{FUNCRETURNLEVELBOOL=EntryExit}(BOOLRETVAL);
//end_wpp
#define WPP_FUNCRETURNLEVELBOOL_BOOLRETVAL_ENABLED(LEVEL, bRet) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_FUNCRETURNLEVELBOOL_BOOLRETVAL_LOGGER(LEVEL, bRet) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_FUNCRETURNLEVELBOOL_BOOLRETVAL_PRE(LEVEL, bRet) { \
bool __bRet = (bRet ? true : false);
#define WPP_FUNCRETURNLEVELBOOL_BOOLRETVAL_POST(LEVEL, bRet) /*TraceMessage()*/; \
return __bRet; \
}
//MACRO: FunctionReturnPtr
//
//begin_wpp config
//USEPREFIX (FunctionReturnPtr, "%!STDPREFIX!%s<--%!FUNC!(): %p", INDENT_STR(__pCtx->CallDepth), __pRet);
//FUNC FunctionReturnPtr{FUNCRETURNLEVELPTR=EntryExit}(TYPE, PRET);
//end_wpp
#define WPP_FUNCRETURNLEVELPTR_TYPE_PRET_ENABLED(LEVEL, Type, pRet) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_FUNCRETURNLEVELPTR_TYPE_PRET_LOGGER(LEVEL, Type, pRet) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_FUNCRETURNLEVELPTR_TYPE_PRET_PRE(LEVEL, Type, pRet) { \
Type __pRet = pRet;
#define WPP_FUNCRETURNLEVELPTR_TYPE_PRET_POST(LEVEL, Type, pRet) /*TraceMessage()*/; \
return __pRet; \
}
// Define Non-empty debug break for checked builds only
#ifndef NDEBUG
#define DEBUG_BREAK() __debugbreak()
#else
#define DEBUG_BREAK() do {} while (false)
#endif
//MACRO: TraceASSERT
//
// ASSERT with tracing
//
//begin_wpp config
//USEPREFIX (TraceASSERT, "%!STDPREFIX!%sWARN: ASSERTION FAILED - expression \"%s\" is false.", INDENT_STR(__pCtx->CallDepth+1), #EXPR);
//FUNC TraceASSERT{ASSERTLEVEL=Warning}(EXPR);
//end_wpp
#define WPP_ASSERTLEVEL_EXPR_ENABLED(LEVEL, EXPR) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_ASSERTLEVEL_EXPR_LOGGER(LEVEL, EXPR) WPP_LEVEL_LOGGER(LEVEL)
#define WPP_ASSERTLEVEL_EXPR_PRE(LEVEL, EXPR) if (!(EXPR)) \
{
#define WPP_ASSERTLEVEL_EXPR_POST(LEVEL, EXPR) /*TraceMessage()*/; \
WUDF_SAMPLE_DRIVER_ASSERT(FALSE); \
}
//MACRO: TraceErrorHR
//
// ERROR trace
//
//begin_wpp config
//USEPREFIX (TraceErrorHR, "%!STDPREFIX!%sERROR: ", INDENT_STR(__pCtx->CallDepth+1));
//FUNC TraceErrorHR{ERRORLEVEL=Error}(HR, MSG, ...);
//USESUFFIX (TraceErrorHR, ": %!HRESULT!", HR);
//end_wpp
#define WPP_ERRORLEVEL_HR_ENABLED(LEVEL, HR) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_ERRORLEVEL_HR_LOGGER(LEVEL, HR) WPP_LEVEL_LOGGER(LEVEL)
//MACRO: TraceInfo
//
//begin_wpp config
//USEPREFIX (TraceInfo, "%!STDPREFIX!%s", INDENT_STR(__pCtx->CallDepth+1));
//FUNC TraceInfo{INFOLEVEL=Info}(MSG, ...);
//end_wpp
#define WPP_INFOLEVEL_ENABLED(LEVEL) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_INFOLEVEL_LOGGER(LEVEL) WPP_LEVEL_LOGGER(LEVEL)
|