internal PropertyBag GetProperties(EventRecord eventRecord) { // We only support top level properties and simple types PropertyBag properties = new PropertyBag(); if (this.hasProperties) { int offset = 0; for (int i = 0; i < traceEventInfo.TopLevelPropertyCount; i++) { EventPropertyInfo info = eventPropertyInfoArray[i]; // Read the current property name string propertyName = Marshal.PtrToStringUni(new IntPtr(address.ToInt64() + info.NameOffset)); object value; string mapName; int length; IntPtr dataPtr = new IntPtr(eventRecord.UserData.ToInt64() + offset); value = ReadPropertyValue(info, dataPtr, out mapName, out length); // If we have a map name, return both map name and map value as a pair. if (!string.IsNullOrEmpty(mapName)) { value = new KeyValuePair <string, object>(mapName, value); } offset += length; properties.Add(propertyName, value); } if (offset < eventRecord.UserDataLength) { // There is some extra information not mapped. IntPtr dataPtr = new IntPtr(eventRecord.UserData.ToInt64() + offset); int length = eventRecord.UserDataLength - offset; byte[] array = new byte[length]; for (int index = 0; index < length; index++) { array[index] = Marshal.ReadByte(dataPtr, index); } properties.Add("__ExtraPayload", array); } } else { // NOTE: It is just a guess that this is an Unicode string string str = Marshal.PtrToStringUni(eventRecord.UserData); properties.Add("EventData", str); } return(properties); }
private void Initialize(EventRecord eventRecord) { int size = 0; const uint BufferTooSmall = 122; const uint ElementNotFound = 1168; int error = NativeMethods.TdhGetEventInformation(ref eventRecord, 0, IntPtr.Zero, IntPtr.Zero, ref size); if (error == ElementNotFound) { // Nothing else to do here. this.hasProperties = false; return; } this.hasProperties = true; if (error != BufferTooSmall) { throw new System.ComponentModel.Win32Exception(error); } // Get the event information (schema) this.address = Marshal.AllocHGlobal(size); this.traceEventInfo = new TraceEventInfo(); error = NativeMethods.TdhGetEventInformation(ref eventRecord, 0, IntPtr.Zero, address, ref size); if (error != 0) { throw new System.ComponentModel.Win32Exception(error); } // Marshal the first part of the trace event information. Marshal.PtrToStructure(this.address, traceEventInfo); // Marshal the second part of the trace event information, the array of property info. int actualSize = Marshal.SizeOf(this.traceEventInfo); if (size != actualSize) { int structSize = Marshal.SizeOf(typeof(EventPropertyInfo)); int itemsLeft = (size - actualSize) / structSize; this.eventPropertyInfoArray = new EventPropertyInfo[itemsLeft]; long baseAddress = address.ToInt64() + actualSize; for (int i = 0; i < itemsLeft; i++) { IntPtr structPtr = new IntPtr(baseAddress + (i * structSize)); EventPropertyInfo info = new EventPropertyInfo(); Marshal.PtrToStructure(structPtr, info); this.eventPropertyInfoArray[i] = info; } } // Get the opcode name if (traceEventInfo.OpcodeNameOffset > 0) { this.EventName = Marshal.PtrToStringUni(new IntPtr(address.ToInt64() + traceEventInfo.OpcodeNameOffset)); } }
private object ReadPropertyValue(EventPropertyInfo info, IntPtr dataPtr, out string mapName, out int length) { length = info.LengthPropertyIndex; if (info.NonStructTypeValue.MapNameOffset != 0) { mapName = Marshal.PtrToStringUni(new IntPtr(this.address.ToInt64() + info.NonStructTypeValue.MapNameOffset)); } else { mapName = string.Empty; } switch (info.NonStructTypeValue.InType) { case TdhInType.Null: break; case TdhInType.UnicodeString: { string str = Marshal.PtrToStringUni(dataPtr); if (str == null) { str = string.Empty; } length = (str.Length + 1) * sizeof(char); return(str); } case TdhInType.AnsiString: { string str = Marshal.PtrToStringAnsi(dataPtr); length = str.Length + 1; return(str); } case TdhInType.Int8: return((sbyte)Marshal.ReadByte(dataPtr)); case TdhInType.UInt8: return(Marshal.ReadByte(dataPtr)); case TdhInType.Int16: return(Marshal.ReadInt16(dataPtr)); case TdhInType.UInt16: return((uint)Marshal.ReadInt16(dataPtr)); case TdhInType.Int32: return(Marshal.ReadInt32(dataPtr)); case TdhInType.UInt32: return((uint)Marshal.ReadInt32(dataPtr)); case TdhInType.Int64: return(Marshal.ReadInt64(dataPtr)); case TdhInType.UInt64: return((ulong)Marshal.ReadInt64(dataPtr)); case TdhInType.Float: break; case TdhInType.Double: break; case TdhInType.Boolean: return((bool)(Marshal.ReadInt32(dataPtr) != 0)); case TdhInType.Binary: break; case TdhInType.Guid: return(new Guid( Marshal.ReadInt32(dataPtr), Marshal.ReadInt16(dataPtr, 4), Marshal.ReadInt16(dataPtr, 6), Marshal.ReadByte(dataPtr, 8), Marshal.ReadByte(dataPtr, 9), Marshal.ReadByte(dataPtr, 10), Marshal.ReadByte(dataPtr, 11), Marshal.ReadByte(dataPtr, 12), Marshal.ReadByte(dataPtr, 13), Marshal.ReadByte(dataPtr, 14), Marshal.ReadByte(dataPtr, 15))); case TdhInType.Pointer: break; case TdhInType.FileTime: break; case TdhInType.SystemTime: break; case TdhInType.SID: break; case TdhInType.HexInt32: break; case TdhInType.HexInt64: break; case TdhInType.CountedString: break; case TdhInType.CountedAnsiString: break; case TdhInType.ReversedCountedString: break; case TdhInType.ReversedCountedAnsiString: break; case TdhInType.NonNullTerminatedString: break; case TdhInType.NonNullTerminatedAnsiString: break; case TdhInType.UnicodeChar: break; case TdhInType.AnsiChar: break; case TdhInType.SizeT: break; case TdhInType.HexDump: break; case TdhInType.WbemSID: break; default: Debugger.Break(); break; } throw new NotSupportedException(); }