/// <summary> /// given that 'eventRecord' is a TraceLogging event (with meta-data 'metaData'), return a eventID that is unique /// to that provider/opcode/meta-data blob. /// </summary> private ushort GetEventIDForTraceLoggingEvent(TraceEventNativeMethods.EVENT_RECORD *eventRecord, TraceEventNativeMethods.EVENT_HEADER_EXTENDED_DATA_ITEM *metaData) { Debug.Assert(metaData->ExtType == TraceEventNativeMethods.EVENT_HEADER_EXT_TYPE_EVENT_SCHEMA_TL); if (m_traceLoggingEventMap == null) // Lazy init. { m_traceLoggingEventMap = new Dictionary <ProviderMetaDataKey, ushort>(); m_nextTraceLoggingIDForProvider = new Dictionary <Guid, ushort>(); } // Check if I am in the table of assigned eventIds for this meta-data- blob ProviderMetaDataKey key = new ProviderMetaDataKey(&eventRecord->EventHeader.ProviderId, eventRecord->EventHeader.Opcode, (byte *)metaData->DataPtr, metaData->DataSize); ushort ret; if (!m_traceLoggingEventMap.TryGetValue(key, out ret)) { // No then get the next ID for this particular provider (and allocate a new one) if (!m_nextTraceLoggingIDForProvider.TryGetValue(eventRecord->EventHeader.ProviderId, out ret)) { ret = 0xFF00; // We arbitrarily pick the 'high end' of the event ID range to stay way from user-allocated IDs. However we also avoid the last 256 ID just in case. } --ret; m_nextTraceLoggingIDForProvider[eventRecord->EventHeader.ProviderId] = ret; if (ret == 0) // means we wrapped around. We have no more! { throw new InvalidOperationException("Error ran out of TraceLogging Event IDs for provider " + eventRecord->EventHeader.ProviderId); } // Make a copy of memory the key points at. Thus the table 'owns' the data the keys point at. // This is reclaimed in 'Dispose' int copyDataSize = (key.DataSize + 3) & ~3; // round it up to a multiple of 4. CopyBlob requires this. byte *copy = (byte *)Marshal.AllocHGlobal(copyDataSize + sizeof(Guid)); key.Provider = (Guid *)(copy); *key.Provider = eventRecord->EventHeader.ProviderId; copy += sizeof(Guid); TraceEvent.CopyBlob((IntPtr)key.Data, (IntPtr)copy, copyDataSize); key.Data = copy; // Add the new key and eventID to the table. m_traceLoggingEventMap.Add(key, ret); } return(ret); }