From 13b4d3ad7ad12b5f4d78e66171dd6206ca00b8e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20K=C5=82ys?= Date: Mon, 9 Feb 2026 10:42:20 +0100 Subject: [PATCH] EventViewerX: honor Reflection mode and avoid explicit factory overriding reflection routing --- Sources/EventViewerX/EventObjectSlim.cs | 86 ++++++++++++++++++------- 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/Sources/EventViewerX/EventObjectSlim.cs b/Sources/EventViewerX/EventObjectSlim.cs index b1a3dd2..8ac3d27 100644 --- a/Sources/EventViewerX/EventObjectSlim.cs +++ b/Sources/EventViewerX/EventObjectSlim.cs @@ -59,8 +59,11 @@ public RuleFactoryRegistration(NamedEvents namedEvent, string logName, IReadOnly public Type? RuleType { get; } } - private static readonly Dictionary _eventRuleTypes = new(); - private static readonly Dictionary<(int EventId, string LogName), List> _eventHandlers = new(); + private static readonly Dictionary _reflectionRuleTypes = new(); + private static readonly Dictionary<(int EventId, string LogName), List> _reflectionHandlers = new(); + + private static readonly Dictionary _explicitRuleTypes = new(); + private static readonly Dictionary<(int EventId, string LogName), List> _explicitHandlers = new(); // AOT-friendly path: explicit, delegate-based rule registration. private static readonly Dictionary _ruleFactories = new(); @@ -145,7 +148,7 @@ public static void RegisterRuleFactory( _ruleFactories[namedEvent] = reg; if (ruleType is not null) { - _eventRuleTypes[namedEvent] = ruleType; + _explicitRuleTypes[namedEvent] = ruleType; } foreach (var eventId in ids) { @@ -160,9 +163,9 @@ public static void RegisterRuleFactory( if (ruleType is not null) { var legacyKey = (eventId, normalizedLog); - if (!_eventHandlers.TryGetValue(legacyKey, out var legacyList)) { + if (!_explicitHandlers.TryGetValue(legacyKey, out var legacyList)) { legacyList = new List(); - _eventHandlers[legacyKey] = legacyList; + _explicitHandlers[legacyKey] = legacyList; } if (!legacyList.Contains(ruleType)) { legacyList.Add(ruleType); @@ -211,14 +214,14 @@ private static void RegisterEventRuleType(Type ruleType) { #pragma warning disable SYSLIB0050 var instance = (EventRuleBase)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(ruleType); #pragma warning restore SYSLIB0050 - _eventRuleTypes[instance.NamedEvent] = ruleType; + _reflectionRuleTypes[instance.NamedEvent] = ruleType; foreach (var eventId in instance.EventIds) { var key = (eventId, instance.LogName); - if (!_eventHandlers.ContainsKey(key)) { - _eventHandlers[key] = new List(); + if (!_reflectionHandlers.ContainsKey(key)) { + _reflectionHandlers[key] = new List(); } - _eventHandlers[key].Add(ruleType); + _reflectionHandlers[key].Add(ruleType); } } catch { return; @@ -226,14 +229,14 @@ private static void RegisterEventRuleType(Type ruleType) { } else { var attr = ruleType.GetCustomAttribute(); if (attr != null) { - _eventRuleTypes[attr.NamedEvent] = ruleType; + _reflectionRuleTypes[attr.NamedEvent] = ruleType; foreach (var eventId in attr.EventIds) { var key = (eventId, attr.LogName); - if (!_eventHandlers.ContainsKey(key)) { - _eventHandlers[key] = new List(); + if (!_reflectionHandlers.ContainsKey(key)) { + _reflectionHandlers[key] = new List(); } - _eventHandlers[key].Add(ruleType); + _reflectionHandlers[key].Add(ruleType); } } } @@ -243,27 +246,59 @@ private static void RegisterEventRuleType(Type ruleType) { /// Gets all event rule types that can handle the given event. /// public static List GetEventHandlers(int eventId, string logName) { - EnsureInitialized(); var key = (eventId, logName); - return _eventHandlers.TryGetValue(key, out var handlers) ? handlers : new List(); + var mode = _discoveryMode; + EnsureInitialized(); + + if (mode == EventRuleDiscoveryMode.ExplicitOnly) { + return _explicitHandlers.TryGetValue(key, out var explicitHandlers) ? explicitHandlers : new List(); + } + if (mode == EventRuleDiscoveryMode.Reflection) { + return _reflectionHandlers.TryGetValue(key, out var reflectionHandlers) ? reflectionHandlers : new List(); + } + + var combined = new List(); + if (_explicitHandlers.TryGetValue(key, out var explicitList)) { + combined.AddRange(explicitList); + } + if (_reflectionHandlers.TryGetValue(key, out var reflectionList)) { + foreach (var t in reflectionList) { + if (!combined.Contains(t)) { + combined.Add(t); + } + } + } + return combined; } /// /// Gets the event rule type for a named event. /// public static Type? GetEventRuleType(NamedEvents namedEvent) { + var mode = _discoveryMode; EnsureInitialized(); - return _eventRuleTypes.TryGetValue(namedEvent, out var type) ? type : null; + + if (mode == EventRuleDiscoveryMode.ExplicitOnly) { + return _explicitRuleTypes.TryGetValue(namedEvent, out var explicitType) ? explicitType : null; + } + if (mode == EventRuleDiscoveryMode.Reflection) { + return _reflectionRuleTypes.TryGetValue(namedEvent, out var reflectionType) ? reflectionType : null; + } + + return _explicitRuleTypes.TryGetValue(namedEvent, out var type) ? type + : _reflectionRuleTypes.TryGetValue(namedEvent, out var reflection) ? reflection + : null; } /// /// Creates an event rule instance from an . /// public static EventObjectSlim? CreateEventRule(EventObject eventObject, List targetNamedEvents) { + var mode = _discoveryMode; EnsureInitialized(); foreach (var namedEvent in targetNamedEvents) { - if (_ruleFactories.TryGetValue(namedEvent, out var reg)) { + if (mode != EventRuleDiscoveryMode.Reflection && _ruleFactories.TryGetValue(namedEvent, out var reg)) { try { if (reg.CanHandle != null && !reg.CanHandle(eventObject)) { continue; @@ -282,8 +317,11 @@ public static List GetEventHandlers(int eventId, string logName) { } } - var ruleType = GetEventRuleType(namedEvent); - if (ruleType == null) { + if (mode == EventRuleDiscoveryMode.ExplicitOnly) { + continue; + } + + if (!_reflectionRuleTypes.TryGetValue(namedEvent, out var ruleType) || ruleType == null) { continue; } @@ -333,12 +371,13 @@ private static NamedEvents GetNamedEventForType(Type type) { /// Gets event IDs and log name for named events using rule classes. /// public static Dictionary> GetEventInfoForNamedEvents(List namedEvents) { + var mode = _discoveryMode; EnsureInitialized(); var eventInfoDict = new Dictionary>(); foreach (var namedEvent in namedEvents) { - if (_ruleFactories.TryGetValue(namedEvent, out var reg)) { + if (mode != EventRuleDiscoveryMode.Reflection && _ruleFactories.TryGetValue(namedEvent, out var reg)) { if (!eventInfoDict.TryGetValue(reg.LogName, out var idSet)) { idSet = new HashSet(); eventInfoDict[reg.LogName] = idSet; @@ -349,8 +388,11 @@ public static Dictionary> GetEventInfoForNamedEvents(List