From 6fa61f16e9ae0168d676eba6eee2bc158e8809c6 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 21 May 2021 19:45:17 +0600 Subject: [PATCH 1/9] Rework of variant tests split --- .../PInvoke/Variant/VariantTest.BuiltInCom.cs | 37 ++++ .../Variant/VariantTest.ComWrappers.cs | 112 +++++++++++ .../Interop/PInvoke/Variant/VariantTest.cs | 179 +++++++++--------- .../PInvoke/Variant/VariantTest.csproj | 3 +- .../VariantTestBuiltInComDisabled.csproj | 18 ++ .../Variant/VariantTestComWrappers.csproj | 18 ++ 6 files changed, 274 insertions(+), 93 deletions(-) create mode 100644 src/tests/Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs create mode 100644 src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs create mode 100644 src/tests/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj create mode 100644 src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs b/src/tests/Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs new file mode 100644 index 00000000000000..9b0af77b7a6414 --- /dev/null +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using TestLibrary; +using static VariantNative; + +#pragma warning disable CS0612, CS0618 +partial class Test +{ + public static int Main() + { + bool builtInComDisabled=false; + var comConfig = AppContext.GetData("System.Runtime.InteropServices.BuiltInComInterop.IsSupported"); + if(comConfig != null && !bool.Parse(comConfig.ToString())) + { + builtInComDisabled=true; + } + + Console.WriteLine($"Built-in COM Disabled?: {builtInComDisabled}"); + try + { + TestByValue(builtInComDisabled); + TestByRef(builtInComDisabled); + TestOut(); + TestFieldByValue(builtInComDisabled); + TestFieldByRef(builtInComDisabled); + } + catch (Exception e) + { + Console.WriteLine($"Test failed: {e}"); + return 101; + } + return 100; + } +} diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs b/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs new file mode 100644 index 00000000000000..7fcef09d8f77c0 --- /dev/null +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs @@ -0,0 +1,112 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using TestLibrary; +using static VariantNative; +using ComTypes = System.Runtime.InteropServices.ComTypes; + +#pragma warning disable CS0612, CS0618 +partial class Test +{ + public static int Main() + { + bool testComMarshal=true; + ComWrappers.RegisterForMarshalling(new ComWrappersImpl()); + try + { + TestByValue(testComMarshal); + TestByRef(testComMarshal); + TestOut(); + TestFieldByValue(testComMarshal); + TestFieldByRef(testComMarshal); + } + catch (Exception e) + { + Console.WriteLine($"Test failed: {e}"); + return 101; + } + return 100; + } +} + +internal unsafe class ComWrappersImpl : ComWrappers +{ + private static readonly ComInterfaceEntry* wrapperEntry; + + static ComWrappersImpl() + { + var vtblRaw = (IntPtr*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IDispatchVtbl), sizeof(IntPtr) * 7); + GetIUnknownImpl(out vtblRaw[0], out vtblRaw[1], out vtblRaw[2]); + + vtblRaw[3] = (IntPtr)(delegate* unmanaged)&IDispatchVtbl.GetTypeInfoCountInternal; + vtblRaw[4] = (IntPtr)(delegate* unmanaged)&IDispatchVtbl.GetTypeInfoInternal; + vtblRaw[5] = (IntPtr)(delegate* unmanaged)&IDispatchVtbl.GetIDsOfNamesInternal; + vtblRaw[6] = (IntPtr)(delegate* unmanaged)&IDispatchVtbl.InvokeInternal; + + wrapperEntry = (ComInterfaceEntry*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IDispatchVtbl), sizeof(ComInterfaceEntry)); + wrapperEntry->IID = new Guid("00020400-0000-0000-C000-000000000046"); + wrapperEntry->Vtable = (IntPtr)vtblRaw; + } + + protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) + { + // Always return the same table mappings. + count = 1; + return wrapperEntry; + } + + protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags) + { + throw new NotImplementedException(); + } + + protected override void ReleaseObjects(IEnumerable objects) + { + throw new NotImplementedException(); + } +} +public struct IDispatchVtbl +{ + [UnmanagedCallersOnly] + public static int GetTypeInfoCountInternal(IntPtr thisPtr, IntPtr i) + { + return 0; // S_OK; + } + + [UnmanagedCallersOnly] + public static int GetTypeInfoInternal(IntPtr thisPtr, int itinfo, int lcid, IntPtr i) + { + return 0; // S_OK; + } + + [UnmanagedCallersOnly] + public static int GetIDsOfNamesInternal( + IntPtr thisPtr, + IntPtr iid, + IntPtr names, + int namesCount, + int lcid, + IntPtr dispIds) + { + return 0; // S_OK; + } + + [UnmanagedCallersOnly] + public static int InvokeInternal( + IntPtr thisPtr, + int dispIdMember, + IntPtr riid, + int lcid, + ComTypes.INVOKEKIND wFlags, + IntPtr pDispParams, + IntPtr VarResult, + IntPtr pExcepInfo, + IntPtr puArgErr) + { + return 0; // S_OK; + } +} diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.cs b/src/tests/Interop/PInvoke/Variant/VariantTest.cs index f4214d4d0d89e9..e15814a9cb6e0c 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTest.cs +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.cs @@ -7,7 +7,7 @@ using static VariantNative; #pragma warning disable CS0612, CS0618 -class Test +partial class Test { private const byte NumericValue = 15; @@ -19,7 +19,7 @@ class Test private static readonly DateTime DateValue = new DateTime(2018, 11, 6); - private unsafe static void TestByValue() + private unsafe static void TestByValue(bool hasComSupport) { Assert.IsTrue(Marshal_ByValue_Byte((byte)NumericValue, NumericValue)); Assert.IsTrue(Marshal_ByValue_SByte((sbyte)NumericValue, (sbyte)NumericValue)); @@ -41,82 +41,89 @@ private unsafe static void TestByValue() Assert.IsTrue(Marshal_ByValue_Null(DBNull.Value)); Assert.IsTrue(Marshal_ByValue_Missing(System.Reflection.Missing.Value)); Assert.IsTrue(Marshal_ByValue_Empty(null)); - Assert.IsTrue(Marshal_ByValue_Object(new object())); - Assert.IsTrue(Marshal_ByValue_Object_IUnknown(new UnknownWrapper(new object()))); + if (hasComSupport) + { + Assert.IsTrue(Marshal_ByValue_Object(new object())); + Assert.IsTrue(Marshal_ByValue_Object_IUnknown(new UnknownWrapper(new object()))); + } + Assert.Throws(() => Marshal_ByValue_Invalid(TimeSpan.Zero)); Assert.Throws(() => Marshal_ByValue_Invalid(new CustomStruct())); Assert.Throws(() => Marshal_ByValue_Invalid(new VariantWrapper(CharValue))); } - private unsafe static void TestByRef() + private unsafe static void TestByRef(bool hasComSupport) { object obj; obj = (byte)NumericValue; Assert.IsTrue(Marshal_ByRef_Byte(ref obj, NumericValue)); - + obj = (sbyte)NumericValue; Assert.IsTrue(Marshal_ByRef_SByte(ref obj, (sbyte)NumericValue)); - + obj = (short)NumericValue; Assert.IsTrue(Marshal_ByRef_Int16(ref obj, NumericValue)); - + obj = (ushort)NumericValue; Assert.IsTrue(Marshal_ByRef_UInt16(ref obj, NumericValue)); - + obj = (int)NumericValue; Assert.IsTrue(Marshal_ByRef_Int32(ref obj, NumericValue)); - + obj = (uint)NumericValue; Assert.IsTrue(Marshal_ByRef_UInt32(ref obj, NumericValue)); - + obj = (long)NumericValue; Assert.IsTrue(Marshal_ByRef_Int64(ref obj, NumericValue)); - + obj = (ulong)NumericValue; Assert.IsTrue(Marshal_ByRef_UInt64(ref obj, NumericValue)); - + obj = (float)NumericValue; Assert.IsTrue(Marshal_ByRef_Single(ref obj, NumericValue)); - + obj = (double)NumericValue; Assert.IsTrue(Marshal_ByRef_Double(ref obj, NumericValue)); - + obj = StringValue; Assert.IsTrue(Marshal_ByRef_String(ref obj, StringValue)); obj = new BStrWrapper(null); Assert.IsTrue(Marshal_ByRef_String(ref obj, null)); - + obj = CharValue; Assert.IsTrue(Marshal_ByRef_Char(ref obj, CharValue)); - + obj = true; Assert.IsTrue(Marshal_ByRef_Boolean(ref obj, true)); - + obj = DateValue; Assert.IsTrue(Marshal_ByRef_DateTime(ref obj, DateValue)); - + obj = DecimalValue; Assert.IsTrue(Marshal_ByRef_Decimal(ref obj, DecimalValue)); obj = new CurrencyWrapper(DecimalValue); Assert.IsTrue(Marshal_ByRef_Currency(ref obj, DecimalValue)); - + obj = DBNull.Value; Assert.IsTrue(Marshal_ByRef_Null(ref obj)); - + obj = System.Reflection.Missing.Value; Assert.IsTrue(Marshal_ByRef_Missing(ref obj)); - + obj = null; Assert.IsTrue(Marshal_ByRef_Empty(ref obj)); - - obj = new object(); - Assert.IsTrue(Marshal_ByRef_Object(ref obj)); - obj = new UnknownWrapper(new object()); - Assert.IsTrue(Marshal_ByRef_Object_IUnknown(ref obj)); + if (hasComSupport) + { + obj = new object(); + Assert.IsTrue(Marshal_ByRef_Object(ref obj)); + + obj = new UnknownWrapper(new object()); + Assert.IsTrue(Marshal_ByRef_Object_IUnknown(ref obj)); + } obj = DecimalValue; Assert.IsTrue(Marshal_ChangeVariantType(ref obj, NumericValue)); @@ -130,164 +137,152 @@ private unsafe static void TestOut() Assert.IsTrue(obj is int); Assert.AreEqual(NumericValue, (int)obj); } - - private unsafe static void TestFieldByValue() + + private unsafe static void TestFieldByValue(bool hasComSupport) { ObjectWrapper wrapper = new ObjectWrapper(); wrapper.value = (byte)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_Byte(wrapper, NumericValue)); - + wrapper.value = (sbyte)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_SByte(wrapper, (sbyte)NumericValue)); - + wrapper.value = (short)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_Int16(wrapper, NumericValue)); - + wrapper.value = (ushort)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_UInt16(wrapper, NumericValue)); - + wrapper.value = (int)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_Int32(wrapper, NumericValue)); - + wrapper.value = (uint)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_UInt32(wrapper, NumericValue)); - + wrapper.value = (long)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_Int64(wrapper, NumericValue)); - + wrapper.value = (ulong)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_UInt64(wrapper, NumericValue)); - + wrapper.value = (float)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_Single(wrapper, NumericValue)); - + wrapper.value = (double)NumericValue; Assert.IsTrue(Marshal_Struct_ByValue_Double(wrapper, NumericValue)); - + wrapper.value = StringValue; Assert.IsTrue(Marshal_Struct_ByValue_String(wrapper, StringValue)); wrapper.value = new BStrWrapper(null); Assert.IsTrue(Marshal_Struct_ByValue_String(wrapper, null)); - + wrapper.value = CharValue; Assert.IsTrue(Marshal_Struct_ByValue_Char(wrapper, CharValue)); - + wrapper.value = true; Assert.IsTrue(Marshal_Struct_ByValue_Boolean(wrapper, true)); - + wrapper.value = DateValue; Assert.IsTrue(Marshal_Struct_ByValue_DateTime(wrapper, DateValue)); - + wrapper.value = DecimalValue; Assert.IsTrue(Marshal_Struct_ByValue_Decimal(wrapper, DecimalValue)); wrapper.value = new CurrencyWrapper(DecimalValue); Assert.IsTrue(Marshal_Struct_ByValue_Currency(wrapper, DecimalValue)); - + wrapper.value = DBNull.Value; Assert.IsTrue(Marshal_Struct_ByValue_Null(wrapper)); - + wrapper.value = System.Reflection.Missing.Value; Assert.IsTrue(Marshal_Struct_ByValue_Missing(wrapper)); - + wrapper.value = null; Assert.IsTrue(Marshal_Struct_ByValue_Empty(wrapper)); - - wrapper.value = new object(); - Assert.IsTrue(Marshal_Struct_ByValue_Object(wrapper)); - - wrapper.value = new UnknownWrapper(new object()); - Assert.IsTrue(Marshal_Struct_ByValue_Object_IUnknown(wrapper)); + + if (hasComSupport) + { + wrapper.value = new object(); + Assert.IsTrue(Marshal_Struct_ByValue_Object(wrapper)); + + wrapper.value = new UnknownWrapper(new object()); + Assert.IsTrue(Marshal_Struct_ByValue_Object_IUnknown(wrapper)); + } } - private unsafe static void TestFieldByRef() + private unsafe static void TestFieldByRef(bool hasComSupport) { ObjectWrapper wrapper = new ObjectWrapper(); wrapper.value = (byte)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_Byte(ref wrapper, NumericValue)); - + wrapper.value = (sbyte)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_SByte(ref wrapper, (sbyte)NumericValue)); - + wrapper.value = (short)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_Int16(ref wrapper, NumericValue)); - + wrapper.value = (ushort)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_UInt16(ref wrapper, NumericValue)); - + wrapper.value = (int)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_Int32(ref wrapper, NumericValue)); - + wrapper.value = (uint)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_UInt32(ref wrapper, NumericValue)); - + wrapper.value = (long)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_Int64(ref wrapper, NumericValue)); - + wrapper.value = (ulong)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_UInt64(ref wrapper, NumericValue)); - + wrapper.value = (float)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_Single(ref wrapper, NumericValue)); - + wrapper.value = (double)NumericValue; Assert.IsTrue(Marshal_Struct_ByRef_Double(ref wrapper, NumericValue)); - + wrapper.value = StringValue; Assert.IsTrue(Marshal_Struct_ByRef_String(ref wrapper, StringValue)); wrapper.value = new BStrWrapper(null); Assert.IsTrue(Marshal_Struct_ByRef_String(ref wrapper, null)); - + wrapper.value = CharValue; Assert.IsTrue(Marshal_Struct_ByRef_Char(ref wrapper, CharValue)); - + wrapper.value = true; Assert.IsTrue(Marshal_Struct_ByRef_Boolean(ref wrapper, true)); - + wrapper.value = DateValue; Assert.IsTrue(Marshal_Struct_ByRef_DateTime(ref wrapper, DateValue)); - + wrapper.value = DecimalValue; Assert.IsTrue(Marshal_Struct_ByRef_Decimal(ref wrapper, DecimalValue)); - + wrapper.value = new CurrencyWrapper(DecimalValue); Assert.IsTrue(Marshal_Struct_ByRef_Currency(ref wrapper, DecimalValue)); - + wrapper.value = DBNull.Value; Assert.IsTrue(Marshal_Struct_ByRef_Null(ref wrapper)); - + wrapper.value = System.Reflection.Missing.Value; Assert.IsTrue(Marshal_Struct_ByRef_Missing(ref wrapper)); - + wrapper.value = null; Assert.IsTrue(Marshal_Struct_ByRef_Empty(ref wrapper)); - - wrapper.value = new object(); - Assert.IsTrue(Marshal_Struct_ByRef_Object(ref wrapper)); - - wrapper.value = new UnknownWrapper(new object()); - Assert.IsTrue(Marshal_Struct_ByRef_Object_IUnknown(ref wrapper)); - } - public static int Main() - { - try - { - TestByValue(); - TestByRef(); - TestOut(); - TestFieldByValue(); - TestFieldByRef(); - } - catch (Exception e) + if (hasComSupport) { - Console.WriteLine($"Test failed: {e}"); - return 101; + wrapper.value = new object(); + Assert.IsTrue(Marshal_Struct_ByRef_Object(ref wrapper)); + + wrapper.value = new UnknownWrapper(new object()); + Assert.IsTrue(Marshal_Struct_ByRef_Object_IUnknown(ref wrapper)); } - return 100; } } diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.csproj b/src/tests/Interop/PInvoke/Variant/VariantTest.csproj index e1b97c6c5c301a..ab5faac931c5f1 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTest.csproj +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.csproj @@ -6,7 +6,8 @@ true - + + diff --git a/src/tests/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj b/src/tests/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj new file mode 100644 index 00000000000000..92a605036174e6 --- /dev/null +++ b/src/tests/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj @@ -0,0 +1,18 @@ + + + Exe + true + + true + + + + + + + + + + + + diff --git a/src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj b/src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj new file mode 100644 index 00000000000000..87d781c45c6780 --- /dev/null +++ b/src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj @@ -0,0 +1,18 @@ + + + Exe + true + + true + + + + + + + + + + + + From 3306160d398cf9d61b108c6f4eb097cd60dd842f Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 24 May 2021 16:52:54 +0600 Subject: [PATCH 2/9] Add missing file --- src/tests/Interop/PInvoke/Variant/VariantTest.csproj | 1 + .../Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj | 1 + src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj | 1 + 3 files changed, 3 insertions(+) diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.csproj b/src/tests/Interop/PInvoke/Variant/VariantTest.csproj index ab5faac931c5f1..13d0f08d40a065 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTest.csproj +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.csproj @@ -6,6 +6,7 @@ true + diff --git a/src/tests/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj b/src/tests/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj index 92a605036174e6..87612cc3fe5d2d 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj +++ b/src/tests/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled.csproj @@ -6,6 +6,7 @@ true + diff --git a/src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj b/src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj index 87d781c45c6780..254ec39cf21d27 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj +++ b/src/tests/Interop/PInvoke/Variant/VariantTestComWrappers.csproj @@ -6,6 +6,7 @@ true + From 39d52a5d3493f41a25752493b9896385ef44dc33 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 25 May 2021 00:07:10 +0600 Subject: [PATCH 3/9] Fix testing of disabled built-in COM --- .../Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs b/src/tests/Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs index 9b0af77b7a6414..a589fd1da7e545 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.BuiltInCom.cs @@ -21,11 +21,11 @@ public static int Main() Console.WriteLine($"Built-in COM Disabled?: {builtInComDisabled}"); try { - TestByValue(builtInComDisabled); - TestByRef(builtInComDisabled); + TestByValue(!builtInComDisabled); + TestByRef(!builtInComDisabled); TestOut(); - TestFieldByValue(builtInComDisabled); - TestFieldByRef(builtInComDisabled); + TestFieldByValue(!builtInComDisabled); + TestFieldByRef(!builtInComDisabled); } catch (Exception e) { From 0961092f8533680917bb729f8f4aaf0749a5cd3b Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 26 May 2021 01:15:45 +0600 Subject: [PATCH 4/9] Address PR feedback --- src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs b/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs index 7fcef09d8f77c0..0c50e2576a6317 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs @@ -36,6 +36,7 @@ public static int Main() internal unsafe class ComWrappersImpl : ComWrappers { private static readonly ComInterfaceEntry* wrapperEntry; + private static readonly IID_IDispatch = new Guid("00020400-0000-0000-C000-000000000046"); static ComWrappersImpl() { @@ -48,7 +49,7 @@ static ComWrappersImpl() vtblRaw[6] = (IntPtr)(delegate* unmanaged)&IDispatchVtbl.InvokeInternal; wrapperEntry = (ComInterfaceEntry*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IDispatchVtbl), sizeof(ComInterfaceEntry)); - wrapperEntry->IID = new Guid("00020400-0000-0000-C000-000000000046"); + wrapperEntry->IID = IID_IDispatch; wrapperEntry->Vtable = (IntPtr)vtblRaw; } From c5e050fc48a48dff797e919e3acbb04b5f9761cf Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 26 May 2021 07:40:06 +0600 Subject: [PATCH 5/9] Return fetched type --- src/coreclr/vm/interopconverter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/interopconverter.cpp b/src/coreclr/vm/interopconverter.cpp index d74eb6c780fbd0..70ce435a6a8077 100644 --- a/src/coreclr/vm/interopconverter.cpp +++ b/src/coreclr/vm/interopconverter.cpp @@ -189,17 +189,19 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType { hr = SafeQueryInterface(pUnk, IID_IDispatch, &pvObj); pUnk->Release(); + FetchedIpType = ComIpType_Dispatch; } else { pvObj = pUnk; + FetchedIpType = ComIpType_Unknown; } if (FAILED(hr)) COMPlusThrowHR(hr); if (pFetchedIpType != NULL) - *pFetchedIpType = ReqIpType; + *pFetchedIpType = FetchedIpType; RETURN pvObj; } From 8d259836fda0142327f6987ddc848bb38054abf5 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 26 May 2021 10:45:45 +0600 Subject: [PATCH 6/9] Fix compilation errors --- src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs b/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs index 0c50e2576a6317..e82d906a5b2396 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs @@ -36,7 +36,6 @@ public static int Main() internal unsafe class ComWrappersImpl : ComWrappers { private static readonly ComInterfaceEntry* wrapperEntry; - private static readonly IID_IDispatch = new Guid("00020400-0000-0000-C000-000000000046"); static ComWrappersImpl() { @@ -49,7 +48,7 @@ static ComWrappersImpl() vtblRaw[6] = (IntPtr)(delegate* unmanaged)&IDispatchVtbl.InvokeInternal; wrapperEntry = (ComInterfaceEntry*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IDispatchVtbl), sizeof(ComInterfaceEntry)); - wrapperEntry->IID = IID_IDispatch; + wrapperEntry->IID = IDispatchVtbl.IID_IDispatch; wrapperEntry->Vtable = (IntPtr)vtblRaw; } @@ -72,6 +71,8 @@ protected override void ReleaseObjects(IEnumerable objects) } public struct IDispatchVtbl { + private static readonly Guid IID_IDispatch = new Guid("00020400-0000-0000-C000-000000000046"); + [UnmanagedCallersOnly] public static int GetTypeInfoCountInternal(IntPtr thisPtr, IntPtr i) { From 23ca8fa8d403bb038a9f79dc88182d12de0a4b25 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 26 May 2021 20:56:57 +0600 Subject: [PATCH 7/9] Fix compilation error --- src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs b/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs index e82d906a5b2396..a4dcc422cbd7dd 100644 --- a/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs +++ b/src/tests/Interop/PInvoke/Variant/VariantTest.ComWrappers.cs @@ -71,7 +71,7 @@ protected override void ReleaseObjects(IEnumerable objects) } public struct IDispatchVtbl { - private static readonly Guid IID_IDispatch = new Guid("00020400-0000-0000-C000-000000000046"); + internal static readonly Guid IID_IDispatch = new Guid("00020400-0000-0000-C000-000000000046"); [UnmanagedCallersOnly] public static int GetTypeInfoCountInternal(IntPtr thisPtr, IntPtr i) From 05fbfc7e25dbca45059b36cbbccd36a91fb015d1 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Thu, 27 May 2021 11:46:12 +0600 Subject: [PATCH 8/9] Address PR feedback --- src/coreclr/vm/interopconverter.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/interopconverter.cpp b/src/coreclr/vm/interopconverter.cpp index 70ce435a6a8077..b130ae9d32cb5e 100644 --- a/src/coreclr/vm/interopconverter.cpp +++ b/src/coreclr/vm/interopconverter.cpp @@ -189,7 +189,14 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType { hr = SafeQueryInterface(pUnk, IID_IDispatch, &pvObj); pUnk->Release(); - FetchedIpType = ComIpType_Dispatch; + if (!FAILED(hr)) + { + FetchedIpType = ComIpType_Dispatch; + } + else + { + FetchedIpType = ComIpType_Unknown; + } } else { From 3409bc5f9ea892725a19f2abb96ddfcbd4d677d5 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 28 May 2021 23:55:02 +0600 Subject: [PATCH 9/9] Fixes to logic --- src/coreclr/vm/interopconverter.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/interopconverter.cpp b/src/coreclr/vm/interopconverter.cpp index b130ae9d32cb5e..fa49b2f4179125 100644 --- a/src/coreclr/vm/interopconverter.cpp +++ b/src/coreclr/vm/interopconverter.cpp @@ -188,13 +188,15 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType if (ReqIpType & ComIpType_Dispatch) { hr = SafeQueryInterface(pUnk, IID_IDispatch, &pvObj); - pUnk->Release(); - if (!FAILED(hr)) + if (SUCCEEDED(hr)) { + pUnk->Release(); FetchedIpType = ComIpType_Dispatch; } - else + else if (ReqIpType & ComIpType_Unknown) { + hr = S_OK; + pvObj = pUnk; FetchedIpType = ComIpType_Unknown; } }