/// <summary>
        /// This function copies the information from the native TRACE_EVENT_INFO structure
        /// to property information in this oject
        /// </summary>
        /// <param name="buffer">IntPtr to TRACE_EVENT_INFO structure</param>
        void CopyMetadata(IntPtr buffer, ref EtwNativeEvent e)
        {
            TRACE_EVENT_INFO *info  = (TRACE_EVENT_INFO *)buffer;
            byte *            start = (byte *)info;
            byte *            end   = start + sizeof(TRACE_EVENT_INFO);

            _template = new Dictionary <string, object>();
            _template.Add("Provider", CopyString(start, info->ProviderNameOffset));
            _template.Add("Level", CopyString(start, info->LevelNameOffset));
            _template.Add("Task", CopyString(start, info->TaskNameOffset));
            _template.Add("Opcode", CopyString(start, info->OpcodeNameOffset));
            _template.Add("Channel", CopyString(start, info->ChannelNameOffset));
            _formatString = TranslateFormatString(CopyString(start, info->EventMessageOffset));

            EVENT_PROPERTY_INFO *prop = (EVENT_PROPERTY_INFO *)end;
            var propList = new List <EtwPropertyInfo>();


            for (int i = 0; i < info->TopLevelPropertyCount; i++)
            {
                var propInfo = prop + i;
                var name     = CopyString(start, propInfo->NameOffset);
                var type     = (TdhInType)(*propInfo).NonStructTypeValue.InType;
                var outType  = (TdhOutType)(*propInfo).NonStructTypeValue.OutType;

                EtwPropertyInfo property = null;
                if (propInfo->Flags == PROPERTY_FLAGS.PropertyParamLength)
                {
                    string lenPropertyName = propList[(int)(propInfo->LengthPropertyIndex)].Name;
                    property = new EtwPropertyInfo {
                        Name = name, Type = type, OutType = outType, LengthPropertyName = lenPropertyName
                    };
                }
                else
                {
                    ushort len = (*propInfo).LengthPropertyIndex;
                    property = new EtwPropertyInfo {
                        Name = name, Length = len, Type = type, OutType = outType
                    };
                }

                if (propInfo->NonStructTypeValue.MapNameOffset > 0)
                {
                    string mapName = CopyString(start, propInfo->NonStructTypeValue.MapNameOffset);
                    property.ValueMap = ReadTdhMap(mapName, ref e);
                }

                propList.Add(property);
            }

            _properties = propList.ToArray();
        }
Beispiel #2
0
        private unsafe uint AddString(TRACE_EVENT_INFO *buffer, ref uint offset, string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return(0);
            }

            var bytes = Encoding.Unicode.GetBytes(str);

            Marshal.Copy(bytes, 0, (IntPtr)((byte *)buffer + offset), bytes.Length);
            ((byte *)buffer)[offset + bytes.Length]     = 0;
            ((byte *)buffer)[offset + bytes.Length + 1] = 0;
            uint result = offset;

            offset += (uint)(bytes.Length + 2);
            return(result);
        }
 public EventTraceOperandBuilderFromTDH(TRACE_EVENT_INFO* traceEventInfo)
 {
     this.traceEventInfo = traceEventInfo;
 }
 public static IEventTraceOperand Build(TRACE_EVENT_INFO *traceEventInfo, int metadataIndex)
 {
     return(new EventTraceOperandBuilderFromTDH(traceEventInfo).Build(metadataIndex));
 }
 public EventTraceOperandBuilderFromTDH(TRACE_EVENT_INFO *traceEventInfo)
 {
     this.traceEventInfo = traceEventInfo;
 }
        protected override DynamicTraceEventData TryLookup(TraceEvent unknownEvent)
        {
            DynamicTraceEventData ret = null;
            // TODO react if 4K is not big enough, cache the buffer?, handle more types, handle structs...
            int   buffSize = 4096;
            byte *buffer   = (byte *)System.Runtime.InteropServices.Marshal.AllocHGlobal(buffSize);
            int   status   = TdhGetEventInformation(unknownEvent.eventRecord, 0, null, buffer, &buffSize);

            if (status == 0)
            {
                TRACE_EVENT_INFO *   eventInfo     = (TRACE_EVENT_INFO *)buffer;
                EVENT_PROPERTY_INFO *propertyInfos = &eventInfo->EventPropertyInfoArray;

                string taskName = null;
                if (eventInfo->TaskNameOffset != 0)
                {
                    taskName = (new string((char *)(&buffer[eventInfo->TaskNameOffset]))).Trim();
                }

                string opcodeName = null;
                if (eventInfo->OpcodeNameOffset != 0)
                {
                    opcodeName = (new string((char *)(&buffer[eventInfo->OpcodeNameOffset]))).Trim();
                    if (opcodeName.StartsWith("win:"))
                    {
                        opcodeName = opcodeName.Substring(4);
                    }
                }

                string providerName = "UnknownProvider";
                if (eventInfo->ProviderNameOffset != 0)
                {
                    providerName = new string((char *)(&buffer[eventInfo->ProviderNameOffset]));
                }

                var eventID     = unknownEvent.ClassicProvider ? TraceEventID.Illegal : unknownEvent.eventID;
                var newTemplate = new DynamicTraceEventData(null, (int)eventID, (int)unknownEvent.task, taskName,
                                                            unknownEvent.taskGuid, (int)unknownEvent.Opcode, opcodeName, unknownEvent.ProviderGuid, providerName);

                newTemplate.payloadNames   = new string[eventInfo->TopLevelPropertyCount];
                newTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[eventInfo->TopLevelPropertyCount];
                ushort offset = 0;
                for (int i = 0; i < eventInfo->TopLevelPropertyCount; i++)
                {
                    var propertyInfo = &propertyInfos[i];
                    var propertyName = new string((char *)(&buffer[propertyInfo->NameOffset]));
                    // Remove anything that does not look like an ID (.e.g space)
                    newTemplate.payloadNames[i]        = Regex.Replace(propertyName, "[^A-Za-z0-9_]", "");
                    newTemplate.payloadFetches[i].type = GetTypeForTdhInType(propertyInfo->InType);

                    // Determine whether the size variable or not, and set 'size' based on that.
                    ushort size = DynamicTraceEventData.UNKNOWN_SIZE;
                    // is this dynamically sized with another field specifying the length?
                    if ((propertyInfo->Flags & PROPERTY_FLAGS.ParamLength) != 0)
                    {
                        if (propertyInfo->LengthOrLengthIndex == i - 1)
                        {
                            if (propertyInfos[i - 1].LengthOrLengthIndex == 4)
                            {
                                size = DynamicTraceEventData.COUNT32_PRECEEDS;
                            }
                            else if (propertyInfos[i - 1].LengthOrLengthIndex == 2)
                            {
                                size = DynamicTraceEventData.COUNT16_PRECEEDS;
                            }
                            else
                            {
                                Trace.WriteLine("WARNING: Unexpected dynamic length, giving up");
                            }
                        }

                        if (size != DynamicTraceEventData.UNKNOWN_SIZE && propertyInfo->InType == TdhInputType.AnsiString)
                        {
                            size |= DynamicTraceEventData.IS_ANSI;
                        }
                    }
                    else
                    {
                        if (propertyInfo->InType == TdhInputType.AnsiString)
                        {
                            size = DynamicTraceEventData.NULL_TERMINATED | DynamicTraceEventData.IS_ANSI;
                        }
                        else if (propertyInfo->InType == TdhInputType.UnicodeString)
                        {
                            size = DynamicTraceEventData.NULL_TERMINATED;
                        }
                        else if (propertyInfo->InType == TdhInputType.Pointer)
                        {
                            size = DynamicTraceEventData.POINTER_SIZE;
                        }
                        else
                        {
                            // No, then it it fixed size (but give up if it is too big)
                            var fixedSize = propertyInfo->CountOrCountIndex * propertyInfo->LengthOrLengthIndex;
                            if (fixedSize < 0x7FF0)
                            {
                                size = (ushort)fixedSize;
                                if (propertyInfo->InType == TdhInputType.AnsiString)
                                {
                                    size += 0x8000;
                                }
                            }
                        }
                    }

                    // Currently we give up on any other flags (arrays, structs).
                    if ((propertyInfo->Flags & ~PROPERTY_FLAGS.ParamLength) != 0)
                    {
                        size = DynamicTraceEventData.UNKNOWN_SIZE;
                    }

                    newTemplate.payloadFetches[i].size   = (ushort)size;
                    newTemplate.payloadFetches[i].offset = offset;
                    if (size >= DynamicTraceEventData.SPECIAL_SIZES)
                    {
                        offset = ushort.MaxValue;           // Indicate that the offset must be computed at run time.
                    }
                    else if (offset != ushort.MaxValue)
                    {
                        Debug.Assert(offset + size < ushort.MaxValue);
                        offset += size;
                    }
                }
                ret = newTemplate;      // return this as the event template for this lookup.
            }

            System.Runtime.InteropServices.Marshal.FreeHGlobal((IntPtr)buffer);
            return(ret);
        }
Beispiel #7
0
 public TraceEventInfoCPtr(IntPtr pTraceEventInfo, UIntPtr cbTraceEventInfo)
 {
     this.pTraceEventInfo  = (TRACE_EVENT_INFO *)pTraceEventInfo;
     this.cbTraceEventInfo = cbTraceEventInfo.ToUInt32();
 }
Beispiel #8
0
 public TraceEventInfoCPtr(TRACE_EVENT_INFO *pTraceEventInfo, uint cbTraceEventInfo)
 {
     this.pTraceEventInfo  = pTraceEventInfo;
     this.cbTraceEventInfo = cbTraceEventInfo;
 }
Beispiel #9
0
 public static unsafe EVENT_PROPERTY_INFO *GetEventPropertyInfoArray(
     TRACE_EVENT_INFO *pTraceEventInfo)
 {
     return(&pTraceEventInfo->EventPropertyInfoArray);
 }