From e5dd47ef100f3c1cc2ad69a549c9bff3a07fc1dc Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Fri, 22 Aug 2025 14:12:45 +0100 Subject: [PATCH 1/7] Simplify pointer arithmetic in `NativeWrapper` Avoids an unnecessary cast to long on 32-bit systems, which could introduce inefficiency without providing any benefit. --- .../Diagnostics/Reader/NativeWrapper.cs | 315 +++++++++--------- 1 file changed, 159 insertions(+), 156 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs index 401c40e866f771..eb6bcb8da08508 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs @@ -789,99 +789,100 @@ public static object EvtGetLogInfo(EventLogHandle handle, UnsafeNativeMethods.Ev public static void EvtRenderBufferWithContextSystem(EventLogHandle contextHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtRenderFlags flag, SystemProperties systemProperties) { - IntPtr buffer = IntPtr.Zero; - IntPtr pointer = IntPtr.Zero; - int bufferNeeded; - int propCount; - - try + unsafe { - bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); - if (!status) + IntPtr buffer = IntPtr.Zero; + int bufferNeeded; + int propCount; + + try { - int error = Marshal.GetLastWin32Error(); - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } + bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); + if (!status) + { + int error = Marshal.GetLastWin32Error(); + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); - int win32Error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(win32Error); + buffer = Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); + int win32Error = Marshal.GetLastWin32Error(); + if (!status) + EventLogException.Throw(win32Error); - pointer = buffer; - // Read each Variant structure - for (int i = 0; i < propCount; i++) - { - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(pointer); - switch (i) + UnsafeNativeMethods.EvtVariant* ptr = (UnsafeNativeMethods.EvtVariant*)buffer; + // Read each Variant structure + for (int i = 0; i < propCount; i++) { - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderName: - systemProperties.ProviderName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderGuid: - systemProperties.ProviderId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventID: - systemProperties.Id = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemQualifiers: - systemProperties.Qualifiers = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemLevel: - systemProperties.Level = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemTask: - systemProperties.Task = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemOpcode: - systemProperties.Opcode = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemKeywords: - systemProperties.Keywords = (ulong?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeHexInt64); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemTimeCreated: - systemProperties.TimeCreated = (DateTime?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeFileTime); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventRecordId: - systemProperties.RecordId = (ulong?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemActivityID: - systemProperties.ActivityId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemRelatedActivityID: - systemProperties.RelatedActivityId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProcessID: - systemProperties.ProcessId = (uint?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemThreadID: - systemProperties.ThreadId = (uint?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemChannel: - systemProperties.ChannelName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemComputer: - systemProperties.ComputerName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemUserID: - systemProperties.UserId = (SecurityIdentifier)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeSid); - break; - case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemVersion: - systemProperties.Version = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); - break; - default: - Debug.Fail($"Do not understand EVT_SYSTEM_PROPERTY_ID {i}. A new case is needed."); - break; + UnsafeNativeMethods.EvtVariant varVal = ptr[i]; + switch (i) + { + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderName: + systemProperties.ProviderName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderGuid: + systemProperties.ProviderId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventID: + systemProperties.Id = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemQualifiers: + systemProperties.Qualifiers = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemLevel: + systemProperties.Level = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemTask: + systemProperties.Task = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemOpcode: + systemProperties.Opcode = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemKeywords: + systemProperties.Keywords = (ulong?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeHexInt64); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemTimeCreated: + systemProperties.TimeCreated = (DateTime?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeFileTime); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventRecordId: + systemProperties.RecordId = (ulong?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemActivityID: + systemProperties.ActivityId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemRelatedActivityID: + systemProperties.RelatedActivityId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProcessID: + systemProperties.ProcessId = (uint?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemThreadID: + systemProperties.ThreadId = (uint?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemChannel: + systemProperties.ChannelName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemComputer: + systemProperties.ComputerName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemUserID: + systemProperties.UserId = (SecurityIdentifier)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeSid); + break; + case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemVersion: + systemProperties.Version = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); + break; + default: + Debug.Fail($"Do not understand EVT_SYSTEM_PROPERTY_ID {i}. A new case is needed."); + break; + } } - pointer = new IntPtr(((long)pointer + Marshal.SizeOf(varVal))); } - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + finally + { + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal(buffer); + } } } @@ -889,45 +890,45 @@ public static void EvtRenderBufferWithContextSystem(EventLogHandle contextHandle // Render with Context = ContextUser or ContextValues (with user defined Xpath query strings) public static IList EvtRenderBufferWithContextUserOrValues(EventLogHandle contextHandle, EventLogHandle eventHandle) { - IntPtr buffer = IntPtr.Zero; - IntPtr pointer; - int bufferNeeded; - int propCount; - UnsafeNativeMethods.EvtRenderFlags flag = UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues; - - try + unsafe { - bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); - if (!status) + IntPtr buffer = IntPtr.Zero; + int bufferNeeded; + int propCount; + UnsafeNativeMethods.EvtRenderFlags flag = UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues; + + try { - int error = Marshal.GetLastWin32Error(); - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } + bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); + if (!status) + { + int error = Marshal.GetLastWin32Error(); + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); - int win32Error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(win32Error); + buffer = Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); + int win32Error = Marshal.GetLastWin32Error(); + if (!status) + EventLogException.Throw(win32Error); - List valuesList = new List(propCount); - if (propCount > 0) - { - pointer = buffer; - for (int i = 0; i < propCount; i++) + List valuesList = new List(propCount); + if (propCount > 0) { - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(pointer); - valuesList.Add(ConvertToObject(varVal)); - pointer = new IntPtr(((long)pointer + Marshal.SizeOf(varVal))); + UnsafeNativeMethods.EvtVariant* ptr = (UnsafeNativeMethods.EvtVariant*)buffer; + for (int i = 0; i < propCount; i++) + { + valuesList.Add(ConvertToObject(ptr[i])); + } } + return valuesList; + } + finally + { + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal(buffer); } - return valuesList; - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); } } @@ -985,56 +986,58 @@ public static string EvtFormatMessageRenderName(EventLogHandle pmHandle, EventLo // The EvtFormatMessage used for the obtaining of the Keywords names. public static IEnumerable EvtFormatMessageRenderKeywords(EventLogHandle pmHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtFormatMessageFlags flag) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - Span emptyBuffer = [ '\0' ]; // issue: https://github.com/dotnet/runtime/issues/100198 - - try + unsafe { - List keywordsList = new List(); - bool status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, 0, emptyBuffer, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); + IntPtr buffer = IntPtr.Zero; + int bufferNeeded; + Span emptyBuffer = ['\0']; // issue: https://github.com/dotnet/runtime/issues/100198 - if (!status) + try { - if (IsNotFoundCase(error)) + List keywordsList = new List(); + bool status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, 0, emptyBuffer, out bufferNeeded); + int error = Marshal.GetLastWin32Error(); + + if (!status) { - return keywordsList.AsReadOnly(); + if (IsNotFoundCase(error)) + { + return keywordsList.AsReadOnly(); + } + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); } - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - buffer = Marshal.AllocHGlobal(bufferNeeded * 2); - status = UnsafeNativeMethods.EvtFormatMessageBuffer(pmHandle, eventHandle, 0, 0, IntPtr.Zero, flag, bufferNeeded, buffer, out bufferNeeded); - error = Marshal.GetLastWin32Error(); - if (!status) - { - if (IsNotFoundCase(error)) + buffer = Marshal.AllocHGlobal(bufferNeeded * 2); + status = UnsafeNativeMethods.EvtFormatMessageBuffer(pmHandle, eventHandle, 0, 0, IntPtr.Zero, flag, bufferNeeded, buffer, out bufferNeeded); + error = Marshal.GetLastWin32Error(); + if (!status) { - return keywordsList; + if (IsNotFoundCase(error)) + { + return keywordsList; + } + EventLogException.Throw(error); } - EventLogException.Throw(error); - } - IntPtr pointer = buffer; + ushort* ptr = (ushort*)buffer; - while (true) + while (true) + { + string s = Marshal.PtrToStringUni((IntPtr)ptr); + if (string.IsNullOrEmpty(s)) + break; + keywordsList.Add(s); + ptr += s.Length + 1; // move to next string (including null terminator) + } + + return keywordsList.AsReadOnly(); + } + finally { - string s = Marshal.PtrToStringUni(pointer); - if (string.IsNullOrEmpty(s)) - break; - keywordsList.Add(s); - // nr of bytes = # chars * 2 + 2 bytes for character '\0'. - pointer = new IntPtr((long)pointer + (s.Length * 2) + 2); + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal(buffer); } - - return keywordsList.AsReadOnly(); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); } } From 35812aec36b71d073d722a51cb71735bb88af328 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Fri, 22 Aug 2025 15:46:10 +0100 Subject: [PATCH 2/7] address review comments --- .../src/System/Diagnostics/Reader/UnsafeNativeMethods.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs index 9f9e2862e0293d..f498e7e31c2b39 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs @@ -106,10 +106,7 @@ internal struct SystemTime public short Milliseconds; } - [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)] -#pragma warning disable 618 // System.Core still uses SecurityRuleSet.Level1 - [SecurityCritical(SecurityCriticalScope.Everything)] -#pragma warning restore 618 + [StructLayout(LayoutKind.Explicit)] internal struct EvtVariant { [FieldOffset(0)] From 8f727a51a77de7759a54377774171409776cc2f6 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Fri, 22 Aug 2025 16:45:06 +0100 Subject: [PATCH 3/7] Replace `PtrToStructure` with unsafe pointers --- .../Diagnostics/Reader/NativeWrapper.cs | 390 +++++++++--------- .../Diagnostics/Reader/UnsafeNativeMethods.cs | 28 +- 2 files changed, 220 insertions(+), 198 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs index eb6bcb8da08508..9b0eb3bb0bd471 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs @@ -352,129 +352,138 @@ public static void EvtUpdateBookmark(EventLogHandle bookmark, EventLogHandle eve public static object EvtGetEventInfo(EventLogHandle handle, UnsafeNativeMethods.EvtEventPropertyId enumType) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - - try + unsafe { - bool status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, 0, IntPtr.Zero, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); - if (!status) + UnsafeNativeMethods.EvtVariant* pBuffer = null; + int bufferNeeded; + + try { - if (error != Interop.Errors.ERROR_SUCCESS - && error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + bool status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, 0, null, out bufferNeeded); + int error = Marshal.GetLastWin32Error(); + if (!status) { + if (error != Interop.Errors.ERROR_SUCCESS + && error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + { + EventLogException.Throw(error); + } + } + pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, bufferNeeded, pBuffer, out bufferNeeded); + error = Marshal.GetLastWin32Error(); + if (!status) EventLogException.Throw(error); + + return ConvertToObject(*pBuffer); + } + finally + { + if (pBuffer is not null) + { + Marshal.FreeHGlobal((IntPtr)pBuffer); } } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, bufferNeeded, buffer, out bufferNeeded); - error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(error); - - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(buffer); - return ConvertToObject(varVal); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); } } public static object EvtGetQueryInfo(EventLogHandle handle, UnsafeNativeMethods.EvtQueryPropertyId enumType) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded = 0; - try + unsafe { - bool status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, 0, IntPtr.Zero, ref bufferNeeded); - int error = Marshal.GetLastWin32Error(); - if (!status) + UnsafeNativeMethods.EvtVariant* pBuffer = null; + int bufferNeeded = 0; + try { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + bool status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, 0, null, ref bufferNeeded); + int error = Marshal.GetLastWin32Error(); + if (!status) + { + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, bufferNeeded, pBuffer, ref bufferNeeded); + error = Marshal.GetLastWin32Error(); + if (!status) EventLogException.Throw(error); - } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, bufferNeeded, buffer, ref bufferNeeded); - error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(error); - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(buffer); - return ConvertToObject(varVal); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + return ConvertToObject(*pBuffer); + } + finally + { + if (pBuffer is not null) + { + Marshal.FreeHGlobal((IntPtr)pBuffer); + } + } } } public static object EvtGetPublisherMetadataProperty(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - - try + unsafe { - bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, IntPtr.Zero, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); - if (!status) + UnsafeNativeMethods.EvtVariant* pBuffer = null; + int bufferNeeded; + + try { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, null, out bufferNeeded); + int error = Marshal.GetLastWin32Error(); + if (!status) + { + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, pBuffer, out bufferNeeded); + error = Marshal.GetLastWin32Error(); + if (!status) EventLogException.Throw(error); - } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, buffer, out bufferNeeded); - error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(error); - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(buffer); - return ConvertToObject(varVal); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + return ConvertToObject(*pBuffer); + } + finally + { + if (pBuffer is not null) + { + Marshal.FreeHGlobal((IntPtr)pBuffer); + } + } } } internal static EventLogHandle EvtGetPublisherMetadataPropertyHandle(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId) { - IntPtr buffer = IntPtr.Zero; - try + unsafe { - int bufferNeeded; - bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, IntPtr.Zero, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); - if (!status) + UnsafeNativeMethods.EvtVariant* pBuffer = null; + try { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + int bufferNeeded; + bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, null, out bufferNeeded); + int error = Marshal.GetLastWin32Error(); + if (!status) + { + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, pBuffer, out bufferNeeded); + error = Marshal.GetLastWin32Error(); + if (!status) EventLogException.Throw(error); - } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, buffer, out bufferNeeded); - error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(error); - // - // note: there is a case where returned variant does have allocated native resources - // associated with (e.g. ConfigArrayHandle). If PtrToStructure throws, then we would - // leak that resource - fortunately PtrToStructure only throws InvalidArgument which - // is a logic error - not a possible runtime condition here. Other System exceptions - // shouldn't be handled anyhow and the application will terminate. - // - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(buffer); - return ConvertToSafeHandle(varVal); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + return ConvertToSafeHandle(*pBuffer); + } + finally + { + if (pBuffer is not null) + { + Marshal.FreeHGlobal((IntPtr)pBuffer); + } + } } } @@ -523,99 +532,104 @@ public static string EvtFormatMessage(EventLogHandle handle, uint msgId) public static object EvtGetObjectArrayProperty(EventLogHandle objArrayHandle, int index, int thePropertyId) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - - try + unsafe { - bool status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, 0, IntPtr.Zero, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); + UnsafeNativeMethods.EvtVariant* pBuffer = null; + int bufferNeeded; - if (!status) + try { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + bool status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, 0, null, out bufferNeeded); + int error = Marshal.GetLastWin32Error(); + + if (!status) + { + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, bufferNeeded, pBuffer, out bufferNeeded); + error = Marshal.GetLastWin32Error(); + if (!status) EventLogException.Throw(error); - } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, bufferNeeded, buffer, out bufferNeeded); - error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(error); - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(buffer); - return ConvertToObject(varVal); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + return ConvertToObject(*pBuffer); + } + finally + { + if (pBuffer is not null) + { + Marshal.FreeHGlobal((IntPtr)pBuffer); + } + } } } public static object EvtGetEventMetadataProperty(EventLogHandle handle, UnsafeNativeMethods.EvtEventMetadataPropertyId enumType) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - - try + unsafe { - bool status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, 0, IntPtr.Zero, out bufferNeeded); - int win32Error = Marshal.GetLastWin32Error(); - if (!status) + UnsafeNativeMethods.EvtVariant* pBuffer = null; + int bufferNeeded; + + try { - if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + bool status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, 0, null, out bufferNeeded); + int win32Error = Marshal.GetLastWin32Error(); + if (!status) + { + if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(win32Error); + } + pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, bufferNeeded, pBuffer, out bufferNeeded); + win32Error = Marshal.GetLastWin32Error(); + if (!status) EventLogException.Throw(win32Error); - } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, bufferNeeded, buffer, out bufferNeeded); - win32Error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(win32Error); - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(buffer); - return ConvertToObject(varVal); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + return ConvertToObject(*pBuffer); + } + finally + { + if (pBuffer is not null) + { + Marshal.FreeHGlobal((IntPtr)pBuffer); + } + } } } public static object EvtGetChannelConfigProperty(EventLogHandle handle, UnsafeNativeMethods.EvtChannelConfigPropertyId enumType) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - - try + unsafe { - bool status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, 0, IntPtr.Zero, out bufferNeeded); - int win32Error = Marshal.GetLastWin32Error(); - if (!status) + UnsafeNativeMethods.EvtVariant* pBuffer = null; + int bufferNeeded; + + try { - if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + bool status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, 0, null, out bufferNeeded); + int win32Error = Marshal.GetLastWin32Error(); + if (!status) + { + if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(win32Error); + } + pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, bufferNeeded, pBuffer, out bufferNeeded); + win32Error = Marshal.GetLastWin32Error(); + if (!status) EventLogException.Throw(win32Error); - } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, bufferNeeded, buffer, out bufferNeeded); - win32Error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(win32Error); - // - // note: there is a case where returned variant does have allocated native resources - // associated with (e.g. ConfigArrayHandle). If PtrToStructure throws, then we would - // leak that resource - fortunately PtrToStructure only throws InvalidArgument which - // is a logic error - not a possible runtime condition here. Other System exceptions - // shouldn't be handled anyhow and the application will terminate. - // - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(buffer); - return ConvertToObject(varVal); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + return ConvertToObject(*pBuffer); + } + finally + { + if (pBuffer is not null) + { + Marshal.FreeHGlobal((IntPtr)pBuffer); + } + } } } @@ -759,31 +773,34 @@ public static string EvtNextPublisherId(EventLogHandle handle, ref bool finish) public static object EvtGetLogInfo(EventLogHandle handle, UnsafeNativeMethods.EvtLogPropertyId enumType) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - - try + unsafe { - bool status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, 0, IntPtr.Zero, out bufferNeeded); - int win32Error = Marshal.GetLastWin32Error(); - if (!status) + UnsafeNativeMethods.EvtVariant* pBuffer = null; + int bufferNeeded; + + try { - if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + bool status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, 0, null, out bufferNeeded); + int win32Error = Marshal.GetLastWin32Error(); + if (!status) + { + if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(win32Error); + } + pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, bufferNeeded, pBuffer, out bufferNeeded); + win32Error = Marshal.GetLastWin32Error(); + if (!status) EventLogException.Throw(win32Error); + return ConvertToObject(*pBuffer); + } + finally + { + if (pBuffer is not null) + { + Marshal.FreeHGlobal((IntPtr)pBuffer); + } } - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, bufferNeeded, buffer, out bufferNeeded); - win32Error = Marshal.GetLastWin32Error(); - if (!status) - EventLogException.Throw(win32Error); - - UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure(buffer); - return ConvertToObject(varVal); - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); } } @@ -1127,7 +1144,7 @@ public static string EvtFormatMessageFormatDescription(EventLogHandle handle, Ev return new string(buffer, 0, len); } - private static object ConvertToObject(UnsafeNativeMethods.EvtVariant val) + private static unsafe object ConvertToObject(UnsafeNativeMethods.EvtVariant val) { switch (val.Type) { @@ -1164,13 +1181,18 @@ private static object ConvertToObject(UnsafeNativeMethods.EvtVariant val) case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSid: return (val.SidVal == IntPtr.Zero) ? null : new SecurityIdentifier(val.SidVal); case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid: - return (val.GuidReference == IntPtr.Zero) ? Guid.Empty : Marshal.PtrToStructure(val.GuidReference); +#if NET + return (val.GuidReference == IntPtr.Zero) ? Guid.Empty : new Guid(MemoryMarshal.CreateReadOnlySpan(ref *(byte*)val.GuidReference, sizeof(Guid))); +#else + Debug.Assert(BitConverter.IsLittleEndian); + return (val.GuidReference == IntPtr.Zero) ? Guid.Empty : *(Guid*)val.GuidReference; +#endif case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeEvtHandle: return ConvertToSafeHandle(val); case (int)(int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeFileTime: return DateTime.FromFileTime((long)val.FileTime); case (int)(int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSysTime: - UnsafeNativeMethods.SystemTime sysTime = Marshal.PtrToStructure(val.SystemTime); + UnsafeNativeMethods.SystemTime sysTime = *(UnsafeNativeMethods.SystemTime*)val.SystemTime; return new DateTime(sysTime.Year, sysTime.Month, sysTime.Day, sysTime.Hour, sysTime.Minute, sysTime.Second, sysTime.Milliseconds); case (int)(int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSizeT: return val.SizeT; diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs index f498e7e31c2b39..44beb4d1d9fe18 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs @@ -485,20 +485,20 @@ internal static partial bool EvtNext( [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtGetEventInfo( + internal static unsafe partial bool EvtGetEventInfo( EventLogHandle eventHandle, EvtEventPropertyId propertyId, int bufferSize, - IntPtr bufferPtr, + EvtVariant* bufferPtr, out int bufferUsed); [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtGetQueryInfo( + internal static unsafe partial bool EvtGetQueryInfo( EventLogHandle queryHandle, EvtQueryPropertyId propertyId, int bufferSize, - IntPtr buffer, + EvtVariant* buffer, ref int bufferRequired); // PUBLISHER METADATA @@ -512,12 +512,12 @@ internal static partial EventLogHandle EvtOpenPublisherMetadata( [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtGetPublisherMetadataProperty( + internal static unsafe partial bool EvtGetPublisherMetadataProperty( EventLogHandle publisherMetadataHandle, EvtPublisherMetadataPropertyId propertyId, int flags, int publisherMetadataPropertyBufferSize, - IntPtr publisherMetadataPropertyBuffer, + EvtVariant* publisherMetadataPropertyBuffer, out int publisherMetadataPropertyBufferUsed); // NEW @@ -530,13 +530,13 @@ internal static partial bool EvtGetObjectArraySize( [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtGetObjectArrayProperty( + internal static unsafe partial bool EvtGetObjectArrayProperty( EventLogHandle objectArray, int propertyId, int arrayIndex, int flags, int propertyValueBufferSize, - IntPtr propertyValueBuffer, + EvtVariant* propertyValueBuffer, out int propertyValueBufferUsed); // NEW 2 @@ -552,12 +552,12 @@ internal static partial EventLogHandle EvtNextEventMetadata( [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtGetEventMetadataProperty( + internal static unsafe partial bool EvtGetEventMetadataProperty( EventLogHandle eventMetadata, EvtEventMetadataPropertyId propertyId, int flags, int eventMetadataPropertyBufferSize, - IntPtr eventMetadataPropertyBuffer, + EvtVariant* eventMetadataPropertyBuffer, out int eventMetadataPropertyBufferUsed); // Channel Configuration Native Api @@ -610,12 +610,12 @@ internal static partial bool EvtSetChannelConfigProperty( [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtGetChannelConfigProperty( + internal static unsafe partial bool EvtGetChannelConfigProperty( EventLogHandle channelConfig, EvtChannelConfigPropertyId propertyId, int flags, int propertyValueBufferSize, - IntPtr propertyValueBuffer, + EvtVariant* propertyValueBuffer, out int propertyValueBufferUsed); // Log Information Native Api @@ -628,11 +628,11 @@ internal static partial EventLogHandle EvtOpenLog( [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtGetLogInfo( + internal static unsafe partial bool EvtGetLogInfo( EventLogHandle log, EvtLogPropertyId propertyId, int propertyValueBufferSize, - IntPtr propertyValueBuffer, + EvtVariant* propertyValueBuffer, out int propertyValueBufferUsed); // LOG MANIPULATION From d4221e6fc8f4226f3ddb91f7aad9bc38f154d1d1 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Fri, 22 Aug 2025 18:19:29 +0100 Subject: [PATCH 4/7] address review comment --- .../src/System/Diagnostics/Reader/NativeWrapper.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs index 9b0eb3bb0bd471..49fe347a4d6a4b 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs @@ -1181,12 +1181,7 @@ private static unsafe object ConvertToObject(UnsafeNativeMethods.EvtVariant val) case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSid: return (val.SidVal == IntPtr.Zero) ? null : new SecurityIdentifier(val.SidVal); case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid: -#if NET - return (val.GuidReference == IntPtr.Zero) ? Guid.Empty : new Guid(MemoryMarshal.CreateReadOnlySpan(ref *(byte*)val.GuidReference, sizeof(Guid))); -#else - Debug.Assert(BitConverter.IsLittleEndian); return (val.GuidReference == IntPtr.Zero) ? Guid.Empty : *(Guid*)val.GuidReference; -#endif case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeEvtHandle: return ConvertToSafeHandle(val); case (int)(int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeFileTime: From 383948539335594e9ae789647128b2bdfa92d06c Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sat, 23 Aug 2025 03:05:35 +0100 Subject: [PATCH 5/7] address comments --- .../Diagnostics/Reader/NativeWrapper.cs | 347 ++++++++---------- .../Diagnostics/Reader/UnsafeNativeMethods.cs | 19 +- 2 files changed, 154 insertions(+), 212 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs index 49fe347a4d6a4b..c28e68af1ac1e6 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs @@ -354,35 +354,30 @@ public static object EvtGetEventInfo(EventLogHandle handle, UnsafeNativeMethods. { unsafe { - UnsafeNativeMethods.EvtVariant* pBuffer = null; - int bufferNeeded; - - try + bool status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, 0, null, out int bufferNeeded); + int error = Marshal.GetLastWin32Error(); + if (!status) { - bool status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, 0, null, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); - if (!status) + if (error != Interop.Errors.ERROR_SUCCESS + && error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) { - if (error != Interop.Errors.ERROR_SUCCESS - && error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - { - EventLogException.Throw(error); - } + EventLogException.Throw(error); } - pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, bufferNeeded, pBuffer, out bufferNeeded); + } + + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + try + { + status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, bufferNeeded, pVar, out bufferNeeded); error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(error); - return ConvertToObject(*pBuffer); + return ConvertToObject(*pVar); } finally { - if (pBuffer is not null) - { - Marshal.FreeHGlobal((IntPtr)pBuffer); - } + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -391,31 +386,27 @@ public static object EvtGetQueryInfo(EventLogHandle handle, UnsafeNativeMethods. { unsafe { - UnsafeNativeMethods.EvtVariant* pBuffer = null; - int bufferNeeded = 0; + bool status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, 0, null, out int bufferNeeded); + int error = Marshal.GetLastWin32Error(); + if (!status) + { + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); try { - bool status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, 0, null, ref bufferNeeded); - int error = Marshal.GetLastWin32Error(); - if (!status) - { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, bufferNeeded, pBuffer, ref bufferNeeded); + status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, bufferNeeded, pVar, out bufferNeeded); error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(error); - return ConvertToObject(*pBuffer); + return ConvertToObject(*pVar); } finally { - if (pBuffer is not null) - { - Marshal.FreeHGlobal((IntPtr)pBuffer); - } + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -424,32 +415,27 @@ public static object EvtGetPublisherMetadataProperty(EventLogHandle pmHandle, Un { unsafe { - UnsafeNativeMethods.EvtVariant* pBuffer = null; - int bufferNeeded; + bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, null, out int bufferNeeded); + int error = Marshal.GetLastWin32Error(); + if (!status) + { + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); try { - bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, null, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); - if (!status) - { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, pBuffer, out bufferNeeded); + status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, pVar, out bufferNeeded); error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(error); - return ConvertToObject(*pBuffer); + return ConvertToObject(*pVar); } finally { - if (pBuffer is not null) - { - Marshal.FreeHGlobal((IntPtr)pBuffer); - } + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -458,31 +444,27 @@ internal static EventLogHandle EvtGetPublisherMetadataPropertyHandle(EventLogHan { unsafe { - UnsafeNativeMethods.EvtVariant* pBuffer = null; + bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, null, out int bufferNeeded); + int error = Marshal.GetLastWin32Error(); + if (!status) + { + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); try { - int bufferNeeded; - bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, null, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); - if (!status) - { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, pBuffer, out bufferNeeded); + status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, pVar, out bufferNeeded); error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(error); - return ConvertToSafeHandle(*pBuffer); + return ConvertToSafeHandle(*pVar); } finally { - if (pBuffer is not null) - { - Marshal.FreeHGlobal((IntPtr)pBuffer); - } + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -534,33 +516,28 @@ public static object EvtGetObjectArrayProperty(EventLogHandle objArrayHandle, in { unsafe { - UnsafeNativeMethods.EvtVariant* pBuffer = null; - int bufferNeeded; + bool status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, 0, null, out int bufferNeeded); + int error = Marshal.GetLastWin32Error(); - try + if (!status) { - bool status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, 0, null, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } - if (!status) - { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, bufferNeeded, pBuffer, out bufferNeeded); + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); + try + { + status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, bufferNeeded, pVar, out bufferNeeded); error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(error); - return ConvertToObject(*pBuffer); + return ConvertToObject(*pVar); } finally { - if (pBuffer is not null) - { - Marshal.FreeHGlobal((IntPtr)pBuffer); - } + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -569,32 +546,27 @@ public static object EvtGetEventMetadataProperty(EventLogHandle handle, UnsafeNa { unsafe { - UnsafeNativeMethods.EvtVariant* pBuffer = null; - int bufferNeeded; + bool status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, 0, null, out int bufferNeeded); + int win32Error = Marshal.GetLastWin32Error(); + if (!status) + { + if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(win32Error); + } + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); try { - bool status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, 0, null, out bufferNeeded); - int win32Error = Marshal.GetLastWin32Error(); - if (!status) - { - if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(win32Error); - } - pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, bufferNeeded, pBuffer, out bufferNeeded); + status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, bufferNeeded, pVar, out bufferNeeded); win32Error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(win32Error); - return ConvertToObject(*pBuffer); + return ConvertToObject(*pVar); } finally { - if (pBuffer is not null) - { - Marshal.FreeHGlobal((IntPtr)pBuffer); - } + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -603,32 +575,27 @@ public static object EvtGetChannelConfigProperty(EventLogHandle handle, UnsafeNa { unsafe { - UnsafeNativeMethods.EvtVariant* pBuffer = null; - int bufferNeeded; + bool status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, 0, null, out int bufferNeeded); + int win32Error = Marshal.GetLastWin32Error(); + if (!status) + { + if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(win32Error); + } + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); try { - bool status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, 0, null, out bufferNeeded); - int win32Error = Marshal.GetLastWin32Error(); - if (!status) - { - if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(win32Error); - } - pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, bufferNeeded, pBuffer, out bufferNeeded); + status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, bufferNeeded, pVar, out bufferNeeded); win32Error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(win32Error); - return ConvertToObject(*pBuffer); + return ConvertToObject(*pVar); } finally { - if (pBuffer is not null) - { - Marshal.FreeHGlobal((IntPtr)pBuffer); - } + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -775,31 +742,26 @@ public static object EvtGetLogInfo(EventLogHandle handle, UnsafeNativeMethods.Ev { unsafe { - UnsafeNativeMethods.EvtVariant* pBuffer = null; - int bufferNeeded; + bool status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, 0, null, out int bufferNeeded); + int win32Error = Marshal.GetLastWin32Error(); + if (!status) + { + if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(win32Error); + } + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); try { - bool status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, 0, null, out bufferNeeded); - int win32Error = Marshal.GetLastWin32Error(); - if (!status) - { - if (win32Error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(win32Error); - } - pBuffer = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, bufferNeeded, pBuffer, out bufferNeeded); + status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, bufferNeeded, pVar, out bufferNeeded); win32Error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(win32Error); - return ConvertToObject(*pBuffer); + return ConvertToObject(*pVar); } finally { - if (pBuffer is not null) - { - Marshal.FreeHGlobal((IntPtr)pBuffer); - } + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -808,31 +770,26 @@ public static void EvtRenderBufferWithContextSystem(EventLogHandle contextHandle { unsafe { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - int propCount; + bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, null, out int bufferNeeded, out int propCount); + if (!status) + { + int error = Marshal.GetLastWin32Error(); + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); try { - bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); - if (!status) - { - int error = Marshal.GetLastWin32Error(); - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); + status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, pVar, out bufferNeeded, out propCount); int win32Error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(win32Error); - UnsafeNativeMethods.EvtVariant* ptr = (UnsafeNativeMethods.EvtVariant*)buffer; // Read each Variant structure for (int i = 0; i < propCount; i++) { - UnsafeNativeMethods.EvtVariant varVal = ptr[i]; + UnsafeNativeMethods.EvtVariant varVal = pVar[i]; switch (i) { case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderName: @@ -897,8 +854,7 @@ public static void EvtRenderBufferWithContextSystem(EventLogHandle contextHandle } finally { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + Marshal.FreeHGlobal((IntPtr)pVar); } } } @@ -909,23 +865,19 @@ public static IList EvtRenderBufferWithContextUserOrValues(EventLogHandl { unsafe { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - int propCount; UnsafeNativeMethods.EvtRenderFlags flag = UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues; + bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, null, out int bufferNeeded, out int propCount); + if (!status) + { + int error = Marshal.GetLastWin32Error(); + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + UnsafeNativeMethods.EvtVariant* pVar = (UnsafeNativeMethods.EvtVariant*)Marshal.AllocHGlobal((int)bufferNeeded); try { - bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); - if (!status) - { - int error = Marshal.GetLastWin32Error(); - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); + status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, pVar, out bufferNeeded, out propCount); int win32Error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(win32Error); @@ -933,18 +885,16 @@ public static IList EvtRenderBufferWithContextUserOrValues(EventLogHandl List valuesList = new List(propCount); if (propCount > 0) { - UnsafeNativeMethods.EvtVariant* ptr = (UnsafeNativeMethods.EvtVariant*)buffer; for (int i = 0; i < propCount; i++) { - valuesList.Add(ConvertToObject(ptr[i])); + valuesList.Add(ConvertToObject(pVar[i])); } } return valuesList; } finally { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + Marshal.FreeHGlobal(pVar); } } } @@ -1005,28 +955,25 @@ public static IEnumerable EvtFormatMessageRenderKeywords(EventLogHandle { unsafe { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - Span emptyBuffer = ['\0']; // issue: https://github.com/dotnet/runtime/issues/100198 + List keywordsList = new List(); + Span emptyBuffer = ['\0']; // workaround for bug in Windows API: https://github.com/dotnet/runtime/issues/100198 + bool status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, 0, emptyBuffer, out int bufferNeeded); + int error = Marshal.GetLastWin32Error(); - try + if (!status) { - List keywordsList = new List(); - bool status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, 0, emptyBuffer, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); - - if (!status) + if (IsNotFoundCase(error)) { - if (IsNotFoundCase(error)) - { - return keywordsList.AsReadOnly(); - } - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); + return keywordsList.AsReadOnly(); } + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } - buffer = Marshal.AllocHGlobal(bufferNeeded * 2); - status = UnsafeNativeMethods.EvtFormatMessageBuffer(pmHandle, eventHandle, 0, 0, IntPtr.Zero, flag, bufferNeeded, buffer, out bufferNeeded); + ushort* pBuffer = (ushort*)Marshal.AllocHGlobal(bufferNeeded * sizeof(ushort)); + try + { + status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, bufferNeeded, pBuffer, out bufferNeeded); error = Marshal.GetLastWin32Error(); if (!status) { @@ -1037,7 +984,7 @@ public static IEnumerable EvtFormatMessageRenderKeywords(EventLogHandle EventLogException.Throw(error); } - ushort* ptr = (ushort*)buffer; + ushort* ptr = pBuffer; while (true) { @@ -1052,41 +999,35 @@ public static IEnumerable EvtFormatMessageRenderKeywords(EventLogHandle } finally { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + Marshal.FreeHGlobal((IntPtr)pBuffer); } } } public static string EvtRenderBookmark(EventLogHandle eventHandle) { - IntPtr buffer = IntPtr.Zero; - int bufferNeeded; - int propCount; UnsafeNativeMethods.EvtRenderFlags flag = UnsafeNativeMethods.EvtRenderFlags.EvtRenderBookmark; + bool status = UnsafeNativeMethods.EvtRender(EventLogHandle.Zero, eventHandle, flag, 0, null, out int bufferNeeded, out int propCount); + int error = Marshal.GetLastWin32Error(); + if (!status) + { + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); + } + ushort* pStr = (ushort*)Marshal.AllocHGlobal((int)bufferNeeded); try { - bool status = UnsafeNativeMethods.EvtRender(EventLogHandle.Zero, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); - int error = Marshal.GetLastWin32Error(); - if (!status) - { - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - - buffer = Marshal.AllocHGlobal((int)bufferNeeded); - status = UnsafeNativeMethods.EvtRender(EventLogHandle.Zero, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); + status = UnsafeNativeMethods.EvtRender(EventLogHandle.Zero, eventHandle, flag, bufferNeeded, pStr, out bufferNeeded, out propCount); error = Marshal.GetLastWin32Error(); if (!status) EventLogException.Throw(error); - return Marshal.PtrToStringUni(buffer); + return Marshal.PtrToStringUni((IntPtr)pStr); } finally { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); + Marshal.FreeHGlobal((IntPtr)pStr); } } @@ -1094,7 +1035,7 @@ public static string EvtRenderBookmark(EventLogHandle eventHandle) public static string EvtFormatMessageFormatDescription(EventLogHandle handle, EventLogHandle eventHandle, string[] values) { int bufferNeeded; - Span emptyBuffer = [ '\0' ]; // issue: https://github.com/dotnet/runtime/issues/100198 + Span emptyBuffer = [ '\0' ]; // workaround for bug in Windows API: https://github.com/dotnet/runtime/issues/100198 UnsafeNativeMethods.EvtStringVariant[] stringVariants = new UnsafeNativeMethods.EvtStringVariant[values.Length]; for (int i = 0; i < values.Length; i++) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs index 44beb4d1d9fe18..5ef14c141a2a99 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs @@ -499,7 +499,7 @@ internal static unsafe partial bool EvtGetQueryInfo( EvtQueryPropertyId propertyId, int bufferSize, EvtVariant* buffer, - ref int bufferRequired); + out int bufferRequired); // PUBLISHER METADATA [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] @@ -683,12 +683,12 @@ internal static partial bool EvtRender( [LibraryImport(Interop.Libraries.Wevtapi, EntryPoint = "EvtRender", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtRender( + internal static unsafe partial bool EvtRender( EventLogHandle context, EventLogHandle eventHandle, EvtRenderFlags flags, int buffSize, - IntPtr buffer, + EvtVariant* buffer, out int buffUsed, out int propCount); @@ -751,28 +751,29 @@ public void FreeNative() [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true, StringMarshalling = StringMarshalling.Utf16)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtFormatMessage( + internal static unsafe partial bool EvtFormatMessage( EventLogHandle publisherMetadataHandle, EventLogHandle eventHandle, uint messageId, int valueCount, - EvtStringVariant[] values, + EvtVariant* values, EvtFormatMessageFlags flags, int bufferSize, Span buffer, out int bufferUsed); - [LibraryImport(Interop.Libraries.Wevtapi, EntryPoint = "EvtFormatMessage", SetLastError = true)] + + [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvtFormatMessageBuffer( + internal static unsafe partial bool EvtFormatMessage( EventLogHandle publisherMetadataHandle, EventLogHandle eventHandle, uint messageId, int valueCount, - IntPtr values, + EvtVariant* values, EvtFormatMessageFlags flags, int bufferSize, - IntPtr buffer, + ushort* buffer, out int bufferUsed); // SESSION From cc63c2dc90bb149b5247d62ea13a91f0b9850e20 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sat, 23 Aug 2025 04:01:25 +0100 Subject: [PATCH 6/7] fix build errors --- .../Diagnostics/Reader/NativeWrapper.cs | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs index c28e68af1ac1e6..526b3a58635e1f 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs @@ -472,44 +472,47 @@ internal static EventLogHandle EvtGetPublisherMetadataPropertyHandle(EventLogHan // implies UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId flag. public static string EvtFormatMessage(EventLogHandle handle, uint msgId) { - int bufferNeeded; - Span emptyBuffer = [ '\0' ]; // issue: https://github.com/dotnet/runtime/issues/100198 - bool status = UnsafeNativeMethods.EvtFormatMessage(handle, EventLogHandle.Zero, msgId, 0, null, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId, 0, emptyBuffer, out bufferNeeded); - int error = Marshal.GetLastWin32Error(); - - // ERROR_EVT_UNRESOLVED_VALUE_INSERT and its cousins are commonly returned for raw message text. - if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT - && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT - && error != UnsafeNativeMethods.ERROR_EVT_MAX_INSERTS_REACHED) + unsafe { - if (IsNotFoundCase(error)) + int bufferNeeded; + Span emptyBuffer = ['\0']; // issue: https://github.com/dotnet/runtime/issues/100198 + bool status = UnsafeNativeMethods.EvtFormatMessage(handle, EventLogHandle.Zero, msgId, 0, null, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId, 0, emptyBuffer, out bufferNeeded); + int error = Marshal.GetLastWin32Error(); + + // ERROR_EVT_UNRESOLVED_VALUE_INSERT and its cousins are commonly returned for raw message text. + if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT + && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT + && error != UnsafeNativeMethods.ERROR_EVT_MAX_INSERTS_REACHED) { - return null; + if (IsNotFoundCase(error)) + { + return null; + } + if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) + EventLogException.Throw(error); } - if (error != Interop.Errors.ERROR_INSUFFICIENT_BUFFER) - EventLogException.Throw(error); - } - char[] buffer = new char[bufferNeeded]; - status = UnsafeNativeMethods.EvtFormatMessage(handle, EventLogHandle.Zero, msgId, 0, null, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId, bufferNeeded, buffer, out bufferNeeded); - error = Marshal.GetLastWin32Error(); + char[] buffer = new char[bufferNeeded]; + status = UnsafeNativeMethods.EvtFormatMessage(handle, EventLogHandle.Zero, msgId, 0, null, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId, bufferNeeded, buffer, out bufferNeeded); + error = Marshal.GetLastWin32Error(); - if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT - && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT - && error != UnsafeNativeMethods.ERROR_EVT_MAX_INSERTS_REACHED) - { - if (IsNotFoundCase(error)) + if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT + && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT + && error != UnsafeNativeMethods.ERROR_EVT_MAX_INSERTS_REACHED) { - return null; + if (IsNotFoundCase(error)) + { + return null; + } + EventLogException.Throw(error); } - EventLogException.Throw(error); - } - int len = bufferNeeded - 1; // buffer includes null terminator - if (len <= 0) - return string.Empty; + int len = bufferNeeded - 1; // buffer includes null terminator + if (len <= 0) + return string.Empty; - return new string(buffer, 0, len); + return new string(buffer, 0, len); + } } public static object EvtGetObjectArrayProperty(EventLogHandle objArrayHandle, int index, int thePropertyId) @@ -770,7 +773,7 @@ public static void EvtRenderBufferWithContextSystem(EventLogHandle contextHandle { unsafe { - bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, null, out int bufferNeeded, out int propCount); + bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, (UnsafeNativeMethods.EvtVariant*)null, out int bufferNeeded, out int propCount); if (!status) { int error = Marshal.GetLastWin32Error(); From a4af4438e57608d5b04dc99edb2e2b22b71e2b55 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sat, 23 Aug 2025 05:07:58 +0100 Subject: [PATCH 7/7] fix --- .../src/System/Diagnostics/Reader/NativeWrapper.cs | 6 +++--- .../src/System/Diagnostics/Reader/UnsafeNativeMethods.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs index 526b3a58635e1f..aebf4fd812e52b 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/NativeWrapper.cs @@ -773,7 +773,7 @@ public static void EvtRenderBufferWithContextSystem(EventLogHandle contextHandle { unsafe { - bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, (UnsafeNativeMethods.EvtVariant*)null, out int bufferNeeded, out int propCount); + bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, default(UnsafeNativeMethods.EvtVariant*), out int bufferNeeded, out int propCount); if (!status) { int error = Marshal.GetLastWin32Error(); @@ -869,7 +869,7 @@ public static IList EvtRenderBufferWithContextUserOrValues(EventLogHandl unsafe { UnsafeNativeMethods.EvtRenderFlags flag = UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues; - bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, null, out int bufferNeeded, out int propCount); + bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, default(UnsafeNativeMethods.EvtVariant*), out int bufferNeeded, out int propCount); if (!status) { int error = Marshal.GetLastWin32Error(); @@ -897,7 +897,7 @@ public static IList EvtRenderBufferWithContextUserOrValues(EventLogHandl } finally { - Marshal.FreeHGlobal(pVar); + Marshal.FreeHGlobal((IntPtr)pVar); } } } diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs index 5ef14c141a2a99..f9c4e34942a668 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs @@ -751,12 +751,12 @@ public void FreeNative() [LibraryImport(Interop.Libraries.Wevtapi, SetLastError = true, StringMarshalling = StringMarshalling.Utf16)] [return: MarshalAs(UnmanagedType.Bool)] - internal static unsafe partial bool EvtFormatMessage( + internal static partial bool EvtFormatMessage( EventLogHandle publisherMetadataHandle, EventLogHandle eventHandle, uint messageId, int valueCount, - EvtVariant* values, + EvtStringVariant[] values, EvtFormatMessageFlags flags, int bufferSize, Span buffer,