summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAaron Robinson <arobins@microsoft.com>2018-07-18 17:52:02 -0700
committerGitHub <noreply@github.com>2018-07-18 17:52:02 -0700
commitf37214ab432e192178ada2d202328f5fd8884cff (patch)
tree81ce0731c863378b01345002fc15ae7cfde0f8d2 /tests
parent965ad0c79743d05f336ec0c049f3b00b6dcac0da (diff)
downloadcoreclr-f37214ab432e192178ada2d202328f5fd8884cff.tar.gz
coreclr-f37214ab432e192178ada2d202328f5fd8884cff.tar.bz2
coreclr-f37214ab432e192178ada2d202328f5fd8884cff.zip
Basic .NET client tests (#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
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt16
-rw-r--r--tests/src/Interop/CMakeLists.txt15
-rw-r--r--tests/src/Interop/COM/NETClients/Primitives/App.manifest18
-rw-r--r--tests/src/Interop/COM/NETClients/Primitives/ArrayTests.cs168
-rw-r--r--tests/src/Interop/COM/NETClients/Primitives/ErrorTests.cs60
-rw-r--r--tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj36
-rw-r--r--tests/src/Interop/COM/NETClients/Primitives/NumericTests.cs193
-rw-r--r--tests/src/Interop/COM/NETClients/Primitives/Program.cs29
-rw-r--r--tests/src/Interop/COM/NETClients/Primitives/StringTests.cs272
-rw-r--r--tests/src/Interop/COM/NETServer/ImportedTypes.cs (renamed from tests/src/Interop/ClassicCOM/COMLib2.cs)4
-rw-r--r--tests/src/Interop/COM/NETServer/NETServer.csproj (renamed from tests/src/Interop/ClassicCOM/COMLib2.csproj)8
-rw-r--r--tests/src/Interop/COM/NativeServer/ArrayTesting.h347
-rw-r--r--tests/src/Interop/COM/NativeServer/CMakeLists.txt20
-rw-r--r--tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest31
-rw-r--r--tests/src/Interop/COM/NativeServer/ComHelpers.h169
-rw-r--r--tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h32
-rw-r--r--tests/src/Interop/COM/NativeServer/Exports.def4
-rw-r--r--tests/src/Interop/COM/NativeServer/NumericTesting.h257
-rw-r--r--tests/src/Interop/COM/NativeServer/Servers.cpp198
-rw-r--r--tests/src/Interop/COM/NativeServer/Servers.h18
-rw-r--r--tests/src/Interop/COM/NativeServer/StringTesting.h321
-rw-r--r--tests/src/Interop/COM/NativeServer/stdafx.cpp5
-rw-r--r--tests/src/Interop/COM/NativeServer/stdafx.h15
-rw-r--r--tests/src/Interop/COM/Reflection/Reflection.cs144
-rw-r--r--tests/src/Interop/COM/Reflection/Reflection.csproj (renamed from tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.csproj)22
-rw-r--r--tests/src/Interop/COM/ServerContracts/Primitives.cs189
-rw-r--r--tests/src/Interop/COM/ServerContracts/PrimitivesNativeServer.cs89
-rw-r--r--tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh656
-rw-r--r--tests/src/Interop/COM/ServerContracts/Server.Contracts.tli571
-rw-r--r--tests/src/Interop/COM/ServerContracts/readme.md9
-rw-r--r--tests/src/Interop/ClassicCOM/CMakeLists.txt13
-rw-r--r--tests/src/Interop/ClassicCOM/COMLib.cs34
-rw-r--r--tests/src/Interop/ClassicCOM/COMLib.csproj32
-rw-r--r--tests/src/Interop/ClassicCOM/ClassicCOMNative.cpp28
-rw-r--r--tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.cs255
-rw-r--r--tests/testsUnsupportedOutsideWindows.txt3
36 files changed, 3890 insertions, 391 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 078d9b8552..e667e59841 100644
--- a/tests/CMakeLists.txt
+++ b/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/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt
index 8780010154..04ec8aaa0e 100644
--- a/tests/src/Interop/CMakeLists.txt
+++ b/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/tests/src/Interop/COM/NETClients/Primitives/App.manifest b/tests/src/Interop/COM/NETClients/Primitives/App.manifest
new file mode 100644
index 0000000000..37b4f65804
--- /dev/null
+++ b/tests/src/Interop/COM/NETClients/Primitives/App.manifest
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+ <assemblyIdentity
+ type="win32"
+ name="NetPrimitivesClient"
+ version="1.0.0.0" />
+
+ <dependency>
+ <dependentAssembly>
+ <!-- RegFree COM -->
+ <assemblyIdentity
+ type="win32"
+ name="COMNativeServer.X"
+ version="1.0.0.0"/>
+ </dependentAssembly>
+ </dependency>
+
+</assembly>
diff --git a/tests/src/Interop/COM/NETClients/Primitives/ArrayTests.cs b/tests/src/Interop/COM/NETClients/Primitives/ArrayTests.cs
new file mode 100644
index 0000000000..1881263242
--- /dev/null
+++ b/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<int> 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/tests/src/Interop/COM/NETClients/Primitives/ErrorTests.cs b/tests/src/Interop/COM/NETClients/Primitives/ErrorTests.cs
new file mode 100644
index 0000000000..9694333b54
--- /dev/null
+++ b/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<NotImplementedException>(() => { this.server.Throw_HResult(unchecked((int)0x80004001)); });
+ Assert.Throws<NullReferenceException>(() => { this.server.Throw_HResult(unchecked((int)0x80004003)); });
+ Assert.Throws<UnauthorizedAccessException>(() => { this.server.Throw_HResult(unchecked((int)0x80070005)); });
+ Assert.Throws<OutOfMemoryException>(() => { this.server.Throw_HResult(unchecked((int)0x8007000E)); });
+ Assert.Throws<ArgumentException>(() => { this.server.Throw_HResult(unchecked((int)0x80070057)); });
+ Assert.Throws<COMException>(() => { this.server.Throw_HResult(unchecked((int)0x8000ffff)); });
+ Assert.Throws<COMException>(() => { 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/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj b/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj
new file mode 100644
index 0000000000..0bb40d739b
--- /dev/null
+++ b/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>NETClientPrimitives</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{85C57688-DA98-4DE3-AC9B-526E4747434C}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{209912F9-0DA1-4184-9CC1-8D583BAF4A28};{87799F5D-CEBD-499D-BDBA-B2C6105CD766}</ProjectTypeGuids>
+ <ApplicationManifest>App.manifest</ApplicationManifest>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DisableProjectBuild Condition="'$(TargetsWindows)' != 'true'">true</DisableProjectBuild>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="ArrayTests.cs" />
+ <Compile Include="ErrorTests.cs" />
+ <Compile Include="NumericTests.cs" />
+ <Compile Include="StringTests.cs" />
+ <Compile Include="../../ServerContracts/Primitives.cs" />
+ <Compile Include="../../ServerContracts/PrimitivesNativeServer.cs" />
+ <Compile Include="../../../common/Assertion.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="../../NativeServer/CMakeLists.txt" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Interop/COM/NETClients/Primitives/NumericTests.cs b/tests/src/Interop/COM/NETClients/Primitives/NumericTests.cs
new file mode 100644
index 0000000000..cff69ec197
--- /dev/null
+++ b/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/tests/src/Interop/COM/NETClients/Primitives/Program.cs b/tests/src/Interop/COM/NETClients/Primitives/Program.cs
new file mode 100644
index 0000000000..4d76417275
--- /dev/null
+++ b/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/tests/src/Interop/COM/NETClients/Primitives/StringTests.cs b/tests/src/Interop/COM/NETClients/Primitives/StringTests.cs
new file mode 100644
index 0000000000..ab5271fd73
--- /dev/null
+++ b/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<Tuple<string, string>> addPairs = new Tuple<string, string>[]
+ {
+ 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<string> 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/tests/src/Interop/ClassicCOM/COMLib2.cs b/tests/src/Interop/COM/NETServer/ImportedTypes.cs
index 8f0ec78c4d..a8d6e1981a 100644
--- a/tests/src/Interop/ClassicCOM/COMLib2.cs
+++ b/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/tests/src/Interop/ClassicCOM/COMLib2.csproj b/tests/src/Interop/COM/NETServer/NETServer.csproj
index 601b94ecf9..cf62cc019c 100644
--- a/tests/src/Interop/ClassicCOM/COMLib2.csproj
+++ b/tests/src/Interop/COM/NETServer/NETServer.csproj
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <AssemblyName>COMLib2</AssemblyName>
+ <AssemblyName>NETServer</AssemblyName>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C04AB564-CC61-499D-9F4C-AA1A9FDE42C9}</ProjectGuid>
<OutputType>library</OutputType>
@@ -23,10 +23,10 @@
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
- <Compile Include="COMLib2.cs" />
+ <Compile Include="ImportedTypes.cs" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/tests/src/Interop/COM/NativeServer/ArrayTesting.h b/tests/src/Interop/COM/NativeServer/ArrayTesting.h
new file mode 100644
index 0000000000..cbf54cfa9c
--- /dev/null
+++ b/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 <cstdint>
+#include "Servers.h"
+
+class DECLSPEC_UUID("B99ABE6A-DFF6-440F-BFB6-55179B8FE18E") ArrayTesting : public UnknownImpl, public IArrayTesting
+{
+private:
+ template<typename L, typename D>
+ double Mean(L l, D *d)
+ {
+ double t = 0.0;
+ for (L i = 0; i < l; ++i)
+ t += d[i];
+
+ return (t / l);
+ }
+ template<VARTYPE E>
+ 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<unsigned char*>(d->pvData));
+ break;
+ case VT_I2:
+ *r = Mean(*l, static_cast<int16_t*>(d->pvData));
+ break;
+ case VT_UI2:
+ *r = Mean(*l, static_cast<uint16_t*>(d->pvData));
+ break;
+ case VT_I4:
+ *r = Mean(*l, static_cast<int32_t*>(d->pvData));
+ break;
+ case VT_UI4:
+ *r = Mean(*l, static_cast<uint32_t*>(d->pvData));
+ break;
+ case VT_I8:
+ *r = Mean(*l, static_cast<int64_t*>(d->pvData));
+ break;
+ case VT_UI8:
+ *r = Mean(*l, static_cast<uint64_t*>(d->pvData));
+ break;
+ case VT_R4:
+ *r = Mean(*l, static_cast<float*>(d->pvData));
+ break;
+ case VT_R8:
+ *r = Mean(*l, static_cast<double *>(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<VT_UI1>(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<VT_I2>(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<VT_UI2>(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<VT_I4>(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<VT_UI4>(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<VT_I8>(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<VT_UI8>(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<VT_R4>(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<VT_R8>(d, len, pRetVal);
+ }
+
+public: // IUnknown
+ STDMETHOD(QueryInterface)(
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
+ {
+ return DoQueryInterface<ArrayTesting, IArrayTesting>(this, riid, ppvObject);
+ }
+
+ DEFINE_REF_COUNTING();
+};
diff --git a/tests/src/Interop/COM/NativeServer/CMakeLists.txt b/tests/src/Interop/COM/NativeServer/CMakeLists.txt
new file mode 100644
index 0000000000..368248d972
--- /dev/null
+++ b/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}/$<CONFIG>/COMNativeServer.X.manifest INPUT ${CMAKE_CURRENT_SOURCE_DIR}/COMNativeServer.X.manifest)
+
+# add the install targets
+install (TARGETS COMNativeServer DESTINATION bin)
diff --git a/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest b/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest
new file mode 100644
index 0000000000..13c36c9099
--- /dev/null
+++ b/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+<assemblyIdentity
+ type="win32"
+ name="COMNativeServer.X"
+ version="1.0.0.0" />
+
+<file name = "COMNativeServer.dll">
+ <!-- NumericTesting -->
+ <comClass
+ clsid="{53169A33-E85D-4E3C-B668-24E438D0929B}"
+ threadingModel="Both" />
+
+ <!-- ArrayTesting -->
+ <comClass
+ clsid="{B99ABE6A-DFF6-440F-BFB6-55179B8FE18E}"
+ threadingModel="Both" />
+
+ <!-- StringTesting -->
+ <comClass
+ clsid="{C73C83E8-51A2-47F8-9B5C-4284458E47A6}"
+ threadingModel="Both" />
+
+ <!-- ErrorMarshalTesting -->
+ <comClass
+ clsid="{71CF5C45-106C-4B32-B418-43A463C6041F}"
+ threadingModel="Both" />
+</file>
+
+</assembly>
diff --git a/tests/src/Interop/COM/NativeServer/ComHelpers.h b/tests/src/Interop/COM/NativeServer/ComHelpers.h
new file mode 100644
index 0000000000..651ccc5364
--- /dev/null
+++ b/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 <Windows.h>
+#include <comdef.h>
+#include <cassert>
+#include <exception>
+#include <type_traits>
+#include <atomic>
+
+// Common macro for working in COM
+#define RETURN_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { return hr; } }
+
+namespace Internal
+{
+ template<typename C, typename I>
+ 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<I*>(obj);
+ }
+ else if (riid == __uuidof(IUnknown))
+ {
+ *ppvObject = static_cast<IUnknown*>(obj);
+ }
+ else
+ {
+ *ppvObject = nullptr;
+ return E_NOINTERFACE;
+ }
+
+ return S_OK;
+ }
+
+ template<typename C, typename I1, typename I2, typename ...R>
+ 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<I1*>(obj);
+ return S_OK;
+ }
+
+ return __QueryInterfaceImpl<C, I2, R...>(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<typename C, typename ...I>
+ 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<C, I...>(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<ULONG> _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<typename T>
+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<ClassFactoryBasic, IClassFactory>(this, riid, ppvObject);
+ }
+
+ DEFINE_REF_COUNTING();
+};
diff --git a/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h b/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h
new file mode 100644
index 0000000000..307abe4a5d
--- /dev/null
+++ b/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<ErrorMarshalTesting, IErrorMarshalTesting>(this, riid, ppvObject);
+ }
+
+ DEFINE_REF_COUNTING();
+};
diff --git a/tests/src/Interop/COM/NativeServer/Exports.def b/tests/src/Interop/COM/NativeServer/Exports.def
new file mode 100644
index 0000000000..2d0de26b05
--- /dev/null
+++ b/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/tests/src/Interop/COM/NativeServer/NumericTesting.h b/tests/src/Interop/COM/NativeServer/NumericTesting.h
new file mode 100644
index 0000000000..9a80230d96
--- /dev/null
+++ b/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 <type_traits>
+#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<unsigned char>(a + b);
+ return S_OK;
+ }
+ DEF_RAWFUNC(Add_Short)(
+ /*[in]*/ short a,
+ /*[in]*/ short b,
+ /*[out,retval]*/ short * pRetVal)
+ {
+ *pRetVal = static_cast<short>(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<unsigned short>(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<std::remove_reference<decltype(*c)>::type>::max())
+ return E_UNEXPECTED;
+ *c = static_cast<unsigned char>(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<std::remove_reference<decltype(*c)>::type>::max())
+ return E_UNEXPECTED;
+ *c = static_cast<short>(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<std::remove_reference<decltype(*c)>::type>::max())
+ return E_UNEXPECTED;
+ *c = static_cast<unsigned short>(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<std::remove_reference<decltype(*c)>::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<std::remove_reference<decltype(*c)>::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<std::remove_reference<decltype(*c)>::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<std::remove_reference<decltype(*c)>::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<std::remove_reference<decltype(*c)>::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<std::remove_reference<decltype(*c)>::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<unsigned char>(a + b);
+ return S_OK;
+ }
+ DEF_RAWFUNC(Add_Short_Out)(
+ /*[in]*/ short a,
+ /*[in]*/ short b,
+ /*[out]*/ short * c)
+ {
+ *c = static_cast<short>(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<unsigned short>(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<NumericTesting, INumericTesting>(this, riid, ppvObject);
+ }
+
+ DEFINE_REF_COUNTING();
+};
diff --git a/tests/src/Interop/COM/NativeServer/Servers.cpp b/tests/src/Interop/COM/NativeServer/Servers.cpp
new file mode 100644
index 0000000000..27f0d29963
--- /dev/null
+++ b/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<std::remove_pointer<LPOLESTR>::type, decltype(&::CoTaskMemFree)>
+ {
+ OleStr(_In_ LPOLESTR raw)
+ : std::unique_ptr<std::remove_pointer<LPOLESTR>::type, decltype(&::CoTaskMemFree)>(raw, ::CoTaskMemFree)
+ { }
+ };
+
+ struct RegKey : public std::unique_ptr<std::remove_pointer<HKEY>::type, decltype(&::RegCloseKey)>
+ {
+ RegKey(_In_ HKEY raw)
+ : std::unique_ptr<std::remove_pointer<HKEY>::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,
+ &regKeyRaw,
+ &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,
+ &regServerKeyRaw,
+ &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<LPCWSTR>(&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<const BYTE*>(fullPath),
+ static_cast<DWORD>(::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<const BYTE*>(threadingModel),
+ static_cast<DWORD>(::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<NumericTesting>::Create(riid, ppv);
+
+ if (rclsid == __uuidof(ArrayTesting))
+ return ClassFactoryBasic<ArrayTesting>::Create(riid, ppv);
+
+ if (rclsid == __uuidof(StringTesting))
+ return ClassFactoryBasic<StringTesting>::Create(riid, ppv);
+
+ if (rclsid == __uuidof(ErrorMarshalTesting))
+ return ClassFactoryBasic<ErrorMarshalTesting>::Create(riid, ppv);
+
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
diff --git a/tests/src/Interop/COM/NativeServer/Servers.h b/tests/src/Interop/COM/NativeServer/Servers.h
new file mode 100644
index 0000000000..5a22e801ab
--- /dev/null
+++ b/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 <Server.Contracts.tlh>
+
+#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/tests/src/Interop/COM/NativeServer/StringTesting.h b/tests/src/Interop/COM/NativeServer/StringTesting.h
new file mode 100644
index 0000000000..7589bf2973
--- /dev/null
+++ b/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 <typename STRING>
+ 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 <typename STRING>
+ STRING ReverseInplace(size_t len, STRING s)
+ {
+ std::reverse(s, s + len);
+ return s;
+ }
+
+ template<typename STRING>
+ 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<LPCSTR>(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<StringTesting, IStringTesting>(this, riid, ppvObject);
+ }
+
+ DEFINE_REF_COUNTING();
+};
diff --git a/tests/src/Interop/COM/NativeServer/stdafx.cpp b/tests/src/Interop/COM/NativeServer/stdafx.cpp
new file mode 100644
index 0000000000..c87158f32c
--- /dev/null
+++ b/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/tests/src/Interop/COM/NativeServer/stdafx.h b/tests/src/Interop/COM/NativeServer/stdafx.h
new file mode 100644
index 0000000000..058ec2ea28
--- /dev/null
+++ b/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 <windows.h>
+
+#include <atomic>
+#include <memory>
+
+
diff --git a/tests/src/Interop/COM/Reflection/Reflection.cs b/tests/src/Interop/COM/Reflection/Reflection.cs
new file mode 100644
index 0000000000..bab341a029
--- /dev/null
+++ b/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
+{
+ /// <summary>
+ /// Reflect load ComImport Types amd enumerate them
+ /// </summary>
+ 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;
+ }
+ }
+
+ /// <summary>
+ /// Type.IsCOMObject
+ /// </summary>
+ 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;
+ }
+ }
+
+ /// <summary>
+ /// Create COM instance via Activator
+ /// </summary>
+ 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/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.csproj b/tests/src/Interop/COM/Reflection/Reflection.csproj
index 673e216fe9..ad03388ca9 100644
--- a/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.csproj
+++ b/tests/src/Interop/COM/Reflection/Reflection.csproj
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <AssemblyName>ClassicCOMUnitTest</AssemblyName>
+ <AssemblyName>Reflection</AssemblyName>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{85C57688-DA98-4DE3-AC9B-526E4747434C}</ProjectGuid>
<OutputType>Exe</OutputType>
@@ -23,25 +23,17 @@
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
- <Compile Include="ClassicCOMUnitTest.cs" />
+ <Compile Include="Reflection.cs" />
</ItemGroup>
<ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
<Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
<Name>CoreCLRTestLibrary</Name>
</ProjectReference>
- <ProjectReference Include="COMLib.csproj">
- <Project>{5FEE5C46-8DD9-49FA-BDC1-AF22867A0704}</Project>
- <Name>COMLib</Name>
- </ProjectReference>
- <ProjectReference Include="COMLib2.csproj">
+ <ProjectReference Include="..\NETServer\NETServer.csproj">
<Project>{C04AB564-CC61-499D-9F4C-AA1A9FDE42C9}</Project>
- <Name>COMLib</Name>
+ <Name>NETServer</Name>
</ProjectReference>
- <ProjectReference Include="CMakeLists.txt" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/tests/src/Interop/COM/ServerContracts/Primitives.cs b/tests/src/Interop/COM/ServerContracts/Primitives.cs
new file mode 100644
index 0000000000..cc6a30344b
--- /dev/null
+++ b/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/tests/src/Interop/COM/ServerContracts/PrimitivesNativeServer.cs b/tests/src/Interop/COM/ServerContracts/PrimitivesNativeServer.cs
new file mode 100644
index 0000000000..4e028804dd
--- /dev/null
+++ b/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;
+
+ /// <summary>
+ /// Managed definition of CoClass
+ /// </summary>
+ [ComImport]
+ [CoClass(typeof(NumericTestingClass))]
+ [Guid("05655A94-A915-4926-815D-A9EA648BAAD9")]
+ internal interface NumericTesting : Server.Contract.INumericTesting
+ {
+ }
+
+ /// <summary>
+ /// Managed activation for CoClass
+ /// </summary>
+ [ComImport]
+ [Guid("53169A33-E85D-4E3C-B668-24E438D0929B")]
+ internal class NumericTestingClass
+ {
+ }
+
+ /// <summary>
+ /// Managed definition of CoClass
+ /// </summary>
+ [ComImport]
+ [CoClass(typeof(ArrayTestingClass))]
+ [Guid("7731CB31-E063-4CC8-BCD2-D151D6BC8F43")]
+ internal interface ArrayTesting : Server.Contract.IArrayTesting
+ {
+ }
+
+ /// <summary>
+ /// Managed activation for CoClass
+ /// </summary>
+ [ComImport]
+ [Guid("B99ABE6A-DFF6-440F-BFB6-55179B8FE18E")]
+ internal class ArrayTestingClass
+ {
+ }
+
+ /// <summary>
+ /// Managed definition of CoClass
+ /// </summary>
+ [ComImport]
+ [CoClass(typeof(StringTestingClass))]
+ [Guid("7044C5C0-C6C6-4713-9294-B4A4E86D58CC")]
+ internal interface StringTesting : Server.Contract.IStringTesting
+ {
+ }
+
+ /// <summary>
+ /// Managed activation for CoClass
+ /// </summary>
+ [ComImport]
+ [Guid("C73C83E8-51A2-47F8-9B5C-4284458E47A6")]
+ internal class StringTestingClass
+ {
+ }
+
+ /// <summary>
+ /// Managed definition of CoClass
+ /// </summary>
+ [ComImport]
+ [CoClass(typeof(ErrorMarshalTestingClass))]
+ [Guid("592386A5-6837-444D-9DE3-250815D18556")]
+ internal interface ErrorMarshalTesting : Server.Contract.IErrorMarshalTesting
+ {
+ }
+
+ /// <summary>
+ /// Managed activation for CoClass
+ /// </summary>
+ [ComImport]
+ [Guid("71CF5C45-106C-4B32-B418-43A463C6041F")]
+ internal class ErrorMarshalTestingClass
+ {
+ }
+}
+
+#pragma warning restore IDE1006 // Naming Styles
diff --git a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh b/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh
new file mode 100644
index 0000000000..55597a9ef7
--- /dev/null
+++ b/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 <comdef.h>
+
+//
+// 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/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli b/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli
new file mode 100644
index 0000000000..a419c654e6
--- /dev/null
+++ b/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/tests/src/Interop/COM/ServerContracts/readme.md b/tests/src/Interop/COM/ServerContracts/readme.md
new file mode 100644
index 0000000000..347c7fc3f2
--- /dev/null
+++ b/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/tests/src/Interop/ClassicCOM/CMakeLists.txt b/tests/src/Interop/ClassicCOM/CMakeLists.txt
deleted file mode 100644
index d3416dd584..0000000000
--- a/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/tests/src/Interop/ClassicCOM/COMLib.cs b/tests/src/Interop/ClassicCOM/COMLib.cs
deleted file mode 100644
index fba866c567..0000000000
--- a/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/tests/src/Interop/ClassicCOM/COMLib.csproj b/tests/src/Interop/ClassicCOM/COMLib.csproj
deleted file mode 100644
index 1f289d6729..0000000000
--- a/tests/src/Interop/ClassicCOM/COMLib.csproj
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <AssemblyName>COMLib</AssemblyName>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{5FEE5C46-8DD9-49FA-BDC1-AF22867A0704}</ProjectGuid>
- <OutputType>library</OutputType>
- <ProjectTypeGuids>{CDC3DF7E-04B4-4464-9A02-7E2B0FAB586A};{68EC03EE-C9EE-47FD-AA08-A954EB2D9816}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
- </PropertyGroup>
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="COMLib.cs" />
- </ItemGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/tests/src/Interop/ClassicCOM/ClassicCOMNative.cpp b/tests/src/Interop/ClassicCOM/ClassicCOMNative.cpp
deleted file mode 100644
index 962313c229..0000000000
--- a/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 <xplatform.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-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/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.cs b/tests/src/Interop/ClassicCOM/ClassicCOMUnitTest.cs
deleted file mode 100644
index 530f02c266..0000000000
--- a/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
-{
- /// <summary>
- /// Try to reflect load ComImport Types by enumerate
- /// </summary>
- /// <returns></returns>
- 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;
- }
- }
-
- /// <summary>
- /// Try to test Type.IsCOMObject
- /// </summary>
- /// <returns></returns>
- 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;
- }
- }
-
- /// <summary>
- /// Try to create COM instance
- /// </summary>
- /// <returns></returns>
- 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);
-
- /// <summary>
- /// Try to Marshal COM Type across managed-native boundary
- /// </summary>
- /// <returns></returns>
- 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;
- }
-
- /// <summary>
- /// Try to call Marshal API for COM Types
- /// </summary>
- /// <returns></returns>
- 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/tests/testsUnsupportedOutsideWindows.txt b/tests/testsUnsupportedOutsideWindows.txt
index b285680d0c..d4928b20aa 100644
--- a/tests/testsUnsupportedOutsideWindows.txt
+++ b/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