@@ -977,6 +977,14 @@ public bool IsClassicProvider
977977 // [SecuritySafeCritical]
978978 get { return ( eventRecord ->EventHeader . Flags & TraceEventNativeMethods . EVENT_HEADER_FLAG_CLASSIC_HEADER ) != 0 ; }
979979 }
980+ /// <summary>
981+ /// Returns true if this event is from the TraceMessage function (typically indicates from a WPP provider)
982+ /// </summary>
983+ public bool IsTraceMessage
984+ {
985+ // [SecuritySafeCritical]
986+ get { return ( eventRecord ->EventHeader . Flags & TraceEventNativeMethods . EVENT_HEADER_FLAG_TRACE_MESSAGE ) != 0 ; }
987+ }
980988
981989 /// <summary>
982990 /// The ID of the container that emitted the event, if available.
@@ -1341,10 +1349,30 @@ public byte[] EventData(byte[] targetBuffer, int targetStartIndex, int sourceSta
13411349 /// <para>This method is more expensive than copy out all the event data from the TraceEvent instance
13421350 /// to a type of your construction.</para>
13431351 /// </summary>
1344- public virtual unsafe TraceEvent Clone ( )
1352+ public virtual TraceEvent Clone ( )
13451353 {
1346- TraceEvent ret = ( TraceEvent ) MemberwiseClone ( ) ; // Clone myself.
1347- ret . next = null ; // the clone is not in any linked list.
1354+ return Clone ( false ) ;
1355+ }
1356+
1357+ internal unsafe TraceEvent Clone ( bool toTemplate )
1358+ {
1359+ TraceEvent ret = ( TraceEvent ) MemberwiseClone ( ) ; // Clone myself.
1360+ ret . next = null ; // the clone is not in any linked list.
1361+
1362+ if ( toTemplate )
1363+ {
1364+ // We are cloning to a template, so we don't need to clone the data.
1365+ ret . eventRecord = null ;
1366+ ret . myBuffer = IntPtr . Zero ;
1367+ ret . instanceContainerID = null ;
1368+
1369+ // Also zero out the dispatch-related fields.
1370+ ret . traceEventSource = null ;
1371+ ret . Target = null ;
1372+
1373+ return ret ;
1374+ }
1375+
13481376 if ( eventRecord != null )
13491377 {
13501378 int userDataLength = ( EventDataLength + 3 ) / 4 * 4 ; // DWORD align
@@ -2013,15 +2041,6 @@ internal int ThreadIDforStacks()
20132041 /// </summary>
20142042 protected internal virtual void SetState ( object state ) { }
20152043
2016- protected internal TraceEvent CloneToTemplate ( )
2017- {
2018- TraceEvent ret = Clone ( ) ;
2019- ret . traceEventSource = null ;
2020- ret . eventRecord = null ;
2021- ret . Target = null ;
2022- return ret ;
2023- }
2024-
20252044 #endregion
20262045 #region Private
20272046 private static char HexDigit ( int digit )
@@ -3663,6 +3682,7 @@ internal TraceEvent Lookup(TraceEventNativeMethods.EVENT_RECORD* eventRecord)
36633682
36643683#if DEBUG // ASSERT we found the event using the mechanism we expected to use.
36653684 Debug . Assert ( ( ( eventRecord ->EventHeader . Flags & TraceEventNativeMethods . EVENT_HEADER_FLAG_CLASSIC_HEADER ) != 0 ) == curTemplate . lookupAsClassic ) ;
3685+ Debug . Assert ( ( ( eventRecord ->EventHeader . Flags & TraceEventNativeMethods . EVENT_HEADER_FLAG_TRACE_MESSAGE ) != 0 ) == curTemplate . lookupAsWPP ) ;
36663686 if ( curTemplate . lookupAsClassic )
36673687 {
36683688 Debug . Assert ( curTemplate . taskGuid == eventRecord ->EventHeader . ProviderId ) ;
@@ -3710,6 +3730,7 @@ internal TraceEvent Lookup(TraceEventNativeMethods.EVENT_RECORD* eventRecord)
37103730 unhandledEventTemplate . userData = eventRecord ->UserData ;
37113731 unhandledEventTemplate . eventIndex = currentID ;
37123732 unhandledEventTemplate . lookupAsClassic = unhandledEventTemplate . IsClassicProvider ;
3733+ unhandledEventTemplate . lookupAsWPP = unhandledEventTemplate . IsTraceMessage ;
37133734 if ( ( ( ( int ) currentID ) & 0xFFFF ) == 0 ) // Every 64K events allow Thread.Interrupt.
37143735 {
37153736 System . Threading . Thread . Sleep ( 0 ) ;
0 commit comments