diff --git a/src/EventLogExpert.Eventing/EventLogExpert.Eventing.csproj b/src/EventLogExpert.Eventing/EventLogExpert.Eventing.csproj
index b896afabf..a4c4a5669 100644
--- a/src/EventLogExpert.Eventing/EventLogExpert.Eventing.csproj
+++ b/src/EventLogExpert.Eventing/EventLogExpert.Eventing.csproj
@@ -17,6 +17,7 @@
+
diff --git a/src/EventLogExpert.Eventing/Interop/NativeMethods.Evt.cs b/src/EventLogExpert.Eventing/Interop/NativeMethods.Evt.cs
index f0d7d3a3e..c26810fd4 100644
--- a/src/EventLogExpert.Eventing/Interop/NativeMethods.Evt.cs
+++ b/src/EventLogExpert.Eventing/Interop/NativeMethods.Evt.cs
@@ -71,17 +71,7 @@ internal static partial class NativeMethods
case (int)EvtVariantType.FileTime:
return DateTime.FromFileTimeUtc((long)variant.FileTimeVal);
case (int)EvtVariantType.SysTime:
- var sysTime = Marshal.PtrToStructure(variant.SysTimeVal);
-
- return new DateTime(
- sysTime.Year,
- sysTime.Month,
- sysTime.Day,
- sysTime.Hour,
- sysTime.Minute,
- sysTime.Second,
- sysTime.Milliseconds,
- DateTimeKind.Utc);
+ return ReadSysTime(variant);
case (int)EvtVariantType.Sid:
return variant.SidVal == IntPtr.Zero ? null : new SecurityIdentifier(variant.SidVal);
case (int)EvtVariantType.HexInt32:
@@ -129,6 +119,47 @@ internal static partial class NativeMethods
}
}
+ internal static EventProperty ConvertVariantToProperty(EvtVariant variant)
+ {
+ switch (variant.Type)
+ {
+ case (int)EvtVariantType.SByte:
+ return variant.SByteVal;
+ case (int)EvtVariantType.Byte:
+ return variant.ByteVal;
+ case (int)EvtVariantType.Int16:
+ return variant.Int16Val;
+ case (int)EvtVariantType.UInt16:
+ return variant.UInt16Val;
+ case (int)EvtVariantType.Int32:
+ case (int)EvtVariantType.HexInt32:
+ return variant.Int32Val;
+ case (int)EvtVariantType.UInt32:
+ return variant.UInt32Val;
+ case (int)EvtVariantType.Int64:
+ return variant.Int64Val;
+ case (int)EvtVariantType.UInt64:
+ case (int)EvtVariantType.HexInt64:
+ return variant.UInt64Val;
+ case (int)EvtVariantType.Single:
+ return variant.SingleVal;
+ case (int)EvtVariantType.Double:
+ return variant.DoubleVal;
+ case (int)EvtVariantType.Boolean:
+ return variant.BooleanVal != 0;
+ case (int)EvtVariantType.SizeT:
+ return variant.SizeTVal;
+ case (int)EvtVariantType.FileTime:
+ return DateTime.FromFileTimeUtc((long)variant.FileTimeVal);
+ case (int)EvtVariantType.SysTime:
+ return ReadSysTime(variant);
+ default:
+ // Reference shapes reuse the boxing converter (reference types add no allocation; the rare boxed
+ // Guid is acceptable). Null / unsupported types throw, preserving the boxed path's ?? throw contract.
+ return EventProperty.FromReference(ConvertVariant(variant) ?? throw new InvalidDataException());
+ }
+ }
+
/// Closes an open handle
[LibraryImport(EventLogApi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
@@ -621,7 +652,7 @@ internal static EventRecord RenderEvent(EvtHandle eventHandle)
}
}
- internal static IReadOnlyList