| 64 | } |
| 65 | |
| 66 | PropertyInfo GetPropertyInfo(TRACE_EVENT_INFO const& tei, EVENT_RECORD const& eventRecord, uint32_t index, uint32_t offset) |
| 67 | { |
| 68 | // We don't handle all flags yet, these are the ones we do: |
| 69 | auto const& epi = tei.EventPropertyInfoArray[index]; |
| 70 | assert((epi.Flags & ~(PropertyStruct | PropertyParamCount | PropertyParamFixedCount)) == 0); |
| 71 | |
| 72 | // Use the epi length and count by default. There are cases where the count |
| 73 | // is valid but (epi.Flags & PropertyParamFixedCount) == 0. |
| 74 | PropertyInfo info; |
| 75 | info.size_ = epi.length; |
| 76 | info.count_ = epi.count; |
| 77 | info.status_ = 0; |
| 78 | |
| 79 | if (epi.Flags & PropertyStruct) { |
| 80 | info.size_ = 0; |
| 81 | for (USHORT i = 0; i < epi.structType.NumOfStructMembers; ++i) { |
| 82 | auto memberInfo = GetPropertyInfo(tei, eventRecord, epi.structType.StructStartIndex + i, UINT32_MAX); |
| 83 | info.size_ += memberInfo.size_ * memberInfo.count_; |
| 84 | } |
| 85 | } else { |
| 86 | switch (epi.nonStructType.InType) { |
| 87 | case TDH_INTYPE_UNICODESTRING: |
| 88 | info.status_ |= PROP_STATUS_WCHAR_STRING; |
| 89 | GetStringPropertyInfo<wchar_t>(tei, eventRecord, index, offset, &info); |
| 90 | break; |
| 91 | case TDH_INTYPE_ANSISTRING: |
| 92 | info.status_ |= PROP_STATUS_CHAR_STRING; |
| 93 | GetStringPropertyInfo<char>(tei, eventRecord, index, offset, &info); |
| 94 | break; |
| 95 | |
| 96 | case TDH_INTYPE_POINTER: // TODO: Not sure this is needed, epi.length seems to be correct? |
| 97 | case TDH_INTYPE_SIZET: |
| 98 | info.status_ |= PROP_STATUS_POINTER_SIZE; |
| 99 | info.size_ = (eventRecord.EventHeader.Flags & EVENT_HEADER_FLAG_64_BIT_HEADER) ? 8 : 4; |
| 100 | break; |
| 101 | |
| 102 | case TDH_INTYPE_SID: |
| 103 | case TDH_INTYPE_WBEMSID: |
| 104 | // TODO: can't figure out how to decode these... so reverting to TDH for now |
| 105 | { |
| 106 | PROPERTY_DATA_DESCRIPTOR descriptor{}; |
| 107 | descriptor.PropertyName = (ULONGLONG) &tei + epi.NameOffset; |
| 108 | descriptor.ArrayIndex = UINT32_MAX; |
| 109 | auto status = TdhGetPropertySize((EVENT_RECORD*) &eventRecord, 0, nullptr, 1, &descriptor, (ULONG*) &info.size_); |
| 110 | (void) status; |
| 111 | } |
| 112 | break; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | if (epi.Flags & PropertyParamCount) { |
| 117 | auto countIdx = epi.countPropertyIndex; |
| 118 | auto addr = (uintptr_t) eventRecord.UserData + GetPropertyDataOffset(tei, eventRecord, countIdx); |
| 119 | |
| 120 | assert(tei.EventPropertyInfoArray[countIdx].Flags == 0); |
| 121 | switch (tei.EventPropertyInfoArray[countIdx].nonStructType.InType) { |
| 122 | case TDH_INTYPE_INT8: info.count_ = *(int8_t const*) addr; break; |
| 123 | case TDH_INTYPE_UINT8: info.count_ = *(uint8_t const*) addr; break; |
no test coverage detected