Dictionary <uint, string> ReadTdhMap(string mapName, ref EtwNativeEvent e) { IntPtr pMapName = Marshal.StringToBSTR(mapName); int bufferSize = 0; int status = EtwNativeMethods.TdhGetEventMapInformation( ref *e.record, pMapName, IntPtr.Zero, ref bufferSize); if (122 != status) // ERROR_INSUFFICIENT_BUFFER { throw new Exception("Unexpected TDH status " + status); } var mybuffer = Marshal.AllocHGlobal(bufferSize); status = EtwNativeMethods.TdhGetEventMapInformation( ref *e.record, pMapName, mybuffer, ref bufferSize); if (status != 0) { throw new Exception("TDH status " + status); } EVENT_MAP_INFO *mapInfo = (EVENT_MAP_INFO *)mybuffer; byte * startMap = (byte *)mapInfo; var name1 = CopyString(startMap, mapInfo->NameOffset); byte * endMap = startMap + sizeof(EVENT_MAP_INFO); var map = new Dictionary <uint, string>(); for (int i = 0; i < mapInfo->EntryCount; i++) { EVENT_MAP_ENTRY *mapEntry = (EVENT_MAP_ENTRY *)endMap + i; uint value = mapEntry->Value; string name = CopyString(startMap, mapEntry->OutputOffset); map.Add(value, name); } return(map); }
private List <EventTracePropertyOperand> IterateProperties(byte *buffer, List <EventTracePropertyOperand> operands, int start, int end, EVENT_PROPERTY_INFO *eventPropertyInfoArr) { var returnList = new List <EventTracePropertyOperand>(); for (int i = start; i < end; ++i) { var eventPropertyInfo = &eventPropertyInfoArr[i]; string propertyName = new string((char *)&buffer[eventPropertyInfo->NameOffset]); int structchildren = eventPropertyInfo->StructType.NumOfStructMembers; bool isStruct = (eventPropertyInfo->Flags & PROPERTY_FLAGS.PropertyStruct) == PROPERTY_FLAGS.PropertyStruct; bool isVariableArray = (eventPropertyInfo->Flags & PROPERTY_FLAGS.PropertyParamCount) == PROPERTY_FLAGS.PropertyParamCount; bool isFixedArray = (eventPropertyInfo->Flags & PROPERTY_FLAGS.PropertyParamFixedCount) == PROPERTY_FLAGS.PropertyParamFixedCount; bool isVariableLength = (eventPropertyInfo->Flags & PROPERTY_FLAGS.PropertyParamLength) == PROPERTY_FLAGS.PropertyParamLength; bool isFixedLength = (eventPropertyInfo->Flags & PROPERTY_FLAGS.PropertyParamFixedLength) == PROPERTY_FLAGS.PropertyParamFixedLength; bool isWbemXmlFragment = (eventPropertyInfo->Flags & PROPERTY_FLAGS.PropertyWBEMXmlFragment) == PROPERTY_FLAGS.PropertyWBEMXmlFragment; // NOTE: Do not remove this special case, there are cases like this, we just assume it's a fixed array if (!isFixedArray && !isVariableArray && eventPropertyInfo->count > 1) { isFixedArray = true; } string mapName = null; Dictionary <uint, string> mapOfValues = null; if (eventPropertyInfo->NonStructType.MapNameOffset != 0) { byte *mapBuffer = (byte *)0; uint bufferSize; var fakeEventRecord = new EVENT_RECORD { ProviderId = this.traceEventInfo->ProviderGuid }; mapName = new string((char *)&buffer[eventPropertyInfo->NonStructType.MapNameOffset]); Tdh.GetEventMapInformation(&fakeEventRecord, mapName, mapBuffer, out bufferSize); mapBuffer = (byte *)Marshal.AllocHGlobal((int)bufferSize); Tdh.GetEventMapInformation(&fakeEventRecord, mapName, mapBuffer, out bufferSize); EVENT_MAP_INFO *mapInfo = (EVENT_MAP_INFO *)mapBuffer; if (mapInfo->MapEntryValueType == MAP_VALUETYPE.EVENTMAP_ENTRY_VALUETYPE_ULONG) { var mapEntry = (EVENT_MAP_ENTRY *)&mapInfo->MapEntryArray; mapOfValues = new Dictionary <uint, string>(); for (int j = 0; j < mapInfo->EntryCount; ++j) { var offset = mapEntry[j].OutputOffset; if (offset > bufferSize) { // TDH has a bug (it seems) that is giving rogue values here // We should log this } else { var mapEntryValue = mapEntry[j].Value; string mapEntryName; if (!mapOfValues.TryGetValue(mapEntryValue, out mapEntryName)) { mapEntryName = new string((char *)&mapBuffer[offset]); mapOfValues.Add(mapEntryValue, mapEntryName); } } } } Marshal.FreeHGlobal((IntPtr)mapBuffer); } /* save important information in an object */ var operand = new EventTracePropertyOperand( new PropertyMetadata((TDH_IN_TYPE)eventPropertyInfo->NonStructType.InType, (TDH_OUT_TYPE)eventPropertyInfo->NonStructType.OutType, propertyName, mapOfValues != null, isStruct, isStruct ? structchildren : 0, new MapInformation(mapName, mapOfValues)), i, isVariableArray, isFixedArray, isVariableLength, isFixedLength, isWbemXmlFragment); this.flatPropertyList.Add(operand); operands.Add(operand); returnList.Add(operand); /* if this references a previous field, we need to capture that as a local */ if (isVariableArray) { var reference = operands[eventPropertyInfo->countPropertyIndex]; reference.IsReferencedByOtherProperties = true; operand.SetVariableArraySize(reference); } else if (isFixedArray) { operand.SetFixedArraySize(eventPropertyInfo->count); } /* if this references a previous field, we need to capture that as a local */ if (isVariableLength) { var reference = operands[eventPropertyInfo->lengthPropertyIndex]; reference.IsReferencedByOtherProperties = true; operand.SetVariableLengthSize(reference); } else if (isFixedLength) { operand.SetFixedLengthSize(eventPropertyInfo->length); } if ((eventPropertyInfo->Flags & PROPERTY_FLAGS.PropertyStruct) == PROPERTY_FLAGS.PropertyStruct) { var innerProps = this.IterateProperties( buffer, operands, eventPropertyInfo->StructType.StructStartIndex, eventPropertyInfo->StructType.StructStartIndex + eventPropertyInfo->StructType.NumOfStructMembers, eventPropertyInfoArr); foreach (var innerProp in innerProps) { operand.Children.Add(innerProp); } } } return(returnList); }
internal static extern int TdhGetEventMapInformation( TraceEventNativeMethods.EVENT_RECORD *pEvent, string pMapName, EVENT_MAP_INFO *info, ref int infoSize );