WinStd Additional templates and function helpers for Microsoft Windows using Standard C++ classes

ETW.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 Amebis
4 Copyright © 2016 GÉANT
5*/
6
7#pragma once
8
9#include "Common.h"
10#include <assert.h>
11#include <evntprov.h>
12#include <evntcons.h>
13#include <stdarg.h>
14#include <tdh.h>
15#include <memory>
16#include <string>
17#include <vector>
18
19#pragma warning(push)
20#pragma warning(disable: 4505) // Don't warn on unused code
21
27
33 template<class _Ty, class _Ax>
34 static _Success_(return == ERROR_SUCCESS) ULONG TdhGetProperty(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_reads_opt_(TdhContextCount) PTDH_CONTEXT pTdhContext, _In_ ULONG PropertyDataCount, _In_reads_(PropertyDataCount) PPROPERTY_DATA_DESCRIPTOR pPropertyData, _Inout_ std::vector<_Ty, _Ax> &aData)
35{
36 ULONG ulSize, ulResult;
37
38 // Query property size.
39 ulResult = TdhGetPropertySize(pEvent, TdhContextCount, pTdhContext, PropertyDataCount, pPropertyData, &ulSize);
40 if (ulResult == ERROR_SUCCESS) {
41 if (ulSize) {
42 // Query property value.
43 aData.resize((ulSize + sizeof(_Ty) - 1) / sizeof(_Ty));
44 ulResult = TdhGetProperty(pEvent, TdhContextCount, pTdhContext, PropertyDataCount, pPropertyData, ulSize, reinterpret_cast<LPBYTE>(aData.data()));
45 } else {
46 // Property value size is zero.
47 aData.clear();
48 }
49 }
50
51 return ulResult;
52}
53
59 static _Success_(return == ERROR_SUCCESS) ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_reads_opt_(TdhContextCount) PTDH_CONTEXT pTdhContext, _Out_ std::unique_ptr<TRACE_EVENT_INFO> &info)
60{
61 BYTE szBuffer[WINSTD_STACK_BUFFER_BYTES];
62 ULONG ulSize = sizeof(szBuffer), ulResult;
63
64 // Try with stack buffer first.
65 ulResult = TdhGetEventInformation(pEvent, TdhContextCount, pTdhContext, (PTRACE_EVENT_INFO)szBuffer, &ulSize);
66 if (ulResult == ERROR_SUCCESS) {
67 // Copy from stack.
68 info.reset(reinterpret_cast<PTRACE_EVENT_INFO>(new char[ulSize]));
69 memcpy(info.get(), szBuffer, ulSize);
70 return ERROR_SUCCESS;
71 } else if (ulResult == ERROR_INSUFFICIENT_BUFFER) {
72 // Create buffer on heap and retry.
73 info.reset(reinterpret_cast<PTRACE_EVENT_INFO>(new char[ulSize]));
74 return TdhGetEventInformation(pEvent, TdhContextCount, pTdhContext, info.get(), &ulSize);
75 }
76
77 return ulResult;
78}
79
85 static _Success_(return == ERROR_SUCCESS) ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pMapName, _Inout_ std::unique_ptr<EVENT_MAP_INFO> &info)
86{
87 BYTE szBuffer[WINSTD_STACK_BUFFER_BYTES];
88 ULONG ulSize = sizeof(szBuffer), ulResult;
89
90 // Try with stack buffer first.
91 ulResult = TdhGetEventMapInformation(pEvent, pMapName, (PEVENT_MAP_INFO)szBuffer, &ulSize);
92 if (ulResult == ERROR_SUCCESS) {
93 // Copy from stack.
94 info.reset(reinterpret_cast<PEVENT_MAP_INFO>(new char[ulSize]));
95 memcpy(info.get(), szBuffer, ulSize);
96 return ERROR_SUCCESS;
97 } else if (ulResult == ERROR_INSUFFICIENT_BUFFER) {
98 // Create buffer on heap and retry.
99 info.reset(reinterpret_cast<PEVENT_MAP_INFO>(new char[ulSize]));
100 return TdhGetEventMapInformation(pEvent, pMapName, info.get(), &ulSize);
101 }
102
103 return ulResult;
104}
105
107
108#pragma warning(pop)
109
110 namespace winstd
111{
114
118 class event_data : public EVENT_DATA_DESCRIPTOR
119 {
120 public:
124 event_data()
125 {
126 Ptr = 0;
127 Size = 0;
128 Reserved = (ULONG)-1; // Used for varadic argument terminator.
129 }
130
138 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
139 event_data(_In_ const char &data)
140 {
141 EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
142 }
143
151 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
152 event_data(_In_ const unsigned char &data)
153 {
154 EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
155 }
156
164 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
165 event_data(_In_ const int &data)
166 {
167 EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
168 }
169
177 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
178 event_data(_In_ const unsigned int &data)
179 {
180 EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
181 }
182
190 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
191 event_data(_In_ const long &data)
192 {
193 EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
194 }
195
203 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
204 event_data(_In_ const unsigned long &data)
205 {
206 EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
207 }
208
216 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
217 event_data(_In_ const GUID &data)
218 {
219 EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
220 }
221
229 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
230 event_data(_In_opt_z_ const char *data)
231 {
232 if (data)
233 EventDataDescCreate(this, data, (ULONG)((strlen(data) + 1) * sizeof(*data)));
234 else {
235 // Writing NULL pointer with 0B length causes trouble in Event Viewer: message template string is displayed only, parameters are not rendered.
236 static const char null[] = "(null)";
237 EventDataDescCreate(this, null, sizeof(null));
238 }
239 }
240
248 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
249 event_data(_In_opt_z_ const wchar_t *data)
250 {
251 if (data)
252 EventDataDescCreate(this, data, (ULONG)((wcslen(data) + 1) * sizeof(*data)));
253 else {
254 // Writing NULL pointer with 0B length causes trouble in Event Viewer: message template string is displayed only, parameters are not rendered.
255 static const wchar_t null[] = L"(null)";
256 EventDataDescCreate(this, null, sizeof(null));
257 }
258 }
259
267 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
268 template<class _Elem, class _Traits, class _Ax>
269 event_data(_In_ const std::basic_string<_Elem, _Traits, _Ax> &data)
270 {
271 EventDataDescCreate(this, data.c_str(), (ULONG)((data.length() + 1) * sizeof(_Elem)));
272 }
273
282 #pragma warning(suppress: 26495) // EventDataDescCreate() initializes all members of EVENT_DATA_DESCRIPTOR
283 event_data(_In_bytecount_(size) const void *data, _In_ ULONG size)
284 {
285 EventDataDescCreate(this, data, size);
286 }
287 };
288
292 static const event_data blank_event_data;
293
297 class event_rec : public EVENT_RECORD
298 {
299 public:
303 event_rec()
304 {
305 memset((EVENT_RECORD*)this, 0, sizeof(EVENT_RECORD));
306 }
307
313 event_rec(_In_ const event_rec &other) : EVENT_RECORD(other)
314 {
315 set_extended_data_internal(other.ExtendedDataCount, other.ExtendedData);
316 set_user_data_internal(other.UserDataLength, other.UserData);
317 }
318
324 event_rec(_In_ const EVENT_RECORD &other) : EVENT_RECORD(other)
325 {
326 set_extended_data_internal(other.ExtendedDataCount, other.ExtendedData);
327 set_user_data_internal(other.UserDataLength, other.UserData);
328 }
329
335 event_rec(_Inout_ event_rec&& other) noexcept : EVENT_RECORD(other)
336 {
337 memset((EVENT_RECORD*)&other, 0, sizeof(EVENT_RECORD));
338 }
339
343 ~event_rec()
344 {
345 if (ExtendedData)
346 delete reinterpret_cast<unsigned char*>(ExtendedData);
347
348 if (UserData)
349 delete reinterpret_cast<unsigned char*>(UserData);
350 }
351
357 event_rec& operator=(_In_ const event_rec &other)
358 {
359 if (this != std::addressof(other)) {
360 (EVENT_RECORD&)*this = other;
361 set_extended_data_internal(other.ExtendedDataCount, other.ExtendedData);
362 set_user_data_internal(other.UserDataLength, other.UserData);
363 }
364
365 return *this;
366 }
367
373 event_rec& operator=(_In_ const EVENT_RECORD &other)
374 {
375 if (this != std::addressof(other)) {
376 (EVENT_RECORD&)*this = other;
377 set_extended_data_internal(other.ExtendedDataCount, other.ExtendedData);
378 set_user_data_internal(other.UserDataLength, other.UserData);
379 }
380
381 return *this;
382 }
383
389 event_rec& operator=(_Inout_ event_rec&& other) noexcept
390 {
391 if (this != std::addressof(other)) {
392 (EVENT_RECORD&)*this = other;
393 memset((EVENT_RECORD*)&other, 0, sizeof(EVENT_RECORD));
394 }
395
396 return *this;
397 }
398
405 void set_extended_data(_In_ USHORT count, _In_count_(count) const EVENT_HEADER_EXTENDED_DATA_ITEM *data)
406 {
407 if (ExtendedData)
408 delete reinterpret_cast<unsigned char*>(ExtendedData);
409
410 set_extended_data_internal(count, data);
411 }
412
419 void set_user_data(_In_ USHORT size, _In_bytecount_(size) LPCVOID data)
420 {
421 if (UserData)
422 delete reinterpret_cast<unsigned char*>(UserData);
423
424 set_user_data_internal(size, data);
425 }
426
427 protected:
434 void set_extended_data_internal(_In_ USHORT count, _In_count_(count) const EVENT_HEADER_EXTENDED_DATA_ITEM *data)
435 {
436 if (count) {
437 assert(data);
438
439 // Count the total required memory.
440 size_t data_size = 0;
441 for (size_t i = 0; i < count; i++)
442 data_size += data[i].DataSize;
443
444 // Allocate memory for extended data.
445 ExtendedData = reinterpret_cast<EVENT_HEADER_EXTENDED_DATA_ITEM*>(new unsigned char[sizeof(EVENT_HEADER_EXTENDED_DATA_ITEM)*count + data_size]);
446
447 // Bulk-copy extended data descriptors.
448 memcpy(ExtendedData, data, sizeof(EVENT_HEADER_EXTENDED_DATA_ITEM) * count);
449
450 // Copy the data.
451 unsigned char *ptr = reinterpret_cast<unsigned char*>(ExtendedData + count);
452 for (size_t i = 0; i < count; i++) {
453 if (data[i].DataSize) {
454 memcpy(ptr, (void*)(data[i].DataPtr), data[i].DataSize);
455 ExtendedData[i].DataPtr = (ULONGLONG)ptr;
456 ptr += data[i].DataSize;
457 } else
458 ExtendedData[i].DataPtr = NULL;
459 }
460 } else
461 ExtendedData = NULL;
462
463 ExtendedDataCount = count;
464 }
465
472 void set_user_data_internal(_In_ USHORT size, _In_bytecount_(size) LPCVOID data)
473 {
474 if (size) {
475 assert(data);
476
477 // Allocate memory for user data.
478 UserData = new unsigned char[size];
479
480 // Copy user data.
481 memcpy(UserData, data, size);
482 } else
483 UserData = NULL;
484
485 UserDataLength = size;
486 }
487 };
488
492 class event_provider : public handle<REGHANDLE, NULL>
493 {
494 WINSTD_HANDLE_IMPL(event_provider, NULL)
495
496 public:
502 virtual ~event_provider()
503 {
504 if (m_h != invalid)
505 free_internal();
506 }
507
517 ULONG create(_In_ LPCGUID ProviderId)
518 {
519 handle_type h;
520 ULONG ulRes = EventRegister(ProviderId, enable_callback, this, &h);
521 if (ulRes == ERROR_SUCCESS)
522 attach(h);
523 return ulRes;
524 }
525
535 ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor)
536 {
537 assert(m_h != invalid);
538 return EventWrite(m_h, EventDescriptor, 0, NULL);
539 }
540
550 ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ ULONG UserDataCount = 0, _In_opt_count_(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData = NULL)
551 {
552 assert(m_h != invalid);
553 return EventWrite(m_h, EventDescriptor, UserDataCount, UserData);
554 }
555
567 ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ const EVENT_DATA_DESCRIPTOR param1, ...)
568 {
569 assert(m_h != invalid);
570
571 // The first argument (param1) is outside of varadic argument list.
572 if (param1.Ptr == winstd::blank_event_data.Ptr &&
573 param1.Size == winstd::blank_event_data.Size &&
574 param1.Reserved == winstd::blank_event_data.Reserved)
575 return EventWrite(m_h, EventDescriptor, 0, NULL);
576
577 va_list arg;
578 va_start(arg, param1);
579 va_list arg_start = arg;
580 std::vector<EVENT_DATA_DESCRIPTOR> params;
581 ULONG param_count;
582
583 // Preallocate array.
584 for (param_count = 1; param_count < MAX_EVENT_DATA_DESCRIPTORS; param_count++) {
585 const EVENT_DATA_DESCRIPTOR &p = va_arg(arg, const EVENT_DATA_DESCRIPTOR);
586 if (p.Ptr == winstd::blank_event_data.Ptr &&
587 p.Size == winstd::blank_event_data.Size &&
588 p.Reserved == winstd::blank_event_data.Reserved) break;
589 }
590 params.reserve(param_count);
591
592 // Copy parameters to array.
593 arg = arg_start;
594 params.push_back(param1);
595 for (;;) {
596 const EVENT_DATA_DESCRIPTOR &p = va_arg(arg, const EVENT_DATA_DESCRIPTOR);
597 if (p.Ptr == winstd::blank_event_data.Ptr &&
598 p.Size == winstd::blank_event_data.Size &&
599 p.Reserved == winstd::blank_event_data.Reserved) break;
600 params.push_back(p);
601 }
602
603 va_end(arg);
604#pragma warning(push)
605#pragma warning(disable: 28020)
606 return EventWrite(m_h, EventDescriptor, param_count, params.data());
607#pragma warning(pop)
608 }
609
621 ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ va_list arg)
622 {
623 assert(m_h != invalid);
624
625 va_list arg_start = arg;
626 std::vector<EVENT_DATA_DESCRIPTOR> params;
627 ULONG param_count;
628
629 // Preallocate array.
630 for (param_count = 0; param_count < MAX_EVENT_DATA_DESCRIPTORS; param_count++) {
631 const EVENT_DATA_DESCRIPTOR &p = va_arg(arg, const EVENT_DATA_DESCRIPTOR);
632 if (p.Ptr == winstd::blank_event_data.Ptr &&
633 p.Size == winstd::blank_event_data.Size &&
634 p.Reserved == winstd::blank_event_data.Reserved) break;
635 }
636 params.reserve(param_count);
637
638 // Copy parameters to array.
639 arg = arg_start;
640 for (;;) {
641 const EVENT_DATA_DESCRIPTOR &p = va_arg(arg, const EVENT_DATA_DESCRIPTOR);
642 if (p.Ptr == winstd::blank_event_data.Ptr &&
643 p.Size == winstd::blank_event_data.Size &&
644 p.Reserved == winstd::blank_event_data.Reserved) break;
645 params.push_back(p);
646 }
647
648#pragma warning(push)
649#pragma warning(disable: 28020)
650 return EventWrite(m_h, EventDescriptor, param_count, params.data());
651#pragma warning(pop)
652 }
653
663 ULONG write(_In_ UCHAR Level, _In_ ULONGLONG Keyword, _In_z_ _Printf_format_string_ PCWSTR String, ...)
664 {
665 assert(m_h != invalid);
666
667 std::wstring msg;
668 va_list arg;
669
670 // Format message.
671 va_start(arg, String);
672 vsprintf(msg, String, arg);
673 va_end(arg);
674
675 // Write string event.
676 return EventWriteString(m_h, Level, Keyword, msg.c_str());
677 }
678
679 protected:
685 void free_internal() noexcept override
686 {
687 EventUnregister(m_h);
688 }
689
695 virtual void enable_callback(_In_ LPCGUID SourceId, _In_ ULONG IsEnabled, _In_ UCHAR Level, _In_ ULONGLONG MatchAnyKeyword, _In_ ULONGLONG MatchAllKeyword, _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData)
696 {
697 UNREFERENCED_PARAMETER(SourceId);
698 UNREFERENCED_PARAMETER(IsEnabled);
699 UNREFERENCED_PARAMETER(Level);
700 UNREFERENCED_PARAMETER(MatchAnyKeyword);
701 UNREFERENCED_PARAMETER(MatchAllKeyword);
702 UNREFERENCED_PARAMETER(FilterData);
703 }
704
710 static VOID NTAPI enable_callback(_In_ LPCGUID SourceId, _In_ ULONG IsEnabled, _In_ UCHAR Level, _In_ ULONGLONG MatchAnyKeyword, _In_ ULONGLONG MatchAllKeyword, _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, _Inout_opt_ PVOID CallbackContext)
711 {
712 if (CallbackContext)
713 static_cast<event_provider*>(CallbackContext)->enable_callback(SourceId, IsEnabled, Level, MatchAnyKeyword, MatchAllKeyword, FilterData);
714 else
715 assert(0); // Where did the "this" pointer get lost?
716 }
717 };
718
722 class event_session : public handle<TRACEHANDLE, 0>
723 {
724 WINSTD_NONCOPYABLE(event_session)
725
726 public:
730 event_session()
731 {
732 }
733
740 event_session(_In_opt_ handle_type h, _In_ const EVENT_TRACE_PROPERTIES *prop) :
741 m_prop(reinterpret_cast<EVENT_TRACE_PROPERTIES*>(new char[prop->Wnode.BufferSize])),
742 handle(h)
743 {
744 memcpy(m_prop.get(), prop, prop->Wnode.BufferSize);
745 }
746
752 event_session(_Inout_ event_session &&other) noexcept :
753 m_prop(std::move(other.m_prop)),
754 handle(std::move(other))
755 {
756 }
757
763 virtual ~event_session()
764 {
765 if (m_h != invalid)
766 free_internal();
767 }
768
774 event_session& operator=(_Inout_ event_session &&other) noexcept
775 {
776 if (this != std::addressof(other)) {
777 (handle<handle_type, 0>&&)*this = std::move(other);
778 m_prop = std::move(other.m_prop);
779 }
780 return *this;
781 }
782
788 operator const EVENT_TRACE_PROPERTIES*() const
789 {
790 return m_prop.get();
791 }
792
798 LPCTSTR name() const
799 {
800 const EVENT_TRACE_PROPERTIES *prop = m_prop.get();
801 return reinterpret_cast<LPCTSTR>(reinterpret_cast<const char*>(prop) + prop->LoggerNameOffset);
802 }
803
812 void attach(_In_opt_ handle_type h, _In_ EVENT_TRACE_PROPERTIES *prop)
813 {
814 handle<handle_type, 0>::attach(h);
815 m_prop.reset(prop);
816 }
817
827 ULONG create(_In_z_ LPCTSTR SessionName, _In_ const EVENT_TRACE_PROPERTIES *Properties)
828 {
829 handle_type h;
830 std::unique_ptr<EVENT_TRACE_PROPERTIES> prop(reinterpret_cast<EVENT_TRACE_PROPERTIES*>(new char[Properties->Wnode.BufferSize]));
831 memcpy(prop.get(), Properties, Properties->Wnode.BufferSize);
832 ULONG ulRes = StartTrace(&h, SessionName, prop.get());
833 if (ulRes == ERROR_SUCCESS)
834 attach(h, prop.release());
835 return ulRes;
836 }
837
847 ULONG enable_trace(_In_ LPCGUID ProviderId, _In_ UCHAR Level, _In_opt_ ULONGLONG MatchAnyKeyword = 0, _In_opt_ ULONGLONG MatchAllKeyword = 0, _In_opt_ ULONG EnableProperty = 0, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc = NULL)
848 {
849 assert(m_h != invalid);
850 return EnableTraceEx(
851 ProviderId,
852 &m_prop->Wnode.Guid,
853 m_h,
854 EVENT_CONTROL_CODE_ENABLE_PROVIDER,
855 Level,
856 MatchAnyKeyword,
857 MatchAllKeyword,
858 EnableProperty,
859 EnableFilterDesc);
860 }
861
871 ULONG disable_trace(_In_ LPCGUID ProviderId, _In_ UCHAR Level, _In_opt_ ULONGLONG MatchAnyKeyword = 0, _In_opt_ ULONGLONG MatchAllKeyword = 0, _In_opt_ ULONG EnableProperty = 0, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc = NULL)
872 {
873 assert(m_h != invalid);
874 return EnableTraceEx(
875 ProviderId,
876 &m_prop->Wnode.Guid,
877 m_h,
878 EVENT_CONTROL_CODE_DISABLE_PROVIDER,
879 Level,
880 MatchAnyKeyword,
881 MatchAllKeyword,
882 EnableProperty,
883 EnableFilterDesc);
884 }
885
886 protected:
892 void free_internal() noexcept override
893 {
894 ControlTrace(m_h, name(), m_prop.get(), EVENT_TRACE_CONTROL_STOP);
895 }
896
897 protected:
898 std::unique_ptr<EVENT_TRACE_PROPERTIES> m_prop;
899 };
900
904 class event_trace : public handle<TRACEHANDLE, INVALID_PROCESSTRACE_HANDLE>
905 {
906 WINSTD_HANDLE_IMPL(event_trace, INVALID_PROCESSTRACE_HANDLE)
907
908 public:
914 virtual ~event_trace()
915 {
916 if (m_h != invalid)
917 free_internal();
918 }
919
929 bool create(_Inout_ PEVENT_TRACE_LOGFILE Logfile)
930 {
931 handle_type h = OpenTrace(Logfile);
932 if (h != invalid) {
933 attach(h);
934 return true;
935 } else
936 return false;
937 }
938
939 protected:
945 void free_internal() noexcept override
946 {
947 CloseTrace(m_h);
948 }
949 };
950
954 class event_trace_enabler
955 {
956 public:
962 event_trace_enabler(
963 _In_opt_ LPCGUID SourceId,
964 _In_ TRACEHANDLE TraceHandle,
965 _In_ LPCGUID ProviderId,
966 _In_ UCHAR Level,
967 _In_opt_ ULONGLONG MatchAnyKeyword = 0,
968 _In_opt_ ULONGLONG MatchAllKeyword = 0,
969 _In_opt_ ULONG EnableProperty = 0,
970 _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc = NULL) :
971 m_provider_id(ProviderId),
972 m_source_id(SourceId),
973 m_trace_handle(TraceHandle),
974 m_level(Level),
975 m_match_any_keyword(MatchAnyKeyword),
976 m_match_all_keyword(MatchAllKeyword),
977 m_enable_property(EnableProperty),
978 m_enable_filter_desc(EnableFilterDesc)
979 {
980 m_status = EnableTraceEx(
981 m_provider_id,
982 m_source_id,
983 m_trace_handle,
984 EVENT_CONTROL_CODE_ENABLE_PROVIDER,
985 m_level,
986 m_match_any_keyword,
987 m_match_all_keyword,
988 m_enable_property,
989 m_enable_filter_desc);
990 }
991
997 event_trace_enabler(
998 _In_ const event_session &session,
999 _In_ LPCGUID ProviderId,
1000 _In_ UCHAR Level,
1001 _In_opt_ ULONGLONG MatchAnyKeyword = 0,
1002 _In_opt_ ULONGLONG MatchAllKeyword = 0,
1003 _In_opt_ ULONG EnableProperty = 0,
1004 _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc = NULL) :
1005 m_provider_id(ProviderId),
1006 m_source_id(&((const EVENT_TRACE_PROPERTIES*)session)->Wnode.Guid),
1007 m_trace_handle(session),
1008 m_level(Level),
1009 m_match_any_keyword(MatchAnyKeyword),
1010 m_match_all_keyword(MatchAllKeyword),
1011 m_enable_property(EnableProperty),
1012 m_enable_filter_desc(EnableFilterDesc)
1013 {
1014 m_status = EnableTraceEx(
1015 m_provider_id,
1016 m_source_id,
1017 m_trace_handle,
1018 EVENT_CONTROL_CODE_ENABLE_PROVIDER,
1019 m_level,
1020 m_match_any_keyword,
1021 m_match_all_keyword,
1022 m_enable_property,
1023 m_enable_filter_desc);
1024 }
1025
1031 ULONG status() const
1032 {
1033 return m_status;
1034 }
1035
1041 virtual ~event_trace_enabler()
1042 {
1043 if (m_status == ERROR_SUCCESS)
1044 EnableTraceEx(
1045 m_provider_id,
1046 m_source_id,
1047 m_trace_handle,
1048 EVENT_CONTROL_CODE_DISABLE_PROVIDER,
1049 m_level,
1050 m_match_any_keyword,
1051 m_match_all_keyword,
1052 m_enable_property,
1053 m_enable_filter_desc);
1054 }
1055
1056 protected:
1057 ULONG m_status;
1058 LPCGUID m_provider_id;
1059 LPCGUID m_source_id;
1060 TRACEHANDLE m_trace_handle;
1061 UCHAR m_level;
1062 ULONGLONG m_match_any_keyword;
1063 ULONGLONG m_match_all_keyword;
1064 ULONG m_enable_property;
1065 PEVENT_FILTER_DESCRIPTOR m_enable_filter_desc;
1066 };
1067
1073 class event_fn_auto
1074 {
1075 public:
1079 event_fn_auto(_In_ event_provider &ep, _In_ const EVENT_DESCRIPTOR *event_cons, _In_ const EVENT_DESCRIPTOR *event_dest, _In_z_ LPCSTR pszFnName) :
1080 m_ep(ep),
1081 m_event_dest(event_dest)
1082 {
1083 EventDataDescCreate(&m_fn_name, pszFnName, (ULONG)(strlen(pszFnName) + 1)*sizeof(*pszFnName));
1084 m_ep.write(event_cons, 1, &m_fn_name);
1085 }
1086
1090 event_fn_auto(_In_ const event_fn_auto &other) :
1091 m_ep(other.m_ep),
1092 m_event_dest(other.m_event_dest),
1093 m_fn_name(other.m_fn_name)
1094 {
1095 }
1096
1100 event_fn_auto(_Inout_ event_fn_auto &&other) noexcept :
1101 m_ep(other.m_ep),
1102 m_event_dest(other.m_event_dest),
1103 m_fn_name(std::move(other.m_fn_name))
1104 {
1105 other.m_event_dest = NULL;
1106 }
1107
1111 ~event_fn_auto()
1112 {
1113 if (m_event_dest)
1114 m_ep.write(m_event_dest, 1, &m_fn_name);
1115 }
1116
1120 event_fn_auto& operator=(_In_ const event_fn_auto &other)
1121 {
1122 if (this != &other) {
1123 assert(&m_ep == &other.m_ep);
1124 m_event_dest = other.m_event_dest;
1125 m_fn_name = other.m_fn_name;
1126 }
1127
1128 return *this;
1129 }
1130
1134 event_fn_auto& operator=(_Inout_ event_fn_auto &&other) noexcept
1135 {
1136 if (this != &other) {
1137 assert(&m_ep == &other.m_ep);
1138 m_event_dest = other.m_event_dest;
1139 m_fn_name = std::move(other.m_fn_name);
1140 other.m_event_dest = NULL;
1141 }
1142
1143 return *this;
1144 }
1145
1146 protected:
1147 event_provider &m_ep;
1148 const EVENT_DESCRIPTOR *m_event_dest;
1149 EVENT_DATA_DESCRIPTOR m_fn_name;
1150 };
1151
1157 template<class T>
1158 class event_fn_auto_ret
1159 {
1160 public:
1164 event_fn_auto_ret(_In_ event_provider &ep, _In_ const EVENT_DESCRIPTOR *event_cons, _In_ const EVENT_DESCRIPTOR *event_dest, _In_z_ LPCSTR pszFnName, T &result) :
1165 m_ep(ep),
1166 m_event_dest(event_dest),
1167 m_result(result)
1168 {
1169 EventDataDescCreate(m_desc + 0, pszFnName, (ULONG)(strlen(pszFnName) + 1)*sizeof(*pszFnName));
1170 m_ep.write(event_cons, 1, m_desc);
1171 }
1172
1176 event_fn_auto_ret(_In_ const event_fn_auto_ret<T> &other) :
1177 m_ep(other.m_ep),
1178 m_event_dest(other.m_event_dest),
1179 m_result(other.m_result)
1180 {
1181 m_desc[0] = other.m_desc[0];
1182 }
1183
1187 event_fn_auto_ret(_Inout_ event_fn_auto_ret<T> &&other) :
1188 m_ep(other.m_ep),
1189 m_event_dest(other.m_event_dest),
1190 m_result(other.m_result)
1191 {
1192 m_desc[0] = std::move(other.m_desc[0]);
1193 other.m_event_dest = NULL;
1194 }
1195
1199 ~event_fn_auto_ret()
1200 {
1201 if (m_event_dest) {
1202 EventDataDescCreate(m_desc + 1, &m_result, sizeof(T));
1203 m_ep.write(m_event_dest, 2, m_desc);
1204 }
1205 }
1206
1210 event_fn_auto_ret& operator=(_In_ const event_fn_auto_ret<T> &other)
1211 {
1212 if (this != &other) {
1213 assert(&m_ep == &other.m_ep);
1214 m_event_dest = other.m_event_dest;
1215 m_desc[0] = other.m_desc[0];
1216 assert(&m_result == &other.m_result);
1217 }
1218
1219 return *this;
1220 }
1221
1225 event_fn_auto_ret& operator=(_Inout_ event_fn_auto_ret<T> &&other)
1226 {
1227 if (this != &other) {
1228 assert(&m_ep == &other.m_ep);
1229 m_event_dest = other.m_event_dest;
1230 m_desc[0] = std::move(other.m_desc[0]);
1231 assert(&m_result == &other.m_result);
1232 other.m_event_dest = NULL;
1233 }
1234
1235 return *this;
1236 }
1237
1238 protected:
1239 event_provider &m_ep;
1240 const EVENT_DESCRIPTOR *m_event_dest;
1241 EVENT_DATA_DESCRIPTOR m_desc[2];
1242 T &m_result;
1243 };
1244
1246}
winstd::event_data
EVENT_DATA_DESCRIPTOR wrapper.
Definition: ETW.h:119
winstd::event_data::event_data
event_data(_In_ const std::basic_string< _Elem, _Traits, _Ax > &data)
Template to construct pointing to a std::basic_string<>.
Definition: ETW.h:269
winstd::event_data::event_data
event_data(_In_ const GUID &data)
Construct class pointing to a GUID.
Definition: ETW.h:217
winstd::event_data::event_data
event_data(_In_ const unsigned long &data)
Construct class pointing to an unsigned long.
Definition: ETW.h:204
winstd::event_data::event_data
event_data(_In_opt_z_ const char *data)
Construct class pointing to a string.
Definition: ETW.h:230
winstd::event_data::event_data
event_data(_In_bytecount_(size) const void *data, _In_ ULONG size)
Construct class pointing to binary data.
Definition: ETW.h:283
winstd::event_data::event_data
event_data(_In_ const unsigned char &data)
Construct class pointing to an unsigned char.
Definition: ETW.h:152
winstd::event_data::event_data
event_data(_In_ const unsigned int &data)
Construct class pointing to an unsigned int.
Definition: ETW.h:178
winstd::event_data::event_data
event_data(_In_ const long &data)
Construct class pointing to a long.
Definition: ETW.h:191
winstd::event_data::event_data
event_data(_In_ const char &data)
Construct class pointing to an char.
Definition: ETW.h:139
winstd::event_data::event_data
event_data()
Construct empty class.
Definition: ETW.h:124
winstd::event_data::event_data
event_data(_In_opt_z_ const wchar_t *data)
Construct class pointing to a wide string.
Definition: ETW.h:249
winstd::event_data::event_data
event_data(_In_ const int &data)
Construct class pointing to an int.
Definition: ETW.h:165
winstd::event_fn_auto_ret
Helper template to write an event on entry/exit of scope with one parameter (typically result).
Definition: ETW.h:1159
winstd::event_fn_auto_ret::event_fn_auto_ret
event_fn_auto_ret(_Inout_ event_fn_auto_ret< T > &&other)
Moves the object.
Definition: ETW.h:1187
winstd::event_fn_auto_ret::~event_fn_auto_ret
~event_fn_auto_ret()
Writes the event_dest event.
Definition: ETW.h:1199
winstd::event_fn_auto_ret::operator=
event_fn_auto_ret & operator=(_In_ const event_fn_auto_ret< T > &other)
Copies the object.
Definition: ETW.h:1210
winstd::event_fn_auto_ret::m_desc
EVENT_DATA_DESCRIPTOR m_desc[2]
Function name and return value.
Definition: ETW.h:1241
winstd::event_fn_auto_ret::event_fn_auto_ret
event_fn_auto_ret(_In_ event_provider &ep, _In_ const EVENT_DESCRIPTOR *event_cons, _In_ const EVENT_DESCRIPTOR *event_dest, _In_z_ LPCSTR pszFnName, T &result)
Writes the event_cons event.
Definition: ETW.h:1164
winstd::event_fn_auto_ret::m_ep
event_provider & m_ep
Reference to event provider in use.
Definition: ETW.h:1239
winstd::event_fn_auto_ret::operator=
event_fn_auto_ret & operator=(_Inout_ event_fn_auto_ret< T > &&other)
Moves the object.
Definition: ETW.h:1225
winstd::event_fn_auto_ret::m_result
T & m_result
Function result.
Definition: ETW.h:1242
winstd::event_fn_auto_ret::m_event_dest
const EVENT_DESCRIPTOR * m_event_dest
Event descriptor at destruction.
Definition: ETW.h:1240
winstd::event_fn_auto_ret::event_fn_auto_ret
event_fn_auto_ret(_In_ const event_fn_auto_ret< T > &other)
Copies the object.
Definition: ETW.h:1176
winstd::event_fn_auto
Helper class to write an event on entry/exit of scope.
Definition: ETW.h:1074
winstd::event_fn_auto::m_event_dest
const EVENT_DESCRIPTOR * m_event_dest
Event descriptor at destruction.
Definition: ETW.h:1148
winstd::event_fn_auto::event_fn_auto
event_fn_auto(_In_ const event_fn_auto &other)
Copies the object.
Definition: ETW.h:1090
winstd::event_fn_auto::operator=
event_fn_auto & operator=(_Inout_ event_fn_auto &&other) noexcept
Moves the object.
Definition: ETW.h:1134
winstd::event_fn_auto::event_fn_auto
event_fn_auto(_In_ event_provider &ep, _In_ const EVENT_DESCRIPTOR *event_cons, _In_ const EVENT_DESCRIPTOR *event_dest, _In_z_ LPCSTR pszFnName)
Writes the event_cons event.
Definition: ETW.h:1079
winstd::event_fn_auto::operator=
event_fn_auto & operator=(_In_ const event_fn_auto &other)
Copies the object.
Definition: ETW.h:1120
winstd::event_fn_auto::~event_fn_auto
~event_fn_auto()
Writes the event_dest event.
Definition: ETW.h:1111
winstd::event_fn_auto::event_fn_auto
event_fn_auto(_Inout_ event_fn_auto &&other) noexcept
Moves the object.
Definition: ETW.h:1100
winstd::event_fn_auto::m_ep
event_provider & m_ep
Reference to event provider in use.
Definition: ETW.h:1147
winstd::event_fn_auto::m_fn_name
EVENT_DATA_DESCRIPTOR m_fn_name
Function name.
Definition: ETW.h:1149
winstd::event_provider
ETW event provider.
Definition: ETW.h:493
winstd::event_provider::enable_callback
virtual void enable_callback(_In_ LPCGUID SourceId, _In_ ULONG IsEnabled, _In_ UCHAR Level, _In_ ULONGLONG MatchAnyKeyword, _In_ ULONGLONG MatchAllKeyword, _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData)
Receive enable or disable notification requests.
Definition: ETW.h:695
winstd::event_provider::create
ULONG create(_In_ LPCGUID ProviderId)
Registers the event provider.
Definition: ETW.h:517
winstd::event_provider::write
ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ ULONG UserDataCount=0, _In_opt_count_(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData=NULL)
Writes an event with parameters stored in array.
Definition: ETW.h:550
winstd::event_provider::write
ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor)
Writes an event with no parameters.
Definition: ETW.h:535
winstd::event_provider::write
ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ const EVENT_DATA_DESCRIPTOR param1,...)
Writes an event with one or more parameter.
Definition: ETW.h:567
winstd::event_provider::~event_provider
virtual ~event_provider()
Closes the event provider.
Definition: ETW.h:502
winstd::event_provider::enable_callback
static VOID NTAPI enable_callback(_In_ LPCGUID SourceId, _In_ ULONG IsEnabled, _In_ UCHAR Level, _In_ ULONGLONG MatchAnyKeyword, _In_ ULONGLONG MatchAllKeyword, _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, _Inout_opt_ PVOID CallbackContext)
Receive enable or disable notification requests.
Definition: ETW.h:710
winstd::event_provider::write
ULONG write(_In_ UCHAR Level, _In_ ULONGLONG Keyword, _In_z_ _Printf_format_string_ PCWSTR String,...)
Writes a string event.
Definition: ETW.h:663
winstd::event_provider::free_internal
void free_internal() noexcept override
Releases the event provider.
Definition: ETW.h:685
winstd::event_provider::write
ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ va_list arg)
Writes an event with variable number of parameters.
Definition: ETW.h:621
winstd::event_rec
EVENT_RECORD wrapper.
Definition: ETW.h:298
winstd::event_rec::set_extended_data_internal
void set_extended_data_internal(_In_ USHORT count, _In_count_(count) const EVENT_HEADER_EXTENDED_DATA_ITEM *data)
Sets event record extended data.
Definition: ETW.h:434
winstd::event_rec::~event_rec
~event_rec()
Destroys event record data and frees the allocated memory.
Definition: ETW.h:343
winstd::event_rec::event_rec
event_rec(_Inout_ event_rec &&other) noexcept
Moves the event record.
Definition: ETW.h:335
winstd::event_rec::event_rec
event_rec(_In_ const EVENT_RECORD &other)
Copies an existing event record.
Definition: ETW.h:324
winstd::event_rec::set_user_data
void set_user_data(_In_ USHORT size, _In_bytecount_(size) LPCVOID data)
Sets event record user data.
Definition: ETW.h:419
winstd::event_rec::operator=
event_rec & operator=(_In_ const EVENT_RECORD &other)
Copies an existing event record.
Definition: ETW.h:373
winstd::event_rec::operator=
event_rec & operator=(_Inout_ event_rec &&other) noexcept
Moves the event record.
Definition: ETW.h:389
winstd::event_rec::set_user_data_internal
void set_user_data_internal(_In_ USHORT size, _In_bytecount_(size) LPCVOID data)
Sets event record user data.
Definition: ETW.h:472
winstd::event_rec::event_rec
event_rec(_In_ const event_rec &other)
Copies an existing event record.
Definition: ETW.h:313
winstd::event_rec::event_rec
event_rec()
Constructs a blank event record.
Definition: ETW.h:303
winstd::event_rec::set_extended_data
void set_extended_data(_In_ USHORT count, _In_count_(count) const EVENT_HEADER_EXTENDED_DATA_ITEM *data)
Sets event record extended data.
Definition: ETW.h:405
winstd::event_rec::operator=
event_rec & operator=(_In_ const event_rec &other)
Copies an existing event record.
Definition: ETW.h:357
winstd::event_session
ETW session.
Definition: ETW.h:723
winstd::event_session::name
LPCTSTR name() const
Auto-typecasting operator.
Definition: ETW.h:798
winstd::event_session::disable_trace
ULONG disable_trace(_In_ LPCGUID ProviderId, _In_ UCHAR Level, _In_opt_ ULONGLONG MatchAnyKeyword=0, _In_opt_ ULONGLONG MatchAllKeyword=0, _In_opt_ ULONG EnableProperty=0, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc=NULL)
Disables the specified event trace provider.
Definition: ETW.h:871
winstd::event_session::event_session
event_session()
Initializes a new empty session.
Definition: ETW.h:730
winstd::event_session::~event_session
virtual ~event_session()
Closes the session.
Definition: ETW.h:763
winstd::event_session::attach
void attach(_In_opt_ handle_type h, _In_ EVENT_TRACE_PROPERTIES *prop)
Sets a new session handle for the class.
Definition: ETW.h:812
winstd::event_session::free_internal
void free_internal() noexcept override
Releases the session.
Definition: ETW.h:892
winstd::event_session::create
ULONG create(_In_z_ LPCTSTR SessionName, _In_ const EVENT_TRACE_PROPERTIES *Properties)
Registers and starts an event tracing session.
Definition: ETW.h:827
winstd::event_session::event_session
event_session(_In_opt_ handle_type h, _In_ const EVENT_TRACE_PROPERTIES *prop)
Initializes a new session with an already available object handle.
Definition: ETW.h:740
winstd::event_session::event_session
event_session(_Inout_ event_session &&other) noexcept
Move constructor.
Definition: ETW.h:752
winstd::event_session::enable_trace
ULONG enable_trace(_In_ LPCGUID ProviderId, _In_ UCHAR Level, _In_opt_ ULONGLONG MatchAnyKeyword=0, _In_opt_ ULONGLONG MatchAllKeyword=0, _In_opt_ ULONG EnableProperty=0, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc=NULL)
Enables the specified event trace provider.
Definition: ETW.h:847
winstd::event_session::m_prop
std::unique_ptr< EVENT_TRACE_PROPERTIES > m_prop
Session properties.
Definition: ETW.h:898
winstd::event_session::operator=
event_session & operator=(_Inout_ event_session &&other) noexcept
Move assignment.
Definition: ETW.h:774
winstd::event_trace_enabler
Helper class to enable event provider in constructor and disables it in destructor.
Definition: ETW.h:955
winstd::event_trace_enabler::m_level
UCHAR m_level
Logging level.
Definition: ETW.h:1061
winstd::event_trace_enabler::event_trace_enabler
event_trace_enabler(_In_ const event_session &session, _In_ LPCGUID ProviderId, _In_ UCHAR Level, _In_opt_ ULONGLONG MatchAnyKeyword=0, _In_opt_ ULONGLONG MatchAllKeyword=0, _In_opt_ ULONG EnableProperty=0, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc=NULL)
Enables event trace.
Definition: ETW.h:997
winstd::event_trace_enabler::m_enable_filter_desc
PEVENT_FILTER_DESCRIPTOR m_enable_filter_desc
Event filter descriptor.
Definition: ETW.h:1065
winstd::event_trace_enabler::m_match_any_keyword
ULONGLONG m_match_any_keyword
Keyword match mask (any)
Definition: ETW.h:1062
winstd::event_trace_enabler::event_trace_enabler
event_trace_enabler(_In_opt_ LPCGUID SourceId, _In_ TRACEHANDLE TraceHandle, _In_ LPCGUID ProviderId, _In_ UCHAR Level, _In_opt_ ULONGLONG MatchAnyKeyword=0, _In_opt_ ULONGLONG MatchAllKeyword=0, _In_opt_ ULONG EnableProperty=0, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc=NULL)
Enables event trace.
Definition: ETW.h:962
winstd::event_trace_enabler::m_status
ULONG m_status
Result of EnableTraceEx call.
Definition: ETW.h:1057
winstd::event_trace_enabler::m_trace_handle
TRACEHANDLE m_trace_handle
Trace handle.
Definition: ETW.h:1060
winstd::event_trace_enabler::~event_trace_enabler
virtual ~event_trace_enabler()
Disables event trace.
Definition: ETW.h:1041
winstd::event_trace_enabler::status
ULONG status() const
Return result of EnableTraceEx() call.
Definition: ETW.h:1031
winstd::event_trace_enabler::m_match_all_keyword
ULONGLONG m_match_all_keyword
Keyword match mask (all)
Definition: ETW.h:1063
winstd::event_trace_enabler::m_provider_id
LPCGUID m_provider_id
Provider ID.
Definition: ETW.h:1058
winstd::event_trace_enabler::m_source_id
LPCGUID m_source_id
Session ID.
Definition: ETW.h:1059
winstd::event_trace_enabler::m_enable_property
ULONG m_enable_property
Enable property.
Definition: ETW.h:1064
winstd::event_trace
ETW trace.
Definition: ETW.h:905
winstd::event_trace::~event_trace
virtual ~event_trace()
Closes the trace.
Definition: ETW.h:914
winstd::event_trace::free_internal
void free_internal() noexcept override
Closes the trace.
Definition: ETW.h:945
winstd::event_trace::create
bool create(_Inout_ PEVENT_TRACE_LOGFILE Logfile)
Opens a real-time trace session or log file for consuming.
Definition: ETW.h:929
winstd::handle
Base abstract template class to support generic object handle keeping.
Definition: Common.h:580
winstd::handle< TRACEHANDLE, 0 >::handle
handle() noexcept
Initializes a new class instance with the object handle set to INVAL.
Definition: Common.h:595
winstd::handle< REGHANDLE, NULL >::handle_type
REGHANDLE handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:585
winstd::handle< REGHANDLE, NULL >::attach
void attach(_In_opt_ handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:794
winstd::handle< REGHANDLE, NULL >::m_h
handle_type m_h
Object handle.
Definition: Common.h:833
WINSTD_NONCOPYABLE
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition: Common.h:53
WINSTD_STACK_BUFFER_BYTES
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition: Common.h:80
WINSTD_HANDLE_IMPL
#define WINSTD_HANDLE_IMPL(C, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition: Common.h:138
winstd::handle< REGHANDLE, NULL >::invalid
static const REGHANDLE invalid
Invalid handle value.
Definition: Common.h:590