Skip to content

Commit 3211693

Browse files
Use System.Runtime.InteropServices.Marshalling.ComVariant instead of custom VARIANT types in libraries (#123060)
Co-authored-by: Aaron R Robinson <[email protected]>
1 parent db67cad commit 3211693

File tree

13 files changed

+28
-588
lines changed

13 files changed

+28
-588
lines changed

src/libraries/Common/src/Interop/Windows/OleAut32/Interop.VariantInit.cs

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/libraries/System.Data.OleDb/src/DbBindings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ internal int MaxLen
188188
{
189189
case (NativeDBType.BSTR): // ADP.PtrSize
190190
case (NativeDBType.HCHAPTER): // ADP.PtrSize
191-
case (NativeDBType.PROPVARIANT): // sizeof(PROPVARIANT)
192-
case (NativeDBType.VARIANT): // 16 or 24 (8 + ADP.PtrSize *2)
191+
case (NativeDBType.PROPVARIANT): // sizeof(ComVariant)
192+
case (NativeDBType.VARIANT): // sizeof(ComVariant)
193193
case (NativeDBType.BYREF | NativeDBType.BYTES): // ADP.PtrSize
194194
case (NativeDBType.BYREF | NativeDBType.WSTR): // ADP.PtrSize
195195
// allocate extra space to cache original value for disposal

src/libraries/System.Data.OleDb/src/DbPropSet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ protected override bool ReleaseHandle()
144144
IntPtr vptr = ADP.IntPtrOffset(rgProperties, ODB.OffsetOf_tagDBPROP_Value);
145145
for (int k = 0; k < cProperties; ++k, vptr = ADP.IntPtrOffset(vptr, ODB.SizeOf_tagDBPROP))
146146
{
147-
Interop.OleAut32.VariantClear(vptr);
147+
Interop.Ole32.PropVariantClear(vptr);
148148
}
149149
Interop.Ole32.CoTaskMemFree(rgProperties);
150150
}

src/libraries/System.Data.OleDb/src/OleDb_Enum.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Data.Common;
5+
using System.Runtime.InteropServices.Marshalling;
56

67
namespace System.Data.OleDb
78
{
@@ -148,8 +149,7 @@ internal sealed class NativeDBType
148149
private static readonly NativeDBType D_LongVarBinary = new NativeDBType(0xff, -1, false, true, OleDbType.LongVarBinary, NativeDBType.BYTES, S_LONGVARBINARY, typeof(byte[]), NativeDBType.BYTES, DbType.Binary); // 19
149150
private static readonly NativeDBType D_LongVarChar = new NativeDBType(0xff, -1, false, true, OleDbType.LongVarChar, NativeDBType.STR, S_LONGVARCHAR, typeof(string), NativeDBType.WSTR/*STR*/, DbType.AnsiString); // 20 - (ansi pointer)
150151
private static readonly NativeDBType D_Numeric = new NativeDBType(28, 19, true, false, OleDbType.Numeric, NativeDBType.NUMERIC, S_NUMERIC, typeof(decimal), NativeDBType.NUMERIC, DbType.Decimal); // 21 - (tagDB_Numeric)
151-
private static readonly unsafe NativeDBType D_PropVariant = new NativeDBType(0xff, sizeof(PROPVARIANT),
152-
true, false, OleDbType.PropVariant, NativeDBType.PROPVARIANT, S_PROPVARIANT, typeof(object), NativeDBType.VARIANT, DbType.Object); // 22
152+
private static readonly unsafe NativeDBType D_PropVariant = new NativeDBType(0xff, sizeof(ComVariant), true, false, OleDbType.PropVariant, NativeDBType.PROPVARIANT, S_PROPVARIANT, typeof(object), NativeDBType.VARIANT, DbType.Object); // 22
153153
private static readonly NativeDBType D_Single = new NativeDBType(7, 4, true, false, OleDbType.Single, NativeDBType.R4, S_R4, typeof(float), NativeDBType.R4, DbType.Single); // 23 - single
154154
private static readonly NativeDBType D_Double = new NativeDBType(15, 8, true, false, OleDbType.Double, NativeDBType.R8, S_R8, typeof(double), NativeDBType.R8, DbType.Double); // 24 - double
155155
private static readonly NativeDBType D_UnsignedTinyInt = new NativeDBType(3, 1, true, false, OleDbType.UnsignedTinyInt, NativeDBType.UI1, S_UI1, typeof(byte), NativeDBType.UI1, DbType.Byte); // 25 - byte7

src/libraries/System.Data.OleDb/src/OleDb_Util.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
using System.Data.Common;
66
using System.Diagnostics;
77
using System.Globalization;
8+
using System.Runtime.CompilerServices;
89
using System.Runtime.InteropServices;
10+
using System.Runtime.InteropServices.Marshalling;
911
using System.Text;
1012

1113
namespace System.Data.OleDb
@@ -569,7 +571,7 @@ internal static InvalidOperationException IDBInfoNotSupported()
569571
internal static readonly int SizeOf_tagDBPROPINFO = IsRunningOnX86 ? Marshal.SizeOf<tagDBPROPINFO_x86>() : Marshal.SizeOf<tagDBPROPINFO>();
570572
internal static readonly int SizeOf_tagDBPROPIDSET = Marshal.SizeOf<tagDBPROPIDSET>();
571573
internal static readonly int SizeOf_Guid = Marshal.SizeOf<Guid>();
572-
internal static readonly int SizeOf_Variant = 8 + (2 * IntPtr.Size); // 16 on 32bit, 24 on 64bit
574+
internal static readonly int SizeOf_Variant = Unsafe.SizeOf<ComVariant>();
573575

574576
internal static readonly int OffsetOf_tagDBPROP_Status = IsRunningOnX86 ? Marshal.OffsetOf(typeof(tagDBPROP_x86), "dwStatus").ToInt32() : Marshal.OffsetOf(typeof(tagDBPROP), "dwStatus").ToInt32();
575577
internal static readonly int OffsetOf_tagDBPROP_Value = IsRunningOnX86 ? Marshal.OffsetOf(typeof(tagDBPROP_x86), "vValue").ToInt32() : Marshal.OffsetOf(typeof(tagDBPROP), "vValue").ToInt32();

src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ protected override bool ReleaseHandle()
125125
for (int k = 0; k < infoCount; ++k)
126126
{
127127
IntPtr valuePtr = ADP.IntPtrOffset(infoPtr, (k * ODB.SizeOf_tagDBPROPINFO) + ODB.OffsetOf_tagDBPROPINFO_Value);
128-
Interop.OleAut32.VariantClear(valuePtr);
128+
Interop.Ole32.PropVariantClear(valuePtr);
129129
}
130130
Interop.Ole32.CoTaskMemFree(infoPtr); // was allocated by provider
131131
}

src/libraries/System.Data.OleDb/src/RowBinding.cs

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Diagnostics;
66
using System.Runtime.CompilerServices;
77
using System.Runtime.InteropServices;
8+
using System.Runtime.InteropServices.Marshalling;
89

910
namespace System.Data.OleDb
1011
{
@@ -407,14 +408,11 @@ private unsafe void ResetValues(IntPtr buffer, object? iaccessor)
407408
ValidateCheck(valueOffset, 2 * IntPtr.Size);
408409
FreeCoTaskMem(buffer, valueOffset);
409410
break;
411+
case NativeDBType.VARIANT:
410412
case NativeDBType.PROPVARIANT:
411-
ValidateCheck(valueOffset, 2 * sizeof(PROPVARIANT));
413+
ValidateCheck(valueOffset, 2 * sizeof(ComVariant));
412414
FreePropVariant(buffer, valueOffset);
413415
break;
414-
case NativeDBType.VARIANT:
415-
ValidateCheck(valueOffset, 2 * ODB.SizeOf_Variant);
416-
FreeVariant(buffer, valueOffset);
417-
break;
418416
case NativeDBType.BSTR:
419417
ValidateCheck(valueOffset, 2 * IntPtr.Size);
420418
FreeBstr(buffer, valueOffset);
@@ -533,48 +531,16 @@ private static void FreeCoTaskMem(IntPtr buffer, int valueOffset)
533531
}
534532
}
535533

536-
private static void FreeVariant(IntPtr buffer, int valueOffset)
537-
{
538-
// two contiguous VARIANT structures that need to be freed
539-
// the second should only be freed if different from the first
540-
541-
Debug.Assert(0 == (ODB.SizeOf_Variant % 8), "unexpected VARIANT size mutiplier");
542-
Debug.Assert(0 == valueOffset % 8, "unexpected unaligned ptr offset");
543-
544-
IntPtr currentHandle = ADP.IntPtrOffset(buffer, valueOffset);
545-
IntPtr originalHandle = ADP.IntPtrOffset(buffer, valueOffset + ODB.SizeOf_Variant);
546-
bool different = NativeOledbWrapper.MemoryCompare(currentHandle, originalHandle, ODB.SizeOf_Variant);
547-
548-
RuntimeHelpers.PrepareConstrainedRegions();
549-
try
550-
{ }
551-
finally
552-
{
553-
// always clear the first structure
554-
Interop.OleAut32.VariantClear(currentHandle);
555-
if (different)
556-
{
557-
// second structure different from the first
558-
Interop.OleAut32.VariantClear(originalHandle);
559-
}
560-
else
561-
{
562-
// second structure same as the first, just clear the field
563-
SafeNativeMethods.ZeroMemory(originalHandle, ODB.SizeOf_Variant);
564-
}
565-
}
566-
}
567-
568534
private static unsafe void FreePropVariant(IntPtr buffer, int valueOffset)
569535
{
570536
// two contiguous PROPVARIANT structures that need to be freed
571537
// the second should only be freed if different from the first
572-
Debug.Assert(0 == (sizeof(PROPVARIANT) % 8), "unexpected PROPVARIANT size mutiplier");
538+
Debug.Assert(0 == (sizeof(ComVariant) % 8), "unexpected PROPVARIANT size mutiplier");
573539
Debug.Assert(0 == valueOffset % 8, "unexpected unaligned ptr offset");
574540

575541
IntPtr currentHandle = ADP.IntPtrOffset(buffer, valueOffset);
576-
IntPtr originalHandle = ADP.IntPtrOffset(buffer, valueOffset + sizeof(PROPVARIANT));
577-
bool different = NativeOledbWrapper.MemoryCompare(currentHandle, originalHandle, sizeof(PROPVARIANT));
542+
IntPtr originalHandle = ADP.IntPtrOffset(buffer, valueOffset + sizeof(ComVariant));
543+
bool different = NativeOledbWrapper.MemoryCompare(currentHandle, originalHandle, sizeof(ComVariant));
578544

579545
RuntimeHelpers.PrepareConstrainedRegions();
580546
try
@@ -591,7 +557,7 @@ private static unsafe void FreePropVariant(IntPtr buffer, int valueOffset)
591557
else
592558
{
593559
// second structure same as the first, just clear the field
594-
SafeNativeMethods.ZeroMemory(originalHandle, sizeof(PROPVARIANT));
560+
SafeNativeMethods.ZeroMemory(originalHandle, sizeof(ComVariant));
595561
}
596562
}
597563
}

0 commit comments

Comments
 (0)