diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props
index 08fca8de6dd644..60e38832295192 100644
--- a/src/coreclr/clr.featuredefines.props
+++ b/src/coreclr/clr.featuredefines.props
@@ -21,6 +21,7 @@
true
true
true
+ true
diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake
index 5a9a161821c852..f82ff1aa4e73e9 100644
--- a/src/coreclr/clrfeatures.cmake
+++ b/src/coreclr/clrfeatures.cmake
@@ -32,7 +32,7 @@ if(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS)
set(FEATURE_SINGLE_FILE_DIAGNOSTICS 1)
endif(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS)
-if (CLR_CMAKE_TARGET_WIN32)
+if (CLR_CMAKE_TARGET_WIN32 OR CLR_CMAKE_TARGET_UNIX)
set(FEATURE_COMWRAPPERS 1)
endif()
diff --git a/src/coreclr/debug/daccess/dacimpl.h b/src/coreclr/debug/daccess/dacimpl.h
index 744ebaf7293ac4..62d99ec574929d 100644
--- a/src/coreclr/debug/daccess/dacimpl.h
+++ b/src/coreclr/debug/daccess/dacimpl.h
@@ -1323,7 +1323,7 @@ class ClrDataAccess
HRESULT DumpManagedObject(CLRDataEnumMemoryFlags flags, OBJECTREF objRef);
HRESULT DumpManagedExcepObject(CLRDataEnumMemoryFlags flags, OBJECTREF objRef);
HRESULT DumpManagedStackTraceStringObject(CLRDataEnumMemoryFlags flags, STRINGREF orefStackTrace);
-#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
+#if (defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)) && !defined(TARGET_UNIX)
HRESULT DumpStowedExceptionObject(CLRDataEnumMemoryFlags flags, CLRDATA_ADDRESS ccwPtr);
HRESULT EnumMemStowedException(CLRDataEnumMemoryFlags flags);
#endif
diff --git a/src/coreclr/debug/daccess/enummem.cpp b/src/coreclr/debug/daccess/enummem.cpp
index 2c7445bf99cf91..577fdcbc6b2e44 100644
--- a/src/coreclr/debug/daccess/enummem.cpp
+++ b/src/coreclr/debug/daccess/enummem.cpp
@@ -1065,7 +1065,7 @@ HRESULT ClrDataAccess::EnumMemDumpAllThreadsStack(CLRDataEnumMemoryFlags flags)
{
SUPPORTS_DAC;
-#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
+#if (defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)) && !defined(TARGET_UNIX)
// Dump the exception object stored in the WinRT stowed exception
EnumMemStowedException(flags);
#endif // defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
@@ -1298,7 +1298,7 @@ HRESULT ClrDataAccess::EnumMemDumpAllThreadsStack(CLRDataEnumMemoryFlags flags)
}
-#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
+#if (defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)) && !defined(TARGET_UNIX)
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// WinRT stowed exception holds the (CCW)pointer to a managed exception object.
@@ -1405,7 +1405,7 @@ HRESULT ClrDataAccess::EnumMemStowedException(CLRDataEnumMemoryFlags flags)
ReportMem(remoteStowedException, sizeof(STOWED_EXCEPTION_INFORMATION_HEADER));
// check if this is a v2 stowed exception
- STOWED_EXCEPTION_INFORMATION_V2 stowedException = { 0 };
+ STOWED_EXCEPTION_INFORMATION_V2 stowedException = { {0} };
if (FAILED(m_pTarget->ReadVirtual(TO_CDADDR(remoteStowedException),
(PBYTE)&stowedException, sizeof(STOWED_EXCEPTION_INFORMATION_HEADER), &bytesRead))
|| bytesRead != sizeof(STOWED_EXCEPTION_INFORMATION_HEADER)
diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc
index 0b4247c17e637a..e8955bf5e1626e 100644
--- a/src/coreclr/dlls/mscorrc/mscorrc.rc
+++ b/src/coreclr/dlls/mscorrc/mscorrc.rc
@@ -317,9 +317,9 @@ BEGIN
IDS_EE_INTEROP_STUB_CA_NO_ACCESS_TO_STUB_METHOD "The interop method '%1' cannot access the stub method '%2' specified in ManagedToNativeComInteropStubAttribute. Please make sure they have compatible access modifiers and security accessibility."
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
IDS_EE_NATIVE_COM_WEAKREF_BAD_TYPE "The object resolved by a native IWeakReference has an incompatible type for its managed WeakReference instance.\r\nExpected WeakReference target type: '%1'\r\nNative IWeakReference returned type: '%2'"
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
IDS_EE_INTEROP_CODE_SIZE_COMMENT "Code size"
diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h
index 8038665a0b8d40..0e39c27f0c88cf 100644
--- a/src/coreclr/dlls/mscorrc/resource.h
+++ b/src/coreclr/dlls/mscorrc/resource.h
@@ -569,9 +569,9 @@
#define IDS_E_PROF_TIMEOUT_WAITING_FOR_CONCURRENT_GC 0x251D
#define IDS_EE_CANNOTCAST_NOMARSHAL 0x2629
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
#define IDS_EE_NATIVE_COM_WEAKREF_BAD_TYPE 0x262e
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
#define IDS_HOST_ASSEMBLY_RESOLVER_ASSEMBLY_ALREADY_LOADED_IN_CONTEXT 0x2636
#define IDS_HOST_ASSEMBLY_RESOLVER_DYNAMICALLY_EMITTED_ASSEMBLIES_UNSUPPORTED 0x2637
diff --git a/src/coreclr/gc/objecthandle.cpp b/src/coreclr/gc/objecthandle.cpp
index 1485f56e9ff2a9..7b406a959df91f 100644
--- a/src/coreclr/gc/objecthandle.cpp
+++ b/src/coreclr/gc/objecthandle.cpp
@@ -1379,9 +1379,9 @@ void Ref_CheckAlive(uint32_t condemned, uint32_t maxgen, uintptr_t lp1)
uint32_t types[] =
{
HNDTYPE_WEAK_SHORT
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
, HNDTYPE_WEAK_NATIVE_COM
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
};
uint32_t flags = (((ScanContext*) lp1)->concurrent) ? HNDGCF_ASYNC : HNDGCF_NORMAL;
diff --git a/src/coreclr/interop/comwrappers.cpp b/src/coreclr/interop/comwrappers.cpp
index 90c366cead4b9b..a4afa67f96abed 100644
--- a/src/coreclr/interop/comwrappers.cpp
+++ b/src/coreclr/interop/comwrappers.cpp
@@ -5,7 +5,10 @@
#include
#include
+#ifdef _WIN32
#include // placement new
+#endif // _WIN32
+
using OBJECTHANDLE = InteropLib::OBJECTHANDLE;
using AllocScenario = InteropLibImports::AllocScenario;
@@ -344,9 +347,9 @@ void ManagedObjectWrapper::GetIUnknownImpl(
&& fpAddRef != nullptr
&& fpRelease != nullptr);
- *fpQueryInterface = ManagedObjectWrapper_IUnknownImpl.QueryInterface;
- *fpAddRef = ManagedObjectWrapper_IUnknownImpl.AddRef;
- *fpRelease = ManagedObjectWrapper_IUnknownImpl.Release;
+ *fpQueryInterface = (void*)ManagedObjectWrapper_IUnknownImpl.QueryInterface;
+ *fpAddRef = (void*)ManagedObjectWrapper_IUnknownImpl.AddRef;
+ *fpRelease = (void*)ManagedObjectWrapper_IUnknownImpl.Release;
}
// The logic here should match code:ClrDataAccess::DACTryGetComWrappersObjectFromCCW in daccess/request.cpp
@@ -393,11 +396,11 @@ HRESULT ManagedObjectWrapper::Create(
if ((flags & CreateComInterfaceFlagsEx::TrackerSupport) == CreateComInterfaceFlagsEx::TrackerSupport)
{
ABI::ComInterfaceEntry& curr = runtimeDefinedLocal[runtimeDefinedCount++];
- curr.IID = __uuidof(IReferenceTrackerTarget);
+ curr.IID = IID_IReferenceTrackerTarget;
curr.Vtable = &ManagedObjectWrapper_IReferenceTrackerTargetImpl;
}
-
- _ASSERTE(runtimeDefinedCount <= ARRAYSIZE(runtimeDefinedLocal));
+
+ _ASSERTE(runtimeDefinedCount <= (int) ARRAYSIZE(runtimeDefinedLocal));
// Compute size for ManagedObjectWrapper instance.
const size_t totalRuntimeDefinedSize = runtimeDefinedCount * sizeof(ABI::ComInterfaceEntry);
@@ -465,7 +468,7 @@ void ManagedObjectWrapper::Destroy(_In_ ManagedObjectWrapper* wrapper)
{
prev = wrapper->_refCount;
refCount = prev | DestroySentinel;
- } while (::InterlockedCompareExchange64(&wrapper->_refCount, refCount, prev) != prev);
+ } while (InterlockedCompareExchange64(&wrapper->_refCount, refCount, prev) != prev);
// The destroy sentinel represents the bit that indicates the wrapper
// should be destroyed. Since the reference count field (64-bit) holds
@@ -547,7 +550,7 @@ void* ManagedObjectWrapper::As(_In_ REFIID riid)
bool ManagedObjectWrapper::TrySetObjectHandle(_In_ OBJECTHANDLE objectHandle, _In_ OBJECTHANDLE current)
{
- return (::InterlockedCompareExchangePointer(&Target, objectHandle, current) == current);
+ return (InterlockedCompareExchangePointer(&Target, objectHandle, current) == current);
}
bool ManagedObjectWrapper::IsSet(_In_ CreateComInterfaceFlagsEx flag) const
@@ -666,6 +669,7 @@ HRESULT ManagedObjectWrapper::QueryInterface(
default:
_ASSERTE(false && "Unknown result value");
+ FALLTHROUGH;
case TryInvokeICustomQueryInterfaceResult::FailedToInvoke:
// Set the 'lacks' flag since our attempt to use ICustomQueryInterface
// indicated the object lacks an implementation.
@@ -744,7 +748,7 @@ HRESULT NativeObjectWrapperContext::Create(
ComHolder trackerObject;
if (flags & InteropLib::Com::CreateObjectFlags_TrackerObject)
{
- hr = external->QueryInterface(&trackerObject);
+ hr = external->QueryInterface(IID_IReferenceTracker, (void**)&trackerObject);
if (SUCCEEDED(hr))
RETURN_IF_FAILED(TrackerObjectManager::OnIReferenceTrackerFound(trackerObject));
}
diff --git a/src/coreclr/interop/comwrappers.hpp b/src/coreclr/interop/comwrappers.hpp
index 31b26e0ea343f2..bd383beabc5dce 100644
--- a/src/coreclr/interop/comwrappers.hpp
+++ b/src/coreclr/interop/comwrappers.hpp
@@ -9,6 +9,19 @@
#include
#include "referencetrackertypes.hpp"
+#ifndef DEFINE_ENUM_FLAG_OPERATORS
+#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) \
+extern "C++" { \
+ inline ENUMTYPE operator | (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a)|((int)b)); } \
+ inline ENUMTYPE operator |= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) |= ((int)b)); } \
+ inline ENUMTYPE operator & (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a)&((int)b)); } \
+ inline ENUMTYPE operator &= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) &= ((int)b)); } \
+ inline ENUMTYPE operator ~ (ENUMTYPE a) { return (ENUMTYPE)(~((int)a)); } \
+ inline ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a)^((int)b)); } \
+ inline ENUMTYPE operator ^= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) ^= ((int)b)); } \
+}
+#endif
+
enum class CreateComInterfaceFlagsEx : int32_t
{
None = InteropLib::Com::CreateComInterfaceFlags_None,
@@ -32,6 +45,8 @@ namespace ABI
struct ComInterfaceEntry;
}
+static constexpr size_t ManagedObjectWrapperRefCountOffset();
+
// Class for wrapping a managed object and projecting it in a non-managed environment
class ManagedObjectWrapper
{
@@ -159,7 +174,7 @@ class NativeObjectWrapperContext
static NativeObjectWrapperContext* MapFromRuntimeContext(_In_ void* cxt);
// Create a NativeObjectWrapperContext instance
- static HRESULT NativeObjectWrapperContext::Create(
+ static HRESULT Create(
_In_ IUnknown* external,
_In_opt_ IUnknown* nativeObjectAsInner,
_In_ InteropLib::Com::CreateObjectFlags flags,
diff --git a/src/coreclr/interop/interoplib.cpp b/src/coreclr/interop/interoplib.cpp
index 70063e16d51f2a..7af7af9e7adcf1 100644
--- a/src/coreclr/interop/interoplib.cpp
+++ b/src/coreclr/interop/interoplib.cpp
@@ -123,7 +123,7 @@ namespace InteropLib
// interface QI. Once we have the IReferenceTracker
// instance we can be sure the QI for IUnknown will really
// be the true identity.
- HRESULT hr = external->QueryInterface(&trackerObject);
+ HRESULT hr = external->QueryInterface(IID_IReferenceTracker, (void**)&trackerObject);
if (SUCCEEDED(hr))
checkForIdentity = trackerObject.p;
}
@@ -131,7 +131,7 @@ namespace InteropLib
HRESULT hr;
IUnknown* identityLocal;
- RETURN_IF_FAILED(checkForIdentity->QueryInterface(&identityLocal));
+ RETURN_IF_FAILED(checkForIdentity->QueryInterface(IID_IUnknown, (void **)&identityLocal));
// Set the inner if scenario dictates an update.
if (*innerMaybe == nullptr // User didn't supply inner - .NET 5 API scenario sanity check.
diff --git a/src/coreclr/interop/platform.h b/src/coreclr/interop/platform.h
index a201540ab20a61..351b5ebf6ec486 100644
--- a/src/coreclr/interop/platform.h
+++ b/src/coreclr/interop/platform.h
@@ -14,13 +14,19 @@
#ifdef _WIN32
#include
+#endif // _WIN32
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
+#endif // !ARRAYSIZE
+
+#if defined(_WIN32) || defined(HOST_UNIX)
#include // COM interfaces
// Common macro for working in COM
#define RETURN_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { _ASSERTE(false && #exp); return hr; } }
#define RETURN_VOID_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { _ASSERTE(false && #exp); return; } }
-
-#endif // _WIN32
+#endif // defined(_WIN32) || defined(HOST_UNIX)
#define ABI_ASSERT(abi_definition) static_assert((abi_definition), "ABI is being invalidated.")
diff --git a/src/coreclr/interop/referencetrackertypes.hpp b/src/coreclr/interop/referencetrackertypes.hpp
index a5887df802dc26..6e703a936413cd 100644
--- a/src/coreclr/interop/referencetrackertypes.hpp
+++ b/src/coreclr/interop/referencetrackertypes.hpp
@@ -8,6 +8,9 @@
// Documentation found at https://docs.microsoft.com/windows/win32/api/windows.ui.xaml.hosting.referencetracker/
+//64bd43f8-bfee-4ec4-b7eb-2935158dae21
+const GUID IID_IReferenceTrackerTarget = { 0x64bd43f8, 0xbfee, 0x4ec4, { 0xb7, 0xeb, 0x29, 0x35, 0x15, 0x8d, 0xae, 0x21} };
+
class DECLSPEC_UUID("64bd43f8-bfee-4ec4-b7eb-2935158dae21") IReferenceTrackerTarget : public IUnknown
{
public:
@@ -43,6 +46,9 @@ class DECLSPEC_UUID("04b3486c-4687-4229-8d14-505ab584dd88") IFindReferenceTarget
STDMETHOD(FoundTrackerTarget)(_In_ IReferenceTrackerTarget* target) = 0;
};
+//11d3b13a-180e-4789-a8be-7712882893e6
+const GUID IID_IReferenceTracker = { 0x11d3b13a, 0x180e, 0x4789, { 0xa8, 0xbe, 0x77, 0x12, 0x88, 0x28, 0x93, 0xe6} };
+
class DECLSPEC_UUID("11d3b13a-180e-4789-a8be-7712882893e6") IReferenceTracker : public IUnknown
{
public:
diff --git a/src/coreclr/interop/trackerobjectmanager.cpp b/src/coreclr/interop/trackerobjectmanager.cpp
index ff5fcdb05c9425..6f4bebc8b57e1a 100644
--- a/src/coreclr/interop/trackerobjectmanager.cpp
+++ b/src/coreclr/interop/trackerobjectmanager.cpp
@@ -9,11 +9,15 @@ using RuntimeCallContext = InteropLibImports::RuntimeCallContext;
namespace
{
- const IID IID_IReferenceTrackerHost = __uuidof(IReferenceTrackerHost);
- const IID IID_IReferenceTrackerTarget = __uuidof(IReferenceTrackerTarget);
- const IID IID_IReferenceTracker = __uuidof(IReferenceTracker);
- const IID IID_IReferenceTrackerManager = __uuidof(IReferenceTrackerManager);
- const IID IID_IFindReferenceTargetsCallback = __uuidof(IFindReferenceTargetsCallback);
+
+ //29a71c6a-3c42-4416-a39d-e2825a07a773
+ const GUID IID_IReferenceTrackerHost = { 0x29a71c6a, 0x3c42, 0x4416, { 0xa3, 0x9d, 0xe2, 0x82, 0x5a, 0x7, 0xa7, 0x73} };
+
+ //3cf184b4-7ccb-4dda-8455-7e6ce99a3298
+ const GUID IID_IReferenceTrackerManager = { 0x3cf184b4, 0x7ccb, 0x4dda, { 0x84, 0x55, 0x7e, 0x6c, 0xe9, 0x9a, 0x32, 0x98} };
+
+ //04b3486c-4687-4229-8d14-505ab584dd88
+ const GUID IID_IFindReferenceTargetsCallback = { 0x04b3486c, 0x4687, 0x4229, { 0x8d, 0x14, 0x50, 0x5a, 0xb5, 0x84, 0xdd, 0x88} };
// In order to minimize the impact of a constructor running on module load,
// the HostServices class should have no instance fields.
@@ -120,7 +124,7 @@ namespace
// QI for IUnknown to get the identity unknown
ComHolder identity;
- RETURN_IF_FAILED(obj->QueryInterface(&identity));
+ RETURN_IF_FAILED(obj->QueryInterface(IID_IUnknown, (void**)&identity));
// Get or create an existing implementation for this external.
ComHolder target;
@@ -274,7 +278,7 @@ HRESULT TrackerObjectManager::OnIReferenceTrackerFound(_In_ IReferenceTracker* o
RETURN_IF_FAILED(g_HostServicesInstance.QueryInterface(IID_IReferenceTrackerHost, (void**)&hostServices));
// Attempt to set the tracker instance.
- if (::InterlockedCompareExchangePointer((void**)&s_TrackerManager, trackerManager.p, nullptr) == nullptr)
+ if (InterlockedCompareExchangePointer((void**)&s_TrackerManager, trackerManager.p, nullptr) == nullptr)
{
(void)trackerManager.Detach(); // Ownership has been transfered
RETURN_IF_FAILED(s_TrackerManager->SetReferenceTrackerHost(hostServices));
diff --git a/src/coreclr/pal/inc/rt/weakreference.h b/src/coreclr/pal/inc/rt/weakreference.h
new file mode 100644
index 00000000000000..d0b88d62e6c156
--- /dev/null
+++ b/src/coreclr/pal/inc/rt/weakreference.h
@@ -0,0 +1,85 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+
+//
+// ===========================================================================
+// File: weakreference.h
+//
+// ===========================================================================
+// simplified weakreference.h for PAL
+
+#include "rpc.h"
+#include "rpcndr.h"
+
+#include "unknwn.h"
+
+#ifndef __IInspectable_INTERFACE_DEFINED__
+#define __IInspectable_INTERFACE_DEFINED__
+
+typedef struct HSTRING__{
+ int unused;
+} HSTRING__;
+
+typedef HSTRING__* HSTRING;
+
+typedef /* [v1_enum] */
+enum TrustLevel
+ {
+ BaseTrust = 0,
+ PartialTrust = ( BaseTrust + 1 ) ,
+ FullTrust = ( PartialTrust + 1 )
+ } TrustLevel;
+
+// AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90
+const IID IID_IInspectable = { 0xaf86e2e0, 0xb12d, 0x4c6a, { 0x9c, 0x5a, 0xd7, 0xaa, 0x65, 0x10, 0x1e, 0x90} };
+
+MIDL_INTERFACE("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")
+IInspectable : public IUnknown
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE GetIids(
+ /* [out] */ ULONG * iidCount,
+ /* [size_is][size_is][out] */ IID * *iids) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetRuntimeClassName(
+ /* [out] */ HSTRING * className) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(
+ /* [out] */ TrustLevel * trustLevel) = 0;
+};
+#endif // __IInspectable_INTERFACE_DEFINED__
+
+#ifndef __IWeakReference_INTERFACE_DEFINED__
+#define __IWeakReference_INTERFACE_DEFINED__
+
+// 00000037-0000-0000-C000-000000000046
+const IID IID_IWeakReference = { 0x00000037, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
+
+MIDL_INTERFACE("00000037-0000-0000-C000-000000000046")
+IWeakReference : public IUnknown
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE Resolve(
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ IInspectable **objectReference) = 0;
+
+};
+
+#endif // __IWeakReference_INTERFACE_DEFINED__
+
+#ifndef __IWeakReferenceSource_INTERFACE_DEFINED__
+#define __IWeakReferenceSource_INTERFACE_DEFINED__
+
+// 00000038-0000-0000-C000-000000000046
+const IID IID_IWeakReferenceSource = { 0x00000038, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
+
+MIDL_INTERFACE("00000038-0000-0000-C000-000000000046")
+IWeakReferenceSource : public IUnknown
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE GetWeakReference(
+ /* [retval][out] */ IWeakReference * *weakReference) = 0;
+};
+
+#endif // __IWeakReferenceSource_INTERFACE_DEFINED__
diff --git a/src/coreclr/vm/appdomain.hpp b/src/coreclr/vm/appdomain.hpp
index 0487299c5f26c9..fb2e45682fc685 100644
--- a/src/coreclr/vm/appdomain.hpp
+++ b/src/coreclr/vm/appdomain.hpp
@@ -1075,7 +1075,7 @@ class BaseDomain
return h;
}
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
OBJECTHANDLE CreateRefcountedHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
@@ -1087,7 +1087,7 @@ class BaseDomain
WRAPPER_NO_CONTRACT;
return ::CreateNativeComWeakHandle(m_handleStore, object, pComWeakHandleInfo);
}
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
OBJECTHANDLE CreateVariableHandle(OBJECTREF object, UINT type)
{
diff --git a/src/coreclr/vm/gcenv.ee.cpp b/src/coreclr/vm/gcenv.ee.cpp
index 82d4ccbd308cbb..f963146ffb6163 100644
--- a/src/coreclr/vm/gcenv.ee.cpp
+++ b/src/coreclr/vm/gcenv.ee.cpp
@@ -354,9 +354,6 @@ bool GCToEEInterface::RefCountedHandleCallbacks(Object * pObject)
bool isReferenced = false;
if (ObjCMarshalNative::IsTrackedReference((OBJECTREF)pObject, &isReferenced))
return isReferenced;
-#endif
-#if (defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)) && defined(FEATURE_OBJCMARSHAL)
-#error COM and Objective-C are not supported at the same time.
#endif
return false;
diff --git a/src/coreclr/vm/gchandleutilities.h b/src/coreclr/vm/gchandleutilities.h
index f6f7991f724809..611316c887f21c 100644
--- a/src/coreclr/vm/gchandleutilities.h
+++ b/src/coreclr/vm/gchandleutilities.h
@@ -6,7 +6,7 @@
#include "gcinterface.h"
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
#include
#endif
@@ -199,7 +199,7 @@ inline OBJECTHANDLE CreateGlobalRefcountedHandle(OBJECTREF object)
// Special handle creation convenience functions
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
struct NativeComWeakHandleInfo
{
@@ -218,7 +218,7 @@ inline OBJECTHANDLE CreateNativeComWeakHandle(IGCHandleStore* store, OBJECTREF o
DiagHandleCreated(hnd, object);
return hnd;
}
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
// Creates a variable-strength handle
inline OBJECTHANDLE CreateVariableHandle(IGCHandleStore* store, OBJECTREF object, uint32_t type)
@@ -368,7 +368,7 @@ inline void DestroyTypedHandle(OBJECTHANDLE handle)
GCHandleUtilities::GetGCHandleManager()->DestroyHandleOfUnknownType(handle);
}
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
inline void DestroyNativeComWeakHandle(OBJECTHANDLE handle)
{
CONTRACTL
@@ -395,7 +395,7 @@ inline void DestroyNativeComWeakHandle(OBJECTHANDLE handle)
DiagHandleDestroyed(handle);
GCHandleUtilities::GetGCHandleManager()->DestroyHandleOfType(handle, HNDTYPE_WEAK_NATIVE_COM);
}
-#endif
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
// Handle holders/wrappers
diff --git a/src/coreclr/vm/interoplibinterface.cpp b/src/coreclr/vm/interoplibinterface.cpp
index b027d6b9d4bbdc..1b46b0de1b2208 100644
--- a/src/coreclr/vm/interoplibinterface.cpp
+++ b/src/coreclr/vm/interoplibinterface.cpp
@@ -6,7 +6,9 @@
// Runtime headers
#include "common.h"
#include "rcwrefcache.h"
+#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
#include "olecontexthelpers.h"
+#endif
#include "finalizerthread.h"
// Interop library header
@@ -17,8 +19,22 @@
using CreateObjectFlags = InteropLib::Com::CreateObjectFlags;
using CreateComInterfaceFlags = InteropLib::Com::CreateComInterfaceFlags;
+
namespace
{
+
+ void* GetCurrentCtxCookieWrapper()
+ {
+ STATIC_CONTRACT_WRAPPER;
+
+ #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ return GetCurrentCtxCookie();
+ #else
+ return NULL;
+ #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
+
+ }
+
// This class is used to track the external object within the runtime.
struct ExternalObjectContext : public InteropLibInterface::ExternalObjectContextBase
{
@@ -837,7 +853,7 @@ namespace
ExternalObjectContext::Construct(
resultHolder.GetContext(),
identity,
- GetCurrentCtxCookie(),
+ GetCurrentCtxCookieWrapper(),
gc.objRefMaybe->GetSyncBlockIndex(),
wrapperId,
eocFlags);
@@ -1056,7 +1072,7 @@ namespace InteropLibImports
ExtObjCxtCache* cache = ExtObjCxtCache::GetInstanceNoThrow();
gc.objsEnumRef = cache->CreateManagedEnumerable(
ExternalObjectContext::Flags_ReferenceTracker,
- GetCurrentCtxCookie());
+ GetCurrentCtxCookieWrapper());
CallReleaseObjects(&gc.implRef, &gc.objsEnumRef);
diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp
index 2b6697887aa97e..80f49e9e395f61 100644
--- a/src/coreclr/vm/interoputil.cpp
+++ b/src/coreclr/vm/interoputil.cpp
@@ -1229,8 +1229,7 @@ HRESULT SafeQueryInterfacePreemp(IUnknown* pUnk, REFIID riid, IUnknown** pResUnk
}
#include
-#ifdef FEATURE_COMINTEROP
-
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
#ifndef CROSSGEN_COMPILE
//--------------------------------------------------------------------------------
@@ -1247,11 +1246,13 @@ void MinorCleanupSyncBlockComData(InteropSyncBlockInfo* pInteropInfo)
}
CONTRACTL_END;
+#ifdef FEATURE_COMINTEROP
// No need to notify the thread that the RCW is in use here.
// This is a privileged function called during GC or shutdown.
RCW* pRCW = pInteropInfo->GetRawRCW();
if (pRCW)
pRCW->MinorCleanup();
+#endif // FEATURE_COMINTEROP
#ifdef FEATURE_COMWRAPPERS
void* eoc;
@@ -1282,6 +1283,7 @@ void CleanupSyncBlockComData(InteropSyncBlockInfo* pInteropInfo)
}
#endif // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
+#ifdef FEATURE_COMINTEROP
// No need to notify the thread that the RCW is in use here.
// This is only called during finalization of a __ComObject so no one
// else could have a reference to this object.
@@ -1298,6 +1300,7 @@ void CleanupSyncBlockComData(InteropSyncBlockInfo* pInteropInfo)
pInteropInfo->SetCCW(NULL);
pCCW->Cleanup();
}
+#endif // FEATURE_COMINTEROP
#ifdef FEATURE_COMWRAPPERS
pInteropInfo->ClearManagedObjectComWrappers(&ComWrappersNative::DestroyManagedObjectComWrapper);
@@ -1311,6 +1314,12 @@ void CleanupSyncBlockComData(InteropSyncBlockInfo* pInteropInfo)
#endif // FEATURE_COMWRAPPERS
}
+#endif // !CROSSGEN_COMPILE
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
+
+#ifdef FEATURE_COMINTEROP
+#ifndef CROSSGEN_COMPILE
+
//--------------------------------------------------------------------------------
// Helper to release all of the RCWs in the specified context across all caches.
// If pCtxCookie is NULL, release all RCWs
diff --git a/src/coreclr/vm/interoputil.h b/src/coreclr/vm/interoputil.h
index b99764688dd535..f9706d88079983 100644
--- a/src/coreclr/vm/interoputil.h
+++ b/src/coreclr/vm/interoputil.h
@@ -168,15 +168,24 @@ HRESULT LoadRegTypeLib(_In_ REFGUID guid,
// Called from EEStartup, to initialize com Interop specific data structures.
void InitializeComInterop();
+#endif // FEATURE_COMINTEROP
+
//--------------------------------------------------------------------------------
// Clean up Helpers
//--------------------------------------------------------------------------------
+
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
+
// called by syncblock, on the finalizer thread to do major cleanup
void CleanupSyncBlockComData(InteropSyncBlockInfo* pInteropInfo);
// called by syncblock, during GC, do only minimal work
void MinorCleanupSyncBlockComData(InteropSyncBlockInfo* pInteropInfo);
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS)
+
+#ifdef FEATURE_COMINTEROP
+
// A wrapper that catches all exceptions - used in the OnThreadTerminate case.
void ReleaseRCWsInCachesNoThrow(LPVOID pCtxCookie);
diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp
index a86cd61a8993cd..1a2c9358bf1baa 100644
--- a/src/coreclr/vm/syncblk.cpp
+++ b/src/coreclr/vm/syncblk.cpp
@@ -712,14 +712,14 @@ void SyncBlockCache::InsertCleanupSyncBlock(SyncBlock* psb)
continue;
}
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
if (psb->m_pInteropInfo)
{
// called during GC
// so do only minorcleanup
MinorCleanupSyncBlockComData(psb->m_pInteropInfo);
}
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
// This method will be called only by the GC thread
//@todo add an assert for the above statement
@@ -974,9 +974,9 @@ void SyncBlockCache::DeleteSyncBlock(SyncBlock *psb)
// clean up comdata
if (psb->m_pInteropInfo)
{
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
CleanupSyncBlockComData(psb->m_pInteropInfo);
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
#ifndef TARGET_UNIX
if (g_fEEShutDown)
diff --git a/src/coreclr/vm/weakreferencenative.cpp b/src/coreclr/vm/weakreferencenative.cpp
index 4d56975daa065d..1354f35582fdb5 100644
--- a/src/coreclr/vm/weakreferencenative.cpp
+++ b/src/coreclr/vm/weakreferencenative.cpp
@@ -100,7 +100,7 @@ struct WeakHandleSpinLockHolder
WeakHandleSpinLockHolder& operator=(const WeakHandleSpinLockHolder& other);
};
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
// Get the native COM information for the object underlying an RCW if applicable. If the incoming object cannot
// use a native COM weak reference, nullptr is returned. Otherwise, a new NativeComWeakHandleInfo containing an
@@ -139,17 +139,20 @@ NativeComWeakHandleInfo* GetComWeakReferenceInfo(OBJECTREF* pObject)
// If the object is a managed type deriving from a COM type, then we also do not want to use a native COM
// weak reference to it. (Otherwise, we'll wind up resolving IWeakReference-s back into the CLR
// when we don't want to have reentrancy).
+#ifdef FEATURE_COMINTEROP
if (pMT->IsComObjectType()
&& (pMT == g_pBaseCOMObject || !pMT->IsExtensibleRCW()))
{
pWeakReferenceSource = reinterpret_cast(GetComIPFromObjectRef(pObject, IID_IWeakReferenceSource, false /* throwIfNoComIP */));
}
-#ifdef FEATURE_COMWRAPPERS
else
+#endif
{
+#ifdef FEATURE_COMWRAPPERS
pWeakReferenceSource = reinterpret_cast(ComWrappersNative::GetIdentityForObject(pObject, IID_IWeakReferenceSource, &wrapperId));
+#endif
}
-#endif
+
if (pWeakReferenceSource == nullptr)
{
@@ -285,11 +288,13 @@ NOINLINE Object* LoadComWeakReferenceTarget(WEAKREFERENCEREF weakReference, Type
(void)GlobalComWrappersForMarshalling::TryGetOrCreateObjectForComInstance(pTargetIdentity, ObjFromComIP::NONE, &gc.rcw);
}
}
+#ifdef FEATURE_COMINTEROP
else
{
// If the original RCW was not created through ComWrappers, fall back to the built-in system.
GetObjectRefFromComIP(&gc.rcw, pTargetIdentity);
}
+#endif // FEATURE_COMINTEROP
}
// If we were able to get an RCW, then we need to reacquire the spin lock and store the RCW in the handle. Note that
@@ -336,7 +341,7 @@ NOINLINE Object* LoadComWeakReferenceTarget(WEAKREFERENCEREF weakReference, Type
return OBJECTREFToObject(gc.target);
}
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
//************************************************************************
@@ -444,7 +449,7 @@ FCIMPL3(void, WeakReferenceNative::Create, WeakReferenceObject * pThisUNSAFE, Ob
_ASSERTE(gc.pThis->GetMethodTable()->CanCastToClass(pWeakReferenceMT));
// Create the handle.
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
NativeComWeakHandleInfo *comWeakHandleInfo = nullptr;
if (gc.pTarget != NULL)
{
@@ -462,7 +467,7 @@ FCIMPL3(void, WeakReferenceNative::Create, WeakReferenceObject * pThisUNSAFE, Ob
infoHolder.SuppressRelease();
}
else
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
{
gc.pThis->m_Handle = GetAppDomain()->CreateTypedHandle(gc.pTarget,
trackResurrection ? HNDTYPE_WEAK_LONG : HNDTYPE_WEAK_SHORT);
@@ -495,7 +500,7 @@ FCIMPL3(void, WeakReferenceOfTNative::Create, WeakReferenceObject * pThisUNSAFE,
_ASSERTE(gc.pThis->GetMethodTable()->GetCanonicalMethodTable() == pWeakReferenceOfTCanonMT);
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
NativeComWeakHandleInfo *comWeakHandleInfo = nullptr;
if (gc.pTarget != NULL)
{
@@ -513,7 +518,7 @@ FCIMPL3(void, WeakReferenceOfTNative::Create, WeakReferenceObject * pThisUNSAFE,
infoHolder.SuppressRelease();
}
else
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
{
gc.pThis->m_Handle = GetAppDomain()->CreateTypedHandle(gc.pTarget,
trackResurrection ? HNDTYPE_WEAK_LONG : HNDTYPE_WEAK_SHORT);
@@ -550,12 +555,12 @@ void FinalizeWeakReference(Object * obj)
// Cache the old handle value
HandleType handleType = GCHandleUtilities::GetGCHandleManager()->HandleFetchType(handleToDestroy);
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
_ASSERTE(handleType == HNDTYPE_WEAK_LONG || handleType == HNDTYPE_WEAK_SHORT || handleType == HNDTYPE_WEAK_NATIVE_COM);
isWeakNativeComHandle = handleType == HNDTYPE_WEAK_NATIVE_COM;
-#else // !FEATURE_COMINTEROP
+#else // !FEATURE_COMINTEROP && !FEATURE_COMWRAPPERS
_ASSERTE(handleType == HNDTYPE_WEAK_LONG || handleType == HNDTYPE_WEAK_SHORT);
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
handle = (handleType == HNDTYPE_WEAK_LONG) ?
SPECIAL_HANDLE_FINALIZED_LONG : SPECIAL_HANDLE_FINALIZED_SHORT;
@@ -569,13 +574,13 @@ void FinalizeWeakReference(Object * obj)
if (handleToDestroy != NULL)
{
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
if (isWeakNativeComHandle)
{
DestroyNativeComWeakHandle(handleToDestroy);
}
else
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
{
DestroyTypedHandle(handleToDestroy);
}
@@ -686,7 +691,7 @@ FCIMPL1(Object *, WeakReferenceNative::GetTarget, WeakReferenceObject * pThisUNS
OBJECTREF pTarget = GetWeakReferenceTarget(pThis);
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
// If we found an object, or we're not a native COM weak reference, then we're done. Othewrise
// we can try to create a new RCW to the underlying native COM object if it's still alive.
if (pTarget != NULL || !IsNativeComWeakReferenceHandle(pThis->m_Handle))
@@ -695,9 +700,9 @@ FCIMPL1(Object *, WeakReferenceNative::GetTarget, WeakReferenceObject * pThisUNS
}
FC_INNER_RETURN(Object*, LoadComWeakReferenceTarget(pThis, g_pObjectClass, GetEEFuncEntryPointMacro(WeakReferenceNative::GetTarget)));
-#else // !FEATURE_COMINTEROP
+#else // !FEATURE_COMINTEROP && !FEATURE_COMWRAPPERS
FC_GC_POLL_AND_RETURN_OBJREF(pTarget);
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
}
FCIMPLEND
@@ -714,7 +719,7 @@ FCIMPL1(Object *, WeakReferenceOfTNative::GetTarget, WeakReferenceObject * pThis
OBJECTREF pTarget = GetWeakReferenceTarget(pThis);
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
// If we found an object, or we're not a native COM weak reference, then we're done. Othewrise
// we can try to create a new RCW to the underlying native COM object if it's still alive.
if (pTarget != NULL || !IsNativeComWeakReferenceHandle(pThis->m_Handle))
@@ -723,9 +728,9 @@ FCIMPL1(Object *, WeakReferenceOfTNative::GetTarget, WeakReferenceObject * pThis
}
FC_INNER_RETURN(Object*, LoadComWeakReferenceTarget(pThis, pThis->GetMethodTable()->GetInstantiation()[0], GetEEFuncEntryPointMacro(WeakReferenceOfTNative::GetTarget)));
-#else // !FEATURE_COMINTEROP
+#else // !FEATURE_COMINTEROP && !FEATURE_COMWRAPPERS
FC_GC_POLL_AND_RETURN_OBJREF(pTarget);
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
}
FCIMPLEND
@@ -762,15 +767,15 @@ NOINLINE void SetWeakReferenceTarget(WEAKREFERENCEREF weakReference, OBJECTREF t
FC_INNER_PROLOG_NO_ME_SETUP();
HELPER_METHOD_FRAME_BEGIN_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, target, weakReference);
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
NewHolder comWeakHandleInfo(GetComWeakReferenceInfo(&target));
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
WeakHandleSpinLockHolder handle(AcquireWeakHandleSpinLock(weakReference), &weakReference);
GCX_NOTRIGGER();
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
//
// We have four combinations to handle here
//
@@ -825,14 +830,14 @@ NOINLINE void SetWeakReferenceTarget(WEAKREFERENCEREF weakReference, OBJECTREF t
DestroyTypedHandle(previousHandle);
}
else
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
{
StoreObjectInHandle(handle.Handle, target);
}
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
comWeakHandleInfo.SuppressRelease();
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
HELPER_METHOD_FRAME_END();
FC_INNER_EPILOG();
diff --git a/src/tests/Interop/CMakeLists.txt b/src/tests/Interop/CMakeLists.txt
index b8f39f741985f6..226e5d128dacd3 100644
--- a/src/tests/Interop/CMakeLists.txt
+++ b/src/tests/Interop/CMakeLists.txt
@@ -94,6 +94,11 @@ if(CLR_CMAKE_TARGET_WIN32)
endif()
endif(CLR_CMAKE_TARGET_WIN32)
+if(CLR_CMAKE_TARGET_UNIX)
+ add_subdirectory(COM/ComWrappers/MockReferenceTrackerRuntime)
+ add_subdirectory(COM/ComWrappers/WeakReference)
+endif(CLR_CMAKE_TARGET_UNIX)
+
if(CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
add_subdirectory(ObjectiveC/AutoReleaseTest)
add_subdirectory(ObjectiveC/ObjectiveCMarshalAPI)
diff --git a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj
index ed35a36e816216..3e40128ed9ac81 100644
--- a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj
+++ b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj
@@ -2,6 +2,7 @@
Exe
true
+ true
diff --git a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj
index a51b1eb40779fc..4c1733ae1404d0 100644
--- a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj
+++ b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj
@@ -2,6 +2,7 @@
Exe
true
+ true
diff --git a/src/tests/Interop/COM/ComWrappers/Directory.Build.props b/src/tests/Interop/COM/ComWrappers/Directory.Build.props
new file mode 100644
index 00000000000000..2815e70883cd5a
--- /dev/null
+++ b/src/tests/Interop/COM/ComWrappers/Directory.Build.props
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.TrackerSupport.cs b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.TrackerSupport.cs
index bdb65f68fe2c57..0eaa5facfae1ed 100644
--- a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.TrackerSupport.cs
+++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.TrackerSupport.cs
@@ -31,15 +31,16 @@ static int Main(string[] doNotUse)
// The first test registers a global ComWrappers instance for tracker support.
// Subsequents tests assume the global instance has already been registered.
ValidateRegisterForTrackerSupport();
-
+#if Windows
ValidateNotRegisteredForMarshalling();
+#endif
IntPtr trackerObjRaw = MockReferenceTrackerRuntime.CreateTrackerObject();
var trackerObj = GlobalComWrappers.Instance.GetOrCreateObjectForComInstance(trackerObjRaw, CreateObjectFlags.TrackerObject);
Marshal.Release(trackerObjRaw);
ValidateNotifyEndOfReferenceTrackingOnThread();
-
+#if Windows
// Register a global ComWrappers instance for marshalling.
ValidateRegisterForMarshalling();
@@ -51,7 +52,7 @@ static int Main(string[] doNotUse)
ValidateComActivation(validateUseRegistered: true);
ValidateComActivation(validateUseRegistered: false);
-
+#endif
ValidateNotifyEndOfReferenceTrackingOnThread();
}
catch (Exception e)
diff --git a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTests.csproj b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTests.csproj
index db96b443c482c2..86c55881f31c7a 100644
--- a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTests.csproj
+++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTests.csproj
@@ -5,6 +5,8 @@
true
true
true
+
+ true
diff --git a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTestsBuiltInComDisabled.csproj b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTestsBuiltInComDisabled.csproj
index 11622e1c77524c..0cc328e7e8cdef 100644
--- a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTestsBuiltInComDisabled.csproj
+++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTestsBuiltInComDisabled.csproj
@@ -5,6 +5,8 @@
true
true
true
+
+ true
diff --git a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj
new file mode 100644
index 00000000000000..56634404240db7
--- /dev/null
+++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj
@@ -0,0 +1,32 @@
+
+
+ Exe
+ App.manifest
+ true
+ true
+ true
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+ false
+ Content
+ Always
+
+
+
+
+ PreserveNewest
+
+
+
diff --git a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests.csproj b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetWindows.csproj
similarity index 80%
rename from src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests.csproj
rename to src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetWindows.csproj
index 40529e85eab8bd..44a5bde6f2acfa 100644
--- a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests.csproj
+++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetWindows.csproj
@@ -5,6 +5,9 @@
true
true
true
+ $(DefineConstants);Windows
+
+ true
diff --git a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp
index bfe96dcebb689d..1af8b0ca095da9 100644
--- a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp
+++ b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp
@@ -3,14 +3,21 @@
#include
#include
+#ifdef _WIN32
+#include
+#else
+#include
+#include
+#endif //_WIN32
#include
#include
#include
-#include
namespace API
{
// Documentation found at https://docs.microsoft.com/windows/win32/api/windows.ui.xaml.hosting.referencetracker/
+ //64bd43f8-bfee-4ec4-b7eb-2935158dae21
+ const GUID IID_IReferenceTrackerTarget = { 0x64bd43f8, 0xbfee, 0x4ec4, { 0xb7, 0xeb, 0x29, 0x35, 0x15, 0x8d, 0xae, 0x21} };
class DECLSPEC_UUID("64bd43f8-bfee-4ec4-b7eb-2935158dae21") IReferenceTrackerTarget : public IUnknown
{
public:
@@ -20,6 +27,8 @@ namespace API
STDMETHOD(Unpeg)() = 0;
};
+ //29a71c6a-3c42-4416-a39d-e2825a07a773
+ const GUID IID_IReferenceTrackerHost = { 0x29a71c6a, 0x3c42, 0x4416, { 0xa3, 0x9d, 0xe2, 0x82, 0x5a, 0x07, 0xa7, 0x73} };
class DECLSPEC_UUID("29a71c6a-3c42-4416-a39d-e2825a07a773") IReferenceTrackerHost : public IUnknown
{
public:
@@ -31,6 +40,8 @@ namespace API
STDMETHOD(RemoveMemoryPressure)(_In_ UINT64 bytesAllocated) = 0;
};
+ //3cf184b4-7ccb-4dda-8455-7e6ce99a3298
+ const GUID IID_IReferenceTrackerManager = { 0x3cf184b4, 0x7ccb, 0x4dda, { 0x84, 0x55, 0x7e, 0x6c, 0xe9, 0x9a, 0x32, 0x98} };
class DECLSPEC_UUID("3cf184b4-7ccb-4dda-8455-7e6ce99a3298") IReferenceTrackerManager : public IUnknown
{
public:
@@ -46,6 +57,8 @@ namespace API
STDMETHOD(FoundTrackerTarget)(_In_ IReferenceTrackerTarget* target) = 0;
};
+ //11d3b13a-180e-4789-a8be-7712882893e6
+ const GUID IID_IReferenceTracker = { 0x11d3b13a, 0x180e, 0x4789, { 0xa8, 0xbe, 0x77, 0x12, 0x88, 0x28, 0x93, 0xe6} };
class DECLSPEC_UUID("11d3b13a-180e-4789-a8be-7712882893e6") IReferenceTracker : public IUnknown
{
public:
@@ -62,11 +75,15 @@ namespace API
namespace
{
// Testing types
+ //447BB9ED-DA48-4ABC-8963-5BB5C3E0AA09
+ const GUID IID_ITest = { 0x447BB9ED, 0xda48, 0x4abc, { 0x89, 0x63, 0x5b, 0xb5, 0xc3, 0xe0, 0xaa, 0x9} };
struct DECLSPEC_UUID("447BB9ED-DA48-4ABC-8963-5BB5C3E0AA09") ITest : public IUnknown
{
STDMETHOD(SetValue)(int i) = 0;
};
+ //42951130-245C-485E-B60B-4ED4254256F8
+ const GUID IID_ITrackerObject = { 0x42951130, 0x245c, 0x485e, { 0xb6, 0x0b, 0x4e, 0xd4, 0x25, 0x42, 0x56, 0xf8} };
struct DECLSPEC_UUID("42951130-245C-485E-B60B-4ED4254256F8") ITrackerObject : public IUnknown
{
STDMETHOD(AddObjectRef)(_In_ IUnknown* c, _Out_ int* id) = 0;
@@ -114,7 +131,7 @@ namespace
while (curr != std::end(_impl._elements))
{
ComSmartPtr mowMaybe;
- if (S_OK == curr->second->QueryInterface(&mowMaybe))
+ if (S_OK == curr->second->QueryInterface(API::IID_IReferenceTrackerTarget, (void**)&mowMaybe))
{
if (shouldPeg)
{
@@ -136,7 +153,7 @@ namespace
if (_impl._outerRefTrackerTarget)
{
ComSmartPtr thisTgtMaybe;
- if (S_OK == _outer->QueryInterface(&thisTgtMaybe))
+ if (S_OK == _outer->QueryInterface(API::IID_IReferenceTrackerTarget, (void**)&thisTgtMaybe))
{
if (shouldPeg)
{
@@ -162,7 +179,7 @@ namespace
if (_impl._outerRefTrackerTarget)
{
ComSmartPtr thisTgtMaybe;
- if (S_OK == _outer->QueryInterface(&thisTgtMaybe))
+ if (S_OK == _outer->QueryInterface(API::IID_IReferenceTrackerTarget, (void**)&thisTgtMaybe))
RETURN_IF_FAILED(thisTgtMaybe->ReleaseFromReferenceTracker());
}
@@ -189,13 +206,13 @@ namespace
{
// Check if we are aggregating with a tracker target
ComSmartPtr tgt;
- if (SUCCEEDED(_implOuter->QueryInterface(&tgt)))
+ if (SUCCEEDED(_implOuter->QueryInterface(API::IID_IReferenceTrackerTarget, (void**)&tgt)))
{
_outerRefTrackerTarget = true;
(void)tgt->AddRefFromReferenceTracker();
if (FAILED(tgt->Peg()))
{
- throw std::exception{ "Peg failure" };
+ throw std::runtime_error{ "Peg failure" };
}
}
}
@@ -205,7 +222,7 @@ namespace
assert(c != nullptr && id != nullptr);
ComSmartPtr mowMaybe;
- if (S_OK == c->QueryInterface(&mowMaybe))
+ if (S_OK == c->QueryInterface(API::IID_IReferenceTrackerTarget, (void**)&mowMaybe))
{
(void)mowMaybe->AddRefFromReferenceTracker();
c = mowMaybe.p;
@@ -234,7 +251,7 @@ namespace
return S_FALSE;
ComSmartPtr mowMaybe;
- if (S_OK == iter->second->QueryInterface(&mowMaybe))
+ if (S_OK == iter->second->QueryInterface(API::IID_IReferenceTrackerTarget, (void**)&mowMaybe))
{
(void)mowMaybe->ReleaseFromReferenceTracker();
(void)mowMaybe->Unpeg();
@@ -286,7 +303,7 @@ namespace
else
{
// Send non-IUnknown queries to the implementation.
- if (riid == __uuidof(API::IReferenceTracker))
+ if (riid == API::IID_IReferenceTracker)
{
tgt = static_cast(&_impl);
}
@@ -399,7 +416,7 @@ namespace
STDMETHOD(SetReferenceTrackerHost)(_In_ API::IReferenceTrackerHost* pHostServices)
{
assert(pHostServices != nullptr);
- return pHostServices->QueryInterface(&_runtimeServices);
+ return pHostServices->QueryInterface(API::IID_IReferenceTrackerHost, (void**)&_runtimeServices);
}
// Lifetime maintained by stack - we don't care about ref counts
@@ -413,7 +430,7 @@ namespace
if (ppvObject == nullptr)
return E_POINTER;
- if (IsEqualIID(riid, __uuidof(API::IReferenceTrackerManager)))
+ if (IsEqualIID(riid, API::IID_IReferenceTrackerManager))
{
*ppvObject = static_cast(this);
}
@@ -453,7 +470,7 @@ namespace
ComSmartPtr mowMaybe;
for (auto& e : _elements)
{
- if (S_OK == e.second->QueryInterface(&mowMaybe))
+ if (S_OK == e.second->QueryInterface(API::IID_IReferenceTrackerTarget, (void**)&mowMaybe))
{
(void)pCallback->FoundTrackerTarget(mowMaybe.p);
mowMaybe.Release();
@@ -466,7 +483,7 @@ namespace
HRESULT STDMETHODCALLTYPE TrackerObject::TrackerObjectImpl::GetReferenceTrackerManager(_Outptr_ API::IReferenceTrackerManager** ppTrackerManager)
{
assert(ppTrackerManager != nullptr);
- return TrackerRuntimeManager.QueryInterface(__uuidof(API::IReferenceTrackerManager), (void**)ppTrackerManager);
+ return TrackerRuntimeManager.QueryInterface(API::IID_IReferenceTrackerManager, (void**)ppTrackerManager);
}
HRESULT STDMETHODCALLTYPE TrackerObject::TrackerObjectImpl::AddRefFromTrackerSource()
@@ -533,7 +550,7 @@ extern "C" DLL_EXPORT void* STDMETHODCALLTYPE TrackerTarget_AddRefFromReferenceT
assert(obj != nullptr);
API::IReferenceTrackerTarget* targetMaybe;
- if (S_OK == obj->QueryInterface(&targetMaybe))
+ if (S_OK == obj->QueryInterface(API::IID_IReferenceTrackerTarget, (void**)&targetMaybe))
{
(void)targetMaybe->AddRefFromReferenceTracker();
(void)targetMaybe->Release();
@@ -559,7 +576,7 @@ extern "C" DLL_EXPORT int STDMETHODCALLTYPE UpdateTestObjectAsIUnknown(IUnknown
HRESULT hr;
ComSmartPtr testObj;
- RETURN_IF_FAILED(obj->QueryInterface(&testObj));
+ RETURN_IF_FAILED(obj->QueryInterface(IID_ITest, (void**)&testObj));
RETURN_IF_FAILED(testObj->SetValue(i));
*out = testObj.Detach();
diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp
index 0d9de17306b35a..5643f26bad7074 100644
--- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp
+++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp
@@ -3,8 +3,10 @@
#include
#include
+#ifdef _WIN32
#include
#include
+#endif //_WIN32
namespace
{
@@ -46,7 +48,32 @@ namespace
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject)
{
+#ifdef _WIN32
return DoQueryInterface(riid, ppvObject, static_cast(this));
+#else
+ if (ppvObject == nullptr)
+ return E_POINTER;
+
+ if (riid == __uuidof(IUnknown))
+ {
+ *ppvObject = static_cast(this);
+ }
+ else
+ {
+ if (riid == __uuidof(IWeakReference))
+ {
+ *ppvObject = static_cast(this);
+ }
+ else
+ {
+ *ppvObject = nullptr;
+ return E_NOINTERFACE;
+ }
+ }
+
+ DoAddRef();
+ return S_OK;
+#endif
}
DEFINE_REF_COUNTING()
@@ -89,7 +116,34 @@ namespace
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject)
{
+#ifdef _WIN32
HRESULT hr = DoQueryInterface(riid, ppvObject, static_cast(this), static_cast(this), static_cast(this));
+#else
+ HRESULT hr;
+
+ if (ppvObject == nullptr)
+ hr = E_POINTER;
+
+ if (riid == __uuidof(IUnknown) || riid == __uuidof(IWeakReferenceSource))
+ {
+ *ppvObject = static_cast(this);
+ hr = S_OK;
+ }
+ else if (riid == __uuidof(IInspectable))
+ {
+ *ppvObject = static_cast(this);
+ hr = S_OK;
+ }
+ else
+ {
+ *ppvObject = nullptr;
+ hr = E_NOINTERFACE;
+ }
+
+
+ if (hr == S_OK)
+ DoAddRef();
+#endif
if (SUCCEEDED(hr) && _weakReference)
{
_weakReference->AddStrongRef();
diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs
index 913dd53f6213ad..38e40d129243f6 100644
--- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs
+++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs
@@ -225,14 +225,17 @@ static int Main(string[] doNotUse)
{
try
{
- ValidateNonComWrappers();
+ if (OperatingSystem.IsWindows())
+ {
+ ValidateNonComWrappers();
+
+ ComWrappers.RegisterForMarshalling(TestComWrappers.MarshallingInstance);
+ ValidateGlobalInstanceMarshalling();
+ }
ComWrappers.RegisterForTrackerSupport(TestComWrappers.TrackerSupportInstance);
ValidateGlobalInstanceTrackerSupport();
- ComWrappers.RegisterForMarshalling(TestComWrappers.MarshallingInstance);
- ValidateGlobalInstanceMarshalling();
-
ValidateLocalInstance();
}
catch (Exception e)
diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj
index 35d1e5dcbbc885..1b0451975d18b0 100644
--- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj
+++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj
@@ -1,8 +1,6 @@
Exe
-
- true
true
true
diff --git a/src/tests/Interop/common/ComHelpers.h b/src/tests/Interop/common/ComHelpers.h
index 93ae4a3a09fdce..70c316e10c1f04 100644
--- a/src/tests/Interop/common/ComHelpers.h
+++ b/src/tests/Interop/common/ComHelpers.h
@@ -2,17 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
#pragma once
-
+#ifdef _WIN32
#include
#include
#include
#include
#include
+#endif
#include
// Common macro for working in COM
#define RETURN_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { return hr; } }
+#ifdef _WIN32
namespace Internal
{
template
@@ -20,7 +22,7 @@ namespace Internal
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject,
/* [in] */ I obj)
- {
+ {
if (riid == __uuidof(I))
{
*ppvObject = static_cast(obj);
@@ -50,19 +52,20 @@ namespace Internal
return __QueryInterfaceImpl(riid, ppvObject, remain...);
}
}
+ #endif
// Implementation of IUnknown operations
class UnknownImpl
{
-public:
- UnknownImpl() = default;
+public:
+ UnknownImpl() : _refCount{ 1 } {};
virtual ~UnknownImpl() = default;
UnknownImpl(const UnknownImpl&) = delete;
UnknownImpl& operator=(const UnknownImpl&) = delete;
- UnknownImpl(UnknownImpl&&) = default;
- UnknownImpl& operator=(UnknownImpl&&) = default;
+ UnknownImpl(UnknownImpl&&) = delete;
+ UnknownImpl& operator=(UnknownImpl&&) = delete;
template
HRESULT DoQueryInterface(
@@ -80,9 +83,15 @@ class UnknownImpl
}
else
{
+ //Internal::__QueryInterfaceImpl available only for _WIN32 due to __uuidof(T) availability
+#ifdef _WIN32
HRESULT hr = Internal::__QueryInterfaceImpl(riid, ppvObject, i1, remain...);
if (hr != S_OK)
return hr;
+#else
+ *ppvObject = nullptr;
+ return E_NOTIMPL;
+#endif
}
DoAddRef();
@@ -111,7 +120,7 @@ class UnknownImpl
}
private:
- std::atomic _refCount = 1;
+ std::atomic _refCount;
};
// Macro to use for defining ref counting impls
@@ -119,6 +128,7 @@ class UnknownImpl
STDMETHOD_(ULONG, AddRef)(void) { return UnknownImpl::DoAddRef(); } \
STDMETHOD_(ULONG, Release)(void) { return UnknownImpl::DoRelease(); }
+#ifdef _WIN32
// Templated class factory
template
class ClassFactoryBasic : public UnknownImpl, public IClassFactory
@@ -336,6 +346,7 @@ class ClassFactoryLicense : public UnknownImpl, public IClassFactory2
DEFINE_REF_COUNTING();
};
+#endif
template
struct ComSmartPtr
diff --git a/src/tests/Interop/common/xplatform.h b/src/tests/Interop/common/xplatform.h
index 35168b575bbecf..7422b7076f4957 100644
--- a/src/tests/Interop/common/xplatform.h
+++ b/src/tests/Interop/common/xplatform.h
@@ -8,6 +8,103 @@
#ifndef WINDOWS
+#define __RPC_FAR
+#define DECLSPEC_UUID(x)
+#define DECLSPEC_NOVTABLE
+#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE
+//Check OBJC_TESTS presence to avoid interface definition on OSX (already defined)
+#ifndef OBJC_TESTS
+#define interface struct
+#endif
+#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method
+#define STDMETHOD_(type,method) virtual type STDMETHODCALLTYPE method
+#undef _In_
+#define _In_
+#undef _Outptr_
+#define _Outptr_
+#undef _Out_
+#define _Out_
+#undef _In_opt_
+#define _In_opt_
+#undef _COM_Outptr_
+#define _COM_Outptr_
+#undef _Inout_
+#define _Inout_
+#define __RPC__out
+#define __RPC__in
+#define __RPC__deref_out
+#define __RPC__deref_out_opt
+#define __RPC__deref_out_ecount_full_opt(x)
+#define __RPC_unique_pointer
+
+
+#define E_POINTER _HRESULT_TYPEDEF_(0x80004003L)
+#define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002L)
+#define S_FALSE _HRESULT_TYPEDEF_(0x00000001L)
+#define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000EL)
+#define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001L)
+
+// Declaring a handle dummy struct for HSTRING the same way DECLARE_HANDLE does.
+typedef struct HSTRING__{
+ int unused;
+} HSTRING__;
+
+// Declare the HSTRING handle for C/C++
+typedef __RPC_unique_pointer HSTRING__* HSTRING;
+
+typedef unsigned __int64 UINT64, *PUINT64;
+typedef unsigned short USHORT;
+typedef USHORT *PUSHORT;
+typedef unsigned char UCHAR;
+typedef UCHAR *PUCHAR;
+
+#ifndef GUID_DEFINED
+typedef struct _GUID {
+ ULONG Data1; // NOTE: diff from Win32, for LP64
+ USHORT Data2;
+ USHORT Data3;
+ UCHAR Data4[ 8 ];
+} GUID;
+typedef const GUID *LPCGUID;
+#define GUID_DEFINED
+#endif // !GUID_DEFINED
+
+
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#endif
+
+
+#ifdef __cplusplus
+extern "C++" {
+#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_
+#define _SYS_GUID_OPERATOR_EQ_
+inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
+ { return !memcmp(&rguid1, &rguid2, sizeof(GUID)); }
+inline int operator==(REFGUID guidOne, REFGUID guidOther)
+ { return IsEqualGUID(guidOne,guidOther); }
+inline int operator!=(REFGUID guidOne, REFGUID guidOther)
+ { return !IsEqualGUID(guidOne,guidOther); }
+#endif
+};
+#endif // __cplusplus
+
+
+typedef GUID IID;
+#ifdef __cplusplus
+#define REFIID const IID &
+#endif
+
+#define IID_NULL { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
+
+#define __uuidof(type) IID_##type
+
+#ifndef assert
+#define assert(e) ((void)0)
+#endif // assert
+
#include
#undef INT_MIN
@@ -88,12 +185,82 @@ typedef struct tagDEC {
#define FALSE 0
#endif
-class IUnknown
+#ifndef __IUnknown_INTERFACE_DEFINED__
+#define __IUnknown_INTERFACE_DEFINED__
+
+
+//00000000-0000-0000-C000-000000000046
+const IID IID_IUnknown = { 0x00000000, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
+
+MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
+IUnknown
+{
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(
+ REFIID riid,
+ void **ppvObject) = 0;
+
+ virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0;
+
+ virtual ULONG STDMETHODCALLTYPE Release( void) = 0;
+
+};
+
+#endif // __IUnknown_INTERFACE_DEFINED__
+
+struct IDispatch : public IUnknown
+{
+
+};
+
+typedef /* [v1_enum] */
+enum TrustLevel
+ {
+ BaseTrust = 0,
+ PartialTrust = ( BaseTrust + 1 ) ,
+ FullTrust = ( PartialTrust + 1 )
+ } TrustLevel;
+
+//AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90
+const IID IID_IInspectable = { 0xaf86e2e0, 0xb12d, 0x4c6a, { 0x9c, 0x5a, 0xd7, 0xaa, 0x65, 0x10, 0x1e, 0x90} };
+
+MIDL_INTERFACE("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")
+IInspectable : public IUnknown
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE GetIids(
+ /* [out] */ __RPC__out ULONG * iidCount,
+ /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID * *iids) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetRuntimeClassName(
+ /* [out] */ __RPC__deref_out_opt HSTRING * className) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(
+ /* [out] */ __RPC__out TrustLevel * trustLevel) = 0;
+};
+
+
+//00000037-0000-0000-C000-000000000046
+const IID IID_IWeakReference = { 0x00000037, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
+
+MIDL_INTERFACE("00000037-0000-0000-C000-000000000046")
+IWeakReference : public IUnknown
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE Resolve(
+ /* [in] */ __RPC__in REFIID riid,
+ /* [iid_is][out] */ __RPC__deref_out IInspectable **objectReference) = 0;
+
+};
+
+//00000038-0000-0000-C000-000000000046
+const IID IID_IWeakReferenceSource = { 0x00000038, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
+
+MIDL_INTERFACE("00000038-0000-0000-C000-000000000046")
+IWeakReferenceSource : public IUnknown
{
public:
- virtual int QueryInterface(void* riid,void** ppvObject) = 0;
- virtual unsigned long AddRef() = 0;
- virtual unsigned long Release() = 0;
+ virtual HRESULT STDMETHODCALLTYPE GetWeakReference(
+ /* [retval][out] */ __RPC__deref_out_opt IWeakReference * *weakReference) = 0;
};
#define DECIMAL_NEG ((BYTE)0x80)
diff --git a/src/tests/issues.targets b/src/tests/issues.targets
index ccf5fcc479c4fb..e6736d598e9f3c 100644
--- a/src/tests/issues.targets
+++ b/src/tests/issues.targets
@@ -1189,6 +1189,9 @@
https://github.com/dotnet/runtime/issues/34371
+
+ Not supported on Mono
+
needs triage