bool GetEventData(EVENT_RECORD* pEventRecord, wchar_t const* name, T* out, bool bPrintOnError = true) { PROPERTY_DATA_DESCRIPTOR descriptor; descriptor.PropertyName = (ULONGLONG) name; descriptor.ArrayIndex = ULONG_MAX; auto status = TdhGetProperty(pEventRecord, 0, nullptr, 1, &descriptor, sizeof(T), (BYTE*) out); if (status != ERROR_SUCCESS) { if (bPrintOnError) { fprintf(stderr, "error: could not get event %ls property (error=%lu).\n", name, status); PrintEventInformation(stderr, pEventRecord); } return false; } return true; }
void CALLBACK EventRecordCallback(_In_ EVENT_RECORD* per) { auto data = static_cast<EventTraceData*>(per->UserContext); static std::unordered_map<GUID, std::vector<BYTE>, GuidHash> fragment; if (false) { std::wostringstream s; WCHAR tmp[39]; if (per->EventHeader.ProviderId == __uuidof(Microsoft_Windows_Networking_Correlation)) { s << "C"; } else if (per->EventHeader.ProviderId == __uuidof(Microsoft_Windows_NDIS_PacketCapture)) { s << "P"; } else { StringFromGUID2(per->EventHeader.ProviderId, tmp, ARRAYSIZE(tmp)); s << tmp; } StringFromGUID2(per->EventHeader.ActivityId, tmp, ARRAYSIZE(tmp)); s << ", Activity ID: " << tmp; for (int i = 0; i < per->ExtendedDataCount; ++i) { const auto& e = per->ExtendedData[i]; if (e.ExtType == EVENT_HEADER_EXT_TYPE_RELATED_ACTIVITYID) { const auto& r = *(const EVENT_EXTENDED_ITEM_RELATED_ACTIVITYID*)(e.DataPtr); StringFromGUID2(r.RelatedActivityId, tmp, ARRAYSIZE(tmp)); s << ", RelatedActivityId: " << tmp; } else { s << ", ExtType: " << e.ExtType; } } if (per->UserDataLength <= 26 || *((BYTE*)per->UserData + 24) != 0x08 || *((BYTE*)per->UserData + 25) != 0x00) { if (per->EventHeader.ProviderId == __uuidof(Microsoft_Windows_NDIS_PacketCapture)) { s << " !"; } } if (per->EventHeader.ProviderId != __uuidof(Microsoft_Windows_Networking_Correlation)) { ULONG bufferSize = 0; auto statusSize = TdhGetEventInformation(per, 0, nullptr, nullptr, &bufferSize); if (statusSize != ERROR_INSUFFICIENT_BUFFER) { return; } auto buffer = std::make_unique<std::uint8_t[]>(bufferSize); auto info = reinterpret_cast<TRACE_EVENT_INFO*>(buffer.get()); auto status = TdhGetEventInformation(per, 0, nullptr, info, &bufferSize); if (status != ERROR_SUCCESS) { return; } for (ULONG i = 0; i < info->TopLevelPropertyCount; i++) { const auto& propertyInfo = info->EventPropertyInfoArray[i]; auto name = reinterpret_cast<PCWSTR>(buffer.get() + propertyInfo.NameOffset); if (std::wcscmp(name, L"FragmentSize") != 0) { continue; } PROPERTY_DATA_DESCRIPTOR desc{ reinterpret_cast<uintptr_t>(name), ULONG_MAX, }; ULONG propertyBufferSize; auto statusPropSize = TdhGetPropertySize(per, 0, nullptr, 1, &desc, &propertyBufferSize); if (statusPropSize != ERROR_SUCCESS) { continue; } auto propertyBuffer = std::make_unique<std::uint8_t[]>(propertyBufferSize); auto statusProp = TdhGetProperty(per, 0, nullptr, 1, &desc, propertyBufferSize, propertyBuffer.get()); if (statusProp != ERROR_SUCCESS) { continue; } if ((propertyInfo.Flags & PropertyStruct) != 0) { continue; } if (propertyInfo.nonStructType.InType != TDH_INTYPE_UINT32) { continue; } s << L", Fragment size: " << *reinterpret_cast<UINT32*>(propertyBuffer.get()); } } s << "\r\n"; OutputDebugStringW(s.str().c_str()); } if (per->EventHeader.ProviderId != __uuidof(Microsoft_Windows_NDIS_PacketCapture)) { return; } ULONG bufferSize = 0; auto statusSize = TdhGetEventInformation(per, 0, nullptr, nullptr, &bufferSize); if (statusSize != ERROR_INSUFFICIENT_BUFFER) { return; } auto buffer = std::make_unique<std::uint8_t[]>(bufferSize); auto info = reinterpret_cast<TRACE_EVENT_INFO*>(buffer.get()); auto status = TdhGetEventInformation(per, 0, nullptr, info, &bufferSize); if (status != ERROR_SUCCESS) { return; } for (ULONG i = 0; i < info->TopLevelPropertyCount; i++) { const auto& propertyInfo = info->EventPropertyInfoArray[i]; auto name = reinterpret_cast<PCWSTR>(buffer.get() + propertyInfo.NameOffset); if (std::wcscmp(name, L"Fragment") != 0) { continue; } PROPERTY_DATA_DESCRIPTOR desc{ reinterpret_cast<uintptr_t>(name), ULONG_MAX, }; ULONG propertyBufferSize; auto statusPropSize = TdhGetPropertySize(per, 0, nullptr, 1, &desc, &propertyBufferSize); if (statusPropSize != ERROR_SUCCESS) { continue; } auto propertyBuffer = std::make_unique<std::uint8_t[]>(propertyBufferSize); auto statusProp = TdhGetProperty(per, 0, nullptr, 1, &desc, propertyBufferSize, propertyBuffer.get()); if (statusProp != ERROR_SUCCESS) { continue; } if ((propertyInfo.Flags & PropertyStruct) != 0) { continue; } if (propertyInfo.nonStructType.InType != TDH_INTYPE_BINARY) { continue; } std::wostringstream s; WCHAR tmp[39]; StringFromGUID2(per->EventHeader.ActivityId, tmp, ARRAYSIZE(tmp)); s << tmp << ' ' << std::hex << per->EventHeader.Flags; auto it = fragment.find(per->EventHeader.ActivityId); if (it == fragment.end()) { if ((per->EventHeader.EventDescriptor.Keyword & KeywordPacketEnd) != 0) { data->Packet.push(std::vector<std::uint8_t>(propertyBuffer.get(), propertyBuffer.get() + propertyBufferSize)); } else { fragment.emplace( per->EventHeader.ActivityId, std::vector<std::uint8_t>(propertyBuffer.get(), propertyBuffer.get() + propertyBufferSize)); } } else { it->second.insert( it->second.end(), propertyBuffer.get(), propertyBuffer.get() + propertyBufferSize); if ((per->EventHeader.EventDescriptor.Keyword & KeywordPacketEnd) != 0) { data->Packet.push(std::move(it->second)); fragment.erase(it); } } } }