• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //**********************************************************************`
2 //* This is an include file generated by Message Compiler.             *`
3 //*                                                                    *`
4 //* Copyright (c) Microsoft Corporation. All Rights Reserved.          *`
5 //**********************************************************************`
6 #pragma once
7 
8 //*****************************************************************************
9 //
10 // Notes on the ETW event code generated by MC:
11 //
12 // - Structures and arrays of structures are treated as an opaque binary blob.
13 //   The caller is responsible for packing the data for the structure into a
14 //   single region of memory, with no padding between values. The macro will
15 //   have an extra parameter for the length of the blob.
16 // - Arrays of nul-terminated strings must be packed by the caller into a
17 //   single binary blob containing the correct number of strings, with a nul
18 //   after each string. The size of the blob is specified in characters, and
19 //   includes the final nul.
20 // - Arrays of SID are treated as a single binary blob. The caller is
21 //   responsible for packing the SID values into a single region of memory with
22 //   no padding.
23 // - The length attribute on the data element in the manifest is significant
24 //   for values with intype win:UnicodeString, win:AnsiString, or win:Binary.
25 //   The length attribute must be specified for win:Binary, and is optional for
26 //   win:UnicodeString and win:AnsiString (if no length is given, the strings
27 //   are assumed to be nul-terminated). For win:UnicodeString, the length is
28 //   measured in characters, not bytes.
29 // - For an array of win:UnicodeString, win:AnsiString, or win:Binary, the
30 //   length attribute applies to every value in the array, so every value in
31 //   the array must have the same length. The values in the array are provided
32 //   to the macro via a single pointer -- the caller is responsible for packing
33 //   all of the values into a single region of memory with no padding between
34 //   values.
35 // - Values of type win:CountedUnicodeString, win:CountedAnsiString, and
36 //   win:CountedBinary can be generated and collected on Vista or later.
37 //   However, they may not decode properly without the Windows 10 2018 Fall
38 //   Update.
39 // - Arrays of type win:CountedUnicodeString, win:CountedAnsiString, and
40 //   win:CountedBinary must be packed by the caller into a single region of
41 //   memory. The format for each item is a UINT16 byte-count followed by that
42 //   many bytes of data. When providing the array to the generated macro, you
43 //   must provide the total size of the packed array data, including the UINT16
44 //   sizes for each item. In the case of win:CountedUnicodeString, the data
45 //   size is specified in WCHAR (16-bit) units. In the case of
46 //   win:CountedAnsiString and win:CountedBinary, the data size is specified in
47 //   bytes.
48 //
49 //*****************************************************************************
50 
51 #include <wmistr.h>
52 #include <evntrace.h>
53 #include <evntprov.h>
54 
55 #ifndef ETW_INLINE
56   #ifdef _ETW_KM_
57     // In kernel mode, save stack space by never inlining templates.
58     #define ETW_INLINE DECLSPEC_NOINLINE __inline
59   #else
60     // In user mode, save code size by inlining templates as appropriate.
61     #define ETW_INLINE __inline
62   #endif
63 #endif // ETW_INLINE
64 
65 #if defined(__cplusplus)
66 extern "C" {
67 #endif
68 
69 //
70 // MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:
71 // Define this macro to have the compiler skip the generated functions in this
72 // header.
73 //
74 #ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION
75 
76 //
77 // MCGEN_USE_KERNEL_MODE_APIS macro:
78 // Controls whether the generated code uses kernel-mode or user-mode APIs.
79 // - Set to 0 to use Windows user-mode APIs such as EventRegister.
80 // - Set to 1 to use Windows kernel-mode APIs such as EtwRegister.
81 // Default is based on whether the _ETW_KM_ macro is defined (i.e. by wdm.h).
82 // Note that the APIs can also be overridden directly, e.g. by setting the
83 // MCGEN_EVENTWRITETRANSFER or MCGEN_EVENTREGISTER macros.
84 //
85 #ifndef MCGEN_USE_KERNEL_MODE_APIS
86   #ifdef _ETW_KM_
87     #define MCGEN_USE_KERNEL_MODE_APIS 1
88   #else
89     #define MCGEN_USE_KERNEL_MODE_APIS 0
90   #endif
91 #endif // MCGEN_USE_KERNEL_MODE_APIS
92 
93 //
94 // MCGEN_HAVE_EVENTSETINFORMATION macro:
95 // Controls how McGenEventSetInformation uses the EventSetInformation API.
96 // - Set to 0 to disable the use of EventSetInformation
97 //   (McGenEventSetInformation will always return an error).
98 // - Set to 1 to directly invoke MCGEN_EVENTSETINFORMATION.
99 // - Set to 2 to to locate EventSetInformation at runtime via GetProcAddress
100 //   (user-mode) or MmGetSystemRoutineAddress (kernel-mode).
101 // Default is determined as follows:
102 // - If MCGEN_EVENTSETINFORMATION has been customized, set to 1
103 //   (i.e. use MCGEN_EVENTSETINFORMATION).
104 // - Else if the target OS version has EventSetInformation, set to 1
105 //   (i.e. use MCGEN_EVENTSETINFORMATION).
106 // - Else set to 2 (i.e. try to dynamically locate EventSetInformation).
107 // Note that an McGenEventSetInformation function will only be generated if one
108 // or more provider in a manifest has provider traits.
109 //
110 #ifndef MCGEN_HAVE_EVENTSETINFORMATION
111   #ifdef MCGEN_EVENTSETINFORMATION             // if MCGEN_EVENTSETINFORMATION has been customized,
112     #define MCGEN_HAVE_EVENTSETINFORMATION   1 //   directly invoke MCGEN_EVENTSETINFORMATION(...).
113   #elif MCGEN_USE_KERNEL_MODE_APIS             // else if using kernel-mode APIs,
114     #if NTDDI_VERSION >= 0x06040000            //   if target OS is Windows 10 or later,
115       #define MCGEN_HAVE_EVENTSETINFORMATION 1 //     directly invoke MCGEN_EVENTSETINFORMATION(...).
116     #else                                      //   else
117       #define MCGEN_HAVE_EVENTSETINFORMATION 2 //     find "EtwSetInformation" via MmGetSystemRoutineAddress.
118     #endif                                     // else (using user-mode APIs)
119   #else                                        //   if target OS and SDK is Windows 8 or later,
120     #if WINVER >= 0x0602 && defined(EVENT_FILTER_TYPE_SCHEMATIZED)
121       #define MCGEN_HAVE_EVENTSETINFORMATION 1 //     directly invoke MCGEN_EVENTSETINFORMATION(...).
122     #else                                      //   else
123       #define MCGEN_HAVE_EVENTSETINFORMATION 2 //     find "EventSetInformation" via GetModuleHandleExW/GetProcAddress.
124     #endif
125   #endif
126 #endif // MCGEN_HAVE_EVENTSETINFORMATION
127 
128 //
129 // MCGEN Override Macros
130 //
131 // The following override macros may be defined before including this header
132 // to control the APIs used by this header:
133 //
134 // - MCGEN_EVENTREGISTER
135 // - MCGEN_EVENTUNREGISTER
136 // - MCGEN_EVENTSETINFORMATION
137 // - MCGEN_EVENTWRITETRANSFER
138 //
139 // If the macro is undefined, the MC implementation will default to the
140 // corresponding ETW APIs. For example, if the MCGEN_EVENTREGISTER macro is
141 // undefined, the EventRegister[MyProviderName] macro will use EventRegister
142 // in user mode and will use EtwRegister in kernel mode.
143 //
144 // To prevent issues from conflicting definitions of these macros, the value
145 // of the override macro will be used as a suffix in certain internal function
146 // names. Because of this, the override macros must follow certain rules:
147 //
148 // - The macro must be defined before any MC-generated header is included and
149 //   must not be undefined or redefined after any MC-generated header is
150 //   included. Different translation units (i.e. different .c or .cpp files)
151 //   may set the macros to different values, but within a translation unit
152 //   (within a single .c or .cpp file), the macro must be set once and not
153 //   changed.
154 // - The override must be an object-like macro, not a function-like macro
155 //   (i.e. the override macro must not have a parameter list).
156 // - The override macro's value must be a simple identifier, i.e. must be
157 //   something that starts with a letter or '_' and contains only letters,
158 //   numbers, and '_' characters.
159 // - If the override macro's value is the name of a second object-like macro,
160 //   the second object-like macro must follow the same rules. (The override
161 //   macro's value can also be the name of a function-like macro, in which
162 //   case the function-like macro does not need to follow the same rules.)
163 //
164 // For example, the following will cause compile errors:
165 //
166 //   #define MCGEN_EVENTWRITETRANSFER MyNamespace::MyClass::MyFunction // Value has non-identifier characters (colon).
167 //   #define MCGEN_EVENTWRITETRANSFER GetEventWriteFunctionPointer(7)  // Value has non-identifier characters (parentheses).
168 //   #define MCGEN_EVENTWRITETRANSFER(h,e,a,r,c,d) EventWrite(h,e,c,d) // Override is defined as a function-like macro.
169 //   #define MY_OBJECT_LIKE_MACRO     MyNamespace::MyClass::MyEventWriteFunction
170 //   #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // Evaluates to something with non-identifier characters (colon).
171 //
172 // The following would be ok:
173 //
174 //   #define MCGEN_EVENTWRITETRANSFER  MyEventWriteFunction1  // OK, suffix will be "MyEventWriteFunction1".
175 //   #define MY_OBJECT_LIKE_MACRO      MyEventWriteFunction2
176 //   #define MCGEN_EVENTWRITETRANSFER  MY_OBJECT_LIKE_MACRO   // OK, suffix will be "MyEventWriteFunction2".
177 //   #define MY_FUNCTION_LIKE_MACRO(h,e,a,r,c,d) MyNamespace::MyClass::MyEventWriteFunction3(h,e,c,d)
178 //   #define MCGEN_EVENTWRITETRANSFER  MY_FUNCTION_LIKE_MACRO // OK, suffix will be "MY_FUNCTION_LIKE_MACRO".
179 //
180 #ifndef MCGEN_EVENTREGISTER
181   #if MCGEN_USE_KERNEL_MODE_APIS
182     #define MCGEN_EVENTREGISTER        EtwRegister
183   #else
184     #define MCGEN_EVENTREGISTER        EventRegister
185   #endif
186 #endif // MCGEN_EVENTREGISTER
187 #ifndef MCGEN_EVENTUNREGISTER
188   #if MCGEN_USE_KERNEL_MODE_APIS
189     #define MCGEN_EVENTUNREGISTER      EtwUnregister
190   #else
191     #define MCGEN_EVENTUNREGISTER      EventUnregister
192   #endif
193 #endif // MCGEN_EVENTUNREGISTER
194 #ifndef MCGEN_EVENTSETINFORMATION
195   #if MCGEN_USE_KERNEL_MODE_APIS
196     #define MCGEN_EVENTSETINFORMATION  EtwSetInformation
197   #else
198     #define MCGEN_EVENTSETINFORMATION  EventSetInformation
199   #endif
200 #endif // MCGEN_EVENTSETINFORMATION
201 #ifndef MCGEN_EVENTWRITETRANSFER
202   #if MCGEN_USE_KERNEL_MODE_APIS
203     #define MCGEN_EVENTWRITETRANSFER   EtwWriteTransfer
204   #else
205     #define MCGEN_EVENTWRITETRANSFER   EventWriteTransfer
206   #endif
207 #endif // MCGEN_EVENTWRITETRANSFER
208 
209 //
210 // MCGEN_EVENT_ENABLED macro:
211 // Override to control how the EventWrite[EventName] macros determine whether
212 // an event is enabled. The default behavior is for EventWrite[EventName] to
213 // use the EventEnabled[EventName] macros.
214 //
215 #ifndef MCGEN_EVENT_ENABLED
216 #define MCGEN_EVENT_ENABLED(EventName) EventEnabled##EventName()
217 #endif
218 
219 //
220 // MCGEN_EVENT_ENABLED_FORCONTEXT macro:
221 // Override to control how the EventWrite[EventName]_ForContext macros
222 // determine whether an event is enabled. The default behavior is for
223 // EventWrite[EventName]_ForContext to use the
224 // EventEnabled[EventName]_ForContext macros.
225 //
226 #ifndef MCGEN_EVENT_ENABLED_FORCONTEXT
227 #define MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, EventName) EventEnabled##EventName##_ForContext(pContext)
228 #endif
229 
230 //
231 // MCGEN_ENABLE_CHECK macro:
232 // Determines whether the specified event would be considered as enabled
233 // based on the state of the specified context. Slightly faster than calling
234 // McGenEventEnabled directly.
235 //
236 #ifndef MCGEN_ENABLE_CHECK
237 #define MCGEN_ENABLE_CHECK(Context, Descriptor) (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor))
238 #endif
239 
240 #if !defined(MCGEN_TRACE_CONTEXT_DEF)
241 #define MCGEN_TRACE_CONTEXT_DEF
242 // This structure is for use by MC-generated code and should not be used directly.
243 typedef struct _MCGEN_TRACE_CONTEXT
244 {
245     TRACEHANDLE            RegistrationHandle;
246     TRACEHANDLE            Logger;      // Used as pointer to provider traits.
247     ULONGLONG              MatchAnyKeyword;
248     ULONGLONG              MatchAllKeyword;
249     ULONG                  Flags;
250     ULONG                  IsEnabled;
251     UCHAR                  Level;
252     UCHAR                  Reserve;
253     USHORT                 EnableBitsCount;
254     PULONG                 EnableBitMask;
255     const ULONGLONG*       EnableKeyWords;
256     const UCHAR*           EnableLevel;
257 } MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT;
258 #endif // MCGEN_TRACE_CONTEXT_DEF
259 
260 #if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF)
261 #define MCGEN_LEVEL_KEYWORD_ENABLED_DEF
262 //
263 // Determines whether an event with a given Level and Keyword would be
264 // considered as enabled based on the state of the specified context.
265 // Note that you may want to use MCGEN_ENABLE_CHECK instead of calling this
266 // function directly.
267 //
268 FORCEINLINE
269 BOOLEAN
McGenLevelKeywordEnabled(_In_ PMCGEN_TRACE_CONTEXT EnableInfo,_In_ UCHAR Level,_In_ ULONGLONG Keyword)270 McGenLevelKeywordEnabled(
271     _In_ PMCGEN_TRACE_CONTEXT EnableInfo,
272     _In_ UCHAR Level,
273     _In_ ULONGLONG Keyword
274     )
275 {
276     //
277     // Check if the event Level is lower than the level at which
278     // the channel is enabled.
279     // If the event Level is 0 or the channel is enabled at level 0,
280     // all levels are enabled.
281     //
282 
283     if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0.
284         (EnableInfo->Level == 0)) {
285 
286         //
287         // Check if Keyword is enabled
288         //
289 
290         if ((Keyword == (ULONGLONG)0) ||
291             ((Keyword & EnableInfo->MatchAnyKeyword) &&
292              ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) {
293             return TRUE;
294         }
295     }
296 
297     return FALSE;
298 }
299 #endif // MCGEN_LEVEL_KEYWORD_ENABLED_DEF
300 
301 #if !defined(MCGEN_EVENT_ENABLED_DEF)
302 #define MCGEN_EVENT_ENABLED_DEF
303 //
304 // Determines whether the specified event would be considered as enabled based
305 // on the state of the specified context. Note that you may want to use
306 // MCGEN_ENABLE_CHECK instead of calling this function directly.
307 //
308 FORCEINLINE
309 BOOLEAN
McGenEventEnabled(_In_ PMCGEN_TRACE_CONTEXT EnableInfo,_In_ PCEVENT_DESCRIPTOR EventDescriptor)310 McGenEventEnabled(
311     _In_ PMCGEN_TRACE_CONTEXT EnableInfo,
312     _In_ PCEVENT_DESCRIPTOR EventDescriptor
313     )
314 {
315     return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword);
316 }
317 #endif // MCGEN_EVENT_ENABLED_DEF
318 
319 #if !defined(MCGEN_CONTROL_CALLBACK)
320 #define MCGEN_CONTROL_CALLBACK
321 
322 // This function is for use by MC-generated code and should not be used directly.
323 DECLSPEC_NOINLINE __inline
324 VOID
325 __stdcall
McGenControlCallbackV2(_In_ LPCGUID SourceId,_In_ ULONG ControlCode,_In_ UCHAR Level,_In_ ULONGLONG MatchAnyKeyword,_In_ ULONGLONG MatchAllKeyword,_In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,_Inout_opt_ PVOID CallbackContext)326 McGenControlCallbackV2(
327     _In_ LPCGUID SourceId,
328     _In_ ULONG ControlCode,
329     _In_ UCHAR Level,
330     _In_ ULONGLONG MatchAnyKeyword,
331     _In_ ULONGLONG MatchAllKeyword,
332     _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,
333     _Inout_opt_ PVOID CallbackContext
334     )
335 /*++
336 
337 Routine Description:
338 
339     This is the notification callback for Windows Vista and later.
340 
341 Arguments:
342 
343     SourceId - The GUID that identifies the session that enabled the provider.
344 
345     ControlCode - The parameter indicates whether the provider
346                   is being enabled or disabled.
347 
348     Level - The level at which the event is enabled.
349 
350     MatchAnyKeyword - The bitmask of keywords that the provider uses to
351                       determine the category of events that it writes.
352 
353     MatchAllKeyword - This bitmask additionally restricts the category
354                       of events that the provider writes.
355 
356     FilterData - The provider-defined data.
357 
358     CallbackContext - The context of the callback that is defined when the provider
359                       called EtwRegister to register itself.
360 
361 Remarks:
362 
363     ETW calls this function to notify provider of enable/disable
364 
365 --*/
366 {
367     PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext;
368     ULONG Ix;
369 #ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2
370     UNREFERENCED_PARAMETER(SourceId);
371     UNREFERENCED_PARAMETER(FilterData);
372 #endif
373 
374     if (Ctx == NULL) {
375         return;
376     }
377 
378     switch (ControlCode) {
379 
380         case EVENT_CONTROL_CODE_ENABLE_PROVIDER:
381             Ctx->Level = Level;
382             Ctx->MatchAnyKeyword = MatchAnyKeyword;
383             Ctx->MatchAllKeyword = MatchAllKeyword;
384             Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER;
385 
386             for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) {
387                 if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) {
388                     Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32));
389                 } else {
390                     Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32));
391                 }
392             }
393             break;
394 
395         case EVENT_CONTROL_CODE_DISABLE_PROVIDER:
396             Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER;
397             Ctx->Level = 0;
398             Ctx->MatchAnyKeyword = 0;
399             Ctx->MatchAllKeyword = 0;
400             if (Ctx->EnableBitsCount > 0) {
401 #pragma warning(suppress: 26451) // Arithmetic overflow cannot occur, no matter the value of EnableBitCount
402                 RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG));
403             }
404             break;
405 
406         default:
407             break;
408     }
409 
410 #ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2
411     //
412     // Call user defined callback
413     //
414     MCGEN_PRIVATE_ENABLE_CALLBACK_V2(
415         SourceId,
416         ControlCode,
417         Level,
418         MatchAnyKeyword,
419         MatchAllKeyword,
420         FilterData,
421         CallbackContext
422         );
423 #endif // MCGEN_PRIVATE_ENABLE_CALLBACK_V2
424 
425     return;
426 }
427 
428 #endif // MCGEN_CONTROL_CALLBACK
429 
430 #ifndef _mcgen_PENABLECALLBACK
431   #if MCGEN_USE_KERNEL_MODE_APIS
432     #define _mcgen_PENABLECALLBACK      PETWENABLECALLBACK
433   #else
434     #define _mcgen_PENABLECALLBACK      PENABLECALLBACK
435   #endif
436 #endif // _mcgen_PENABLECALLBACK
437 
438 #if !defined(_mcgen_PASTE2)
439 // This macro is for use by MC-generated code and should not be used directly.
440 #define _mcgen_PASTE2(a, b) _mcgen_PASTE2_imp(a, b)
441 #define _mcgen_PASTE2_imp(a, b) a##b
442 #endif // _mcgen_PASTE2
443 
444 #if !defined(_mcgen_PASTE3)
445 // This macro is for use by MC-generated code and should not be used directly.
446 #define _mcgen_PASTE3(a, b, c) _mcgen_PASTE3_imp(a, b, c)
447 #define _mcgen_PASTE3_imp(a, b, c) a##b##_##c
448 #endif // _mcgen_PASTE3
449 
450 //
451 // Macro validation
452 //
453 
454 // Validate MCGEN_EVENTREGISTER:
455 
456 // Trigger an error if MCGEN_EVENTREGISTER is not an unqualified (simple) identifier:
457 struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER);
458 
459 // Trigger an error if MCGEN_EVENTREGISTER is redefined:
460 typedef struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER)
461     MCGEN_EVENTREGISTER_must_not_be_redefined_between_headers;
462 
463 // Trigger an error if MCGEN_EVENTREGISTER is defined as a function-like macro:
464 typedef void MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTREGISTER;
465 typedef int _mcgen_PASTE2(MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTREGISTER);
466 
467 // Validate MCGEN_EVENTUNREGISTER:
468 
469 // Trigger an error if MCGEN_EVENTUNREGISTER is not an unqualified (simple) identifier:
470 struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER);
471 
472 // Trigger an error if MCGEN_EVENTUNREGISTER is redefined:
473 typedef struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER)
474     MCGEN_EVENTUNREGISTER_must_not_be_redefined_between_headers;
475 
476 // Trigger an error if MCGEN_EVENTUNREGISTER is defined as a function-like macro:
477 typedef void MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTUNREGISTER;
478 typedef int _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTUNREGISTER);
479 
480 // Validate MCGEN_EVENTSETINFORMATION:
481 
482 // Trigger an error if MCGEN_EVENTSETINFORMATION is not an unqualified (simple) identifier:
483 struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION);
484 
485 // Trigger an error if MCGEN_EVENTSETINFORMATION is redefined:
486 typedef struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION)
487     MCGEN_EVENTSETINFORMATION_must_not_be_redefined_between_headers;
488 
489 // Trigger an error if MCGEN_EVENTSETINFORMATION is defined as a function-like macro:
490 typedef void MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_MCGEN_EVENTSETINFORMATION;
491 typedef int _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_, MCGEN_EVENTSETINFORMATION);
492 
493 // Validate MCGEN_EVENTWRITETRANSFER:
494 
495 // Trigger an error if MCGEN_EVENTWRITETRANSFER is not an unqualified (simple) identifier:
496 struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER);
497 
498 // Trigger an error if MCGEN_EVENTWRITETRANSFER is redefined:
499 typedef struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER)
500     MCGEN_EVENTWRITETRANSFER_must_not_be_redefined_between_headers;;
501 
502 // Trigger an error if MCGEN_EVENTWRITETRANSFER is defined as a function-like macro:
503 typedef void MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_MCGEN_EVENTWRITETRANSFER;
504 typedef int _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_, MCGEN_EVENTWRITETRANSFER);
505 
506 #ifndef McGenEventWrite_def
507 #define McGenEventWrite_def
508 
509 // This macro is for use by MC-generated code and should not be used directly.
510 #define McGenEventWrite _mcgen_PASTE2(McGenEventWrite_, MCGEN_EVENTWRITETRANSFER)
511 
512 // This function is for use by MC-generated code and should not be used directly.
513 DECLSPEC_NOINLINE __inline
514 ULONG __stdcall
515 McGenEventWrite(
516     _In_ PMCGEN_TRACE_CONTEXT Context,
517     _In_ PCEVENT_DESCRIPTOR Descriptor,
518     _In_opt_ LPCGUID ActivityId,
519     _In_range_(1, 128) ULONG EventDataCount,
520     _Pre_cap_(EventDataCount) EVENT_DATA_DESCRIPTOR* EventData
521     )
522 {
523     const USHORT UNALIGNED* Traits;
524 
525     // Some customized MCGEN_EVENTWRITETRANSFER macros might ignore ActivityId.
526     UNREFERENCED_PARAMETER(ActivityId);
527 
528     Traits = (const USHORT UNALIGNED*)(UINT_PTR)Context->Logger;
529 
530     if (Traits == NULL) {
531         EventData[0].Ptr = 0;
532         EventData[0].Size = 0;
533         EventData[0].Reserved = 0;
534     } else {
535         EventData[0].Ptr = (ULONG_PTR)Traits;
536         EventData[0].Size = *Traits;
537         EventData[0].Reserved = 2; // EVENT_DATA_DESCRIPTOR_TYPE_PROVIDER_METADATA
538     }
539 
540     return MCGEN_EVENTWRITETRANSFER(
541         Context->RegistrationHandle,
542         Descriptor,
543         ActivityId,
544         NULL,
545         EventDataCount,
546         EventData);
547 }
548 #endif // McGenEventWrite_def
549 
550 #if !defined(McGenEventRegisterUnregister)
551 #define McGenEventRegisterUnregister
552 
553 // This macro is for use by MC-generated code and should not be used directly.
554 #define McGenEventRegister _mcgen_PASTE2(McGenEventRegister_, MCGEN_EVENTREGISTER)
555 
556 #pragma warning(push)
557 #pragma warning(disable:6103)
558 // This function is for use by MC-generated code and should not be used directly.
559 DECLSPEC_NOINLINE __inline
560 ULONG __stdcall
McGenEventRegister(_In_ LPCGUID ProviderId,_In_opt_ _mcgen_PENABLECALLBACK EnableCallback,_In_opt_ PVOID CallbackContext,_Inout_ PREGHANDLE RegHandle)561 McGenEventRegister(
562     _In_ LPCGUID ProviderId,
563     _In_opt_ _mcgen_PENABLECALLBACK EnableCallback,
564     _In_opt_ PVOID CallbackContext,
565     _Inout_ PREGHANDLE RegHandle
566     )
567 /*++
568 
569 Routine Description:
570 
571     This function registers the provider with ETW.
572 
573 Arguments:
574 
575     ProviderId - Provider ID to register with ETW.
576 
577     EnableCallback - Callback to be used.
578 
579     CallbackContext - Context for the callback.
580 
581     RegHandle - Pointer to registration handle.
582 
583 Remarks:
584 
585     Should not be called if the provider is already registered (i.e. should not
586     be called if *RegHandle != 0). Repeatedly registering a provider is a bug
587     and may indicate a race condition. However, for compatibility with previous
588     behavior, this function will return SUCCESS in this case.
589 
590 --*/
591 {
592     ULONG Error;
593 
594     if (*RegHandle != 0)
595     {
596         Error = 0; // ERROR_SUCCESS
597     }
598     else
599     {
600         Error = MCGEN_EVENTREGISTER(ProviderId, EnableCallback, CallbackContext, RegHandle);
601     }
602 
603     return Error;
604 }
605 #pragma warning(pop)
606 
607 // This macro is for use by MC-generated code and should not be used directly.
608 #define McGenEventUnregister _mcgen_PASTE2(McGenEventUnregister_, MCGEN_EVENTUNREGISTER)
609 
610 // This function is for use by MC-generated code and should not be used directly.
611 DECLSPEC_NOINLINE __inline
612 ULONG __stdcall
McGenEventUnregister(_Inout_ PREGHANDLE RegHandle)613 McGenEventUnregister(_Inout_ PREGHANDLE RegHandle)
614 /*++
615 
616 Routine Description:
617 
618     Unregister from ETW and set *RegHandle = 0.
619 
620 Arguments:
621 
622     RegHandle - the pointer to the provider registration handle
623 
624 Remarks:
625 
626     If provider has not been registered (i.e. if *RegHandle == 0),
627     return SUCCESS. It is safe to call McGenEventUnregister even if the
628     call to McGenEventRegister returned an error.
629 
630 --*/
631 {
632     ULONG Error;
633 
634     if(*RegHandle == 0)
635     {
636         Error = 0; // ERROR_SUCCESS
637     }
638     else
639     {
640         Error = MCGEN_EVENTUNREGISTER(*RegHandle);
641         *RegHandle = (REGHANDLE)0;
642     }
643 
644     return Error;
645 }
646 
647 #endif // McGenEventRegisterUnregister
648 
649 #ifndef _mcgen_EVENT_BIT_SET
650   #if defined(_M_IX86) || defined(_M_X64)
651     // This macro is for use by MC-generated code and should not be used directly.
652     #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((((const unsigned char*)EnableBits)[BitPosition >> 3] & (1u << (BitPosition & 7))) != 0)
653   #else // CPU type
654     // This macro is for use by MC-generated code and should not be used directly.
655     #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((EnableBits[BitPosition >> 5] & (1u << (BitPosition & 31))) != 0)
656   #endif // CPU type
657 #endif // _mcgen_EVENT_BIT_SET
658 
659 #endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION
660 
661 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
662 // Provider "microsoft-windows-mimalloc" event count 2
663 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
664 
665 // Provider GUID = 138f4dbb-ee04-4899-aa0a-572ad4475779
666 EXTERN_C __declspec(selectany) const GUID ETW_MI_Provider = {0x138f4dbb, 0xee04, 0x4899, {0xaa, 0x0a, 0x57, 0x2a, 0xd4, 0x47, 0x57, 0x79}};
667 
668 #ifndef ETW_MI_Provider_Traits
669 #define ETW_MI_Provider_Traits NULL
670 #endif // ETW_MI_Provider_Traits
671 
672 //
673 // Event Descriptors
674 //
675 EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_ALLOC = {0x64, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0};
676 #define ETW_MI_ALLOC_value 0x64
677 EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_FREE = {0x65, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0};
678 #define ETW_MI_FREE_value 0x65
679 
680 //
681 // MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:
682 // Define this macro to have the compiler skip the generated functions in this
683 // header.
684 //
685 #ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION
686 
687 //
688 // Event Enablement Bits
689 // These variables are for use by MC-generated code and should not be used directly.
690 //
691 EXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG microsoft_windows_mimallocEnableBits[1];
692 EXTERN_C __declspec(selectany) const ULONGLONG microsoft_windows_mimallocKeywords[1] = {0x0};
693 EXTERN_C __declspec(selectany) const unsigned char microsoft_windows_mimallocLevels[1] = {4};
694 
695 //
696 // Provider context
697 //
698 EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT ETW_MI_Provider_Context = {0, (ULONG_PTR)ETW_MI_Provider_Traits, 0, 0, 0, 0, 0, 0, 1, microsoft_windows_mimallocEnableBits, microsoft_windows_mimallocKeywords, microsoft_windows_mimallocLevels};
699 
700 //
701 // Provider REGHANDLE
702 //
703 #define microsoft_windows_mimallocHandle (ETW_MI_Provider_Context.RegistrationHandle)
704 
705 //
706 // This macro is set to 0, indicating that the EventWrite[Name] macros do not
707 // have an Activity parameter. This is controlled by the -km and -um options.
708 //
709 #define ETW_MI_Provider_EventWriteActivity 0
710 
711 //
712 // Register with ETW using the control GUID specified in the manifest.
713 // Invoke this macro during module initialization (i.e. program startup,
714 // DLL process attach, or driver load) to initialize the provider.
715 // Note that if this function returns an error, the error means that
716 // will not work, but no action needs to be taken -- even if EventRegister
717 // returns an error, it is generally safe to use EventWrite and
718 // EventUnregister macros (they will be no-ops if EventRegister failed).
719 //
720 #ifndef EventRegistermicrosoft_windows_mimalloc
721 #define EventRegistermicrosoft_windows_mimalloc() McGenEventRegister(&ETW_MI_Provider, McGenControlCallbackV2, &ETW_MI_Provider_Context, &microsoft_windows_mimallocHandle)
722 #endif
723 
724 //
725 // Register with ETW using a specific control GUID (i.e. a GUID other than what
726 // is specified in the manifest). Advanced scenarios only.
727 //
728 #ifndef EventRegisterByGuidmicrosoft_windows_mimalloc
729 #define EventRegisterByGuidmicrosoft_windows_mimalloc(Guid) McGenEventRegister(&(Guid), McGenControlCallbackV2, &ETW_MI_Provider_Context, &microsoft_windows_mimallocHandle)
730 #endif
731 
732 //
733 // Unregister with ETW and close the provider.
734 // Invoke this macro during module shutdown (i.e. program exit, DLL process
735 // detach, or driver unload) to unregister the provider.
736 // Note that you MUST call EventUnregister before DLL or driver unload
737 // (not optional): failure to unregister a provider before DLL or driver unload
738 // will result in crashes.
739 //
740 #ifndef EventUnregistermicrosoft_windows_mimalloc
741 #define EventUnregistermicrosoft_windows_mimalloc() McGenEventUnregister(&microsoft_windows_mimallocHandle)
742 #endif
743 
744 //
745 // MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION macro:
746 // Define this macro to enable support for caller-allocated provider context.
747 //
748 #ifdef MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION
749 
750 //
751 // Advanced scenarios: Caller-allocated provider context.
752 // Use when multiple differently-configured provider handles are needed,
753 // e.g. for container-aware drivers, one context per container.
754 //
755 // Usage:
756 //
757 // - Caller enables the feature before including this header, e.g.
758 //   #define MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION 1
759 // - Caller allocates memory, e.g. pContext = malloc(sizeof(McGenContext_microsoft_windows_mimalloc));
760 // - Caller registers the provider, e.g. EventRegistermicrosoft_windows_mimalloc_ForContext(pContext);
761 // - Caller writes events, e.g. EventWriteMyEvent_ForContext(pContext, ...);
762 // - Caller unregisters, e.g. EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext);
763 // - Caller frees memory, e.g. free(pContext);
764 //
765 
766 typedef struct tagMcGenContext_microsoft_windows_mimalloc {
767     // The fields of this structure are subject to change and should
768     // not be accessed directly. To access the provider's REGHANDLE,
769     // use microsoft_windows_mimallocHandle_ForContext(pContext).
770     MCGEN_TRACE_CONTEXT Context;
771     ULONG EnableBits[1];
772 } McGenContext_microsoft_windows_mimalloc;
773 
774 #define EventRegistermicrosoft_windows_mimalloc_ForContext(pContext)             _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&ETW_MI_Provider, pContext)
775 #define EventRegisterByGuidmicrosoft_windows_mimalloc_ForContext(Guid, pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&(Guid), pContext)
776 #define EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext)           McGenEventUnregister(&(pContext)->Context.RegistrationHandle)
777 
778 //
779 // Provider REGHANDLE for caller-allocated context.
780 //
781 #define microsoft_windows_mimallocHandle_ForContext(pContext) ((pContext)->Context.RegistrationHandle)
782 
783 // This function is for use by MC-generated code and should not be used directly.
784 // Initialize and register the caller-allocated context.
785 __inline
786 ULONG __stdcall
_mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_,MCGEN_EVENTREGISTER)787 _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(
788     _In_ LPCGUID pProviderId,
789     _Out_ McGenContext_microsoft_windows_mimalloc* pContext)
790 {
791     RtlZeroMemory(pContext, sizeof(*pContext));
792     pContext->Context.Logger = (ULONG_PTR)ETW_MI_Provider_Traits;
793     pContext->Context.EnableBitsCount = 1;
794     pContext->Context.EnableBitMask = pContext->EnableBits;
795     pContext->Context.EnableKeyWords = microsoft_windows_mimallocKeywords;
796     pContext->Context.EnableLevel = microsoft_windows_mimallocLevels;
797     return McGenEventRegister(
798         pProviderId,
799         McGenControlCallbackV2,
800         &pContext->Context,
801         &pContext->Context.RegistrationHandle);
802 }
803 
804 // This function is for use by MC-generated code and should not be used directly.
805 // Trigger a compile error if called with the wrong parameter type.
806 FORCEINLINE
807 _Ret_ McGenContext_microsoft_windows_mimalloc*
_mcgen_CheckContextType_microsoft_windows_mimalloc(_In_ McGenContext_microsoft_windows_mimalloc * pContext)808 _mcgen_CheckContextType_microsoft_windows_mimalloc(_In_ McGenContext_microsoft_windows_mimalloc* pContext)
809 {
810     return pContext;
811 }
812 
813 #endif // MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION
814 
815 //
816 // Enablement check macro for event "ETW_MI_ALLOC"
817 //
818 #define EventEnabledETW_MI_ALLOC() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0)
819 #define EventEnabledETW_MI_ALLOC_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0)
820 
821 //
822 // Event write macros for event "ETW_MI_ALLOC"
823 //
824 #define EventWriteETW_MI_ALLOC(Address, Size) \
825         MCGEN_EVENT_ENABLED(ETW_MI_ALLOC) \
826         ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size) : 0
827 #define EventWriteETW_MI_ALLOC_AssumeEnabled(Address, Size) \
828         _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size)
829 #define EventWriteETW_MI_ALLOC_ForContext(pContext, Address, Size) \
830         MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_ALLOC) \
831         ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&(pContext)->Context, &ETW_MI_ALLOC, Address, Size) : 0
832 #define EventWriteETW_MI_ALLOC_ForContextAssumeEnabled(pContext, Address, Size) \
833         _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_ALLOC, Address, Size)
834 
835 // This macro is for use by MC-generated code and should not be used directly.
836 #define _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)
837 
838 //
839 // Enablement check macro for event "ETW_MI_FREE"
840 //
841 #define EventEnabledETW_MI_FREE() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0)
842 #define EventEnabledETW_MI_FREE_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0)
843 
844 //
845 // Event write macros for event "ETW_MI_FREE"
846 //
847 #define EventWriteETW_MI_FREE(Address, Size) \
848         MCGEN_EVENT_ENABLED(ETW_MI_FREE) \
849         ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size) : 0
850 #define EventWriteETW_MI_FREE_AssumeEnabled(Address, Size) \
851         _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size)
852 #define EventWriteETW_MI_FREE_ForContext(pContext, Address, Size) \
853         MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_FREE) \
854         ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&(pContext)->Context, &ETW_MI_FREE, Address, Size) : 0
855 #define EventWriteETW_MI_FREE_ForContextAssumeEnabled(pContext, Address, Size) \
856         _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_FREE, Address, Size)
857 
858 // This macro is for use by MC-generated code and should not be used directly.
859 #define _mcgen_TEMPLATE_FOR_ETW_MI_FREE _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)
860 
861 #endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION
862 
863 //
864 // MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:
865 // Define this macro to have the compiler skip the generated functions in this
866 // header.
867 //
868 #ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION
869 
870 //
871 // Template Functions
872 //
873 
874 //
875 // Function for template "ETW_CUSTOM_HEAP_ALLOC_DATA" (and possibly others).
876 // This function is for use by MC-generated code and should not be used directly.
877 //
878 #ifndef McTemplateU0xx_def
879 #define McTemplateU0xx_def
880 ETW_INLINE
881 ULONG
_mcgen_PASTE2(McTemplateU0xx_,MCGEN_EVENTWRITETRANSFER)882 _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)(
883     _In_ PMCGEN_TRACE_CONTEXT Context,
884     _In_ PCEVENT_DESCRIPTOR Descriptor,
885     _In_ const unsigned __int64  _Arg0,
886     _In_ const unsigned __int64  _Arg1
887     )
888 {
889 #define McTemplateU0xx_ARGCOUNT 2
890 
891     EVENT_DATA_DESCRIPTOR EventData[McTemplateU0xx_ARGCOUNT + 1];
892 
893     EventDataDescCreate(&EventData[1],&_Arg0, sizeof(const unsigned __int64)  );
894 
895     EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned __int64)  );
896 
897     return McGenEventWrite(Context, Descriptor, NULL, McTemplateU0xx_ARGCOUNT + 1, EventData);
898 }
899 #endif // McTemplateU0xx_def
900 
901 #endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION
902 
903 #if defined(__cplusplus)
904 }
905 #endif
906