Add Public API Marshal.GetEndComSlot and Marshal.IsTypeVisibleFromCom (dotnet/corefx...
authorLuqun Lou <luqunl@users.noreply.github.com>
Fri, 7 Sep 2018 23:01:25 +0000 (16:01 -0700)
committerGitHub <noreply@github.com>
Fri, 7 Sep 2018 23:01:25 +0000 (16:01 -0700)
Commit migrated from https://github.com/dotnet/corefx/commit/0ae9863e1db8da810a34a28951e1d4f45f316fce

15 files changed:
src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs
src/libraries/System.Runtime.InteropServices/src/ApiCompatBaseline.netcoreappaot.txt
src/libraries/System.Runtime.InteropServices/src/ApiCompatBaseline.uapaot.txt
src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/ChangeWrapperHandleStrengthTests.nonnetstandard.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/Common/CommonTypes.Windows.cs
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetEndComSlotTests.Windows.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetEndComSlotTests.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.nonnetstandard.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.Windows.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.nonnetstandard.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsComObjectTests.nonnetstandard.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsTypeVisibleFromComTests.Windows.cs [new file with mode: 0644]
src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsTypeVisibleFromComTests.cs [new file with mode: 0644]

index a1f0b04..ae7f20a 100644 (file)
@@ -567,6 +567,7 @@ namespace System.Runtime.InteropServices
         [System.ObsoleteAttribute("GetObjectsForNativeVariants<T>(IntPtr, Int32) may be unavailable in future releases.")]
         public static T[] GetObjectsForNativeVariants<T>(System.IntPtr aSrcNativeVariant, int cVars) { throw null; }
         public static int GetStartComSlot(System.Type t) { throw null; }
+        public static int GetEndComSlot(System.Type t) { throw null; }
         public static object GetTypedObjectForIUnknown(System.IntPtr pUnk, System.Type t) { throw null; }         
         public static System.Type GetTypeFromCLSID(System.Guid clsid) { throw null; }
         public static string GetTypeInfoName(System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo) { throw null; }
@@ -592,6 +593,7 @@ namespace System.Runtime.InteropServices
         public static object PtrToStructure(System.IntPtr ptr, System.Type structureType) { throw null; }
         public static T PtrToStructure<T>(System.IntPtr ptr) { throw null; }
         public static void PtrToStructure<T>(System.IntPtr ptr, T structure) { }
+        public static bool IsTypeVisibleFromCom(Type t) { throw null;}
         public static int QueryInterface(System.IntPtr pUnk, ref System.Guid iid, out System.IntPtr ppv) { throw null; }
         public static byte ReadByte(System.IntPtr ptr) { throw null; }
         public static byte ReadByte(System.IntPtr ptr, int ofs) { throw null; }
index ed81ff9..34f564f 100644 (file)
@@ -13,5 +13,7 @@ MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.StringToCoTask
 MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.ZeroFreeCoTaskMemUTF8(System.IntPtr)' does not exist in the implementation but it does exist in the contract.
 MembersMustExist : Member 'System.Runtime.InteropServices.UnmanagedType System.Runtime.InteropServices.UnmanagedType.LPUTF8Str' does not exist in the implementation but it does exist in the contract.
 MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.GetExceptionPointers()' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.GetEndComSlot(System.Type)' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.IsTypeVisibleFromCom(System.Type)' does not exist in the implementation but it does exist in the contract.
 TypeCannotChangeClassification : Type 'System.Runtime.InteropServices.HandleRef' is marked as readonly in the contract so it must also be marked readonly in the implementation.
-Total Issues: 13
\ No newline at end of file
+Total Issues: 15
\ No newline at end of file
index c1fa489..1f819b9 100644 (file)
@@ -13,5 +13,7 @@ MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.StringToCoTask
 MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.ZeroFreeCoTaskMemUTF8(System.IntPtr)' does not exist in the implementation but it does exist in the contract.
 MembersMustExist : Member 'System.Runtime.InteropServices.UnmanagedType System.Runtime.InteropServices.UnmanagedType.LPUTF8Str' does not exist in the implementation but it does exist in the contract.
 MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.GetExceptionPointers()' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.GetEndComSlot(System.Type)' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'System.Runtime.InteropServices.Marshal.IsTypeVisibleFromCom(System.Type)' does not exist in the implementation but it does exist in the contract.
 TypeCannotChangeClassification : Type 'System.Runtime.InteropServices.HandleRef' is marked as readonly in the contract so it must also be marked readonly in the implementation.
-Total Issues: 13
+Total Issues: 17
index 7171540..e87a27a 100644 (file)
@@ -70,6 +70,8 @@
     <Compile Include="System\Runtime\InteropServices\Marshal\GetNativeVariantForObjectTests.cs" />
     <Compile Include="System\Runtime\InteropServices\Marshal\GetObjectForNativeVariantTests.cs" />
     <Compile Include="System\Runtime\InteropServices\Marshal\GetObjectsForNativeVariantsTests.cs" />
+    <Compile Include="System\Runtime\InteropServices\Marshal\GetStartComSlotTests.cs" />
+    <Compile Include="System\Runtime\InteropServices\Marshal\GetStartComSlotTests.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
     <Compile Include="System\Runtime\InteropServices\Marshal\IsComObjectTests.cs" />
     <Compile Include="System\Runtime\InteropServices\Marshal\IsComObjectTests.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
     <Compile Include="System\Runtime\InteropServices\Marshal\PtrToStructureTests.cs" />
     <Compile Include="System\Runtime\InteropServices\Marshal\GenerateGuidForTypeTests.cs" />
     <Compile Include="System\Runtime\InteropServices\Marshal\GenerateProgIdForTypeTests.cs" />
     <Compile Include="System\Runtime\InteropServices\Marshal\GetComObjectDataTests.cs" />
+    <Compile Include="System\Runtime\InteropServices\Marshal\GetEndComSlotTests.cs" />
+    <Compile Include="System\Runtime\InteropServices\Marshal\GetEndComSlotTests.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
     <Compile Include="System\Runtime\InteropServices\Marshal\GetExceptionPointersTests.cs" />
     <Compile Include="System\Runtime\InteropServices\Marshal\GetHINSTANCETests.cs" />
-    <Compile Include="System\Runtime\InteropServices\Marshal\GetIDispatchForObjectTests.cs" />
+    <Compile Include="System\Runtime\InteropServices\Marshal\GetIDispatchForObjectTests.cs" />    
     <Compile Include="System\Runtime\InteropServices\Marshal\GetTypedObjectForIUnknownTests.cs" />
+    <Compile Include="System\Runtime\InteropServices\Marshal\IsTypeVisibleFromComTests.cs" />
+    <Compile Include="System\Runtime\InteropServices\Marshal\IsTypeVisibleFromComTests.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
     <Compile Include="System\Runtime\InteropServices\Marshal\SetComObjectDataTests.cs" />
     <Compile Include="System\Runtime\InteropServices\TypeLibFuncAttributeTests.cs" />
     <Compile Include="System\Runtime\InteropServices\TypeLibImportClassAttributeTests.cs" />
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/ChangeWrapperHandleStrengthTests.nonnetstandard.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/ChangeWrapperHandleStrengthTests.nonnetstandard.cs
new file mode 100644 (file)
index 0000000..570b4be
--- /dev/null
@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class ChangeWrapperHandleStrengthTests
+    {
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNetNative))]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void ChangeWrapperHandleStrength_ObjectNotCollectible_ThrowsNotSupportedException()
+        {
+            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.RunAndCollect);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type");
+            Type type = typeBuilder.CreateType();
+
+            object o = Activator.CreateInstance(type);
+            Assert.Throws<NotSupportedException>(() => Marshal.ChangeWrapperHandleStrength(o, fIsWeak: true));
+        }
+    }
+}
\ No newline at end of file
index de608be..05e2ec8 100644 (file)
@@ -93,6 +93,44 @@ namespace System.Runtime.InteropServices.Tests.Common
     [Guid("927971f5-0939-11d1-8be1-00c04fd8d503")]
     [ClassInterface(ClassInterfaceType.AutoDual)]
     public class AutoDualComObjectEmpty { }
+
+    [ClassInterface(ClassInterfaceType.AutoDispatch)]
+    public class ManagedAutoDispatchClass { }
+
+    [ClassInterface(ClassInterfaceType.AutoDual)]
+    public class ManagedAutoDualClass{ }
+
+    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+    [Guid("710D252E-22BF-4A33-9544-40D8D03C29FF")]
+    public interface ManagedInterfaceSupportIUnknown { }
+    
+    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+    [Guid("B68116E6-B341-4596-951F-F95262CA5612")]
+    public interface ManagedInterfaceSupportIUnknownWithMethods
+    { 
+        void M1();
+        void M2();
+    }
+
+    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
+    [Guid("E0B128C2-C560-42B7-9824-BE753F321B09")]
+    public interface ManagedInterfaceSupportIDispatch { }
+
+    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
+    [Guid("857A6ACD-E462-4379-8314-44B9C0078217")]
+    public interface ManagedInterfaceSupportIDispatchWithMethods
+    { 
+        void M1();
+        void M2();
+    }
+
+    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
+    [Guid("D235E3E7-344F-4645-BBB6-6A82C2B34C34")]
+    public interface ManagedInterfaceSupportDualInterfaceWithMethods
+    { 
+        void M1();
+        void M2();
+    }
 }
 
 #pragma warning restore CS0618 // Type or member is obsolete
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetEndComSlotTests.Windows.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetEndComSlotTests.Windows.cs
new file mode 100644 (file)
index 0000000..5f5a838
--- /dev/null
@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class GetEndComSlotTests
+    {
+        public static IEnumerable<object[]> GetEndComSlot_TestData()
+        {
+            yield return new object[] { typeof(ComImportObject), -1 };
+            yield return new object[] { typeof(SubComImportObject), -1 };
+            yield return new object[] { typeof(InterfaceComImportObject), -1 };
+            yield return new object[] { typeof(IComImportObject), 6 };
+            yield return new object[] { typeof(ManagedInterfaceSupportIUnknown), 2 };
+            yield return new object[] { typeof(ManagedInterfaceSupportIUnknownWithMethods), 4 };
+            yield return new object[] { typeof(ManagedInterfaceSupportDualInterfaceWithMethods), 8 };
+            yield return new object[] { typeof(ManagedInterfaceSupportIDispatch), 6 };
+            yield return new object[] { typeof(ManagedInterfaceSupportIDispatchWithMethods), 8 };
+            yield return new object[] { typeof(ManagedAutoDispatchClass), -1};
+            yield return new object[] { typeof(ManagedAutoDualClass), 10 };
+        }
+
+        [MemberData(nameof(GetEndComSlot_TestData))]
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "Not approved COM object for app")]
+        public void GetEndComSlot_Windows_ReturnsExpected(Type type, int expected)
+        {
+            Assert.Equal(expected, Marshal.GetEndComSlot(type));
+        }
+    }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetEndComSlotTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetEndComSlotTests.cs
new file mode 100644 (file)
index 0000000..2e8e220
--- /dev/null
@@ -0,0 +1,95 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class GetEndComSlotTests
+    {
+        [Theory]
+        [InlineData(typeof(int), -1)]
+        [InlineData(typeof(string), -1)]
+        [InlineData(typeof(NonGenericClass), -1)]
+        [InlineData(typeof(NonGenericStruct), -1)]
+        [InlineData(typeof(NonGenericInterface), 6)]
+        [InlineData(typeof(int*), -1)]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        [ActiveIssue(31068, ~TargetFrameworkMonikers.NetFramework)]
+        public void GetEndComSlot_ValidType_ReturnsExpected(Type type, int expected)
+        {
+            Assert.Equal(expected, Marshal.GetEndComSlot(type));
+        }
+        
+        [Fact]
+        [PlatformSpecific(TestPlatforms.AnyUnix)]
+        public void GetEndComSlot_Unix_ThrowsPlatformNotSupportedException()
+        {
+            Assert.Throws<PlatformNotSupportedException>(() => Marshal.GetEndComSlot(null));
+        }
+        
+        [Fact]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetEndComSlot_NullType_ThrowsArgumentNullException()
+        {
+            AssertExtensions.Throws<ArgumentNullException>(null, () => Marshal.GetEndComSlot(null));
+        }
+        
+        [Fact]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetEndComSlot_NotRuntimeType_ThrowsArgumentException()
+        {
+            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.Run);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type");
+            AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetEndComSlot(typeBuilder));
+        }
+        
+        public static IEnumerable<object[]> GetStartComSlot_InvalidGenericType_TestData()
+        {
+            yield return new object[] { typeof(int).MakeByRefType() };
+            yield return new object[] { typeof(GenericClass<>).GetTypeInfo().GenericTypeParameters[0] };
+        }
+        
+        [Theory]
+        [MemberData(nameof(GetStartComSlot_InvalidGenericType_TestData))]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetEndComSlot_InvalidGenericType_ThrowsArgumentNullException(Type type)
+        {
+            AssertExtensions.Throws<ArgumentNullException>(null, () => Marshal.GetEndComSlot(type));
+        }
+        public static IEnumerable<object[]> GetStartComSlot_NotComVisibleType_TestData()
+        {
+            yield return new object[] { typeof(GenericClass<>) };
+            yield return new object[] { typeof(GenericClass<string>) };
+            yield return new object[] { typeof(GenericStruct<>) };
+            yield return new object[] { typeof(GenericStruct<string>) };
+            yield return new object[] { typeof(GenericInterface<>) };
+            yield return new object[] { typeof(GenericInterface<string>) };
+            yield return new object[] { typeof(NonComVisibleClass) };
+            yield return new object[] { typeof(NonComVisibleStruct) };
+            yield return new object[] { typeof(NonComVisibleInterface) };
+            yield return new object[] { typeof(int[]) };
+            yield return new object[] { typeof(int[][]) };
+            yield return new object[] { typeof(int[,]) };
+             AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.RunAndCollect);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type");
+            Type collectibleType = typeBuilder.CreateType();
+            yield return new object[] { collectibleType };
+        }
+        
+        [Theory]
+        [MemberData(nameof(GetStartComSlot_NotComVisibleType_TestData))]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetEndComSlot_NotComVisibleType_ThrowsArgumentException(Type type)
+        {
+            AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetEndComSlot(type));
+        }
+    }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.nonnetstandard.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.nonnetstandard.cs
new file mode 100644 (file)
index 0000000..4136e48
--- /dev/null
@@ -0,0 +1,44 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Drawing;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+#pragma warning disable 618
+
+namespace System.Runtime.InteropServices.Tests
+{
+    [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "GetNativeVariantForObject() not supported on UWP")]
+    public partial class GetNativeVariantForObjectTests
+    {
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNetNative))]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetNativeVariantForObject_ObjectNotCollectible_ThrowsNotSupportedException()
+        {
+            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.RunAndCollect);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type");
+            Type type = typeBuilder.CreateType();
+
+            object o = Activator.CreateInstance(type);
+
+            var v = new Variant();
+            IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+            try
+            {
+                Assert.Throws<NotSupportedException>(() => Marshal.GetNativeVariantForObject(o, pNative));
+            }
+            finally
+            {
+                Marshal.FreeHGlobal(pNative);
+            }
+        }  
+    }
+}
+
+#pragma warning restore 618
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.Windows.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.Windows.cs
new file mode 100644 (file)
index 0000000..fc7515d
--- /dev/null
@@ -0,0 +1,53 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class GetStartComSlotTests
+    {
+        public static IEnumerable<object[]> GetStartComSlot_TestData()
+        {
+            yield return new object[] { typeof(ComImportObject), -1 };
+            yield return new object[] { typeof(SubComImportObject), -1 };
+            yield return new object[] { typeof(InterfaceComImportObject), -1 };
+            yield return new object[] { typeof(InterfaceAndComImportObject), 7 };
+            yield return new object[] { typeof(IComImportObject), 7 };
+
+            yield return new object[] { typeof(DualInterface), 7};
+            yield return new object[] { typeof(IUnknownInterface), 3};
+            yield return new object[] { typeof(IDispatchInterface), 7};
+            yield return new object[] { typeof(IInspectableInterface), 6};
+            yield return new object[] { typeof(DualComObject), 7};
+            yield return new object[] { typeof(IUnknownComObject), 3};
+            yield return new object[] { typeof(IDispatchComObject), 7};
+            yield return new object[] { typeof(IInspectableComObject), 6};
+            yield return new object[] { typeof(NonDualComObject), 7};
+            yield return new object[] { typeof(AutoDispatchComObject), 7};
+            yield return new object[] { typeof(AutoDualComObject), 7};
+            yield return new object[] { typeof(NonDualComObjectEmpty), -1};
+            yield return new object[] { typeof(AutoDispatchComObjectEmpty), -1};
+            yield return new object[] { typeof(AutoDualComObjectEmpty), -1};
+
+            yield return new object[] { typeof(ManagedInterfaceSupportIUnknown), 3 };
+            yield return new object[] { typeof(ManagedInterfaceSupportIUnknownWithMethods), 3 };
+            yield return new object[] { typeof(ManagedInterfaceSupportDualInterfaceWithMethods), 7 };
+            yield return new object[] { typeof(ManagedInterfaceSupportIDispatch), 7 };
+            yield return new object[] { typeof(ManagedInterfaceSupportIDispatchWithMethods), 7 };
+            yield return new object[] { typeof(ManagedAutoDispatchClass), -1 };
+            yield return new object[] { typeof(ManagedAutoDualClass), 7 };
+        }
+
+        [MemberData(nameof(GetStartComSlot_TestData))]
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "Not approved COM object for app")]
+        public void GetStartComSlot_Windows_ReturnsExpected(Type type, int expected)
+        {
+            Assert.Equal(expected, Marshal.GetStartComSlot(type));
+        }
+    }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.cs
new file mode 100644 (file)
index 0000000..b6baafc
--- /dev/null
@@ -0,0 +1,90 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class GetStartComSlotTests
+    {
+        [Theory]
+        [InlineData(typeof(int), -1)]
+        [InlineData(typeof(string), -1)]
+        [InlineData(typeof(NonGenericClass), -1)]
+        [InlineData(typeof(NonGenericStruct), -1)]
+        [InlineData(typeof(NonGenericInterface), 7)]
+        [InlineData(typeof(int*), -1)]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        [ActiveIssue(31068, ~TargetFrameworkMonikers.NetFramework)]
+        public void GetStartComSlot_ValidType_ReturnsExpected(Type type, int expected)
+        {
+            Assert.Equal(expected, Marshal.GetStartComSlot(type));
+        }
+        
+        [Fact]
+        [PlatformSpecific(TestPlatforms.AnyUnix)]
+        public void GetStartComSlot_Unix_ThrowsPlatformNotSupportedException()
+        {
+            Assert.Throws<PlatformNotSupportedException>(() => Marshal.GetStartComSlot(null));
+        }
+        
+        [Fact]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetStartComSlot_NullType_ThrowsArgumentNullException()
+        {
+            AssertExtensions.Throws<ArgumentNullException>(null, () => Marshal.GetStartComSlot(null));
+        }
+        
+        [Fact]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetStartComSlot_NotRuntimeType_ThrowsArgumentException()
+        {
+            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.Run);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type");
+            AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetStartComSlot(typeBuilder));
+        }
+        
+        public static IEnumerable<object[]> GetStartComSlot_InvalidGenericType_TestData()
+        {
+            yield return new object[] { typeof(int).MakeByRefType() };
+            yield return new object[] { typeof(GenericClass<>).GetTypeInfo().GenericTypeParameters[0] };
+        }
+        
+        [Theory]
+        [MemberData(nameof(GetStartComSlot_InvalidGenericType_TestData))]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetStartComSlot_InvalidGenericType_ThrowsArgumentNullException(Type type)
+        {
+            AssertExtensions.Throws<ArgumentNullException>(null, () => Marshal.GetStartComSlot(type));
+        }
+        public static IEnumerable<object[]> GetStartComSlot_NotComVisibleType_TestData()
+        {
+            yield return new object[] { typeof(GenericClass<>) };
+            yield return new object[] { typeof(GenericClass<string>) };
+            yield return new object[] { typeof(GenericStruct<>) };
+            yield return new object[] { typeof(GenericStruct<string>) };
+            yield return new object[] { typeof(GenericInterface<>) };
+            yield return new object[] { typeof(GenericInterface<string>) };
+            yield return new object[] { typeof(NonComVisibleClass) };
+            yield return new object[] { typeof(NonComVisibleStruct) };
+            yield return new object[] { typeof(NonComVisibleInterface) };
+            yield return new object[] { typeof(int[]) };
+            yield return new object[] { typeof(int[][]) };
+            yield return new object[] { typeof(int[,]) };
+        }
+        
+        [Theory]
+        [MemberData(nameof(GetStartComSlot_NotComVisibleType_TestData))]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetStartComSlot_NotComVisibleType_ThrowsArgumentException(Type type)
+        {
+            AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetStartComSlot(type));
+        }
+    }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.nonnetstandard.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/GetStartComSlotTests.nonnetstandard.cs
new file mode 100644 (file)
index 0000000..204cd48
--- /dev/null
@@ -0,0 +1,32 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class GetStartComSlotTests
+    {
+        public static IEnumerable<object[]> GetStartComSlot_NotComVisibleType_TestData()
+        {
+             AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.RunAndCollect);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type");
+            Type collectibleType = typeBuilder.CreateType();
+            yield return new object[] { collectibleType };
+        }
+        
+        [Theory]
+        [MemberData(nameof(GetStartComSlot_NotComVisibleType_TestData))]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        public void GetStartComSlot_NotComVisibleType_ThrowsArgumentException(Type type)
+        {
+            AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetStartComSlot(type));
+        }
+    }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsComObjectTests.nonnetstandard.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsComObjectTests.nonnetstandard.cs
new file mode 100644 (file)
index 0000000..a9841d3
--- /dev/null
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class IsComObjectTests
+    {
+        public static IEnumerable<object[]> IsComObject_TestData()
+        {
+            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.RunAndCollect);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type");
+            Type collectibleType = typeBuilder.CreateType();
+            object collectibleObject = Activator.CreateInstance(collectibleType);
+            yield return new object[] { collectibleObject };
+            
+            ConstructorInfo comImportConstructor = typeof(ComImportAttribute).GetConstructor(new Type[0]);
+            var comImportAttributeBuilder = new CustomAttributeBuilder(comImportConstructor, new object[0]);
+
+            AssemblyBuilder comImportAssemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.RunAndCollect);
+            ModuleBuilder comImportModuleBuilder = comImportAssemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder comImportTypeBuilder = comImportModuleBuilder.DefineType("Type");
+            comImportTypeBuilder.SetCustomAttribute(comImportAttributeBuilder);
+
+            Type collectibleComImportObject = comImportTypeBuilder.CreateType();
+            yield return new object[] { collectibleComImportObject };
+        }
+
+        [Theory]
+        [MemberData(nameof(IsComObject_TestData))]
+        public void IsComObject_NonComObject_ReturnsFalse(object value)
+        {
+            Assert.False(Marshal.IsComObject(value));
+        }
+    }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsTypeVisibleFromComTests.Windows.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsTypeVisibleFromComTests.Windows.cs
new file mode 100644 (file)
index 0000000..15d3e8e
--- /dev/null
@@ -0,0 +1,64 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class IsTypeVisibleFromComTests
+    {
+        public static IEnumerable<object[]> IsTypeVisibleFromCom_Windows_TestData()
+        {
+            yield return new object[] { typeof(ComImportObject), true };
+            yield return new object[] { typeof(InterfaceAndComImportObject), true };
+            yield return new object[] { typeof(InterfaceComImportObject), true };
+            
+            yield return new object[] { typeof(IsTypeVisibleFromComTests), true };
+            yield return new object[] { typeof(PrivateType), false };
+            yield return new object[] { typeof(ProtectedType), false };
+            yield return new object[] { typeof(InternalType), false };
+            yield return new object[] { typeof(InnerManagedInterface), false};
+            yield return new object[] { typeof(NonGenericInterface), true };
+            yield return new object[] { typeof(NonGenericStruct), true };
+            yield return new object[] { typeof(ManagedClassWithComVisibleFalse), false };
+            yield return new object[] { typeof(ManagedClassWithComVisibleTrue), true };
+        }
+
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [MemberData(nameof(IsTypeVisibleFromCom_Windows_TestData))]
+        [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "Not approved COM object for app")]
+        public void IsTypeVisibleFromCom_Windows_ReturnsExpected(Type value, bool expected)
+        {
+            Assert.Equal(expected, Marshal.IsTypeVisibleFromCom(value));
+        }
+
+        private class PrivateType
+        {
+        }
+
+        protected class ProtectedType
+        {
+        }
+
+        internal class InternalType
+        {
+        }
+
+        interface InnerManagedInterface
+        {
+        }
+    }
+
+    [ComVisibleAttribute(false)]
+    public class ManagedClassWithComVisibleFalse
+    {
+    }
+
+    [ComVisibleAttribute(true)]
+    public class ManagedClassWithComVisibleTrue
+    {
+    }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsTypeVisibleFromComTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/IsTypeVisibleFromComTests.cs
new file mode 100644 (file)
index 0000000..24ef4c9
--- /dev/null
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Runtime.InteropServices.Tests.Common;
+using Xunit;
+
+namespace System.Runtime.InteropServices.Tests
+{
+    public partial class IsTypeVisibleFromComTests
+    {
+        [Fact]
+        public void IsTypeVisibleFromCom_NullType_ThrowsArgumentNullException()
+        {
+            AssertExtensions.Throws<ArgumentNullException>("t", () => Marshal.IsTypeVisibleFromCom(null));
+        }
+    }
+}