From ac40501a5e98ce6bc12e046826458dc245ca9287 Mon Sep 17 00:00:00 2001 From: Andrey Rusyaev Date: Fri, 7 Nov 2025 21:47:02 +0400 Subject: [PATCH] Add Record struct and field to ComVariant to ensure that it has proper binary size (4 pointers (16 bytes) on a 32-bit processor, 3 pointers (24 bytes) on a 64-bit processor). (#20017) Based on dotnet/runtime implementation https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ComVariant.cs --- .../Marshalling/ComVariant.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/Windows/Avalonia.Win32.Automation/Marshalling/ComVariant.cs b/src/Windows/Avalonia.Win32.Automation/Marshalling/ComVariant.cs index d5da462f8c..a7fcd6776c 100644 --- a/src/Windows/Avalonia.Win32.Automation/Marshalling/ComVariant.cs +++ b/src/Windows/Avalonia.Win32.Automation/Marshalling/ComVariant.cs @@ -18,6 +18,25 @@ internal struct ComVariant : IDisposable internal const short VARIANT_TRUE = -1; internal const short VARIANT_FALSE = 0; +#if DEBUG + static unsafe ComVariant() + { + // Variant size is the size of 4 pointers (16 bytes) on a 32-bit processor, + // and 3 pointers (24 bytes) on a 64-bit processor. + // See definition in oaidl.h in the Windows SDK. + int variantSize = sizeof(ComVariant); + if (IntPtr.Size == 4) + { + Debug.Assert(variantSize == (4 * IntPtr.Size)); + } + else + { + Debug.Assert(IntPtr.Size == 8); + Debug.Assert(variantSize == (3 * IntPtr.Size)); + } + } +#endif + // Most of the data types in the Variant are carried in _typeUnion [FieldOffset(0)] private TypeUnion _typeUnion; @@ -32,6 +51,13 @@ internal struct ComVariant : IDisposable public UnionTypes _unionTypes; } + [StructLayout(LayoutKind.Sequential)] + private struct Record + { + public IntPtr _record; + public IntPtr _recordInfo; + } + [StructLayout(LayoutKind.Explicit)] private unsafe struct UnionTypes { @@ -56,6 +82,7 @@ internal struct ComVariant : IDisposable [FieldOffset(0)] public IntPtr _dispatch; [FieldOffset(0)] public IntPtr _pvarVal; [FieldOffset(0)] public IntPtr _byref; + [FieldOffset(0)] public Record _record; [FieldOffset(0)] public SafeArrayRef parray; [FieldOffset(0)] public SafeArrayRef*pparray; }