diff --git a/EnabledProvider.cs b/EnabledProvider.cs index bdcf7a0..a0c05ae 100644 --- a/EnabledProvider.cs +++ b/EnabledProvider.cs @@ -26,19 +26,21 @@ namespace etwlib { public class EnabledProvider : IEquatable, IComparable, IDisposable { - public Guid Id; - public EventTraceLevel Level; - public ulong AllKeywords; - public ulong AnyKeywords; - private List m_FilterDescriptors; - private nint m_AggregatedPayloadFilters; - private bool m_Disposed; - private nint m_ParametersBuffer; - private nint m_FiltersBuffer; - - public EnabledProvider(Guid Id, EventTraceLevel Level, ulong AllKeywords, ulong AnyKeywords) + public Guid Id { get; set; } + public string? Name { get; set; } + public byte Level { get; set; } + public ulong AllKeywords { get; set; } + public ulong AnyKeywords { get; set; } + private List m_FilterDescriptors { get; set; } + private nint m_AggregatedPayloadFilters { get; set; } + private bool m_Disposed { get; set; } + private nint m_ParametersBuffer { get; set; } + private nint m_FiltersBuffer { get; set; } + + public EnabledProvider(Guid Id, string Name, byte Level, ulong AllKeywords, ulong AnyKeywords) { this.Id = Id; + this.Name = Name; this.Level = Level; this.AllKeywords = AllKeywords; this.AnyKeywords = AnyKeywords; @@ -162,7 +164,7 @@ public override string ToString() public uint Disable(long SessionHandle) { return EnableTraceEx2(SessionHandle, - ref Id, + Id, EventControlCode.DisableProvider, Level, 0, 0, 0, @@ -174,7 +176,7 @@ public uint Enable(long SessionHandle) GenerateTraceParameters(); return EnableTraceEx2( SessionHandle, - ref Id, + Id, EventControlCode.EnableProvider, Level, AnyKeywords, @@ -417,7 +419,7 @@ public void SetStackwalkLevelKw(EventTraceLevel Level, ulong MatchAnyKeyword, ul } var filter = new EVENT_FILTER_LEVEL_KW(); - filter.Level = Level; + filter.Level = (byte)Level; filter.MatchAllKeyword = MatchAllKeyword; filter.MatchAnyKeyword = MatchAnyKeyword; filter.FilterIn = FilterIn; diff --git a/NativeDefinitions.cs b/NativeDefinitions.cs index ddf9619..89a8d70 100644 --- a/NativeDefinitions.cs +++ b/NativeDefinitions.cs @@ -357,7 +357,7 @@ public struct EVENT_FILTER_LEVEL_KW { public ulong MatchAnyKeyword; public ulong MatchAllKeyword; - public EventTraceLevel Level; + public byte Level; [MarshalAs(UnmanagedType.U1)] public bool FilterIn; } @@ -385,7 +385,7 @@ public struct TRACE_PROVIDER_INSTANCE_INFO public struct TRACE_ENABLE_INFO { public uint IsEnabled; - public EventTraceLevel Level; + public byte Level; public byte Reserved1; public ushort LoggerId; public EnableTraceProperties EnableProperty; @@ -432,9 +432,9 @@ public static extern uint ProcessTrace( [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern uint EnableTraceEx2( [In] long SessionHandle, - [In] ref Guid ProviderId, + [In] Guid ProviderId, [In] EventControlCode ControlCode, - [In] EventTraceLevel Level, + [In] byte Level, [In] ulong MatchAnyKeyword, [In] ulong MatchAllKeyword, [In] uint Timeout, @@ -649,7 +649,7 @@ public struct EVENT_DESCRIPTOR public ushort Id; public byte Version; public byte Channel; - public NativeTraceControl.EventTraceLevel Level; + public byte Level; public byte Opcode; public ushort Task; public ulong Keyword; @@ -671,7 +671,7 @@ public struct EVENT_TRACE_HEADER public ushort Size; public ushort FieldTypeFlags; public byte Type; - public NativeTraceControl.EventTraceLevel Level; + public byte Level; public ushort Version; public uint ThreadId; public uint ProcessId; diff --git a/ParsedEtwManifest.cs b/ParsedEtwManifest.cs index 0772360..4da4e67 100644 --- a/ParsedEtwManifest.cs +++ b/ParsedEtwManifest.cs @@ -23,14 +23,14 @@ namespace etwlib { public class ParsedEtwManifest { - public ParsedEtwProvider Provider; - public List Events; - public List Channels; - public List Keywords; - public Dictionary> Tasks; - public List GlobalOpcodes; - public Dictionary> Templates; - public List StringTable; + public ParsedEtwProvider Provider { get; set; } + public List Events { get; set; } + public List Channels { get; set; } + public List Keywords { get; set; } + public Dictionary> Tasks { get; set; } + public List GlobalOpcodes { get; set; } + public Dictionary> Templates { get; set; } + public List StringTable { get; set; } public ParsedEtwManifest() { diff --git a/ParsedEtwManifestEvent.cs b/ParsedEtwManifestEvent.cs index 55ce569..45ad924 100644 --- a/ParsedEtwManifestEvent.cs +++ b/ParsedEtwManifestEvent.cs @@ -21,14 +21,16 @@ namespace etwlib { public class ParsedEtwManifestEvent : IEquatable, IComparable { - public string Id; - public string Version; - public string? Opcode; - public string? Channel; - public string Level; - public string? Keywords; - public string Task; - public string? Template; + public string Id { get; set; } + public string Version { get; set; } + public string? Opcode { get; set; } + public string? Channel { get; set; } + public string Level { get; set; } + public string? Keywords { get; set; } + public string Task { get; set; } + public string? Template { get; set; } + + private ParsedEtwManifestEvent() { } // For XML serialization public ParsedEtwManifestEvent( string id, diff --git a/ParsedEtwManifestField.cs b/ParsedEtwManifestField.cs index 0eace55..863159c 100644 --- a/ParsedEtwManifestField.cs +++ b/ParsedEtwManifestField.cs @@ -21,9 +21,11 @@ namespace etwlib { public class ParsedEtwManifestField : IEquatable, IComparable { - public string Name; - public string Description; - public ulong Value; + public string Name { get; set; } + public string Description { get; set; } + public ulong Value { get; set; } + + private ParsedEtwManifestField() { } // For XML serialization public ParsedEtwManifestField(string name, string description, ulong value) { diff --git a/ParsedEtwProvider.cs b/ParsedEtwProvider.cs index 12b0f94..f657d3e 100644 --- a/ParsedEtwProvider.cs +++ b/ParsedEtwProvider.cs @@ -21,9 +21,12 @@ namespace etwlib { public class ParsedEtwProvider : IEquatable, IComparable { - public Guid Id; - public string? Name; - public string? Source; + public Guid Id { get; set; } + public string? Name { get; set; } + public string? Source { get; set; } + public bool HasManifest { get; set; } + + public ParsedEtwProvider() { } // For XML serialization public override bool Equals(object? Other) { @@ -79,7 +82,7 @@ public int CompareTo(ParsedEtwProvider? Other) public override string ToString() { var name = string.IsNullOrEmpty(Name) ? Id.ToString() : Name; - return $"{name} : ({Id}/{Source})"; + return $"{name} : ({Id}/{Source}/Manifest={(HasManifest? "yes" : "no")})"; } } } diff --git a/ParsedEtwSession.cs b/ParsedEtwSession.cs index 5c9a108..9954ac4 100644 --- a/ParsedEtwSession.cs +++ b/ParsedEtwSession.cs @@ -24,19 +24,20 @@ namespace etwlib public class SessionEnabledProvider { - public Guid ProviderId; - public uint ProcessId; - public TRACE_PROVIDER_INSTANCE_FLAGS InstanceFlags; - public EventTraceLevel Level; - public EnableTraceProperties EnableProperty; - public ulong MatchAnyKeyword; - public ulong MatchAllKeyword; + public Guid ProviderId { get; set; } + public uint ProcessId { get; set; } + public TRACE_PROVIDER_INSTANCE_FLAGS InstanceFlags { get; set; } + public byte Level { get; set; } + public EnableTraceProperties EnableProperty { get; set; } + public ulong MatchAnyKeyword { get; set; } + public ulong MatchAllKeyword { get; set; } + private SessionEnabledProvider() { } // For XML serialization public SessionEnabledProvider( Guid providerId, uint processId, TRACE_PROVIDER_INSTANCE_FLAGS instanceFlags, - EventTraceLevel level, + byte level, EnableTraceProperties enableProperty, ulong matchAnyKeyword, ulong matchAllKeyword) @@ -65,8 +66,14 @@ public override string ToString() public class ParsedEtwSession : IEquatable, IComparable { - public ushort LoggerId; - public List EnabledProviders; + public ushort LoggerId { get; set; } + public List EnabledProviders { get; set; } + + private ParsedEtwSession() // For xml serialization + { + LoggerId = 0; + EnabledProviders = new List(); + } public ParsedEtwSession(ushort Id) { diff --git a/ParsedEtwString.cs b/ParsedEtwString.cs index 5eceef7..c86b6bf 100644 --- a/ParsedEtwString.cs +++ b/ParsedEtwString.cs @@ -21,8 +21,10 @@ namespace etwlib { public class ParsedEtwString : IEquatable, IComparable { - public string Name; - public ulong Value; + public string Name { get; set; } + public ulong Value { get; set; } + + private ParsedEtwString() { } // For XML serialization public ParsedEtwString(string name, ulong value) { diff --git a/ParsedEtwTemplateItem.cs b/ParsedEtwTemplateItem.cs index 47ae406..551bdff 100644 --- a/ParsedEtwTemplateItem.cs +++ b/ParsedEtwTemplateItem.cs @@ -30,18 +30,20 @@ public Backreference(int Index, bool IsCounted) FieldIndex = Index; IsCountedField = IsCounted; } - public string? FieldName; // must be resolved - public int FieldIndex; // match to ParsedEtwTemplateItem.Index - public bool IsCountedField; // if false, size field + public string? FieldName { get; set; } // must be resolved + public int FieldIndex { get; set; } // match to ParsedEtwTemplateItem.Index + public bool IsCountedField { get; set; } // if false, size field } - public string Name; - public TdhInputType InType; - public TdhOutputType OutType; - public int Length; - public string Value; - public Backreference? FieldBackreference; - public int Index; // the index when it was parsed + public string Name { get; set; } + public TdhInputType InType { get; set; } + public TdhOutputType OutType { get; set; } + public int Length { get; set; } + public string Value { get; set; } + public Backreference? FieldBackreference { get; set; } + public int Index { get; set; } // the index when it was parsed + + private ParsedEtwTemplateItem() { } // For XML serialization public ParsedEtwTemplateItem( string name, diff --git a/ProviderParser.cs b/ProviderParser.cs index 0651fe6..d54cb2d 100644 --- a/ProviderParser.cs +++ b/ProviderParser.cs @@ -116,6 +116,7 @@ public static class ProviderParser // provider.Source = providerInfo.SchemaSource == 0 ? "xml" : "MOF"; provider.Name = "(unnamed)"; + provider.HasManifest = IsManifestKnown(provider.Id); if (providerInfo.ProviderNameOffset != 0) { diff --git a/SessionParser.cs b/SessionParser.cs index d4a7d59..16d7731 100644 --- a/SessionParser.cs +++ b/SessionParser.cs @@ -199,7 +199,8 @@ public static class SessionParser pointer, typeof(TRACE_PROVIDER_INSTANCE_INFO))!; if (instance.EnableCount > 0) { - var sessionPointer = pointer; + var sessionPointer = nint.Add(pointer, Marshal.SizeOf( + typeof(TRACE_PROVIDER_INSTANCE_INFO))); for (int j = 0; j < instance.EnableCount; j++) { var sessionInfo = (TRACE_ENABLE_INFO)Marshal.PtrToStructure( @@ -226,6 +227,16 @@ public static class SessionParser Marshal.SizeOf(typeof(TRACE_ENABLE_INFO))); } } + if (instance.NextOffset == 0) + { + // + // The docs aren't clear. They state that if this value is 0, + // there are no more instances, but logically that should not + // ever be the case, as we're guided by the parent struct's + // InstanceCount which should always be accurate.. + // + break; + } pointer = nint.Add(pointer, (int)instance.NextOffset); } return sessions; diff --git a/TraceSession.cs b/TraceSession.cs index 21dd6e9..e219005 100644 --- a/TraceSession.cs +++ b/TraceSession.cs @@ -58,9 +58,16 @@ public virtual void Dispose() GC.SuppressFinalize(this); } - public EnabledProvider AddProvider(Guid Id, EventTraceLevel traceLevel, ulong matchAnyKeyword, ulong matchAllKeyword) + public EnabledProvider AddProvider(Guid Id, string Name, byte traceLevel, ulong matchAnyKeyword, ulong matchAllKeyword) { - var provider = new EnabledProvider(Id, traceLevel, matchAllKeyword, matchAnyKeyword); + var provider = new EnabledProvider(Id, Name, traceLevel, matchAllKeyword, matchAnyKeyword); + m_EnabledProviders.Add(provider); + return provider; + } + + public EnabledProvider AddProvider(Guid Id, string Name, EventTraceLevel traceLevel, ulong matchAnyKeyword, ulong matchAllKeyword) + { + var provider = new EnabledProvider(Id, Name, (byte)traceLevel, matchAllKeyword, matchAnyKeyword); m_EnabledProviders.Add(provider); return provider; } diff --git a/UnitTests/FilterByEventIdTests.cs b/UnitTests/FilterByEventIdTests.cs index 35890a5..0cbd06b 100644 --- a/UnitTests/FilterByEventIdTests.cs +++ b/UnitTests/FilterByEventIdTests.cs @@ -53,7 +53,7 @@ public void Basic(bool Enable, bool Stackwalk) try { var provider = trace.AddProvider( - s_RpcEtwGuid, EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); + s_RpcEtwGuid, "RPC", EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); // // We'll use RpcClientCallStart_V1 and RpcClientCallStop7_V1 @@ -182,9 +182,9 @@ public void Basic(bool Enable, bool Stackwalk) return 1; })); } - catch (AssertFailedException ex) + catch (AssertFailedException) { - throw ex; + throw; } catch (Exception ex) { diff --git a/UnitTests/FilterByExeNameTests.cs b/UnitTests/FilterByExeNameTests.cs index 6272630..aa25329 100644 --- a/UnitTests/FilterByExeNameTests.cs +++ b/UnitTests/FilterByExeNameTests.cs @@ -52,7 +52,7 @@ public void Basic(string ExeName) try { var provider = trace.AddProvider( - s_RpcEtwGuid, EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); + s_RpcEtwGuid, "RPC", EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); provider.SetFilteredExeName(ExeName); trace.Start(); @@ -139,9 +139,9 @@ public void Basic(string ExeName) return 1; })); } - catch (AssertFailedException ex) + catch (AssertFailedException) { - throw ex; + throw; } catch (Exception ex) { diff --git a/UnitTests/FilterByPackageTests.cs b/UnitTests/FilterByPackageTests.cs index 166179b..2f52a94 100644 --- a/UnitTests/FilterByPackageTests.cs +++ b/UnitTests/FilterByPackageTests.cs @@ -110,7 +110,7 @@ private bool TryWindowsStoreApp(string PackageId, string AppId, bool TestPackage try { var provider = trace.AddProvider( - s_LoggingChannel, EventTraceLevel.Verbose, 0xFFFFFFFFFFFFFFFF, 0); + s_LoggingChannel, "LoggingChannel", EventTraceLevel.Verbose, 0xFFFFFFFFFFFFFFFF, 0); if (TestPackageId) { Assert.IsNotNull(PackageId); @@ -214,9 +214,9 @@ private bool TryWindowsStoreApp(string PackageId, string AppId, bool TestPackage return 1; })); } - catch (AssertFailedException ex) + catch (AssertFailedException) { - throw ex; + throw; } catch (Exception ex) { diff --git a/UnitTests/FilterByPayloadTests.cs b/UnitTests/FilterByPayloadTests.cs index 7e2a3d0..79af0a4 100644 --- a/UnitTests/FilterByPayloadTests.cs +++ b/UnitTests/FilterByPayloadTests.cs @@ -70,7 +70,7 @@ public void IntegerEquality( }; var provider = trace.AddProvider( - s_WinKernelRegistryGuid, EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); + s_WinKernelRegistryGuid, "WinKernelReg", EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); provider.AddPayloadFilters(filters); trace.Start(); @@ -181,9 +181,9 @@ public void IntegerEquality( return 1; })); } - catch (AssertFailedException ex) + catch (AssertFailedException) { - throw ex; + throw; } catch (Exception ex) { @@ -229,7 +229,7 @@ public void IntegerRange( } var provider = trace.AddProvider( - s_WinKernelRegistryGuid, EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); + s_WinKernelRegistryGuid, "WinKernelReg", EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); provider.AddPayloadFilters(filters); trace.Start(); @@ -323,9 +323,9 @@ public void IntegerRange( return 1; })); } - catch (AssertFailedException ex) + catch (AssertFailedException) { - throw ex; + throw; } catch (Exception ex) { @@ -372,7 +372,7 @@ public void StringEquality( } var provider = trace.AddProvider( - s_WinKernelRegistryGuid, EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); + s_WinKernelRegistryGuid, "WinKernelReg", EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); provider.AddPayloadFilters(filters); trace.Start(); @@ -481,9 +481,9 @@ public void StringEquality( return 1; })); } - catch (AssertFailedException ex) + catch (AssertFailedException) { - throw ex; + throw; } catch (Exception ex) { @@ -572,7 +572,7 @@ public void MultiplePredicates( } var provider = trace.AddProvider( - s_WinKernelRegistryGuid, EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); + s_WinKernelRegistryGuid, "WinKernelReg", EventTraceLevel.Information, 0xFFFFFFFFFFFFFFFF, 0); provider.AddPayloadFilters(filters); trace.Start(); @@ -696,9 +696,9 @@ public void MultiplePredicates( return 1; })); } - catch (AssertFailedException ex) + catch (AssertFailedException) { - throw ex; + throw; } catch (Exception ex) { diff --git a/UnitTests/FilterByProcessTests.cs b/UnitTests/FilterByProcessTests.cs index eb7f52d..a476c2f 100644 --- a/UnitTests/FilterByProcessTests.cs +++ b/UnitTests/FilterByProcessTests.cs @@ -58,7 +58,7 @@ public void Basic(int ProcessCount) p => p.Id).Take(ProcessCount).ToList(); Debug.Assert(targets.Count > 0); var provider = trace.AddProvider( - s_RpcEtwGuid, EventTraceLevel.LogAlways, 0xFFFFFFFFFFFFFFFF, 0); + s_RpcEtwGuid, "RPC", EventTraceLevel.LogAlways, 0xFFFFFFFFFFFFFFFF, 0); provider.SetProcessFilter(targets); trace.Start(); diff --git a/UnitTests/FilterByStackwalkTests.cs b/UnitTests/FilterByStackwalkTests.cs index e0ebae6..5ff2338 100644 --- a/UnitTests/FilterByStackwalkTests.cs +++ b/UnitTests/FilterByStackwalkTests.cs @@ -55,7 +55,7 @@ public void LevelKw( try { var provider = trace.AddProvider( - s_WinKernelRegistryGuid, Level, (ulong)MatchAnyKeyword, 0); + s_WinKernelRegistryGuid, "WinKernelReg", Level, (ulong)MatchAnyKeyword, 0); provider.SetStackwalkLevelKw(Level, (ulong)MatchAnyKeyword, 0, Enable); trace.Start(); @@ -175,9 +175,9 @@ public void LevelKw( return 1; })); } - catch (AssertFailedException ex) + catch (AssertFailedException) { - throw ex; + throw; } catch (Exception ex) { diff --git a/UnitTests/RealTimeTraceTests.cs b/UnitTests/RealTimeTraceTests.cs index 8937d88..cb1b5c9 100644 --- a/UnitTests/RealTimeTraceTests.cs +++ b/UnitTests/RealTimeTraceTests.cs @@ -48,7 +48,7 @@ public void Basic(EventTraceLevel Level) { try { - var provider = trace.AddProvider(s_RpcEtwGuid, Level, 0xFFFFFFFFFFFFFFFF, 0); + var provider = trace.AddProvider(s_RpcEtwGuid, "RPC", Level, 0xFFFFFFFFFFFFFFFF, 0); trace.Start(); // diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index aa3fc0b..554b6b4 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -1,7 +1,7 @@  - net7.0-windows + net8.0-windows true true true diff --git a/etwlib.csproj b/etwlib.csproj index 480466f..0d2fac4 100644 --- a/etwlib.csproj +++ b/etwlib.csproj @@ -1,7 +1,7 @@ - net7.0-windows + net8.0-windows7.0 enable enable True @@ -17,7 +17,7 @@ True 1.1.0 1.1.0 - 1.1.0 + 1.6.0