| 237 | std::vector<EventProperty> properties_; |
| 238 | |
| 239 | Event(EVENT_DESCRIPTOR const& desc, TRACE_EVENT_INFO* eventInfo) |
| 240 | : EVENT_DESCRIPTOR(desc) |
| 241 | { |
| 242 | // Note: MSDN doesn't say that task/opcode/level offsets can be zero |
| 243 | // but there are cases of that |
| 244 | if (eventInfo->TaskNameOffset == 0) { |
| 245 | wchar_t b[126]; |
| 246 | _snwprintf_s(b, _TRUNCATE, L"Task_%u", desc.Task); |
| 247 | taskName_ = b; |
| 248 | } else { |
| 249 | taskName_ = GetStringPtr(eventInfo, eventInfo->TaskNameOffset); |
| 250 | } |
| 251 | if (eventInfo->OpcodeNameOffset == 0) { |
| 252 | wchar_t b[126]; |
| 253 | _snwprintf_s(b, _TRUNCATE, L"Opcode_%u", desc.Opcode); |
| 254 | opcodeName_ = b; |
| 255 | } else { |
| 256 | opcodeName_ = GetStringPtr(eventInfo, eventInfo->OpcodeNameOffset); |
| 257 | |
| 258 | // ETL-loaded opcode names can have "win:" prepended. |
| 259 | if (opcodeName_.rfind(L"win:", 0) == 0) { |
| 260 | opcodeName_.erase(0, 4); |
| 261 | } |
| 262 | } |
| 263 | if (eventInfo->LevelNameOffset == 0) { |
| 264 | wchar_t b[126]; |
| 265 | _snwprintf_s(b, _TRUNCATE, L"Level_%u", desc.Level); |
| 266 | levelName_ = b; |
| 267 | } else { |
| 268 | levelName_ = GetStringPtr(eventInfo, eventInfo->LevelNameOffset); |
| 269 | } |
| 270 | |
| 271 | if (eventInfo->EventMessageOffset != 0) { |
| 272 | message_ = GetStringPtr(eventInfo, eventInfo->EventMessageOffset); |
| 273 | } |
| 274 | |
| 275 | auto propCount = eventInfo->TopLevelPropertyCount; |
| 276 | properties_.reserve(propCount); |
| 277 | for (ULONG i = 0; i < propCount; ++i) { |
| 278 | properties_.emplace_back(eventInfo, eventInfo->EventPropertyInfoArray[i]); |
| 279 | } |
| 280 | |
| 281 | name_ = taskName_ + L'_' + opcodeName_; |
| 282 | } |
| 283 | }; |
| 284 | |
| 285 | void EnumerateSystemEvents(GUID const& providerGuid, std::vector<Event>* events, std::wstring* outProviderName) |
nothing calls this directly
no test coverage detected