示例#1
0
        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
     );