ULONG_PTR _actCookie;
};
+class ClrInstanceDetails
+{
+ static void * _currentClrInstance;
+ static unsigned int _currentAppDomainId;
+
+public: // static
+ static HRESULT GetDetails(void **clrInstance, unsigned int *appDomainId)
+ {
+ *clrInstance = _currentClrInstance;
+ *appDomainId = _currentAppDomainId;
+ return S_OK;
+ }
+
+public:
+ ClrInstanceDetails(void *clrInstance, unsigned int appDomainId)
+ {
+ _currentClrInstance = clrInstance;
+ _currentAppDomainId = appDomainId;
+ }
+
+ ~ClrInstanceDetails()
+ {
+ _currentClrInstance = nullptr;
+ _currentAppDomainId = 0;
+ }
+};
+
+void * ClrInstanceDetails::_currentClrInstance;
+unsigned int ClrInstanceDetails::_currentAppDomainId;
+
+extern "C" __declspec(dllexport) HRESULT __cdecl GetCurrentClrDetails(void **clrInstance, unsigned int *appDomainId)
+{
+ return ClrInstanceDetails::GetDetails(clrInstance, appDomainId);
+}
+
bool TryLoadHostPolicy(StackSString& hostPolicyPath)
{
const WCHAR *hostpolicyName = W("hostpolicy.dll");
{
ActivationContext cxt{ log, managedAssemblyFullName.GetUnicode() };
+ ClrInstanceDetails current{ host, domainId };
hr = host->ExecuteAssembly(domainId, managedAssemblyFullName, argc - 1, (argc - 1) ? &(argv[1]) : NULL, &exitCode);
if (FAILED(hr))
coreclr::coreclr(_Inout_ AutoModule hmod)
: _hmod{ std::move(hmod) }
+ , _attached{ false }
, _clrInst{ nullptr }
, _appDomainId{ std::numeric_limits<uint32_t>::max() }
{
coreclr::~coreclr()
{
- if (_clrInst != nullptr)
+ if (_clrInst != nullptr && !_attached)
{
HRESULT hr = _shutdown(_clrInst, _appDomainId);
assert(SUCCEEDED(hr));
appDomainName = "CoreShim";
HRESULT hr;
+
+ // Check if this is hosted scenario - launched via CoreRun.exe
+ HMODULE mod = ::GetModuleHandleW(W("CoreRun.exe"));
+ if (mod != NULL)
+ {
+ using GetCurrentClrDetailsFunc = HRESULT(*)(void **clrInstance, unsigned int *appDomainId);
+ auto getCurrentClrDetails = (GetCurrentClrDetailsFunc)::GetProcAddress(mod, "GetCurrentClrDetails");
+ RETURN_IF_FAILED(getCurrentClrDetails(&_clrInst, &_appDomainId));
+ if (_clrInst != nullptr)
+ {
+ _attached = true;
+ return S_OK;
+ }
+ }
+
try
{
const std::wstring exePathW = GetExePath();
private:
AutoModule _hmod;
+ bool _attached;
void *_clrInst;
uint32_t _appDomainId;
LPCUTF8 pszNamespace;
if (SUCCEEDED(m_pMT->GetMDImport()->GetNameOfTypeDef(m_pMT->GetCl(), &pszClassName, &pszNamespace)))
{
- OBJECTHANDLE handle = GetMainWrapper()->GetRawObjectHandle();
+ OBJECTHANDLE handle = GetMainWrapper()->GetObjectHandle();
_UNCHECKED_OBJECTREF obj = NULL;
// Force retriving the handle without using OBJECTREF and under cooperative mode
//
//--------------------------------------------------------------------------
-
//--------------------------------------------------------------------------
-// void ComCallWrapper::MarkHandleWeak()
-// mark the wrapper as holding a weak handle to the object
+// Check if the wrapper has been deactivated
//--------------------------------------------------------------------------
+BOOL ComCallWrapper::IsHandleWeak()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ SimpleComCallWrapper* simpleWrap = GetSimpleWrapper();
+ _ASSERTE(simpleWrap);
+ return simpleWrap->IsHandleWeak();
+}
+//--------------------------------------------------------------------------
+// Mark the wrapper as holding a weak handle to the object
+//--------------------------------------------------------------------------
void ComCallWrapper::MarkHandleWeak()
{
CONTRACTL
}
CONTRACTL_END;
- SyncBlock* pSyncBlock = GetSyncBlock();
- _ASSERTE(pSyncBlock);
+ SimpleComCallWrapper* simpleWrap = GetSimpleWrapper();
+ _ASSERTE(simpleWrap);
+ simpleWrap->MarkHandleWeak();
+}
+
+//--------------------------------------------------------------------------
+// Mark the wrapper as not having a weak handle
+//--------------------------------------------------------------------------
+void ComCallWrapper::ResetHandleStrength()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
- GetSimpleWrapper()->MarkHandleWeak();
+ SimpleComCallWrapper* simpleWrap = GetSimpleWrapper();
+ _ASSERTE(simpleWrap);
+ simpleWrap->ResetHandleStrength();
}
//--------------------------------------------------------------------------
-// void ComCallWrapper::ResetHandleStrength()
-// mark the wrapper as not having a weak handle
+// Check if the wrapper was activated via COM
//--------------------------------------------------------------------------
+BOOL ComCallWrapper::IsComActivated()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
-void ComCallWrapper::ResetHandleStrength()
+ SimpleComCallWrapper* simpleWrap = GetSimpleWrapper();
+ _ASSERTE(simpleWrap);
+ return simpleWrap->IsComActivated();
+}
+
+//--------------------------------------------------------------------------
+// Mark the wrapper as being created via COM activation
+//--------------------------------------------------------------------------
+VOID ComCallWrapper::MarkComActivated()
{
CONTRACTL
{
MODE_ANY;
}
CONTRACTL_END;
-
- SyncBlock* pSyncBlock = GetSyncBlock();
- _ASSERTE(pSyncBlock);
- GetSimpleWrapper()->ResetHandleStrength();
+ SimpleComCallWrapper* simpleWrap = GetSimpleWrapper();
+ _ASSERTE(simpleWrap);
+ simpleWrap->MarkComActivated();
}
//--------------------------------------------------------------------------
};
public:
- VOID ResetHandleStrength();
+ BOOL IsHandleWeak();
VOID MarkHandleWeak();
+ VOID ResetHandleStrength();
- BOOL IsHandleWeak();
+ BOOL IsComActivated();
+ VOID MarkComActivated();
- OBJECTHANDLE GetObjectHandle();
- OBJECTHANDLE GetRawObjectHandle() { LIMITED_METHOD_CONTRACT; return m_ppThis; } // no NULL check
+ OBJECTHANDLE GetObjectHandle() { LIMITED_METHOD_CONTRACT; return m_ppThis; }
-protected:
// don't instantiate this class directly
- ComCallWrapper()
- {
- LIMITED_METHOD_CONTRACT;
- }
- ~ComCallWrapper()
- {
- LIMITED_METHOD_CONTRACT;
- }
-
- void Init();
+ ComCallWrapper() = delete;
+ ~ComCallWrapper() = delete;
+protected:
#ifndef DACCESS_COMPILE
inline static void SetNext(ComCallWrapper* pWrap, ComCallWrapper* pNextWrapper)
{
enum_IsAggregated = 0x1,
enum_IsExtendsCom = 0x2,
enum_IsHandleWeak = 0x4,
- // unused = 0x8,
+ enum_IsComActivated = 0x8,
// unused = 0x10,
enum_IsPegged = 0x80,
// unused = 0x100,
return m_flags & enum_IsExtendsCom;
}
+ BOOL IsComActivated()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_flags & enum_IsComActivated;
+ }
+
+ void MarkComActivated()
+ {
+ LIMITED_METHOD_CONTRACT;
+ FastInterlockOr((ULONG*)&m_flags, enum_IsComActivated);
+ }
+
inline BOOL IsPegged()
{
LIMITED_METHOD_DAC_CONTRACT;
LONGLONG m_llRefCount;
};
-inline OBJECTHANDLE ComCallWrapper::GetObjectHandle()
-{
- CONTRACT (OBJECTHANDLE)
- {
- WRAPPER(THROWS);
- WRAPPER(GC_TRIGGERS);
- MODE_COOPERATIVE;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN m_ppThis;
-}
-
//--------------------------------------------------------------------------------
// ComCallWrapper* ComCallWrapper::InlineGetWrapper(OBJECTREF* ppObj, ComCallWrapperTemplate *pTemplate)
// returns the wrapper for the object, if not yet created, creates one
return m_pSimpleWrapper->GetJupiterRefCount();
}
-
-
inline PTR_ComCallWrapper ComCallWrapper::GetWrapperFromIP(PTR_IUnknown pUnk)
{
CONTRACT (PTR_ComCallWrapper)
return GetSimpleWrapper()->GetComCallWrapperTemplate();
}
-//--------------------------------------------------------------------------
-// BOOL ComCallWrapper::BOOL IsHandleWeak()
-// check if the wrapper has been deactivated
-// Moved here to make DAC build happy and hopefully get it inlined
-//--------------------------------------------------------------------------
-inline BOOL ComCallWrapper::IsHandleWeak()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- SimpleComCallWrapper* pSimpleWrap = GetSimpleWrapper();
- _ASSERTE(pSimpleWrap);
-
- return pSimpleWrap->IsHandleWeak();
-}
-
inline BOOL ComCallWrapper::IsWrapperActive()
{
CONTRACTL
BOOL bHasStrongCOMRefCount = ((cbRef > 0) || bHasJupiterStrongRefCount);
- BOOL bIsWrapperActive = (bHasStrongCOMRefCount && !IsHandleWeak());
+ BOOL bIsWrapperActive = (bHasStrongCOMRefCount && !m_pSimpleWrapper->IsHandleWeak());
LOG((LF_INTEROP, LL_INFO1000,
"CCW 0x%p: cbRef = 0x%x, cbJupiterRef = 0x%x, IsPegged = %d, GlobalPegging = %d, IsHandleWeak = %d\n",
this,
- cbRef, cbJupiterRef, IsPegged(), RCWWalker::IsGlobalPeggingOn(), IsHandleWeak()));
+ cbRef, cbJupiterRef, m_pSimpleWrapper->IsPegged(), RCWWalker::IsGlobalPeggingOn(), m_pSimpleWrapper->IsHandleWeak()));
LOG((LF_INTEROP, LL_INFO1000, "CCW 0x%p: IsWrapperActive returned %d\n", this, bIsWrapperActive));
return bIsWrapperActive;
// GetObjectRefFromComIP
// pUnk : input IUnknown
// pMTClass : specifies the type of instance to be returned
-// NOTE:** As per COM Rules, the IUnknown passed is shouldn't be AddRef'ed
+// NOTE:** As per COM Rules, the IUnknown passed in shouldn't be AddRef'ed
//+----------------------------------------------------------------------------
void GetObjectRefFromComIP(OBJECTREF* pObjOut, IUnknown **ppUnk, MethodTable *pMTClass, MethodTable *pItfMT, DWORD dwFlags)
{
if (pUnk != NULL)
{
// get CCW for IUnknown
- ComCallWrapper* pWrap = GetCCWFromIUnknown(pUnk);
- if (pWrap == NULL)
+ ComCallWrapper *ccw = GetCCWFromIUnknown(pUnk);
+ if (ccw == NULL)
{
// could be aggregated scenario
HRESULT hr = SafeQueryInterface(pUnk, IID_IUnknown, &pOuter);
LogInteropQI(pUnk, IID_IUnknown, hr, "GetObjectRefFromComIP: QI for Outer");
IfFailThrow(hr);
-
+
// store the outer in the auto pointer
pAutoOuterUnk = pOuter;
- pWrap = GetCCWFromIUnknown(pOuter);
+ ccw = GetCCWFromIUnknown(pOuter);
}
- if (pWrap != NULL)
- { // our tear-off
- _ASSERTE(pWrap != NULL);
- AppDomain* pCurrDomain = pThread->GetDomain();
- *pObjOut = pWrap->GetObjectRef();
+ // If the CCW was activated via COM, do not unwrap it.
+ // Unwrapping a CCW would deliver the underlying OBJECTREF,
+ // but when a managed class is activated via COM it should
+ // remain a COM object and adhere to COM rules.
+ if (ccw != NULL
+ && !ccw->IsComActivated())
+ {
+ *pObjOut = ccw->GetObjectRef();
}
if (*pObjOut != NULL)
ThrowHRMsg(hr, IDS_EE_CREATEINSTANCE_LIC_FAILED);
}
+ // If the activated COM class has a CCW, mark the
+ // CCW as being activated via COM.
+ ComCallWrapper *ccw = GetCCWFromIUnknown(pUnk);
+ if (ccw != NULL)
+ ccw->MarkComActivated();
+
pUnk.SuppressRelease();
RETURN pUnk;
}
<ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NETClients/Events/NETClientEvents/*">
<Issue>22784</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NETClients/ConsumeNETServer/ConsumeNETServer/*">
+ <Issue>20682</Issue>
+ </ExcludeList>
</ItemGroup>
<!-- Windows arm64 specific excludes -->
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
- <Compile Include="../../ServerContracts/NativeServers.cs" />
+ <Compile Include="../../ServerContracts/Server.CoClasses.cs" />
<Compile Include="../../ServerContracts/Server.Contracts.cs" />
<Compile Include="../../ServerContracts/ServerGuids.cs" />
</ItemGroup>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+ <assemblyIdentity
+ type="win32"
+ name="ConsumeNETServer"
+ version="1.0.0.0" />
+
+ <dependency>
+ <dependentAssembly>
+ <!-- RegFree COM to activate Managed Server -->
+ <assemblyIdentity
+ type="win32"
+ name="CoreShim.X"
+ version="1.0.0.0"/>
+ </dependentAssembly>
+ </dependency>
+
+</assembly>
--- /dev/null
+<?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>ConsumeNETServer</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4BDB75BD-30D8-4603-98DB-C6CFDC5F6F0E}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{209912F9-0DA1-4184-9CC1-8D583BAF4A28};{87799F5D-CEBD-499D-BDBA-B2C6105CD766}</ProjectTypeGuids>
+ <ApplicationManifest>App.manifest</ApplicationManifest>
+ <CLRTestScriptLocalCoreShim>true</CLRTestScriptLocalCoreShim>
+ <RequiresMockHostPolicy>true</RequiresMockHostPolicy>
+
+ <!-- Blocked on ILAsm supporting embedding resources. See https://github.com/dotnet/coreclr/issues/20819 -->
+ <IlrtTestKind>BuildOnly</IlrtTestKind>
+
+ <!-- Blocked on CrossGen.exe supporting embedding resources. See https://github.com/dotnet/coreclr/issues/21006 -->
+ <CrossGenTest>false</CrossGenTest>
+
+ <!-- Test unsupported outside of windows -->
+ <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows>
+ <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild>
+ <!-- This test would require the runincontext.exe to include App.manifest describing the COM interfaces -->
+ <UnloadabilityIncompatible>true</UnloadabilityIncompatible>
+
+ <!-- Suppress warning about conflicting type names. This occurs because of the reference to NETServer.
+ The reference is only to ensure the project is built and properly copied. The test itself uses
+ COM to activate the server rather than typical class activation via 'new' -->
+ <NoWarn>$(NoWarn),0436</NoWarn>
+ </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="../../ServerContracts/Server.CoClasses.cs" />
+ <Compile Include="../../ServerContracts/Server.Contracts.cs" />
+ <Compile Include="../../ServerContracts/ServerGuids.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="../../NETServer/NETServer.csproj" />
+ <ProjectReference Include="../../../../Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="CoreShim.X.manifest">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+<assemblyIdentity
+ type="win32"
+ name="CoreShim.X"
+ version="1.0.0.0" />
+
+<file name="CoreShim.dll">
+ <!-- ConsumeNETServerTesting -->
+ <comClass
+ clsid="{DE4ACF53-5957-4D31-8BE2-EA6C80683246}"
+ threadingModel="Both" />
+</file>
+
+</assembly>
--- /dev/null
+// 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;
+ using System.Collections.Generic;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+
+ using TestLibrary;
+ using Server.Contract;
+
+ using CoClass = Server.Contract.Servers;
+
+ class Program
+ {
+ static void Validate_Activation()
+ {
+ Console.WriteLine($"{nameof(Validate_Activation)}...");
+
+ var test = new CoClass.ConsumeNETServerTesting();
+ test.ReleaseResources();
+
+ // The CoClass should be the activated type, _not_ the activation interface.
+ Assert.AreEqual(test.GetType(), typeof(CoClass.ConsumeNETServerTestingClass));
+ }
+
+ static void Validate_CCW_Wasnt_Unwrapped()
+ {
+ Console.WriteLine($"{nameof(Validate_CCW_Wasnt_Unwrapped)}...");
+
+ var test = new CoClass.ConsumeNETServerTesting();
+ test.ReleaseResources();
+
+ // The CoClass should be the activated type, _not_ the implementation class.
+ // This indicates the real implementation class is wrapped in its CCW and exposed
+ // to the runtime as an RCW.
+ Assert.AreNotEqual(test.GetType(), typeof(ConsumeNETServerTesting));
+ }
+
+ static void Validate_Client_CCW_RCW()
+ {
+ Console.WriteLine($"{nameof(Validate_Client_CCW_RCW)}...");
+
+ IntPtr ccw = IntPtr.Zero;
+
+ // Validate the client side view is consistent
+ var test = new CoClass.ConsumeNETServerTesting();
+ try
+ {
+ ccw = test.GetCCW();
+ object rcw = Marshal.GetObjectForIUnknown(ccw);
+ object inst = test.GetRCW();
+ Assert.AreEqual(rcw, inst);
+ }
+ finally
+ {
+ if (ccw != IntPtr.Zero)
+ {
+ Marshal.Release(ccw);
+ }
+
+ test.ReleaseResources();
+ }
+ }
+
+ static void Validate_Server_CCW_RCW()
+ {
+ Console.WriteLine($"{nameof(Validate_Server_CCW_RCW)}...");
+
+ // Validate the server side view is consistent
+ var test = new CoClass.ConsumeNETServerTesting();
+ try
+ {
+ Assert.IsTrue(test.EqualByCCW(test));
+ Assert.IsTrue(test.NotEqualByRCW(test));
+ }
+ finally
+ {
+ test.ReleaseResources();
+ }
+ }
+
+ static int Main(string[] doNotUse)
+ {
+ // RegFree COM is not supported on Windows Nano
+ if (Utilities.IsWindowsNanoServer)
+ {
+ return 100;
+ }
+
+ // Initialize CoreShim and hostpolicymock
+ HostPolicyMock.Initialize(Environment.CurrentDirectory, null);
+ Environment.SetEnvironmentVariable("CORESHIM_COMACT_ASSEMBLYNAME", "NETServer");
+ Environment.SetEnvironmentVariable("CORESHIM_COMACT_TYPENAME", "ConsumeNETServerTesting");
+
+ try
+ {
+ using (HostPolicyMock.Mock_corehost_resolve_component_dependencies(
+ 0,
+ string.Empty,
+ string.Empty,
+ string.Empty))
+ {
+ Validate_Activation();
+ Validate_CCW_Wasnt_Unwrapped();
+ Validate_Client_CCW_RCW();
+ Validate_Server_CCW_RCW();
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Test Failure: {e}");
+ return 101;
+ }
+
+ return 100;
+ }
+ }
+}
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
- <Compile Include="../../ServerContracts/NativeServers.cs" />
+ <Compile Include="../../ServerContracts/Server.CoClasses.cs" />
<Compile Include="../../ServerContracts/Server.Contracts.cs" />
<Compile Include="../../ServerContracts/Server.Events.cs" />
<Compile Include="../../ServerContracts/ServerGuids.cs" />
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
- <Compile Include="../../ServerContracts/NativeServers.cs" />
+ <Compile Include="../../ServerContracts/Server.CoClasses.cs" />
<Compile Include="../../ServerContracts/Server.Contracts.cs" />
<Compile Include="../../ServerContracts/ServerGuids.cs" />
</ItemGroup>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
- <Compile Include="../../ServerContracts/NativeServers.cs" />
+ <Compile Include="../../ServerContracts/Server.CoClasses.cs" />
<Compile Include="../../ServerContracts/Server.Contracts.cs" />
<Compile Include="../../ServerContracts/ServerGuids.cs" />
</ItemGroup>
<Compile Include="NumericTests.cs" />
<Compile Include="StringTests.cs" />
<Compile Include="ColorTests.cs" />
- <Compile Include="../../ServerContracts/NativeServers.cs" />
+ <Compile Include="../../ServerContracts/Server.CoClasses.cs" />
<Compile Include="../../ServerContracts/Server.Contracts.cs" />
<Compile Include="../../ServerContracts/ServerGuids.cs" />
</ItemGroup>
--- /dev/null
+// 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.Runtime.InteropServices;
+
+[ComVisible(true)]
+[Guid(Server.Contract.Guids.ConsumeNETServerTesting)]
+public class ConsumeNETServerTesting : Server.Contract.IConsumeNETServer
+{
+ private IntPtr _ccw;
+ private object _rcwUnwrapped;
+
+ public ConsumeNETServerTesting()
+ {
+ _ccw = Marshal.GetIUnknownForObject(this);
+ _rcwUnwrapped = Marshal.GetObjectForIUnknown(_ccw);
+ }
+
+ public IntPtr GetCCW()
+ {
+ return _ccw;
+ }
+
+ public object GetRCW()
+ {
+ return _rcwUnwrapped;
+ }
+
+ public void ReleaseResources()
+ {
+ Marshal.Release(_ccw);
+ _ccw = IntPtr.Zero;
+ _rcwUnwrapped = null;
+ }
+
+ public bool EqualByCCW(object obj)
+ {
+ IntPtr ccwMaybe = Marshal.GetIUnknownForObject(obj);
+ bool areEqual = ccwMaybe == _ccw;
+ Marshal.Release(ccwMaybe);
+
+ return areEqual;
+ }
+
+ public bool NotEqualByRCW(object obj)
+ {
+ return _rcwUnwrapped != obj;
+ }
+}
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
</PropertyGroup>
<ItemGroup>
- <Compile Include="ImportedTypes.cs" />
- <Compile Include="NumericTesting.cs" />
- <Compile Include="ArrayTesting.cs" />
- <Compile Include="StringTesting.cs" />
- <Compile Include="ErrorMarshalTesting.cs" />
- <Compile Include="ColorTesting.cs" />
- <Compile Include="LicenseTesting.cs" />
+ <Compile Include="*.cs" />
<Compile Include="../ServerContracts/Server.Contracts.cs" />
<Compile Include="../ServerContracts/ServerGuids.cs" />
</ItemGroup>
{
}
*/
+
+ /// <summary>
+ /// Managed definition of CoClass
+ /// </summary>
+ /// <remarks>
+ /// This interface is used to test consumption of the NET server from a NET client only.
+ /// </remarks>
+ [ComImport]
+ [CoClass(typeof(ConsumeNETServerTestingClass))]
+ [Guid("CCBC1915-3252-4F6B-98AA-411CE6213D94")]
+ internal interface ConsumeNETServerTesting : Server.Contract.IConsumeNETServer
+ {
+ }
+
+ /// <summary>
+ /// Managed activation for CoClass
+ /// </summary>
+ /// <remarks>
+ /// This interface is used to test consumption of the NET server from a NET client only.
+ /// </remarks>
+ [ComImport]
+ [Guid(Server.Contract.Guids.ConsumeNETServerTesting)]
+ internal class ConsumeNETServerTestingClass
+ {
+ }
}
#pragma warning restore 618 // Must test deprecated features
void SetNextLicense([MarshalAs(UnmanagedType.LPWStr)] string lic);
}
+
+ /// <remarks>
+ /// This interface is used to test consumption of the NET server from a NET client only.
+ /// </remarks>
+ [ComVisible(true)]
+ [Guid("CCBC1915-3252-4F6B-98AA-411CE6213D94")]
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IConsumeNETServer
+ {
+ IntPtr GetCCW();
+ object GetRCW();
+ void ReleaseResources();
+
+ bool EqualByCCW(object obj);
+ bool NotEqualByRCW(object obj);
+ }
}
#pragma warning restore 618 // Must test deprecated features
public const string ColorTesting = "C222F472-DA5A-4FC6-9321-92F4F7053A65";
public const string LicenseTesting = "66DB7882-E2B0-471D-92C7-B2B52A0EA535";
public const string DefaultInterfaceTesting = "FAEF42AE-C1A4-419F-A912-B768AC2679EA";
+ public const string ConsumeNETServerTesting = "DE4ACF53-5957-4D31-8BE2-EA6C80683246";
}
}