From: Aaron Robinson Date: Thu, 19 Jul 2018 00:52:02 +0000 (-0700) Subject: Basic .NET client tests (dotnet/coreclr#18843) X-Git-Tag: submit/tizen/20210909.063632~11030^2~4336 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=166e5f0628b12f200eff5ca36c31f6d1a9205a6a;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Basic .NET client tests (dotnet/coreclr#18843) - Add support for a testing primitive marshalling with a native COM server and .NET client. This uses RegFree COM for activation. - Remove ClassicCOM tests - Bring back tests for activation via reflection Commit migrated from https://github.com/dotnet/coreclr/commit/f37214ab432e192178ada2d202328f5fd8884cff --- diff --git a/src/coreclr/tests/CMakeLists.txt b/src/coreclr/tests/CMakeLists.txt index 078d9b8..e667e59 100644 --- a/src/coreclr/tests/CMakeLists.txt +++ b/src/coreclr/tests/CMakeLists.txt @@ -36,7 +36,21 @@ endif() # Compile options if (WIN32) - add_compile_options(-wd4100 -wd4514 -wd4668 -wd4710 -wd4711 -wd4820) + # 4100 - unreferenced formal parameter + # 4514 - unreferenced inline function has been removed + # 4625 - copy constructor was implicitly defined as deleted because a base class copy constructor is inaccessible or deleted + # 4626 - assignment operator was implicitly defined as deleted because a base class assignment operator is inaccessible or deleted + # 4668 - 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives' + # 4710 - function not inlined + # 4711 - 'function' selected for inline expansion + # 4774 - format string expected in argument number is not a string literal + # 4820 - bytes padding added after construct 'member_name' + # 5025 - move assignment operator was implicitly defined as deleted + # 5026 - move constructor was implicitly defined as deleted + # 5027 - move assignment operator was implicitly defined as deleted + # 5039 - pointer or reference to potentially throwing function passed to extern C function under -EHc. Undefined behavior may occur if this function throws an exception. + add_compile_options(-wd4100 -wd4514 -wd4625 -wd4626 -wd4668 -wd4710 -wd4711 -wd4774 -wd4820 -wd5025 -wd5026 -wd5027 -wd5039) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") endif() if(CLR_CMAKE_PLATFORM_UNIX) diff --git a/src/coreclr/tests/src/Interop/CMakeLists.txt b/src/coreclr/tests/src/Interop/CMakeLists.txt index 8780010..04ec8aa 100644 --- a/src/coreclr/tests/src/Interop/CMakeLists.txt +++ b/src/coreclr/tests/src/Interop/CMakeLists.txt @@ -1,10 +1,10 @@ if(WIN32) - if(CLR_CMAKE_HOST_ARCH STREQUAL arm) - list(APPEND LINK_LIBRARIES_ADDITIONAL - ole32.lib - ) - endif(CLR_CMAKE_HOST_ARCH STREQUAL arm) + if(CLR_CMAKE_HOST_ARCH STREQUAL arm) + list(APPEND LINK_LIBRARIES_ADDITIONAL + ole32.lib + ) + endif(CLR_CMAKE_HOST_ARCH STREQUAL arm) endif(WIN32) include_directories(common) @@ -26,7 +26,10 @@ add_subdirectory(StringMarshalling/UTF8) add_subdirectory(MarshalAPI/FunctionPointer) add_subdirectory(MarshalAPI/IUnknown) add_subdirectory(SizeConst) -add_subdirectory(ClassicCOM) add_subdirectory(DllImportAttribute/ExeFile) add_subdirectory(DllImportAttribute/FileNameContainDot) add_subdirectory(DllImportAttribute/Simple) + +if(WIN32) + add_subdirectory(COM/NativeServer) +endif(WIN32) diff --git a/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/App.manifest b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/App.manifest new file mode 100644 index 0000000..37b4f65 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/App.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/ArrayTests.cs b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/ArrayTests.cs new file mode 100644 index 0000000..1881263 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/ArrayTests.cs @@ -0,0 +1,168 @@ +// 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. + +namespace NetClient +{ + using CoreFXTestLibrary; + using System; + using System.Collections.Generic; + using System.Linq; + + class ArrayTests + { + static private readonly IEnumerable BaseData = Enumerable.Range(0, 10); + + private readonly Server.Contract.Servers.ArrayTesting server; + private readonly double expectedMean; + + public ArrayTests() + { + this.server = (Server.Contract.Servers.ArrayTesting)new Server.Contract.Servers.ArrayTestingClass(); + + double acc = 0.0; + int[] rawData = BaseData.ToArray(); + foreach (var d in rawData) + { + acc += d; + } + + expectedMean = acc / rawData.Length; + } + + public void Run() + { + this.Marshal_ByteArray(); + this.Marshal_ShortArray(); + this.Marshal_UShortArray(); + this.Marshal_IntArray(); + this.Marshal_UIntArray(); + this.Marshal_LongArray(); + this.Marshal_ULongArray(); + this.Marshal_FloatArray(); + this.Marshal_DoubleArray(); + } + + static private bool EqualByBound(double expected, double actual) + { + double low = expected - 0.00001; + double high = expected + 0.00001; + double eps = Math.Abs(expected - actual); + bool isEqual = eps < double.Epsilon || (low < actual && actual < high); + if (!isEqual) + { + Console.WriteLine($"{expected} {actual}"); + } + + return isEqual; + } + + private void Marshal_ByteArray() + { + int len; + byte[] data = BaseData.Select(i => (byte)i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Byte_LP_PreLen(data.Length, data)), $"Mean_Byte_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Byte_LP_PostLen(data, data.Length)), $"Mean_Byte_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Byte_SafeArray_OutLen(data, out len)), $"Mean_Byte_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + + private void Marshal_ShortArray() + { + int len; + short[] data = BaseData.Select(i => (short)i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Short_LP_PreLen(data.Length, data)), $"Mean_Short_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Short_LP_PostLen(data, data.Length)), $"Mean_Short_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Short_SafeArray_OutLen(data, out len)), $"Mean_Short_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + + private void Marshal_UShortArray() + { + int len; + ushort[] data = BaseData.Select(i => (ushort)i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_UShort_LP_PreLen(data.Length, data)), $"Mean_UShort_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_UShort_LP_PostLen(data, data.Length)), $"Mean_UShort_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_UShort_SafeArray_OutLen(data, out len)), $"Mean_UShort_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + + private void Marshal_IntArray() + { + int len; + int[] data = BaseData.Select(i => i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Int_LP_PreLen(data.Length, data)), $"Mean_Int_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Int_LP_PostLen(data, data.Length)), $"Mean_Int_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Int_SafeArray_OutLen(data, out len)), $"Mean_Int_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + + private void Marshal_UIntArray() + { + int len; + uint[] data = BaseData.Select(i => (uint)i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_UInt_LP_PreLen(data.Length, data)), $"Mean_UInt_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_UInt_LP_PostLen(data, data.Length)), $"Mean_UInt_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_UInt_SafeArray_OutLen(data, out len)), $"Mean_UInt_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + + private void Marshal_LongArray() + { + int len; + long[] data = BaseData.Select(i => (long)i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Long_LP_PreLen(data.Length, data)), $"Mean_Long_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Long_LP_PostLen(data, data.Length)), $"Mean_Long_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Long_SafeArray_OutLen(data, out len)), $"Mean_Long_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + + private void Marshal_ULongArray() + { + int len; + ulong[] data = BaseData.Select(i => (ulong)i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_ULong_LP_PreLen(data.Length, data)), $"Mean_ULong_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_ULong_LP_PostLen(data, data.Length)), $"Mean_ULong_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_ULong_SafeArray_OutLen(data, out len)), $"Mean_ULong_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + + private void Marshal_FloatArray() + { + int len; + float[] data = BaseData.Select(i => (float)i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Float_LP_PreLen(data.Length, data)), $"Mean_Float_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Float_LP_PostLen(data, data.Length)), $"Mean_Float_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Float_SafeArray_OutLen(data, out len)), $"Mean_Float_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + + private void Marshal_DoubleArray() + { + int len; + double[] data = BaseData.Select(i => (double)i).ToArray(); + + Console.WriteLine($"{data.GetType().Name} marshalling"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Double_LP_PreLen(data.Length, data)), $"Mean_Double_LP_PreLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Double_LP_PostLen(data, data.Length)), $"Mean_Double_LP_PostLen"); + Assert.IsTrue(EqualByBound(expectedMean, this.server.Mean_Double_SafeArray_OutLen(data, out len)), $"Mean_Double_SafeArray_OutLen"); + Assert.AreEqual(data.Length, len); + } + } +} diff --git a/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/ErrorTests.cs b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/ErrorTests.cs new file mode 100644 index 0000000..9694333 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/ErrorTests.cs @@ -0,0 +1,60 @@ +// 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. + +namespace NetClient +{ + using CoreFXTestLibrary; + using System; + using System.Runtime.InteropServices; + + class ErrorTests + { + private readonly Server.Contract.Servers.ErrorMarshalTesting server; + public ErrorTests() + { + this.server = (Server.Contract.Servers.ErrorMarshalTesting)new Server.Contract.Servers.ErrorMarshalTestingClass(); + } + + public void Run() + { + this.VerifyExpectedException(); + this.VerifyReturnHResult(); + } + + private void VerifyExpectedException() + { + Console.WriteLine($"Verify expected exception from HRESULT"); + + Assert.Throws(() => { this.server.Throw_HResult(unchecked((int)0x80004001)); }); + Assert.Throws(() => { this.server.Throw_HResult(unchecked((int)0x80004003)); }); + Assert.Throws(() => { this.server.Throw_HResult(unchecked((int)0x80070005)); }); + Assert.Throws(() => { this.server.Throw_HResult(unchecked((int)0x8007000E)); }); + Assert.Throws(() => { this.server.Throw_HResult(unchecked((int)0x80070057)); }); + Assert.Throws(() => { this.server.Throw_HResult(unchecked((int)0x8000ffff)); }); + Assert.Throws(() => { this.server.Throw_HResult(unchecked((int)-1)); }); + } + + private void VerifyReturnHResult() + { + Console.WriteLine($"Verify preserved function signature"); + + var hrs = new[] + { + unchecked((int)0x80004001), + unchecked((int)0x80004003), + unchecked((int)0x80070005), + unchecked((int)0x80070057), + unchecked((int)0x8000ffff), + -1, + 1, + 2 + }; + + foreach (var hr in hrs) + { + Assert.AreEqual(hr, this.server.Return_As_HResult(hr)); + } + } + } +} diff --git a/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj new file mode 100644 index 0000000..0bb40d7 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj @@ -0,0 +1,36 @@ + + + + + Debug + AnyCPU + NETClientPrimitives + 2.0 + {85C57688-DA98-4DE3-AC9B-526E4747434C} + Exe + {209912F9-0DA1-4184-9CC1-8D583BAF4A28};{87799F5D-CEBD-499D-BDBA-B2C6105CD766} + App.manifest + + + true + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/NumericTests.cs b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/NumericTests.cs new file mode 100644 index 0000000..cff69ec --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/NumericTests.cs @@ -0,0 +1,193 @@ +// 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. + +namespace NetClient +{ + using CoreFXTestLibrary; + using System; + + class NumericTests + { + private readonly int seed; + private readonly Random rng; + private readonly Server.Contract.Servers.NumericTesting server; + + public NumericTests(int seed = 37) + { + this.seed = seed; + Console.WriteLine($"Numeric RNG seed: {this.seed}"); + + this.rng = new Random(this.seed); + this.server = (Server.Contract.Servers.NumericTesting)new Server.Contract.Servers.NumericTestingClass(); + } + + public void Run() + { + int a = this.rng.Next(); + int b = this.rng.Next(); + + this.Marshal_Byte((byte)a, (byte)b); + this.Marshal_Short((short)a, (short)b); + this.Marshal_UShort((ushort)a, (ushort)b); + this.Marshal_Int(a, b); + this.Marshal_UInt((uint)a, (uint)b); + this.Marshal_Long(a, b); + this.Marshal_ULong((ulong)a, (ulong)b); + + this.Marshal_Float(a / 100f, b / 100f); + this.Marshal_Double(a / 100.0, b / 100.0); + } + + static private bool EqualByBound(float expected, float actual) + { + float low = expected - 0.0001f; + float high = expected + 0.0001f; + float eps = Math.Abs(expected - actual); + return eps < float.Epsilon || (low < actual && actual < high); + } + + static private bool EqualByBound(double expected, double actual) + { + double low = expected - 0.00001; + double high = expected + 0.00001; + double eps = Math.Abs(expected - actual); + return eps < double.Epsilon || (low < actual && actual < high); + } + + private void Marshal_Byte(byte a, byte b) + { + var expected = (byte)(a + b); + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.AreEqual(expected, this.server.Add_Byte(a, b)); + + var c = byte.MaxValue; + this.server.Add_Byte_Ref(a, b, ref c); + Assert.AreEqual(expected, c); + + c = 0; + this.server.Add_Byte_Out(a, b, out c); + Assert.AreEqual(expected, c); + } + + private void Marshal_Short(short a, short b) + { + var expected = (short)(a + b); + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.AreEqual(expected, this.server.Add_Short(a, b)); + + var c = short.MaxValue; + this.server.Add_Short_Ref(a, b, ref c); + Assert.AreEqual(expected, c); + + c = 0; + this.server.Add_Short_Out(a, b, out c); + Assert.AreEqual(expected, c); + } + + private void Marshal_UShort(ushort a, ushort b) + { + var expected = (ushort)(a + b); + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.AreEqual(expected, this.server.Add_UShort(a, b)); + + var c = ushort.MaxValue; + this.server.Add_UShort_Ref(a, b, ref c); + Assert.AreEqual(expected, c); + + c = 0; + this.server.Add_UShort_Out(a, b, out c); + Assert.AreEqual(expected, c); + } + + private void Marshal_Int(int a, int b) + { + var expected = a + b; + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.AreEqual(expected, this.server.Add_Int(a, b)); + + var c = int.MaxValue; + this.server.Add_Int_Ref(a, b, ref c); + Assert.AreEqual(expected, c); + + c = 0; + this.server.Add_Int_Out(a, b, out c); + Assert.AreEqual(expected, c); + } + + private void Marshal_UInt(uint a, uint b) + { + var expected = a + b; + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.AreEqual(expected, this.server.Add_UInt(a, b)); + + var c = uint.MaxValue; + this.server.Add_UInt_Ref(a, b, ref c); + Assert.AreEqual(expected, c); + + c = 0; + this.server.Add_UInt_Out(a, b, out c); + Assert.AreEqual(expected, c); + } + + private void Marshal_Long(long a, long b) + { + var expected = a + b; + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.AreEqual(expected, this.server.Add_Long(a, b)); + + var c = long.MaxValue; + this.server.Add_Long_Ref(a, b, ref c); + Assert.AreEqual(expected, c); + + c = 0; + this.server.Add_Long_Out(a, b, out c); + Assert.AreEqual(expected, c); + } + + private void Marshal_ULong(ulong a, ulong b) + { + var expected = a + b; + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.AreEqual(expected, this.server.Add_ULong(a, b)); + + var c = ulong.MaxValue; + this.server.Add_ULong_Ref(a, b, ref c); + Assert.AreEqual(expected, c); + + c = 0; + this.server.Add_ULong_Out(a, b, out c); + Assert.AreEqual(expected, c); + } + + private void Marshal_Float(float a, float b) + { + var expected = a + b; + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.IsTrue(EqualByBound(expected, this.server.Add_Float(a, b)), $"Add_Float: {this.server.Add_Float(a, b)}"); + + var c = float.MaxValue; + this.server.Add_Float_Ref(a, b, ref c); + Assert.IsTrue(EqualByBound(expected, c), "Add_Float_Ref"); + + c = 0; + this.server.Add_Float_Out(a, b, out c); + Assert.IsTrue(EqualByBound(expected, c), "Add_Float_Out"); + } + + private void Marshal_Double(double a, double b) + { + var expected = a + b; + Console.WriteLine($"{expected.GetType().Name} test invariant: {a} + {b} = {expected}"); + Assert.IsTrue(EqualByBound(expected, this.server.Add_Double(a, b))); + + var c = double.MaxValue; + this.server.Add_Double_Ref(a, b, ref c); + Assert.IsTrue(EqualByBound(expected, c)); + + c = 0; + this.server.Add_Double_Out(a, b, out c); + Assert.IsTrue(EqualByBound(expected, c)); + } + } +} diff --git a/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/Program.cs b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/Program.cs new file mode 100644 index 0000000..4d76417 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/Program.cs @@ -0,0 +1,29 @@ +// 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. + +namespace NetClient +{ + using System; + + class Program + { + static int Main(string[] doNotUse) + { + try + { + new NumericTests().Run(); + new ArrayTests().Run(); + new StringTests().Run(); + new ErrorTests().Run(); + } + catch (Exception e) + { + Console.WriteLine($"Test Failure: {e.Message}\n{e.StackTrace}"); + return 101; + } + + return 100; + } + } +} diff --git a/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/StringTests.cs b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/StringTests.cs new file mode 100644 index 0000000..ab5271f --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NETClients/Primitives/StringTests.cs @@ -0,0 +1,272 @@ +// 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. + +namespace NetClient +{ + using CoreFXTestLibrary; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Runtime.InteropServices; + + class StringTests + { + private readonly Server.Contract.Servers.StringTesting server; + + private readonly IEnumerable> addPairs = new Tuple[] + { + Tuple.Create("", ""), + Tuple.Create("", "def"), + Tuple.Create("abc", ""), + Tuple.Create("abc", "def"), + Tuple.Create("", "结合"), + Tuple.Create("结合", ""), + Tuple.Create("a", "结合"), + Tuple.Create("结合", "a"), + Tuple.Create("结合", "结合"), + + // String marshalling is optimized where strings shorter than MAX_PATH are + // allocated on the stack. Longer strings have memory allocated for them. + Tuple.Create("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901") + }; + + private readonly IEnumerable reversableStrings = new string[] + { + "", + "a", + "abc", + "reversable string", + "Unicode 相反 Unicode", + + // Long string optimization validation + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901" + }; + + public StringTests() + { + this.server = (Server.Contract.Servers.StringTesting)new Server.Contract.Servers.StringTestingClass(); + } + + public void Run() + { + this.Marshal_LPString(); + this.Marshal_LPWString(); + this.Marshal_BStrString(); + } + + static private string Reverse(string s) + { + var chars = s.ToCharArray(); + Array.Reverse(chars); + return new string(chars); + } + + static private bool AllAscii(string s) + { + const int MaxAscii = 0x7f; + return s.ToCharArray().All(c => c <= MaxAscii); + } + + private void Marshal_LPString() + { + Console.WriteLine($"Marshal strings as { UnmanagedType.LPStr }"); + foreach (var p in addPairs) + { + if (!AllAscii(p.Item1) || !AllAscii(p.Item2)) + { + // LPStr doesn't support non-ascii characters + continue; + } + + string expected = p.Item1 + p.Item2; + string actual = this.server.Add_LPStr(p.Item1, p.Item2); + Assert.AreEqual(expected, actual, "Add_String_LPStr (simple)"); + } + + foreach (var s in reversableStrings) + { + if (!AllAscii(s)) + { + // LPStr doesn't support non-ascii characters + continue; + } + + string local = s; + string expected = Reverse(local); + + string actual = this.server.Reverse_LPStr(local); + Assert.AreEqual(expected, actual); + + actual = this.server.Reverse_LPStr_Ref(ref local); + Assert.AreEqual(expected, actual); + Assert.AreEqual(expected, local); + + local = s; + actual = this.server.Reverse_LPStr_InRef(ref local); + Assert.AreEqual(expected, actual); + Assert.AreEqual(s, local); + + this.server.Reverse_LPStr_Out(local, out actual); + Assert.AreEqual(expected, actual); + + actual = local; + this.server.Reverse_LPStr_OutAttr(local, actual); // No-op for strings + Assert.AreEqual(local, actual); + } + + foreach (var s in reversableStrings) + { + if (!AllAscii(s)) + { + // LPStr doesn't support non-ascii characters + continue; + } + + var local = new StringBuilder(s); + string expected = Reverse(local.ToString()); + + StringBuilder actual = this.server.Reverse_SB_LPStr(local); + Assert.AreEqual(expected, actual.ToString()); + Assert.AreEqual(expected, local.ToString()); + + local = new StringBuilder(s); + actual = this.server.Reverse_SB_LPStr_Ref(ref local); + Assert.AreEqual(expected, actual.ToString()); + Assert.AreEqual(expected, local.ToString()); + + local = new StringBuilder(s); + actual = this.server.Reverse_SB_LPStr_InRef(ref local); + Assert.AreEqual(expected, actual.ToString()); + + // Palindromes are _always_ equal + if (!string.Equals(s, expected)) + { + Assert.AreNotEqual(expected, local.ToString()); + } + + local = new StringBuilder(s); + actual = new StringBuilder(); + this.server.Reverse_SB_LPStr_Out(local, out actual); + Assert.AreEqual(expected, actual.ToString()); + Assert.AreEqual(expected, local.ToString()); + + local = new StringBuilder(s); + actual = new StringBuilder(s.Length); + this.server.Reverse_SB_LPStr_OutAttr(local, actual); + Assert.AreEqual(expected, actual.ToString()); + Assert.AreEqual(expected, local.ToString()); + } + } + + private void Marshal_LPWString() + { + Console.WriteLine($"Marshal strings as { UnmanagedType.LPWStr }"); + foreach (var p in addPairs) + { + string expected = p.Item1 + p.Item2; + string actual = this.server.Add_LPWStr(p.Item1, p.Item2); + Assert.AreEqual(expected, actual, "Add_String_LPWStr (simple)"); + } + + foreach (var s in reversableStrings) + { + string local = s; + string expected = Reverse(local); + + string actual = this.server.Reverse_LPWStr(local); + Assert.AreEqual(expected, actual); + + actual = this.server.Reverse_LPWStr_Ref(ref local); + Assert.AreEqual(expected, actual); + Assert.AreEqual(expected, local); + + local = s; + actual = this.server.Reverse_LPWStr_InRef(ref local); + Assert.AreEqual(expected, actual); + Assert.AreEqual(s, local); + + this.server.Reverse_LPWStr_Out(local, out actual); + Assert.AreEqual(expected, actual); + + actual = local; + this.server.Reverse_LPWStr_OutAttr(local, actual); // No-op for strings + Assert.AreEqual(local, actual); + } + + foreach (var s in reversableStrings) + { + var local = new StringBuilder(s); + string expected = Reverse(local.ToString()); + + StringBuilder actual = this.server.Reverse_SB_LPWStr(local); + Assert.AreEqual(expected, actual.ToString()); + Assert.AreEqual(expected, local.ToString()); + + local = new StringBuilder(s); + actual = this.server.Reverse_SB_LPWStr_Ref(ref local); + Assert.AreEqual(expected, actual.ToString()); + Assert.AreEqual(expected, local.ToString()); + + local = new StringBuilder(s); + actual = this.server.Reverse_SB_LPWStr_InRef(ref local); + Assert.AreEqual(expected, actual.ToString()); + + // Palindromes are _always_ equal + if (!string.Equals(s, expected)) + { + Assert.AreNotEqual(expected, local.ToString()); + } + + local = new StringBuilder(s); + actual = new StringBuilder(); + this.server.Reverse_SB_LPWStr_Out(local, out actual); + Assert.AreEqual(expected, actual.ToString()); + Assert.AreEqual(expected, local.ToString()); + + local = new StringBuilder(s); + actual = new StringBuilder(s.Length); + this.server.Reverse_SB_LPWStr_OutAttr(local, actual); + Assert.AreEqual(expected, actual.ToString()); + Assert.AreEqual(expected, local.ToString()); + } + } + + private void Marshal_BStrString() + { + Console.WriteLine($"Marshal strings as { UnmanagedType.BStr }"); + foreach (var p in addPairs) + { + string expected = p.Item1 + p.Item2; + string actual = this.server.Add_BStr(p.Item1, p.Item2); + Assert.AreEqual(expected, actual, "Add_String_BStr (simple)"); + } + + foreach (var s in reversableStrings) + { + string local = s; + string expected = Reverse(local); + + string actual = this.server.Reverse_BStr(local); + Assert.AreEqual(expected, actual); + + actual = this.server.Reverse_BStr_Ref(ref local); + Assert.AreEqual(expected, actual); + Assert.AreEqual(expected, local); + + local = s; + actual = this.server.Reverse_BStr_InRef(ref local); + Assert.AreEqual(expected, actual); + Assert.AreEqual(s, local); + + this.server.Reverse_BStr_Out(local, out actual); + Assert.AreEqual(expected, actual); + + actual = local; + this.server.Reverse_BStr_OutAttr(local, actual); // No-op for strings + Assert.AreEqual(local, actual); + } + } + } +} diff --git a/src/coreclr/tests/src/Interop/ClassicCOM/COMLib2.cs b/src/coreclr/tests/src/Interop/COM/NETServer/ImportedTypes.cs similarity index 97% rename from src/coreclr/tests/src/Interop/ClassicCOM/COMLib2.cs rename to src/coreclr/tests/src/Interop/COM/NETServer/ImportedTypes.cs index 8f0ec78..a8d6e19 100644 --- a/src/coreclr/tests/src/Interop/ClassicCOM/COMLib2.cs +++ b/src/coreclr/tests/src/Interop/COM/NETServer/ImportedTypes.cs @@ -7,7 +7,7 @@ using System.Text; using System.Security; using System.Runtime.InteropServices; -namespace COMLib2 +namespace NETServer { [Guid("00020404-0000-0000-C000-000000000046")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] @@ -31,4 +31,4 @@ namespace COMLib2 public class ContextMenu { } -} +} \ No newline at end of file diff --git a/src/coreclr/tests/src/Interop/ClassicCOM/COMLib2.csproj b/src/coreclr/tests/src/Interop/COM/NETServer/NETServer.csproj similarity index 92% rename from src/coreclr/tests/src/Interop/ClassicCOM/COMLib2.csproj rename to src/coreclr/tests/src/Interop/COM/NETServer/NETServer.csproj index 601b94e..cf62cc0 100644 --- a/src/coreclr/tests/src/Interop/ClassicCOM/COMLib2.csproj +++ b/src/coreclr/tests/src/Interop/COM/NETServer/NETServer.csproj @@ -1,10 +1,10 @@ - + Debug AnyCPU - COMLib2 + NETServer 2.0 {C04AB564-CC61-499D-9F4C-AA1A9FDE42C9} library @@ -23,10 +23,10 @@ - + - + \ No newline at end of file diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/ArrayTesting.h b/src/coreclr/tests/src/Interop/COM/NativeServer/ArrayTesting.h new file mode 100644 index 0000000..cbf54cf --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/ArrayTesting.h @@ -0,0 +1,347 @@ +// 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. + +#pragma once + +#include +#include "Servers.h" + +class DECLSPEC_UUID("B99ABE6A-DFF6-440F-BFB6-55179B8FE18E") ArrayTesting : public UnknownImpl, public IArrayTesting +{ +private: + template + double Mean(L l, D *d) + { + double t = 0.0; + for (L i = 0; i < l; ++i) + t += d[i]; + + return (t / l); + } + template + HRESULT Mean(SAFEARRAY *d, long *l, double *r) + { + HRESULT hr; + + VARTYPE type; + RETURN_IF_FAILED(::SafeArrayGetVartype(d, &type)); + + if (E != type) + return E_UNEXPECTED; + + LONG upperBoundIndex; + RETURN_IF_FAILED(::SafeArrayGetUBound(d, 1, &upperBoundIndex)); + + // Upper bound is index so add '1' + *l = (upperBoundIndex + 1); + + switch (type) + { + case VT_UI1: + *r = Mean(*l, static_cast(d->pvData)); + break; + case VT_I2: + *r = Mean(*l, static_cast(d->pvData)); + break; + case VT_UI2: + *r = Mean(*l, static_cast(d->pvData)); + break; + case VT_I4: + *r = Mean(*l, static_cast(d->pvData)); + break; + case VT_UI4: + *r = Mean(*l, static_cast(d->pvData)); + break; + case VT_I8: + *r = Mean(*l, static_cast(d->pvData)); + break; + case VT_UI8: + *r = Mean(*l, static_cast(d->pvData)); + break; + case VT_R4: + *r = Mean(*l, static_cast(d->pvData)); + break; + case VT_R8: + *r = Mean(*l, static_cast(d->pvData)); + break; + default: + return E_INVALIDARG; + } + + return S_OK; + } + +public: // IArrayTesting + DEF_RAWFUNC(Mean_Byte_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ unsigned char * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Short_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ short * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_UShort_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ unsigned short * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Int_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ long * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_UInt_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ unsigned long * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Long_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ __int64 * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_ULong_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ unsigned __int64 * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Float_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ float * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Double_LP_PreLen)( + /*[in]*/ long len, + /*[in]*/ double * d, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Byte_LP_PostLen)( + /*[in]*/ unsigned char * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Short_LP_PostLen)( + /*[in]*/ short * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_UShort_LP_PostLen)( + /*[in]*/ unsigned short * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Int_LP_PostLen)( + /*[in]*/ long * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_UInt_LP_PostLen)( + /*[in]*/ unsigned long * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Long_LP_PostLen)( + /*[in]*/ __int64 * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_ULong_LP_PostLen)( + /*[in]*/ unsigned __int64 * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Float_LP_PostLen)( + /*[in]*/ float * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Double_LP_PostLen)( + /*[in]*/ double * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + *pRetVal = Mean(len, d); + return S_OK; + } + DEF_RAWFUNC(Mean_Byte_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + DEF_RAWFUNC(Mean_Short_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + DEF_RAWFUNC(Mean_UShort_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + DEF_RAWFUNC(Mean_Int_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + DEF_RAWFUNC(Mean_UInt_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + DEF_RAWFUNC(Mean_Long_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + DEF_RAWFUNC(Mean_ULong_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + DEF_RAWFUNC(Mean_Float_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + DEF_RAWFUNC(Mean_Double_SafeArray_OutLen)( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal) + { + if (pRetVal == nullptr) + return E_POINTER; + return Mean(d, len, pRetVal); + } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return DoQueryInterface(this, riid, ppvObject); + } + + DEFINE_REF_COUNTING(); +}; diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/CMakeLists.txt b/src/coreclr/tests/src/Interop/COM/NativeServer/CMakeLists.txt new file mode 100644 index 0000000..368248d --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required (VERSION 2.6) +project (COMNativeServer) +include_directories( ${INC_PLATFORM_DIR} ) +include_directories( "../ServerContracts" ) +set(SOURCES Servers.cpp stdafx.cpp Exports.def COMNativeServer.X.manifest) + +if (WIN32) + # 4365 - signed/unsigned mismatch + add_compile_options(-wd4365) +endif() + +# add the shared library +add_library (COMNativeServer SHARED ${SOURCES}) +target_link_libraries(COMNativeServer ${LINK_LIBRARIES_ADDITIONAL}) + +# Copy manifest file to project output +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$/COMNativeServer.X.manifest INPUT ${CMAKE_CURRENT_SOURCE_DIR}/COMNativeServer.X.manifest) + +# add the install targets +install (TARGETS COMNativeServer DESTINATION bin) diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest b/src/coreclr/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest new file mode 100644 index 0000000..13c36c9 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/ComHelpers.h b/src/coreclr/tests/src/Interop/COM/NativeServer/ComHelpers.h new file mode 100644 index 0000000..651ccc5 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/ComHelpers.h @@ -0,0 +1,169 @@ +// 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. + +#pragma once + +#include +#include +#include +#include +#include +#include + +// Common macro for working in COM +#define RETURN_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { return hr; } } + +namespace Internal +{ + template + HRESULT __QueryInterfaceImpl( + /* [in] */ C *obj, + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + if (riid == __uuidof(I)) + { + *ppvObject = static_cast(obj); + } + else if (riid == __uuidof(IUnknown)) + { + *ppvObject = static_cast(obj); + } + else + { + *ppvObject = nullptr; + return E_NOINTERFACE; + } + + return S_OK; + } + + template + HRESULT __QueryInterfaceImpl( + /* [in] */ C *obj, + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + if (riid == __uuidof(I1)) + { + *ppvObject = static_cast(obj); + return S_OK; + } + + return __QueryInterfaceImpl(obj, riid, ppvObject); + } +} + +// Implementation of IUnknown operations +class UnknownImpl +{ +public: + UnknownImpl() = default; + virtual ~UnknownImpl() = default; + + UnknownImpl(const UnknownImpl&) = delete; + UnknownImpl& operator=(const UnknownImpl&) = delete; + + UnknownImpl(UnknownImpl&&) = default; + UnknownImpl& operator=(UnknownImpl&&) = default; + + template + HRESULT DoQueryInterface( + /* [in] */ C *derived, + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void **ppvObject) + { + assert(derived != nullptr); + if (ppvObject == nullptr) + return E_POINTER; + + HRESULT hr = Internal::__QueryInterfaceImpl(derived, riid, ppvObject); + if (hr == S_OK) + DoAddRef(); + + return hr; + } + + ULONG DoAddRef() + { + assert(_refCount > 0); + return (++_refCount); + } + + ULONG DoRelease() + { + assert(_refCount > 0); + ULONG c = (--_refCount); + if (c == 0) + delete this; + return c; + } + +private: + std::atomic _refCount = 1; +}; + +// Marco to use for defining ref counting impls +#define DEFINE_REF_COUNTING() \ + STDMETHOD_(ULONG, AddRef)(void) { return UnknownImpl::DoAddRef(); } \ + STDMETHOD_(ULONG, Release)(void) { return UnknownImpl::DoRelease(); } + +// Templated class factory +template +class ClassFactoryBasic : public UnknownImpl, public IClassFactory +{ +public: // static + static HRESULT Create(_In_ REFIID riid, _Outptr_ LPVOID FAR* ppv) + { + try + { + auto cf = new ClassFactoryBasic(); + HRESULT hr = cf->QueryInterface(riid, ppv); + cf->Release(); + return hr; + } + catch (const std::bad_alloc&) + { + return E_OUTOFMEMORY; + } + } + +public: // IClassFactory + STDMETHOD(CreateInstance)( + _In_opt_ IUnknown *pUnkOuter, + _In_ REFIID riid, + _COM_Outptr_ void **ppvObject) + { + if (pUnkOuter != nullptr) + return CLASS_E_NOAGGREGATION; + + try + { + auto ti = new T(); + HRESULT hr = ti->QueryInterface(riid, ppvObject); + ti->Release(); + return hr; + } + catch (const std::bad_alloc&) + { + return E_OUTOFMEMORY; + } + } + + STDMETHOD(LockServer)(/* [in] */ BOOL fLock) + { + assert(false && "Not impl"); + return E_NOTIMPL; + } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return DoQueryInterface(this, riid, ppvObject); + } + + DEFINE_REF_COUNTING(); +}; diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h b/src/coreclr/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h new file mode 100644 index 0000000..307abe4 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h @@ -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. + +#pragma once + +#include "Servers.h" + +class DECLSPEC_UUID("71CF5C45-106C-4B32-B418-43A463C6041F") ErrorMarshalTesting : public UnknownImpl, public IErrorMarshalTesting +{ +public: // IErrorMarshalTesting + DEF_RAWFUNC(Throw_HResult)( + /*[in]*/ long hresultToReturn) + { + return HRESULT{ hresultToReturn }; + } + long __stdcall Return_As_HResult( + /*[in]*/ long hresultToReturn) + { + return hresultToReturn; + } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return DoQueryInterface(this, riid, ppvObject); + } + + DEFINE_REF_COUNTING(); +}; diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/Exports.def b/src/coreclr/tests/src/Interop/COM/NativeServer/Exports.def new file mode 100644 index 0000000..2d0de26 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/Exports.def @@ -0,0 +1,4 @@ +EXPORTS + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE \ No newline at end of file diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/NumericTesting.h b/src/coreclr/tests/src/Interop/COM/NativeServer/NumericTesting.h new file mode 100644 index 0000000..9a80230 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/NumericTesting.h @@ -0,0 +1,257 @@ +// 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. + +#pragma once + +#include +#include "Servers.h" + +class DECLSPEC_UUID("53169A33-E85D-4E3C-B668-24E438D0929B") NumericTesting : public UnknownImpl, public INumericTesting +{ +public: + DEF_RAWFUNC(Add_Byte)( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[out,retval]*/ unsigned char * pRetVal) + { + *pRetVal = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_Short)( + /*[in]*/ short a, + /*[in]*/ short b, + /*[out,retval]*/ short * pRetVal) + { + *pRetVal = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_UShort)( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[out,retval]*/ unsigned short * pRetVal) + { + *pRetVal = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_Int)( + /*[in]*/ long a, + /*[in]*/ long b, + /*[out,retval]*/ long * pRetVal) + { + *pRetVal = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_UInt)( + /*[in]*/ unsigned long a, + /*[in]*/ unsigned long b, + /*[out,retval]*/ unsigned long * pRetVal) + { + *pRetVal = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Long)( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[out,retval]*/ __int64 * pRetVal) + { + *pRetVal = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_ULong)( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[out,retval]*/ unsigned __int64 * pRetVal) + { + *pRetVal = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Float)( + /*[in]*/ float a, + /*[in]*/ float b, + /*[out,retval]*/ float * pRetVal) + { + *pRetVal = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Double)( + /*[in]*/ double a, + /*[in]*/ double b, + /*[out,retval]*/ double * pRetVal) + { + *pRetVal = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Byte_Ref)( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[in,out]*/ unsigned char * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_Short_Ref)( + /*[in]*/ short a, + /*[in]*/ short b, + /*[in,out]*/ short * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_UShort_Ref)( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[in,out]*/ unsigned short * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_Int_Ref)( + /*[in]*/ long a, + /*[in]*/ long b, + /*[in,out]*/ long * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_UInt_Ref)( + /*[in]*/ unsigned long a, + /*[in]*/ unsigned long b, + /*[in,out]*/ unsigned long * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Long_Ref)( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[in,out]*/ __int64 * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_ULong_Ref)( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[in,out]*/ unsigned __int64 * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Float_Ref)( + /*[in]*/ float a, + /*[in]*/ float b, + /*[in,out]*/ float * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Double_Ref)( + /*[in]*/ double a, + /*[in]*/ double b, + /*[in,out]*/ double * c) + { + if (*c != std::numeric_limits::type>::max()) + return E_UNEXPECTED; + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Byte_Out)( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[out]*/ unsigned char * c) + { + *c = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_Short_Out)( + /*[in]*/ short a, + /*[in]*/ short b, + /*[out]*/ short * c) + { + *c = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_UShort_Out)( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[out]*/ unsigned short * c) + { + *c = static_cast(a + b); + return S_OK; + } + DEF_RAWFUNC(Add_Int_Out)( + /*[in]*/ long a, + /*[in]*/ long b, + /*[out]*/ long * c) + { + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_UInt_Out)( + /*[in]*/ unsigned long a, + /*[in]*/ unsigned long b, + /*[out]*/ unsigned long * c) + { + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Long_Out)( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[out]*/ __int64 * c) + { + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_ULong_Out)( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[out]*/ unsigned __int64 * c) + { + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Float_Out)( + /*[in]*/ float a, + /*[in]*/ float b, + /*[out]*/ float * c) + { + *c = a + b; + return S_OK; + } + DEF_RAWFUNC(Add_Double_Out)( + /*[in]*/ double a, + /*[in]*/ double b, + /*[out]*/ double * c) + { + *c = a + b; + return S_OK; + } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return DoQueryInterface(this, riid, ppvObject); + } + + DEFINE_REF_COUNTING(); +}; diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/Servers.cpp b/src/coreclr/tests/src/Interop/COM/NativeServer/Servers.cpp new file mode 100644 index 0000000..27f0d29 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/Servers.cpp @@ -0,0 +1,198 @@ +// 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. + +#include "stdafx.h" +#include "Servers.h" + +namespace +{ + const WCHAR EntryKeyFmt[] = L"SOFTWARE\\Classes\\CLSID\\%s"; + + struct OleStr : public std::unique_ptr::type, decltype(&::CoTaskMemFree)> + { + OleStr(_In_ LPOLESTR raw) + : std::unique_ptr::type, decltype(&::CoTaskMemFree)>(raw, ::CoTaskMemFree) + { } + }; + + struct RegKey : public std::unique_ptr::type, decltype(&::RegCloseKey)> + { + RegKey(_In_ HKEY raw) + : std::unique_ptr::type, decltype(&::RegCloseKey)>(raw, ::RegCloseKey) + { } + }; + + HRESULT RemoveClsid(_In_ REFCLSID clsid) + { + HRESULT hr; + + LPOLESTR clsidAsStrRaw; + RETURN_IF_FAILED(::StringFromCLSID(clsid, &clsidAsStrRaw)); + + OleStr clsidAsStr{ clsidAsStrRaw }; + + WCHAR regKeyPath[1024]; + ::swprintf_s(regKeyPath, EntryKeyFmt, clsidAsStr.get()); + + LSTATUS res; + + // Handle sub keys + { + HKEY toDeleteRaw; + res = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, regKeyPath, 0, KEY_READ | KEY_WRITE, &toDeleteRaw); + if (ERROR_FILE_NOT_FOUND == res) + { + return S_OK; + } + else if (ERROR_SUCCESS != res) + { + return __HRESULT_FROM_WIN32(res); + } + + RegKey toDelete{ toDeleteRaw }; + res = ::RegDeleteTreeW(toDelete.get(), nullptr); + if (ERROR_SUCCESS != res) + return __HRESULT_FROM_WIN32(res); + } + + res = ::RegDeleteKeyW(HKEY_LOCAL_MACHINE, regKeyPath); + if (ERROR_SUCCESS != res) + return __HRESULT_FROM_WIN32(res); + + return S_OK; + } + + HRESULT RegisterClsid(_In_ REFCLSID clsid, _In_opt_z_ const WCHAR *threadingModel) + { + HRESULT hr; + + // Remove the CLSID in case it exists and has undesirable settings + RETURN_IF_FAILED(RemoveClsid(clsid)); + + LPOLESTR clsidAsStrRaw; + RETURN_IF_FAILED(::StringFromCLSID(clsid, &clsidAsStrRaw)); + + OleStr clsidAsStr{ clsidAsStrRaw }; + + WCHAR regKeyClsidPath[1024]; + ::swprintf_s(regKeyClsidPath, EntryKeyFmt, clsidAsStr.get()); + + HKEY regKeyRaw; + DWORD disp; + LSTATUS res = ::RegCreateKeyExW( + HKEY_LOCAL_MACHINE, + regKeyClsidPath, + 0, + REG_NONE, + REG_OPTION_NON_VOLATILE, + (KEY_READ | KEY_WRITE), + nullptr, + ®KeyRaw, + &disp); + if (res != ERROR_SUCCESS) + return __HRESULT_FROM_WIN32(res); + + RegKey regKey{ regKeyRaw }; + + WCHAR regKeyServerPath[1024]; + ::swprintf_s(regKeyServerPath, L"%s\\InProcServer32", regKeyClsidPath); + + HKEY regServerKeyRaw; + res = ::RegCreateKeyExW( + HKEY_LOCAL_MACHINE, + regKeyServerPath, + 0, + REG_NONE, + REG_OPTION_NON_VOLATILE, + (KEY_READ | KEY_WRITE), + nullptr, + ®ServerKeyRaw, + &disp); + if (res != ERROR_SUCCESS) + return __HRESULT_FROM_WIN32(res); + + regKey.reset(regServerKeyRaw); + + WCHAR fullPath[MAX_PATH + 1]; + + HMODULE mod; + if (FALSE == ::GetModuleHandleExW( + (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT), + reinterpret_cast(&RegisterClsid), + &mod)) + { + return HRESULT_FROM_WIN32(::GetLastError()); + } + + ::GetModuleFileNameW(mod, fullPath, ARRAYSIZE(fullPath)); + + // The default value for the key is the path to the DLL + res = ::RegSetValueExW( + regKey.get(), + nullptr, + 0, + REG_SZ, + reinterpret_cast(fullPath), + static_cast(::wcslen(fullPath) + 1) * sizeof(fullPath[0])); + if (res != ERROR_SUCCESS) + return __HRESULT_FROM_WIN32(res); + + // Set the threading model if provided + if (threadingModel != nullptr) + { + res = ::RegSetValueExW( + regKey.get(), + L"ThreadingModel", + 0, + REG_SZ, + reinterpret_cast(threadingModel), + static_cast(::wcslen(threadingModel) + 1) * sizeof(threadingModel[0])); + if (res != ERROR_SUCCESS) + return __HRESULT_FROM_WIN32(res); + } + + return S_OK; + } +} + +STDAPI DllRegisterServer(void) +{ + HRESULT hr; + + RETURN_IF_FAILED(RegisterClsid(__uuidof(NumericTesting), L"Both")); + RETURN_IF_FAILED(RegisterClsid(__uuidof(ArrayTesting), L"Both")); + RETURN_IF_FAILED(RegisterClsid(__uuidof(StringTesting), L"Both")); + RETURN_IF_FAILED(RegisterClsid(__uuidof(ErrorMarshalTesting), L"Both")); + + return S_OK; +} + +STDAPI DllUnregisterServer(void) +{ + HRESULT hr; + + RETURN_IF_FAILED(RemoveClsid(__uuidof(NumericTesting))); + RETURN_IF_FAILED(RemoveClsid(__uuidof(ArrayTesting))); + RETURN_IF_FAILED(RemoveClsid(__uuidof(StringTesting))); + RETURN_IF_FAILED(RemoveClsid(__uuidof(ErrorMarshalTesting))); + + return S_OK; +} + +STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Out_ LPVOID FAR* ppv) +{ + if (rclsid == __uuidof(NumericTesting)) + return ClassFactoryBasic::Create(riid, ppv); + + if (rclsid == __uuidof(ArrayTesting)) + return ClassFactoryBasic::Create(riid, ppv); + + if (rclsid == __uuidof(StringTesting)) + return ClassFactoryBasic::Create(riid, ppv); + + if (rclsid == __uuidof(ErrorMarshalTesting)) + return ClassFactoryBasic::Create(riid, ppv); + + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/Servers.h b/src/coreclr/tests/src/Interop/COM/NativeServer/Servers.h new file mode 100644 index 0000000..5a22e80 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/Servers.h @@ -0,0 +1,18 @@ +// 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. + +#pragma once + +#include "ComHelpers.h" + +//#import "Server.Contract.tlb" no_namespace +#include + +#define DEF_RAWFUNC(n) virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE raw_ ## n +#define DEF_FUNC(n) virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE ## n + +#include "NumericTesting.h" +#include "ArrayTesting.h" +#include "StringTesting.h" +#include "ErrorMarshalTesting.h" diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/StringTesting.h b/src/coreclr/tests/src/Interop/COM/NativeServer/StringTesting.h new file mode 100644 index 0000000..7589bf2 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/StringTesting.h @@ -0,0 +1,321 @@ +// 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. + +#pragma once + +#include "Servers.h" + +class DECLSPEC_UUID("C73C83E8-51A2-47F8-9B5C-4284458E47A6") StringTesting : public UnknownImpl, public IStringTesting +{ +private: + template + bool EqualValue(STRING l, STRING r) + { + STRING tmp = l; + int len = 1; // Include 1 for null + while (*tmp++) + ++len; + + return (0 == ::memcmp(l, r, len * sizeof(l[0]))); + } + + template + STRING ReverseInplace(size_t len, STRING s) + { + std::reverse(s, s + len); + return s; + } + + template + HRESULT Reverse(STRING str, STRING *res) + { + STRING tmp = str; + size_t len = 0; + while (*tmp++) + ++len; + + size_t strDataLen = (len + 1) * sizeof(str[0]); + auto resLocal = (STRING)::CoTaskMemAlloc(strDataLen); + if (resLocal == nullptr) + return E_OUTOFMEMORY; + + ::memcpy_s(resLocal, strDataLen, str, strDataLen); + *res = ReverseInplace(len, resLocal); + + return S_OK; + } + + HRESULT ReverseBstr(BSTR str, BSTR *res) + { + UINT strDataLen = ::SysStringByteLen(str); + BSTR resLocal = ::SysAllocStringByteLen(reinterpret_cast(str), strDataLen); + if (resLocal == nullptr) + return E_OUTOFMEMORY; + + UINT len = ::SysStringLen(str); + *res = ReverseInplace(len, resLocal); + + return S_OK; + } + +public: // IStringTesting + DEF_RAWFUNC(Add_LPStr)( + /*[in]*/ LPSTR a, + /*[in]*/ LPSTR b, + /*[out,retval]*/ LPSTR * pRetVal) + { + if (a == nullptr || b == nullptr) + return E_POINTER; + + size_t aLen = ::strlen(a); + size_t bLen = ::strlen(b); + auto buf = (LPSTR)::CoTaskMemAlloc((aLen + bLen + 1) * sizeof(*b)); + + ::strcpy_s(buf, aLen + 1, a); + ::strcpy_s(buf + aLen, bLen + 1, b); + + *pRetVal = buf; + return S_OK; + } + DEF_RAWFUNC(Add_LPWStr)( + /*[in]*/ LPWSTR a, + /*[in]*/ LPWSTR b, + /*[out,retval]*/ LPWSTR * pRetVal) + { + if (a == nullptr || b == nullptr) + return E_POINTER; + + size_t aLen = ::wcslen(a); + size_t bLen = ::wcslen(b); + auto buf = (LPWSTR)::CoTaskMemAlloc((aLen + bLen + 1) * sizeof(*b)); + + ::wcscpy_s(buf, aLen + 1, a); + ::wcscpy_s(buf + aLen, bLen + 1, b); + + *pRetVal = buf; + return S_OK; + } + DEF_RAWFUNC(Add_BStr)( + /*[in]*/ BSTR a, + /*[in]*/ BSTR b, + /*[out,retval]*/ BSTR * pRetVal) + { + if (a == nullptr || b == nullptr) + return E_POINTER; + + UINT aLen = ::SysStringLen(a); + UINT bLen = ::SysStringLen(b); + BSTR buf = ::SysAllocStringByteLen(nullptr, (aLen + bLen) * sizeof(a[0])); + + ::wcscpy_s(buf, aLen + 1, a); + ::wcscpy_s(buf + aLen, bLen + 1, b); + + *pRetVal = buf; + return S_OK; + } + DEF_RAWFUNC(Reverse_LPStr)( + /*[in]*/ LPSTR a, + /*[out,retval]*/ LPSTR * pRetVal) + { + return Reverse(a, pRetVal); + } + DEF_RAWFUNC(Reverse_LPStr_Ref)( + /*[in,out]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(*a, pRetVal)); + ReverseInplace(::strlen(*a), *a); + return S_OK; + } + DEF_RAWFUNC(Reverse_LPStr_InRef)( + /*[in]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal) + { + return Reverse(*a, pRetVal); + } + DEF_RAWFUNC(Reverse_LPStr_Out)( + /*[in]*/ LPSTR a, + /*[out]*/ LPSTR * b) + { + return Reverse(a, b); + } + DEF_RAWFUNC(Reverse_LPStr_OutAttr)( + /*[in]*/ LPSTR a, + /*[out]*/ LPSTR b) + { + ReverseInplace(::strlen(b), b); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPStr)( + /*[in,out]*/ LPSTR a, + /*[out,retval]*/ LPSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(a, pRetVal)); + ReverseInplace(::strlen(a), a); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPStr_Ref)( + /*[in,out]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(*a, pRetVal)); + ReverseInplace(::strlen(*a), *a); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPStr_InRef)( + /*[in]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(*a, pRetVal)); + ReverseInplace(::strlen(*a), *a); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPStr_Out)( + /*[in,out]*/ LPSTR a, + /*[out]*/ LPSTR * b) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(a, b)); + ReverseInplace(::strlen(a), a); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPStr_OutAttr)( + /*[in,out]*/ LPSTR a, + /*[out]*/ LPSTR b) + { + size_t len = ::strlen(a); + ReverseInplace(len, a); + size_t byteLen = (len + 1) * sizeof(*a); + ::memcpy_s(b, byteLen, a, byteLen); + return S_OK; + } + DEF_RAWFUNC(Reverse_LPWStr)( + /*[in]*/ LPWSTR a, + /*[out,retval]*/ LPWSTR * pRetVal) + { + return Reverse(a, pRetVal); + } + DEF_RAWFUNC(Reverse_LPWStr_Ref)( + /*[in,out]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(*a, pRetVal)); + ReverseInplace(::wcslen(*a), *a); + return S_OK; + } + DEF_RAWFUNC(Reverse_LPWStr_InRef)( + /*[in]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal) + { + return Reverse(*a, pRetVal); + } + DEF_RAWFUNC(Reverse_LPWStr_Out)( + /*[in]*/ LPWSTR a, + /*[out]*/ LPWSTR * b) + { + return Reverse(a, b); + } + DEF_RAWFUNC(Reverse_LPWStr_OutAttr)( + /*[in]*/ LPWSTR a, + /*[out]*/ LPWSTR b) + { + ReverseInplace(::wcslen(b), b); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPWStr)( + /*[in,out]*/ LPWSTR a, + /*[out,retval]*/ LPWSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(a, pRetVal)); + ReverseInplace(::wcslen(a), a); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPWStr_Ref)( + /*[in,out]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(*a, pRetVal)); + ReverseInplace(::wcslen(*a), *a); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPWStr_InRef)( + /*[in]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(*a, pRetVal)); + ReverseInplace(::wcslen(*a), *a); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPWStr_Out)( + /*[in,out]*/ LPWSTR a, + /*[out]*/ LPWSTR * b) + { + HRESULT hr; + RETURN_IF_FAILED(Reverse(a, b)); + ReverseInplace(::wcslen(a), a); + return S_OK; + } + DEF_RAWFUNC(Reverse_SB_LPWStr_OutAttr)( + /*[in,out]*/ LPWSTR a, + /*[out]*/ LPWSTR b) + { + size_t len = ::wcslen(a); + ReverseInplace(len, a); + size_t byteLen = (len + 1) * sizeof(*a); + ::memcpy_s(b, byteLen, a, byteLen); + return S_OK; + } + DEF_RAWFUNC(Reverse_BStr)( + /*[in]*/ BSTR a, + /*[out,retval]*/ BSTR * pRetVal) + { + return ReverseBstr(a, pRetVal); + } + DEF_RAWFUNC(Reverse_BStr_Ref)( + /*[in,out]*/ BSTR * a, + /*[out,retval]*/ BSTR * pRetVal) + { + HRESULT hr; + RETURN_IF_FAILED(ReverseBstr(*a, pRetVal)); + ReverseInplace(::SysStringLen(*a), *a); + return S_OK; + } + DEF_RAWFUNC(Reverse_BStr_InRef)( + /*[in]*/ BSTR * a, + /*[out,retval]*/ BSTR * pRetVal) + { + return ReverseBstr(*a, pRetVal); + } + DEF_RAWFUNC(Reverse_BStr_Out)( + /*[in]*/ BSTR a, + /*[out]*/ BSTR * b) + { + return ReverseBstr(a, b); + } + DEF_RAWFUNC(Reverse_BStr_OutAttr)( + /*[in]*/ BSTR a, + /*[out]*/ BSTR b) + { + ReverseInplace(::SysStringLen(b), b); + return S_OK; + } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return DoQueryInterface(this, riid, ppvObject); + } + + DEFINE_REF_COUNTING(); +}; diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/stdafx.cpp b/src/coreclr/tests/src/Interop/COM/NativeServer/stdafx.cpp new file mode 100644 index 0000000..c87158f --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/stdafx.cpp @@ -0,0 +1,5 @@ +// 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. + +#include "stdafx.h" diff --git a/src/coreclr/tests/src/Interop/COM/NativeServer/stdafx.h b/src/coreclr/tests/src/Interop/COM/NativeServer/stdafx.h new file mode 100644 index 0000000..058ec2e --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/NativeServer/stdafx.h @@ -0,0 +1,15 @@ +// 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. + +#pragma once + +#define NOMINMAX +#define WIN32_LEAN_AND_MEAN +// Windows Header Files +#include + +#include +#include + + diff --git a/src/coreclr/tests/src/Interop/COM/Reflection/Reflection.cs b/src/coreclr/tests/src/Interop/COM/Reflection/Reflection.cs new file mode 100644 index 0000000..bab341a --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/Reflection/Reflection.cs @@ -0,0 +1,144 @@ +// 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; +using System.Text; +using System.Security; +using System.Reflection; +using System.Runtime.InteropServices; +using TestLibrary; + +public class Reflection +{ + /// + /// Reflect load ComImport Types amd enumerate them + /// + static bool ReflectionLoad() + { + try + { + Console.WriteLine("Scenario: ReflectionLoad"); + var asm = Assembly.LoadFrom("NETServer.dll"); + foreach (Type t in asm.GetTypes()) + { + Console.WriteLine(t.Name); + } + + return true; + } + catch (Exception e) + { + Console.WriteLine($"Caught unexpected exception: {e}"); + return false; + } + } + + /// + /// Type.IsCOMObject + /// + static bool TypeIsComObject() + { + try + { + Console.WriteLine("Scenario: TypeIsComObject"); + Type classType = typeof(NETServer.ContextMenu); + if (!classType.IsCOMObject) + { + Console.WriteLine("ComImport Class's IsCOMObject should return true"); + return false; + } + + Type interfaceType = typeof(NETServer.IEnumVARIANT); + if (interfaceType.IsCOMObject) + { + Console.WriteLine("ComImport interface's IsCOMObject should return false"); + return false; + } + + return true; + } + catch (Exception e) + { + Console.WriteLine($"Caught unexpected exception: {e}"); + return false; + } + } + + /// + /// Create COM instance via Activator + /// + static bool ActivateCOMType() + { + try + { + Console.WriteLine("Scenario: ActivateCOMType"); + var contextMenu = (NETServer.ContextMenu)Activator.CreateInstance(typeof(NETServer.ContextMenu)); + + // Non-Windows should throw PlatformNotSupportedException + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return false; + } + + if (contextMenu == null) + { + Console.WriteLine("ActivateCOMType failed"); + return false; + } + + return true; + } + catch (TargetInvocationException e) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && e.InnerException is PlatformNotSupportedException) + { + return true; + } + + Console.WriteLine($"Caught unexpected {nameof(PlatformNotSupportedException)}: {e}"); + return false; + } + catch(COMException e) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return true; + } + + Console.WriteLine($"Caught unexpected {nameof(COMException)}: {e}"); + return false; + } + catch (Exception e) + { + Console.WriteLine($"Caught unexpected exception: {e}"); + return false; + } + } + + [System.Security.SecuritySafeCritical] + static int Main() + { + int failures = 0; + if (!ReflectionLoad()) + { + Console.WriteLine("ReflectionLoad Failed"); + failures++; + } + + if (!TypeIsComObject()) + { + Console.WriteLine("TypeIsComObject Failed"); + failures++; + } + + if (!ActivateCOMType()) + { + Console.WriteLine("ActivateCOMType Failed"); + failures++; + } + + return failures > 0 ? 101 : 100; + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.csproj b/src/coreclr/tests/src/Interop/COM/Reflection/Reflection.csproj similarity index 73% rename from src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.csproj rename to src/coreclr/tests/src/Interop/COM/Reflection/Reflection.csproj index 673e216f..ad03388 100644 --- a/src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.csproj +++ b/src/coreclr/tests/src/Interop/COM/Reflection/Reflection.csproj @@ -1,10 +1,10 @@ - + Debug AnyCPU - ClassicCOMUnitTest + Reflection 2.0 {85C57688-DA98-4DE3-AC9B-526E4747434C} Exe @@ -23,25 +23,17 @@ - + - - - - + {c8c0dc74-fac4-45b1-81fe-70c4808366e0} CoreCLRTestLibrary - - {5FEE5C46-8DD9-49FA-BDC1-AF22867A0704} - COMLib - - + {C04AB564-CC61-499D-9F4C-AA1A9FDE42C9} - COMLib + NETServer - - + \ No newline at end of file diff --git a/src/coreclr/tests/src/Interop/COM/ServerContracts/Primitives.cs b/src/coreclr/tests/src/Interop/COM/ServerContracts/Primitives.cs new file mode 100644 index 0000000..cc6a303 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ServerContracts/Primitives.cs @@ -0,0 +1,189 @@ +// 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. + +#pragma warning disable 618 // Must test deprecated features + +namespace Server.Contract +{ + using System; + using System.Runtime.InteropServices; + using System.Text; + + [ComVisible(true)] + [Guid("05655A94-A915-4926-815D-A9EA648BAAD9")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface INumericTesting + { + byte Add_Byte(byte a, byte b); + short Add_Short(short a, short b); + ushort Add_UShort(ushort a, ushort b); + int Add_Int(int a, int b); + uint Add_UInt(uint a, uint b); + long Add_Long(long a, long b); + ulong Add_ULong(ulong a, ulong b); + float Add_Float(float a, float b); + double Add_Double(double a, double b); + + void Add_Byte_Ref(byte a, byte b, ref byte c); + void Add_Short_Ref(short a, short b, ref short c); + void Add_UShort_Ref(ushort a, ushort b, ref ushort c); + void Add_Int_Ref(int a, int b, ref int c); + void Add_UInt_Ref(uint a, uint b, ref uint c); + void Add_Long_Ref(long a, long b, ref long c); + void Add_ULong_Ref(ulong a, ulong b, ref ulong c); + void Add_Float_Ref(float a, float b, ref float c); + void Add_Double_Ref(double a, double b, ref double c); + + void Add_Byte_Out(byte a, byte b, out byte c); + void Add_Short_Out(short a, short b, out short c); + void Add_UShort_Out(ushort a, ushort b, out ushort c); + void Add_Int_Out(int a, int b, out int c); + void Add_UInt_Out(uint a, uint b, out uint c); + void Add_Long_Out(long a, long b, out long c); + void Add_ULong_Out(ulong a, ulong b, out ulong c); + void Add_Float_Out(float a, float b, out float c); + void Add_Double_Out(double a, double b, out double c); + } + + [ComVisible(true)] + [Guid("7731CB31-E063-4CC8-BCD2-D151D6BC8F43")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IArrayTesting + { + double Mean_Byte_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] byte[] d); + double Mean_Short_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] short[] d); + double Mean_UShort_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] ushort[] d); + double Mean_Int_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] int[] d); + double Mean_UInt_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] uint[] d); + double Mean_Long_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] long[] d); + double Mean_ULong_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] ulong[] d); + double Mean_Float_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] float[] d); + double Mean_Double_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] double[] d); + + double Mean_Byte_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] byte[] d, int len); + double Mean_Short_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] short[] d, int len); + double Mean_UShort_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] ushort[] d, int len); + double Mean_Int_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] int[] d, int len); + double Mean_UInt_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] uint[] d, int len); + double Mean_Long_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] long[] d, int len); + double Mean_ULong_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] ulong[] d, int len); + double Mean_Float_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] float[] d, int len); + double Mean_Double_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] double[] d, int len); + + double Mean_Byte_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] byte[] d, out int len); + double Mean_Short_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] short[] d, out int len); + double Mean_UShort_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] ushort[] d, out int len); + double Mean_Int_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] int[] d, out int len); + double Mean_UInt_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] uint[] d, out int len); + double Mean_Long_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] long[] d, out int len); + double Mean_ULong_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] ulong[] d, out int len); + double Mean_Float_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] float[] d, out int len); + double Mean_Double_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] double[] d, out int len); + } + + [ComVisible(true)] + [Guid("7044C5C0-C6C6-4713-9294-B4A4E86D58CC")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IStringTesting + { + [return: MarshalAs(UnmanagedType.LPStr)] + string Add_LPStr( + [MarshalAs(UnmanagedType.LPStr)] string a, + [MarshalAs(UnmanagedType.LPStr)] string b); + + [return: MarshalAs(UnmanagedType.LPWStr)] + string Add_LPWStr( + [MarshalAs(UnmanagedType.LPWStr)] string a, + [MarshalAs(UnmanagedType.LPWStr)] string b); + + [return: MarshalAs(UnmanagedType.BStr)] + string Add_BStr( + [MarshalAs(UnmanagedType.BStr)] string a, + [MarshalAs(UnmanagedType.BStr)] string b); + + // LPStr + + [return: MarshalAs(UnmanagedType.LPStr)] + string Reverse_LPStr([MarshalAs(UnmanagedType.LPStr)] string a); + + [return: MarshalAs(UnmanagedType.LPStr)] + string Reverse_LPStr_Ref([MarshalAs(UnmanagedType.LPStr)] ref string a); + + [return: MarshalAs(UnmanagedType.LPStr)] + string Reverse_LPStr_InRef([In][MarshalAs(UnmanagedType.LPStr)] ref string a); + + void Reverse_LPStr_Out([MarshalAs(UnmanagedType.LPStr)] string a, [MarshalAs(UnmanagedType.LPStr)] out string b); + + void Reverse_LPStr_OutAttr([MarshalAs(UnmanagedType.LPStr)] string a, [Out][MarshalAs(UnmanagedType.LPStr)] string b); + + [return: MarshalAs(UnmanagedType.LPStr)] + StringBuilder Reverse_SB_LPStr([MarshalAs(UnmanagedType.LPStr)] StringBuilder a); + + [return: MarshalAs(UnmanagedType.LPStr)] + StringBuilder Reverse_SB_LPStr_Ref([MarshalAs(UnmanagedType.LPStr)] ref StringBuilder a); + + [return: MarshalAs(UnmanagedType.LPStr)] + StringBuilder Reverse_SB_LPStr_InRef([In][MarshalAs(UnmanagedType.LPStr)] ref StringBuilder a); + + void Reverse_SB_LPStr_Out([MarshalAs(UnmanagedType.LPStr)] StringBuilder a, [MarshalAs(UnmanagedType.LPStr)] out StringBuilder b); + + void Reverse_SB_LPStr_OutAttr([MarshalAs(UnmanagedType.LPStr)] StringBuilder a, [Out][MarshalAs(UnmanagedType.LPStr)] StringBuilder b); + + // LPWStr + + [return: MarshalAs(UnmanagedType.LPWStr)] + string Reverse_LPWStr([MarshalAs(UnmanagedType.LPWStr)] string a); + + [return: MarshalAs(UnmanagedType.LPWStr)] + string Reverse_LPWStr_Ref([MarshalAs(UnmanagedType.LPWStr)] ref string a); + + [return: MarshalAs(UnmanagedType.LPWStr)] + string Reverse_LPWStr_InRef([In][MarshalAs(UnmanagedType.LPWStr)] ref string a); + + void Reverse_LPWStr_Out([MarshalAs(UnmanagedType.LPWStr)] string a, [MarshalAs(UnmanagedType.LPWStr)] out string b); + + void Reverse_LPWStr_OutAttr([MarshalAs(UnmanagedType.LPWStr)] string a, [Out][MarshalAs(UnmanagedType.LPWStr)] string b); + + [return: MarshalAs(UnmanagedType.LPWStr)] + StringBuilder Reverse_SB_LPWStr([MarshalAs(UnmanagedType.LPWStr)] StringBuilder a); + + [return: MarshalAs(UnmanagedType.LPWStr)] + StringBuilder Reverse_SB_LPWStr_Ref([MarshalAs(UnmanagedType.LPWStr)] ref StringBuilder a); + + [return: MarshalAs(UnmanagedType.LPWStr)] + StringBuilder Reverse_SB_LPWStr_InRef([In][MarshalAs(UnmanagedType.LPWStr)] ref StringBuilder a); + + void Reverse_SB_LPWStr_Out([MarshalAs(UnmanagedType.LPWStr)] StringBuilder a, [MarshalAs(UnmanagedType.LPWStr)] out StringBuilder b); + + void Reverse_SB_LPWStr_OutAttr([MarshalAs(UnmanagedType.LPWStr)] StringBuilder a, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder b); + + // BSTR + + [return: MarshalAs(UnmanagedType.BStr)] + string Reverse_BStr([MarshalAs(UnmanagedType.BStr)] string a); + + [return: MarshalAs(UnmanagedType.BStr)] + string Reverse_BStr_Ref([MarshalAs(UnmanagedType.BStr)] ref string a); + + [return: MarshalAs(UnmanagedType.BStr)] + string Reverse_BStr_InRef([In][MarshalAs(UnmanagedType.BStr)] ref string a); + + void Reverse_BStr_Out([MarshalAs(UnmanagedType.BStr)] string a, [MarshalAs(UnmanagedType.BStr)] out string b); + + void Reverse_BStr_OutAttr([MarshalAs(UnmanagedType.BStr)] string a, [Out][MarshalAs(UnmanagedType.BStr)] string b); + } + + [ComVisible(true)] + [Guid("592386A5-6837-444D-9DE3-250815D18556")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IErrorMarshalTesting + { + void Throw_HResult(int hresultToReturn); + + [PreserveSig] + int Return_As_HResult(int hresultToReturn); + } +} + +#pragma warning restore 618 // Must test deprecated features diff --git a/src/coreclr/tests/src/Interop/COM/ServerContracts/PrimitivesNativeServer.cs b/src/coreclr/tests/src/Interop/COM/ServerContracts/PrimitivesNativeServer.cs new file mode 100644 index 0000000..4e02880 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ServerContracts/PrimitivesNativeServer.cs @@ -0,0 +1,89 @@ +// 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. + +#pragma warning disable IDE1006 // Naming Styles + +namespace Server.Contract.Servers +{ + using System; + using System.Runtime.InteropServices; + + /// + /// Managed definition of CoClass + /// + [ComImport] + [CoClass(typeof(NumericTestingClass))] + [Guid("05655A94-A915-4926-815D-A9EA648BAAD9")] + internal interface NumericTesting : Server.Contract.INumericTesting + { + } + + /// + /// Managed activation for CoClass + /// + [ComImport] + [Guid("53169A33-E85D-4E3C-B668-24E438D0929B")] + internal class NumericTestingClass + { + } + + /// + /// Managed definition of CoClass + /// + [ComImport] + [CoClass(typeof(ArrayTestingClass))] + [Guid("7731CB31-E063-4CC8-BCD2-D151D6BC8F43")] + internal interface ArrayTesting : Server.Contract.IArrayTesting + { + } + + /// + /// Managed activation for CoClass + /// + [ComImport] + [Guid("B99ABE6A-DFF6-440F-BFB6-55179B8FE18E")] + internal class ArrayTestingClass + { + } + + /// + /// Managed definition of CoClass + /// + [ComImport] + [CoClass(typeof(StringTestingClass))] + [Guid("7044C5C0-C6C6-4713-9294-B4A4E86D58CC")] + internal interface StringTesting : Server.Contract.IStringTesting + { + } + + /// + /// Managed activation for CoClass + /// + [ComImport] + [Guid("C73C83E8-51A2-47F8-9B5C-4284458E47A6")] + internal class StringTestingClass + { + } + + /// + /// Managed definition of CoClass + /// + [ComImport] + [CoClass(typeof(ErrorMarshalTestingClass))] + [Guid("592386A5-6837-444D-9DE3-250815D18556")] + internal interface ErrorMarshalTesting : Server.Contract.IErrorMarshalTesting + { + } + + /// + /// Managed activation for CoClass + /// + [ComImport] + [Guid("71CF5C45-106C-4B32-B418-43A463C6041F")] + internal class ErrorMarshalTestingClass + { + } +} + +#pragma warning restore IDE1006 // Naming Styles diff --git a/src/coreclr/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh b/src/coreclr/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh new file mode 100644 index 0000000..55597a9 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh @@ -0,0 +1,656 @@ +// Created by Microsoft (R) C/C++ Compiler + +#pragma once +#pragma pack(push, 8) + +#include + +// +// Forward references and typedefs +// + +struct __declspec(uuid("3b973377-8c69-4208-96c1-475da757861c")) +/* LIBID */ __Server_Contract; +struct __declspec(uuid("05655a94-a915-4926-815d-a9ea648baad9")) +/* interface */ INumericTesting; +struct __declspec(uuid("7731cb31-e063-4cc8-bcd2-d151d6bc8f43")) +/* interface */ IArrayTesting; +struct __declspec(uuid("7044c5c0-c6c6-4713-9294-b4a4e86d58cc")) +/* interface */ IStringTesting; +struct __declspec(uuid("592386a5-6837-444d-9de3-250815d18556")) +/* interface */ IErrorMarshalTesting; + +// +// Smart pointer typedef declarations +// + +_COM_SMARTPTR_TYPEDEF(INumericTesting, __uuidof(INumericTesting)); +_COM_SMARTPTR_TYPEDEF(IArrayTesting, __uuidof(IArrayTesting)); +_COM_SMARTPTR_TYPEDEF(IStringTesting, __uuidof(IStringTesting)); +_COM_SMARTPTR_TYPEDEF(IErrorMarshalTesting, __uuidof(IErrorMarshalTesting)); + +// +// Type library items +// + +struct __declspec(uuid("05655a94-a915-4926-815d-a9ea648baad9")) +INumericTesting : IUnknown +{ + // + // Wrapper methods for error-handling + // + + unsigned char Add_Byte ( + unsigned char a, + unsigned char b ); + short Add_Short ( + short a, + short b ); + unsigned short Add_UShort ( + unsigned short a, + unsigned short b ); + long Add_Int ( + long a, + long b ); + unsigned long Add_UInt ( + unsigned long a, + unsigned long b ); + __int64 Add_Long ( + __int64 a, + __int64 b ); + unsigned __int64 Add_ULong ( + unsigned __int64 a, + unsigned __int64 b ); + float Add_Float ( + float a, + float b ); + double Add_Double ( + double a, + double b ); + HRESULT Add_Byte_Ref ( + unsigned char a, + unsigned char b, + unsigned char * c ); + HRESULT Add_Short_Ref ( + short a, + short b, + short * c ); + HRESULT Add_UShort_Ref ( + unsigned short a, + unsigned short b, + unsigned short * c ); + HRESULT Add_Int_Ref ( + long a, + long b, + long * c ); + HRESULT Add_UInt_Ref ( + unsigned long a, + unsigned long b, + unsigned long * c ); + HRESULT Add_Long_Ref ( + __int64 a, + __int64 b, + __int64 * c ); + HRESULT Add_ULong_Ref ( + unsigned __int64 a, + unsigned __int64 b, + unsigned __int64 * c ); + HRESULT Add_Float_Ref ( + float a, + float b, + float * c ); + HRESULT Add_Double_Ref ( + double a, + double b, + double * c ); + HRESULT Add_Byte_Out ( + unsigned char a, + unsigned char b, + unsigned char * c ); + HRESULT Add_Short_Out ( + short a, + short b, + short * c ); + HRESULT Add_UShort_Out ( + unsigned short a, + unsigned short b, + unsigned short * c ); + HRESULT Add_Int_Out ( + long a, + long b, + long * c ); + HRESULT Add_UInt_Out ( + unsigned long a, + unsigned long b, + unsigned long * c ); + HRESULT Add_Long_Out ( + __int64 a, + __int64 b, + __int64 * c ); + HRESULT Add_ULong_Out ( + unsigned __int64 a, + unsigned __int64 b, + unsigned __int64 * c ); + HRESULT Add_Float_Out ( + float a, + float b, + float * c ); + HRESULT Add_Double_Out ( + double a, + double b, + double * c ); + + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall raw_Add_Byte ( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[out,retval]*/ unsigned char * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_Short ( + /*[in]*/ short a, + /*[in]*/ short b, + /*[out,retval]*/ short * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_UShort ( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[out,retval]*/ unsigned short * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_Int ( + /*[in]*/ long a, + /*[in]*/ long b, + /*[out,retval]*/ long * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_UInt ( + /*[in]*/ unsigned long a, + /*[in]*/ unsigned long b, + /*[out,retval]*/ unsigned long * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_Long ( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[out,retval]*/ __int64 * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_ULong ( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[out,retval]*/ unsigned __int64 * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_Float ( + /*[in]*/ float a, + /*[in]*/ float b, + /*[out,retval]*/ float * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_Double ( + /*[in]*/ double a, + /*[in]*/ double b, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_Byte_Ref ( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[in,out]*/ unsigned char * c ) = 0; + virtual HRESULT __stdcall raw_Add_Short_Ref ( + /*[in]*/ short a, + /*[in]*/ short b, + /*[in,out]*/ short * c ) = 0; + virtual HRESULT __stdcall raw_Add_UShort_Ref ( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[in,out]*/ unsigned short * c ) = 0; + virtual HRESULT __stdcall raw_Add_Int_Ref ( + /*[in]*/ long a, + /*[in]*/ long b, + /*[in,out]*/ long * c ) = 0; + virtual HRESULT __stdcall raw_Add_UInt_Ref ( + /*[in]*/ unsigned long a, + /*[in]*/ unsigned long b, + /*[in,out]*/ unsigned long * c ) = 0; + virtual HRESULT __stdcall raw_Add_Long_Ref ( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[in,out]*/ __int64 * c ) = 0; + virtual HRESULT __stdcall raw_Add_ULong_Ref ( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[in,out]*/ unsigned __int64 * c ) = 0; + virtual HRESULT __stdcall raw_Add_Float_Ref ( + /*[in]*/ float a, + /*[in]*/ float b, + /*[in,out]*/ float * c ) = 0; + virtual HRESULT __stdcall raw_Add_Double_Ref ( + /*[in]*/ double a, + /*[in]*/ double b, + /*[in,out]*/ double * c ) = 0; + virtual HRESULT __stdcall raw_Add_Byte_Out ( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[out]*/ unsigned char * c ) = 0; + virtual HRESULT __stdcall raw_Add_Short_Out ( + /*[in]*/ short a, + /*[in]*/ short b, + /*[out]*/ short * c ) = 0; + virtual HRESULT __stdcall raw_Add_UShort_Out ( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[out]*/ unsigned short * c ) = 0; + virtual HRESULT __stdcall raw_Add_Int_Out ( + /*[in]*/ long a, + /*[in]*/ long b, + /*[out]*/ long * c ) = 0; + virtual HRESULT __stdcall raw_Add_UInt_Out ( + /*[in]*/ unsigned long a, + /*[in]*/ unsigned long b, + /*[out]*/ unsigned long * c ) = 0; + virtual HRESULT __stdcall raw_Add_Long_Out ( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[out]*/ __int64 * c ) = 0; + virtual HRESULT __stdcall raw_Add_ULong_Out ( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[out]*/ unsigned __int64 * c ) = 0; + virtual HRESULT __stdcall raw_Add_Float_Out ( + /*[in]*/ float a, + /*[in]*/ float b, + /*[out]*/ float * c ) = 0; + virtual HRESULT __stdcall raw_Add_Double_Out ( + /*[in]*/ double a, + /*[in]*/ double b, + /*[out]*/ double * c ) = 0; +}; + +struct __declspec(uuid("7731cb31-e063-4cc8-bcd2-d151d6bc8f43")) +IArrayTesting : IUnknown +{ + // + // Wrapper methods for error-handling + // + + double Mean_Byte_LP_PreLen ( + long len, + unsigned char * d ); + double Mean_Short_LP_PreLen ( + long len, + short * d ); + double Mean_UShort_LP_PreLen ( + long len, + unsigned short * d ); + double Mean_Int_LP_PreLen ( + long len, + long * d ); + double Mean_UInt_LP_PreLen ( + long len, + unsigned long * d ); + double Mean_Long_LP_PreLen ( + long len, + __int64 * d ); + double Mean_ULong_LP_PreLen ( + long len, + unsigned __int64 * d ); + double Mean_Float_LP_PreLen ( + long len, + float * d ); + double Mean_Double_LP_PreLen ( + long len, + double * d ); + double Mean_Byte_LP_PostLen ( + unsigned char * d, + long len ); + double Mean_Short_LP_PostLen ( + short * d, + long len ); + double Mean_UShort_LP_PostLen ( + unsigned short * d, + long len ); + double Mean_Int_LP_PostLen ( + long * d, + long len ); + double Mean_UInt_LP_PostLen ( + unsigned long * d, + long len ); + double Mean_Long_LP_PostLen ( + __int64 * d, + long len ); + double Mean_ULong_LP_PostLen ( + unsigned __int64 * d, + long len ); + double Mean_Float_LP_PostLen ( + float * d, + long len ); + double Mean_Double_LP_PostLen ( + double * d, + long len ); + double Mean_Byte_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + double Mean_Short_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + double Mean_UShort_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + double Mean_Int_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + double Mean_UInt_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + double Mean_Long_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + double Mean_ULong_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + double Mean_Float_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + double Mean_Double_SafeArray_OutLen ( + SAFEARRAY * d, + long * len ); + + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall raw_Mean_Byte_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ unsigned char * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Short_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ short * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_UShort_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ unsigned short * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Int_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ long * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_UInt_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ unsigned long * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Long_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ __int64 * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_ULong_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ unsigned __int64 * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Float_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ float * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Double_LP_PreLen ( + /*[in]*/ long len, + /*[in]*/ double * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Byte_LP_PostLen ( + /*[in]*/ unsigned char * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Short_LP_PostLen ( + /*[in]*/ short * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_UShort_LP_PostLen ( + /*[in]*/ unsigned short * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Int_LP_PostLen ( + /*[in]*/ long * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_UInt_LP_PostLen ( + /*[in]*/ unsigned long * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Long_LP_PostLen ( + /*[in]*/ __int64 * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_ULong_LP_PostLen ( + /*[in]*/ unsigned __int64 * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Float_LP_PostLen ( + /*[in]*/ float * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Double_LP_PostLen ( + /*[in]*/ double * d, + /*[in]*/ long len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Byte_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Short_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_UShort_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Int_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_UInt_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Long_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_ULong_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Float_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Mean_Double_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ long * len, + /*[out,retval]*/ double * pRetVal ) = 0; +}; + +struct __declspec(uuid("7044c5c0-c6c6-4713-9294-b4a4e86d58cc")) +IStringTesting : IUnknown +{ + // + // Wrapper methods for error-handling + // + + LPSTR Add_LPStr ( + LPSTR a, + LPSTR b ); + LPWSTR Add_LPWStr ( + LPWSTR a, + LPWSTR b ); + _bstr_t Add_BStr ( + _bstr_t a, + _bstr_t b ); + LPSTR Reverse_LPStr ( + LPSTR a ); + LPSTR Reverse_LPStr_Ref ( + LPSTR * a ); + LPSTR Reverse_LPStr_InRef ( + LPSTR * a ); + HRESULT Reverse_LPStr_Out ( + LPSTR a, + LPSTR * b ); + HRESULT Reverse_LPStr_OutAttr ( + LPSTR a, + LPSTR b ); + LPSTR Reverse_SB_LPStr ( + LPSTR a ); + LPSTR Reverse_SB_LPStr_Ref ( + LPSTR * a ); + LPSTR Reverse_SB_LPStr_InRef ( + LPSTR * a ); + HRESULT Reverse_SB_LPStr_Out ( + LPSTR a, + LPSTR * b ); + HRESULT Reverse_SB_LPStr_OutAttr ( + LPSTR a, + LPSTR b ); + LPWSTR Reverse_LPWStr ( + LPWSTR a ); + LPWSTR Reverse_LPWStr_Ref ( + LPWSTR * a ); + LPWSTR Reverse_LPWStr_InRef ( + LPWSTR * a ); + HRESULT Reverse_LPWStr_Out ( + LPWSTR a, + LPWSTR * b ); + HRESULT Reverse_LPWStr_OutAttr ( + LPWSTR a, + LPWSTR b ); + LPWSTR Reverse_SB_LPWStr ( + LPWSTR a ); + LPWSTR Reverse_SB_LPWStr_Ref ( + LPWSTR * a ); + LPWSTR Reverse_SB_LPWStr_InRef ( + LPWSTR * a ); + HRESULT Reverse_SB_LPWStr_Out ( + LPWSTR a, + LPWSTR * b ); + HRESULT Reverse_SB_LPWStr_OutAttr ( + LPWSTR a, + LPWSTR b ); + _bstr_t Reverse_BStr ( + _bstr_t a ); + _bstr_t Reverse_BStr_Ref ( + BSTR * a ); + _bstr_t Reverse_BStr_InRef ( + BSTR * a ); + HRESULT Reverse_BStr_Out ( + _bstr_t a, + BSTR * b ); + HRESULT Reverse_BStr_OutAttr ( + _bstr_t a, + _bstr_t b ); + + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall raw_Add_LPStr ( + /*[in]*/ LPSTR a, + /*[in]*/ LPSTR b, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_LPWStr ( + /*[in]*/ LPWSTR a, + /*[in]*/ LPWSTR b, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Add_BStr ( + /*[in]*/ BSTR a, + /*[in]*/ BSTR b, + /*[out,retval]*/ BSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPStr ( + /*[in]*/ LPSTR a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPStr_Ref ( + /*[in,out]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPStr_InRef ( + /*[in]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPStr_Out ( + /*[in]*/ LPSTR a, + /*[out]*/ LPSTR * b ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPStr_OutAttr ( + /*[in]*/ LPSTR a, + /*[out]*/ LPSTR b ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPStr ( + /*[in,out]*/ LPSTR a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPStr_Ref ( + /*[in,out]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPStr_InRef ( + /*[in]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPStr_Out ( + /*[in,out]*/ LPSTR a, + /*[out]*/ LPSTR * b ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPStr_OutAttr ( + /*[in,out]*/ LPSTR a, + /*[out]*/ LPSTR b ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPWStr ( + /*[in]*/ LPWSTR a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPWStr_Ref ( + /*[in,out]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPWStr_InRef ( + /*[in]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPWStr_Out ( + /*[in]*/ LPWSTR a, + /*[out]*/ LPWSTR * b ) = 0; + virtual HRESULT __stdcall raw_Reverse_LPWStr_OutAttr ( + /*[in]*/ LPWSTR a, + /*[out]*/ LPWSTR b ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPWStr ( + /*[in,out]*/ LPWSTR a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPWStr_Ref ( + /*[in,out]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPWStr_InRef ( + /*[in]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPWStr_Out ( + /*[in,out]*/ LPWSTR a, + /*[out]*/ LPWSTR * b ) = 0; + virtual HRESULT __stdcall raw_Reverse_SB_LPWStr_OutAttr ( + /*[in,out]*/ LPWSTR a, + /*[out]*/ LPWSTR b ) = 0; + virtual HRESULT __stdcall raw_Reverse_BStr ( + /*[in]*/ BSTR a, + /*[out,retval]*/ BSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_BStr_Ref ( + /*[in,out]*/ BSTR * a, + /*[out,retval]*/ BSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_BStr_InRef ( + /*[in]*/ BSTR * a, + /*[out,retval]*/ BSTR * pRetVal ) = 0; + virtual HRESULT __stdcall raw_Reverse_BStr_Out ( + /*[in]*/ BSTR a, + /*[out]*/ BSTR * b ) = 0; + virtual HRESULT __stdcall raw_Reverse_BStr_OutAttr ( + /*[in]*/ BSTR a, + /*[out]*/ BSTR b ) = 0; +}; + +struct __declspec(uuid("592386a5-6837-444d-9de3-250815d18556")) +IErrorMarshalTesting : IUnknown +{ + // + // Wrapper methods for error-handling + // + + HRESULT Throw_HResult ( + long hresultToReturn ); + + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall raw_Throw_HResult ( + /*[in]*/ long hresultToReturn ) = 0; + virtual long __stdcall Return_As_HResult ( + /*[in]*/ long hresultToReturn ) = 0; +}; + +// +// Wrapper method implementations +// + +#include "Server.Contracts.tli" + +#pragma pack(pop) diff --git a/src/coreclr/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli b/src/coreclr/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli new file mode 100644 index 0000000..a419c65 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli @@ -0,0 +1,571 @@ +// Created by Microsoft (R) C/C++ Compiler + +#pragma once + +// +// interface INumericTesting wrapper method implementations +// + +inline unsigned char INumericTesting::Add_Byte ( unsigned char a, unsigned char b ) { + unsigned char _result = 0; + HRESULT _hr = raw_Add_Byte(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline short INumericTesting::Add_Short ( short a, short b ) { + short _result = 0; + HRESULT _hr = raw_Add_Short(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline unsigned short INumericTesting::Add_UShort ( unsigned short a, unsigned short b ) { + unsigned short _result = 0; + HRESULT _hr = raw_Add_UShort(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline long INumericTesting::Add_Int ( long a, long b ) { + long _result = 0; + HRESULT _hr = raw_Add_Int(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline unsigned long INumericTesting::Add_UInt ( unsigned long a, unsigned long b ) { + unsigned long _result = 0; + HRESULT _hr = raw_Add_UInt(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline __int64 INumericTesting::Add_Long ( __int64 a, __int64 b ) { + __int64 _result = 0; + HRESULT _hr = raw_Add_Long(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline unsigned __int64 INumericTesting::Add_ULong ( unsigned __int64 a, unsigned __int64 b ) { + unsigned __int64 _result = 0; + HRESULT _hr = raw_Add_ULong(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline float INumericTesting::Add_Float ( float a, float b ) { + float _result = 0; + HRESULT _hr = raw_Add_Float(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double INumericTesting::Add_Double ( double a, double b ) { + double _result = 0; + HRESULT _hr = raw_Add_Double(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline HRESULT INumericTesting::Add_Byte_Ref ( unsigned char a, unsigned char b, unsigned char * c ) { + HRESULT _hr = raw_Add_Byte_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Short_Ref ( short a, short b, short * c ) { + HRESULT _hr = raw_Add_Short_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_UShort_Ref ( unsigned short a, unsigned short b, unsigned short * c ) { + HRESULT _hr = raw_Add_UShort_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Int_Ref ( long a, long b, long * c ) { + HRESULT _hr = raw_Add_Int_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_UInt_Ref ( unsigned long a, unsigned long b, unsigned long * c ) { + HRESULT _hr = raw_Add_UInt_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Long_Ref ( __int64 a, __int64 b, __int64 * c ) { + HRESULT _hr = raw_Add_Long_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_ULong_Ref ( unsigned __int64 a, unsigned __int64 b, unsigned __int64 * c ) { + HRESULT _hr = raw_Add_ULong_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Float_Ref ( float a, float b, float * c ) { + HRESULT _hr = raw_Add_Float_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Double_Ref ( double a, double b, double * c ) { + HRESULT _hr = raw_Add_Double_Ref(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Byte_Out ( unsigned char a, unsigned char b, unsigned char * c ) { + HRESULT _hr = raw_Add_Byte_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Short_Out ( short a, short b, short * c ) { + HRESULT _hr = raw_Add_Short_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_UShort_Out ( unsigned short a, unsigned short b, unsigned short * c ) { + HRESULT _hr = raw_Add_UShort_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Int_Out ( long a, long b, long * c ) { + HRESULT _hr = raw_Add_Int_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_UInt_Out ( unsigned long a, unsigned long b, unsigned long * c ) { + HRESULT _hr = raw_Add_UInt_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Long_Out ( __int64 a, __int64 b, __int64 * c ) { + HRESULT _hr = raw_Add_Long_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_ULong_Out ( unsigned __int64 a, unsigned __int64 b, unsigned __int64 * c ) { + HRESULT _hr = raw_Add_ULong_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Float_Out ( float a, float b, float * c ) { + HRESULT _hr = raw_Add_Float_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT INumericTesting::Add_Double_Out ( double a, double b, double * c ) { + HRESULT _hr = raw_Add_Double_Out(a, b, c); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +// +// interface IArrayTesting wrapper method implementations +// + +inline double IArrayTesting::Mean_Byte_LP_PreLen ( long len, unsigned char * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_Byte_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Short_LP_PreLen ( long len, short * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_Short_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_UShort_LP_PreLen ( long len, unsigned short * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_UShort_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Int_LP_PreLen ( long len, long * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_Int_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_UInt_LP_PreLen ( long len, unsigned long * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_UInt_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Long_LP_PreLen ( long len, __int64 * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_Long_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_ULong_LP_PreLen ( long len, unsigned __int64 * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_ULong_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Float_LP_PreLen ( long len, float * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_Float_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Double_LP_PreLen ( long len, double * d ) { + double _result = 0; + HRESULT _hr = raw_Mean_Double_LP_PreLen(len, d, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Byte_LP_PostLen ( unsigned char * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Byte_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Short_LP_PostLen ( short * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Short_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_UShort_LP_PostLen ( unsigned short * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_UShort_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Int_LP_PostLen ( long * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Int_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_UInt_LP_PostLen ( unsigned long * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_UInt_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Long_LP_PostLen ( __int64 * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Long_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_ULong_LP_PostLen ( unsigned __int64 * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_ULong_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Float_LP_PostLen ( float * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Float_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Double_LP_PostLen ( double * d, long len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Double_LP_PostLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Byte_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Byte_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Short_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Short_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_UShort_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_UShort_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Int_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Int_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_UInt_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_UInt_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Long_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Long_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_ULong_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_ULong_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Float_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Float_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline double IArrayTesting::Mean_Double_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { + double _result = 0; + HRESULT _hr = raw_Mean_Double_SafeArray_OutLen(d, len, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +// +// interface IStringTesting wrapper method implementations +// + +inline LPSTR IStringTesting::Add_LPStr ( LPSTR a, LPSTR b ) { + LPSTR _result = 0; + HRESULT _hr = raw_Add_LPStr(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPWSTR IStringTesting::Add_LPWStr ( LPWSTR a, LPWSTR b ) { + LPWSTR _result = 0; + HRESULT _hr = raw_Add_LPWStr(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline _bstr_t IStringTesting::Add_BStr ( _bstr_t a, _bstr_t b ) { + BSTR _result = 0; + HRESULT _hr = raw_Add_BStr(a, b, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _bstr_t(_result, false); +} + +inline LPSTR IStringTesting::Reverse_LPStr ( LPSTR a ) { + LPSTR _result = 0; + HRESULT _hr = raw_Reverse_LPStr(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPSTR IStringTesting::Reverse_LPStr_Ref ( LPSTR * a ) { + LPSTR _result = 0; + HRESULT _hr = raw_Reverse_LPStr_Ref(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPSTR IStringTesting::Reverse_LPStr_InRef ( LPSTR * a ) { + LPSTR _result = 0; + HRESULT _hr = raw_Reverse_LPStr_InRef(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline HRESULT IStringTesting::Reverse_LPStr_Out ( LPSTR a, LPSTR * b ) { + HRESULT _hr = raw_Reverse_LPStr_Out(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT IStringTesting::Reverse_LPStr_OutAttr ( LPSTR a, LPSTR b ) { + HRESULT _hr = raw_Reverse_LPStr_OutAttr(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline LPSTR IStringTesting::Reverse_SB_LPStr ( LPSTR a ) { + LPSTR _result = 0; + HRESULT _hr = raw_Reverse_SB_LPStr(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPSTR IStringTesting::Reverse_SB_LPStr_Ref ( LPSTR * a ) { + LPSTR _result = 0; + HRESULT _hr = raw_Reverse_SB_LPStr_Ref(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPSTR IStringTesting::Reverse_SB_LPStr_InRef ( LPSTR * a ) { + LPSTR _result = 0; + HRESULT _hr = raw_Reverse_SB_LPStr_InRef(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline HRESULT IStringTesting::Reverse_SB_LPStr_Out ( LPSTR a, LPSTR * b ) { + HRESULT _hr = raw_Reverse_SB_LPStr_Out(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT IStringTesting::Reverse_SB_LPStr_OutAttr ( LPSTR a, LPSTR b ) { + HRESULT _hr = raw_Reverse_SB_LPStr_OutAttr(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline LPWSTR IStringTesting::Reverse_LPWStr ( LPWSTR a ) { + LPWSTR _result = 0; + HRESULT _hr = raw_Reverse_LPWStr(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPWSTR IStringTesting::Reverse_LPWStr_Ref ( LPWSTR * a ) { + LPWSTR _result = 0; + HRESULT _hr = raw_Reverse_LPWStr_Ref(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPWSTR IStringTesting::Reverse_LPWStr_InRef ( LPWSTR * a ) { + LPWSTR _result = 0; + HRESULT _hr = raw_Reverse_LPWStr_InRef(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline HRESULT IStringTesting::Reverse_LPWStr_Out ( LPWSTR a, LPWSTR * b ) { + HRESULT _hr = raw_Reverse_LPWStr_Out(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT IStringTesting::Reverse_LPWStr_OutAttr ( LPWSTR a, LPWSTR b ) { + HRESULT _hr = raw_Reverse_LPWStr_OutAttr(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline LPWSTR IStringTesting::Reverse_SB_LPWStr ( LPWSTR a ) { + LPWSTR _result = 0; + HRESULT _hr = raw_Reverse_SB_LPWStr(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPWSTR IStringTesting::Reverse_SB_LPWStr_Ref ( LPWSTR * a ) { + LPWSTR _result = 0; + HRESULT _hr = raw_Reverse_SB_LPWStr_Ref(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline LPWSTR IStringTesting::Reverse_SB_LPWStr_InRef ( LPWSTR * a ) { + LPWSTR _result = 0; + HRESULT _hr = raw_Reverse_SB_LPWStr_InRef(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _result; +} + +inline HRESULT IStringTesting::Reverse_SB_LPWStr_Out ( LPWSTR a, LPWSTR * b ) { + HRESULT _hr = raw_Reverse_SB_LPWStr_Out(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT IStringTesting::Reverse_SB_LPWStr_OutAttr ( LPWSTR a, LPWSTR b ) { + HRESULT _hr = raw_Reverse_SB_LPWStr_OutAttr(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline _bstr_t IStringTesting::Reverse_BStr ( _bstr_t a ) { + BSTR _result = 0; + HRESULT _hr = raw_Reverse_BStr(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _bstr_t(_result, false); +} + +inline _bstr_t IStringTesting::Reverse_BStr_Ref ( BSTR * a ) { + BSTR _result = 0; + HRESULT _hr = raw_Reverse_BStr_Ref(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _bstr_t(_result, false); +} + +inline _bstr_t IStringTesting::Reverse_BStr_InRef ( BSTR * a ) { + BSTR _result = 0; + HRESULT _hr = raw_Reverse_BStr_InRef(a, &_result); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _bstr_t(_result, false); +} + +inline HRESULT IStringTesting::Reverse_BStr_Out ( _bstr_t a, BSTR * b ) { + HRESULT _hr = raw_Reverse_BStr_Out(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +inline HRESULT IStringTesting::Reverse_BStr_OutAttr ( _bstr_t a, _bstr_t b ) { + HRESULT _hr = raw_Reverse_BStr_OutAttr(a, b); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} + +// +// interface IErrorMarshalTesting wrapper method implementations +// + +inline HRESULT IErrorMarshalTesting::Throw_HResult ( long hresultToReturn ) { + HRESULT _hr = raw_Throw_HResult(hresultToReturn); + if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); + return _hr; +} diff --git a/src/coreclr/tests/src/Interop/COM/ServerContracts/readme.md b/src/coreclr/tests/src/Interop/COM/ServerContracts/readme.md new file mode 100644 index 0000000..347c7fc --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ServerContracts/readme.md @@ -0,0 +1,9 @@ +## Server Contracts + +This directory contains the API contracts for the testing of .NET COM interop. The contract is defined in C# to the degree that the [TlbExp.exe](https://docs.microsoft.com/en-us/dotnet/framework/tools/tlbexp-exe-type-library-exporter) tool can be used to generate a TLB that can then be used by the Microsoft VC++ compiler to generate the `tlh` and `tli` files. This is a manual process at the moment, but as more support is added to CoreCLR, this may change. + +The process to create a TLB and update the native contracts are as follows: + +1) Take the `Primitives.cs` file and create a DLL using a SDK project. +1) Use the .NET Framework [TlbExp.exe](https://docs.microsoft.com/en-us/dotnet/framework/tools/tlbexp-exe-type-library-exporter) to create a `tlb` based on the DLL previously compiled. +1) Using the Microsoft VC++ compiler consume the `tlb` using the [`#import`](https://msdn.microsoft.com/en-us/library/8etzzkb6.aspx) directive (See commented out line in `Servers.h`). The compiler will generate two files (`tlh` and `tli`). The files in this directory can then be updated. \ No newline at end of file diff --git a/src/coreclr/tests/src/Interop/ClassicCOM/CMakeLists.txt b/src/coreclr/tests/src/Interop/ClassicCOM/CMakeLists.txt deleted file mode 100644 index d3416dd..0000000 --- a/src/coreclr/tests/src/Interop/ClassicCOM/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required (VERSION 2.6) -project (ClassicCOMNative) -include_directories(${INC_PLATFORM_DIR}) -set(SOURCES ClassicCOMNative.cpp) - -# add the executable -add_library (ClassicCOMNative SHARED ${SOURCES}) -target_link_libraries(ClassicCOMNative ${LINK_LIBRARIES_ADDITIONAL}) - -# add the install targets -install (TARGETS ClassicCOMNative DESTINATION bin) - - diff --git a/src/coreclr/tests/src/Interop/ClassicCOM/COMLib.cs b/src/coreclr/tests/src/Interop/ClassicCOM/COMLib.cs deleted file mode 100644 index fba866c..0000000 --- a/src/coreclr/tests/src/Interop/ClassicCOM/COMLib.cs +++ /dev/null @@ -1,34 +0,0 @@ -// 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; -using System.Text; -using System.Security; -using System.Runtime.InteropServices; - -public class COMLib -{ - [Guid("00020404-0000-0000-C000-000000000046")] - [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] - [ComImport] - public interface IEnumVARIANT - { - [PreserveSig] - int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] object[] rgVar, IntPtr pceltFetched); - - [PreserveSig] - int Skip(int celt); - - [PreserveSig] - int Reset(); - - IEnumVARIANT Clone(); - } - - [ComImport] - [Guid("78A51822-51F4-11D0-8F20-00805F2CD064")] - public class ProcessDebugManager - { - } -} diff --git a/src/coreclr/tests/src/Interop/ClassicCOM/COMLib.csproj b/src/coreclr/tests/src/Interop/ClassicCOM/COMLib.csproj deleted file mode 100644 index 1f289d6..0000000 --- a/src/coreclr/tests/src/Interop/ClassicCOM/COMLib.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - - Debug - AnyCPU - COMLib - 2.0 - {5FEE5C46-8DD9-49FA-BDC1-AF22867A0704} - library - {CDC3DF7E-04B4-4464-9A02-7E2B0FAB586A};{68EC03EE-C9EE-47FD-AA08-A954EB2D9816} - ..\..\ - $(DefineConstants);STATIC - - - - - - - - - False - - - - - - - - - - diff --git a/src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMNative.cpp b/src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMNative.cpp deleted file mode 100644 index 962313c..0000000 --- a/src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMNative.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -#include -#include -#include - -extern "C" DLL_EXPORT void PassObjectToNative(void * ptr) -{ - // TODO: Add check -} - -extern "C" DLL_EXPORT void PassObjectArrayToNative(void ** pptr) -{ - // TODO: Add check -} - -extern "C" DLL_EXPORT void GetObjectFromNative(void ** pptr) -{ - *pptr = NULL; - // TODO: Add check -} - -extern "C" DLL_EXPORT void GetObjectFromNativeAsRef(void ** pptr) -{ - // TODO: Add check -} \ No newline at end of file diff --git a/src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.cs b/src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.cs deleted file mode 100644 index 530f02c..0000000 --- a/src/coreclr/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.cs +++ /dev/null @@ -1,255 +0,0 @@ -// 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. -// - -// -// Adding tests for Classic COM code coverage -// - -using System; -using System.Text; -using System.Security; -using System.Reflection; -using System.Runtime.InteropServices; -using TestLibrary; - -public class ClassicCOMUnitTest -{ - /// - /// Try to reflect load ComImport Types by enumerate - /// - /// - static bool RelectionLoad() - { - try - { - Console.WriteLine("Scenario: RelectionLoad"); - var asm = Assembly.LoadFrom("COMLib.dll"); - foreach (Type t in asm.GetTypes()) - { - Console.WriteLine(t.Name); - } - - return true; - } - catch (Exception e) - { - Console.WriteLine("Caught unexpected exception: " + e); - return false; - } - } - - /// - /// Try to test Type.IsCOMObject - /// - /// - static bool TypeIsComObject() - { - try - { - Console.WriteLine("Scenario: TypeIsComObject"); - Type classType = typeof(COMLib2.ContextMenu); - if (!classType.IsCOMObject) - { - Console.WriteLine("ComImport Class's IsCOMObject should return true"); - return false; - } - - Type interfaceType = typeof(COMLib2.IEnumVARIANT); - if (interfaceType.IsCOMObject) - { - Console.WriteLine("ComImport interface's IsCOMObject should return false"); - return false; - } - - return true; - } - catch (Exception e) - { - Console.WriteLine("Caught unexpected exception: " + e); - return false; - } - } - - /// - /// Try to create COM instance - /// - /// - static bool AcivateCOMType() - { - try - { - Console.WriteLine("Scenario: AcivateCOMType"); - COMLib2.ContextMenu contextMenu = (COMLib2.ContextMenu)Activator.CreateInstance(typeof(COMLib2.ContextMenu)); - - // Linux should throw PlatformNotSupportedException - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return false; - } - - if (contextMenu == null) - { - Console.WriteLine("AcivateCOMType failed"); - return false; - } - - return true; - } - catch (System.Reflection.TargetInvocationException e) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && e.InnerException is PlatformNotSupportedException) - { - return true; - } - - Console.WriteLine("Caught unexpected PlatformNotSupportedException: " + e); - return false; - } - catch(System.Runtime.InteropServices.COMException e) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return true; - } - - Console.WriteLine("Caught unexpected COMException: " + e); - return false; - } - catch (Exception e) - { - Console.WriteLine("Caught unexpected exception: " + e); - return false; - } - } - - [DllImport("ClassicCOMNative.dll")] - extern static void PassObjectToNative([In, MarshalAs( UnmanagedType.Interface)] object o); - - [DllImport("ClassicCOMNative.dll")] - extern static void PassObjectArrayToNative([In,Out] object[] o); - - [DllImport("ClassicCOMNative.dll")] - extern static void GetObjectFromNative(out object o); - - [DllImport("ClassicCOMNative.dll")] - extern static void GetObjectFromNativeAsRef(ref object o); - - /// - /// Try to Marshal COM Type across managed-native boundary - /// - /// - static bool MarshalCOMType() - { - Console.WriteLine("Scenario: MarshalCOMType"); - try - { - object o = new object(); - PassObjectToNative(o); - } - catch (System.Runtime.InteropServices.MarshalDirectiveException e) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return true; - } - Console.WriteLine("Caught unexpected MarshalDirectiveException: " + e); - return false; - } - catch (Exception e) - { - Console.WriteLine("Caught unexpected exception in PassObjectToNative: " + e); - return false; - } - - try - { - object [] oa = new object[2]; - PassObjectArrayToNative(oa); - } - catch (Exception e) - { - Console.WriteLine("Caught unexpected exception in GetObjectFromNative: " + e); - return false; - } - - - try - { - object o; - GetObjectFromNative(out o); - } - catch (Exception e) - { - Console.WriteLine("Caught unexpected exception in GetObjectFromNative: " + e); - return false; - } - - try - { - object o = new object(); - GetObjectFromNativeAsRef(ref o); - } - catch (Exception e) - { - Console.WriteLine("Caught unexpected exception in GetObjectFromNativeAsRef: " + e); - return false; - } - - return true; - } - - /// - /// Try to call Marshal API for COM Types - /// - /// - static bool MarshalAPI() - { - Console.WriteLine("Scenario: MarshalAPI"); - // MarshalAPI - if (Marshal.AreComObjectsAvailableForCleanup()) - { - Console.WriteLine("AreComObjectsAvailableForCleanup should return false"); - return false; - } - return true; - } - - [System.Security.SecuritySafeCritical] - static int Main() - { - int failures = 0; - if (!RelectionLoad()) - { - Console.WriteLine("RelectionLoad Failed"); - failures++; - } - - if (!TypeIsComObject()) - { - Console.WriteLine("TypeIsComObject Failed"); - failures++; - } - - if (!AcivateCOMType()) - { - Console.WriteLine("AcivateCOMType Failed"); - failures++; - } - - if (!MarshalCOMType()) - { - Console.WriteLine("MarshalCOMType Failed"); - failures++; - } - - if (!MarshalAPI()) - { - Console.WriteLine("MarshalAPI Failed"); - failures++; - } - - return failures > 0 ? 101 : 100; - } -} diff --git a/src/coreclr/tests/testsUnsupportedOutsideWindows.txt b/src/coreclr/tests/testsUnsupportedOutsideWindows.txt index b285680..d4928b2 100644 --- a/src/coreclr/tests/testsUnsupportedOutsideWindows.txt +++ b/src/coreclr/tests/testsUnsupportedOutsideWindows.txt @@ -123,10 +123,12 @@ CoreMangLib/cti/system/reflection/emit/DynMethodJumpStubTests/DynMethodJumpStubT CoreMangLib/system/collections/generic/hashset/Regression_Dev10_609271/Regression_Dev10_609271.sh CoreMangLib/system/collections/generic/hashset/Regression_Dev10_624201/Regression_Dev10_624201.sh GC/Coverage/smalloom/smalloom.sh +Interop/COM/NETClients/Primitives/NETClientPrimitives/NETClientPrimitives.sh Interop/MarshalAPI/GetNativeVariantForObject/GetNativeVariantForObject/GetNativeVariantForObject.sh Interop/MarshalAPI/GetObjectForNativeVariant/GetObjectForNativeVariant/GetObjectForNativeVariant.sh Interop/MarshalAPI/GetObjectsForNativeVariants/GetObjectsForNativeVariants/GetObjectsForNativeVariants.sh Interop/MarshalAPI/IUnknown/IUnknownTest/IUnknownTest.sh +Interop/SizeConst/SizeConstTest/SizeConstTest.sh JIT/Directed/coverage/oldtests/callipinvoke/callipinvoke.sh JIT/Directed/coverage/oldtests/Desktop/callipinvoke_il_d/callipinvoke_il_d.sh JIT/Directed/coverage/oldtests/Desktop/callipinvoke_il_r/callipinvoke_il_r.sh @@ -340,5 +342,4 @@ JIT/Regression/VS-ia64-JIT/V2.0-RTM/b286991/b286991/b286991.sh managed/Compilation/Compilation/Compilation.sh readytorun/r2rdump/R2RDumpTest/R2RDumpTest.sh Regressions/coreclr/0584/Test584/Test584.sh -Interop/SizeConst/SizeConstTest/SizeConstTest.sh tracing/eventsource/eventpipeandetw/eventpipeandetw/eventpipeandetw.sh