Enable ComWrappers API for cross-platform (#54838)
authoralesomas <a.somaschini@reply.it>
Thu, 29 Jul 2021 22:09:56 +0000 (00:09 +0200)
committerGitHub <noreply@github.com>
Thu, 29 Jul 2021 22:09:56 +0000 (15:09 -0700)
* Product changes to enable comwrappers on linux

* Some enhancement (ArraySize, Stowed exception exclusion, etc.)

* Further enhancements + gcenv.ee.cpp change for build failures

* Array size definition moved below windows.h

* MockReferenceTrackerRuntime test project changes for Linux

* Use FALLTHROUGH macro in place of [[fallthrough]]

* WeakReference test project changes for Linux

* Moved back comhelpers.h code from xplatform.h

* OBJC_TEST logic to avoid OSX errors

* Fix for GCC pipeline errors

* Arraysize result comparison error

* Fix IID_IReferenceTracker GUID typo

* QueryInterface implementation and other minor changes

* UnknowImpl fix to remove WIN32 constructor cases

* UnknownImpl error fix

* Included ComWrappers Managed tests

* Excluded Unix ComWrappers test for Mono

* Disabled comwrappers test for mono + other code enhancements

* Enable interop info sync block cleanup under FEATURE_COMWRAPPERS

* Fix local instance ComWrappers WeakReference tests

* Enable NativeComWeakHandleInfo under FEATURE_COMWRAPPERS

* weakreferencenative.cpp and ComHelpers.h code enhancements

Co-authored-by: Ubuntu <creditsuisse@BuildVM.hqykqmymov3ebcqudt35mscinc.ax.internal.cloudapp.net>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
38 files changed:
src/coreclr/clr.featuredefines.props
src/coreclr/clrfeatures.cmake
src/coreclr/debug/daccess/dacimpl.h
src/coreclr/debug/daccess/enummem.cpp
src/coreclr/dlls/mscorrc/mscorrc.rc
src/coreclr/dlls/mscorrc/resource.h
src/coreclr/gc/objecthandle.cpp
src/coreclr/interop/comwrappers.cpp
src/coreclr/interop/comwrappers.hpp
src/coreclr/interop/interoplib.cpp
src/coreclr/interop/platform.h
src/coreclr/interop/referencetrackertypes.hpp
src/coreclr/interop/trackerobjectmanager.cpp
src/coreclr/pal/inc/rt/weakreference.h [new file with mode: 0644]
src/coreclr/vm/appdomain.hpp
src/coreclr/vm/gcenv.ee.cpp
src/coreclr/vm/gchandleutilities.h
src/coreclr/vm/interoplibinterface.cpp
src/coreclr/vm/interoputil.cpp
src/coreclr/vm/interoputil.h
src/coreclr/vm/syncblk.cpp
src/coreclr/vm/weakreferencenative.cpp
src/tests/Interop/CMakeLists.txt
src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj
src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj
src/tests/Interop/COM/ComWrappers/Directory.Build.props [new file with mode: 0644]
src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.TrackerSupport.cs
src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTests.csproj
src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceMarshallingTestsBuiltInComDisabled.csproj
src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj [new file with mode: 0644]
src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetWindows.csproj [moved from src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests.csproj with 80% similarity]
src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp
src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp
src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs
src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj
src/tests/Interop/common/ComHelpers.h
src/tests/Interop/common/xplatform.h
src/tests/issues.targets

index 08fca8d..60e3883 100644 (file)
@@ -21,6 +21,7 @@
         <FeaturePortableShuffleThunks Condition="'$(Platform)' != 'x86'">true</FeaturePortableShuffleThunks>
         <FeatureInstantiatingStubAsIL>true</FeatureInstantiatingStubAsIL>
         <FeatureStubsAsIL>true</FeatureStubsAsIL>
+        <FeatureComWrappers>true</FeatureComWrappers>
     </PropertyGroup>
 
     <PropertyGroup Condition="'$(TargetsWindows)' == 'true'">
index 5a9a161..f82ff1a 100644 (file)
@@ -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()
 
index 744ebaf..62d99ec 100644 (file)
@@ -1323,7 +1323,7 @@ public:
     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
index 2c7445b..577fdcb 100644 (file)
@@ -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)
index 0b4247c..e8955bf 100644 (file)
@@ -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"
 
index 8038665..0e39c27 100644 (file)
 #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
index 971452f..cd5c1dc 100644 (file)
@@ -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;
 
index 90c366c..a4afa67 100644 (file)
@@ -5,7 +5,10 @@
 #include <interoplibimports.h>
 #include <corerror.h>
 
+#ifdef _WIN32
 #include <new> // 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<IReferenceTracker> 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));
     }
index 31b26e0..bd383be 100644 (file)
@@ -9,6 +9,19 @@
 #include <interoplibabi.h>
 #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 @@ public: // static
     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,
index 70063e1..7af7af9 100644 (file)
@@ -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.
index a201540..351b5eb 100644 (file)
 
 #ifdef _WIN32
 #include <Windows.h>
+#endif // _WIN32
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(x)    (sizeof(x)/sizeof(x[0]))
+#endif // !ARRAYSIZE
+
+#if defined(_WIN32) || defined(HOST_UNIX)
 #include <objidl.h> // 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.")
 
index a5887df..6e703a9 100644 (file)
@@ -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 @@ public:
     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:
index ff5fcdb..6f4bebc 100644 (file)
@@ -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<IUnknown> 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<IUnknown> 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 (file)
index 0000000..d0b88d6
--- /dev/null
@@ -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__
index 0487299..fb2e456 100644 (file)
@@ -1075,7 +1075,7 @@ public:
         return h;
     }
 
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
     OBJECTHANDLE CreateRefcountedHandle(OBJECTREF object)
     {
         WRAPPER_NO_CONTRACT;
@@ -1087,7 +1087,7 @@ public:
         WRAPPER_NO_CONTRACT;
         return ::CreateNativeComWeakHandle(m_handleStore, object, pComWeakHandleInfo);
     }
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
 
     OBJECTHANDLE CreateVariableHandle(OBJECTREF object, UINT type)
     {
index 82d4ccb..f963146 100644 (file)
@@ -355,9 +355,6 @@ bool GCToEEInterface::RefCountedHandleCallbacks(Object * pObject)
     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;
 }
index f6f7991..611316c 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "gcinterface.h"
 
-#ifdef FEATURE_COMINTEROP
+#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
 #include <weakreference.h>
 #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
 
index b9b02eb..746c228 100644 (file)
@@ -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
 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
     {
@@ -836,7 +852,7 @@ namespace
                 ExternalObjectContext::Construct(
                     resultHolder.GetContext(),
                     identity,
-                    GetCurrentCtxCookie(),
+                    GetCurrentCtxCookieWrapper(),
                     gc.objRefMaybe->GetSyncBlockIndex(),
                     wrapperId,
                     eocFlags);
@@ -1055,7 +1071,7 @@ namespace InteropLibImports
             ExtObjCxtCache* cache = ExtObjCxtCache::GetInstanceNoThrow();
             gc.objsEnumRef = cache->CreateManagedEnumerable(
                 ExternalObjectContext::Flags_ReferenceTracker,
-                GetCurrentCtxCookie());
+                GetCurrentCtxCookieWrapper());
 
             CallReleaseObjects(&gc.implRef, &gc.objsEnumRef);
 
index 2b66978..80f49e9 100644 (file)
@@ -1229,8 +1229,7 @@ HRESULT SafeQueryInterfacePreemp(IUnknown* pUnk, REFIID riid, IUnknown** pResUnk
 }
 #include <optdefault.h>
 
-#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
index b997646..f9706d8 100644 (file)
@@ -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);
 
index a86cd61..1a2c935 100644 (file)
@@ -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>@todo add an assert for the above statement</TODO>
@@ -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)
index 4d56975..1354f35 100644 (file)
@@ -100,7 +100,7 @@ private:
     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<IWeakReferenceSource*>(GetComIPFromObjectRef(pObject, IID_IWeakReferenceSource, false /* throwIfNoComIP */));
     }
-#ifdef FEATURE_COMWRAPPERS
     else
+#endif
     {
+#ifdef FEATURE_COMWRAPPERS        
         pWeakReferenceSource = reinterpret_cast<IWeakReferenceSource*>(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<NativeComWeakHandleInfo> 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();
index b8f39f7..226e5d1 100644 (file)
@@ -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)
index ed35a36..3e40128 100644 (file)
@@ -2,6 +2,7 @@
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'mono'">true</DisableProjectBuild>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="Program.cs" />
index a51b1eb..4c1733a 100644 (file)
@@ -2,6 +2,7 @@
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'mono'">true</DisableProjectBuild>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="Program.cs" />
diff --git a/src/tests/Interop/COM/ComWrappers/Directory.Build.props b/src/tests/Interop/COM/ComWrappers/Directory.Build.props
new file mode 100644 (file)
index 0000000..2815e70
--- /dev/null
@@ -0,0 +1,9 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props, $(MSBuildThisFileDirectory)..))" />
+
+  <PropertyGroup>
+    <!-- Unlike COM, ComWrappers are cross-platform -->
+    <CLRTestTargetUnsupported></CLRTestTargetUnsupported>
+  </PropertyGroup>
+
+</Project>
index bdb65f6..0eaa5fa 100644 (file)
@@ -31,15 +31,16 @@ namespace ComWrappersTests.GlobalInstance
                 // 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 @@ namespace ComWrappersTests.GlobalInstance
 
                 ValidateComActivation(validateUseRegistered: true);
                 ValidateComActivation(validateUseRegistered: false);
-
+#endif
                 ValidateNotifyEndOfReferenceTrackingOnThread();
             }
             catch (Exception e)
index db96b44..86c5588 100644 (file)
@@ -5,6 +5,8 @@
     <UseManagedCOMServer>true</UseManagedCOMServer>
     <IsManagedCOMClient>true</IsManagedCOMClient>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <!-- There is only a Windows version of this test -->
+    <CLRTestTargetUnsupported Condition="'$(TargetsWindows)' != 'true'">true</CLRTestTargetUnsupported>    
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="GlobalInstance.cs" />
index 11622e1..0cc328e 100644 (file)
@@ -5,6 +5,8 @@
     <UseManagedCOMServer>true</UseManagedCOMServer>
     <IsManagedCOMClient>true</IsManagedCOMClient>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <!-- There is only a Windows version of this test -->
+    <CLRTestTargetUnsupported Condition="'$(TargetsWindows)' != 'true'">true</CLRTestTargetUnsupported>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="GlobalInstance.cs" />
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 (file)
index 0000000..5663440
--- /dev/null
@@ -0,0 +1,32 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <ApplicationManifest>App.manifest</ApplicationManifest>
+    <UseManagedCOMServer>true</UseManagedCOMServer>
+    <IsManagedCOMClient>true</IsManagedCOMClient>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <!-- There is a Windows and a non-Windows version of this test to allow it to be compiled for all targets -->
+    <CLRTestTargetUnsupported Condition="'$(TargetsWindows)' == 'true'">true</CLRTestTargetUnsupported>
+    <DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'mono'">true</DisableProjectBuild>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="GlobalInstance.cs" />
+    <Compile Include="GlobalInstance.TrackerSupport.cs" />
+    <Compile Include="../Common.cs" />
+    <Compile Include="../../ServerContracts/Server.Contracts.cs" />
+    <Compile Include="../../ServerContracts/ServerGuids.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="../MockReferenceTrackerRuntime/CMakeLists.txt" />
+    <ProjectReference Include="../../NETServer/NETServer.csproj">
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+      <OutputItemType>Content</OutputItemType>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="CoreShim.X.manifest">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+</Project>
@@ -5,6 +5,9 @@
     <UseManagedCOMServer>true</UseManagedCOMServer>
     <IsManagedCOMClient>true</IsManagedCOMClient>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DefineConstants>$(DefineConstants);Windows</DefineConstants>
+    <!-- There is a Windows and a non-Windows version of this test to allow it to be compiled for all targets -->
+    <CLRTestTargetUnsupported Condition="'$(TargetsWindows)' != 'true'">true</CLRTestTargetUnsupported>    
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="GlobalInstance.cs" />
index bfe96dc..1af8b0c 100644 (file)
@@ -3,14 +3,21 @@
 
 #include <xplatform.h>
 #include <ComHelpers.h>
+#ifdef _WIN32
+#include <inspectable.h>
+#else
+#include <atomic>
+#include <exception>
+#endif //_WIN32
 #include <unordered_map>
 #include <list>
 #include <mutex>
-#include <inspectable.h>
 
 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<API::IReferenceTrackerTarget> 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<API::IReferenceTrackerTarget> 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<API::IReferenceTrackerTarget> 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<API::IReferenceTrackerTarget> 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<API::IReferenceTrackerTarget> 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<API::IReferenceTrackerTarget> 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<API::IReferenceTracker*>(&_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<API::IReferenceTrackerManager*>(this);
             }
@@ -453,7 +470,7 @@ namespace
         ComSmartPtr<API::IReferenceTrackerTarget> 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<ITest> 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();
index 0d9de17..5643f26 100644 (file)
@@ -3,8 +3,10 @@
 
 #include <xplatform.h>
 #include <ComHelpers.h>
+#ifdef _WIN32
 #include <inspectable.h>
 #include <WeakReference.h>
+#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<IWeakReference*>(this));
+#else
+            if (ppvObject == nullptr)
+               return E_POINTER;
+
+            if (riid == __uuidof(IUnknown))
+            {
+                *ppvObject = static_cast<IUnknown*>(this);
+            }
+            else
+            {
+                if (riid == __uuidof(IWeakReference))
+                {
+                    *ppvObject = static_cast<IWeakReference*>(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<IWeakReferenceSource*>(this), static_cast<IInspectable*>(this), static_cast<IWeakReferenceSource*>(this));
+#else        
+            HRESULT hr;
+
+            if (ppvObject == nullptr)
+               hr = E_POINTER;
+
+            if (riid == __uuidof(IUnknown) || riid == __uuidof(IWeakReferenceSource))
+            {
+                *ppvObject = static_cast<IWeakReferenceSource*>(this);
+                hr = S_OK;
+            }
+            else if (riid == __uuidof(IInspectable))
+            {
+                *ppvObject = static_cast<IInspectable*>(this);
+                hr = S_OK;
+            }
+            else
+            {
+                *ppvObject = nullptr;
+                hr = E_NOINTERFACE;
+            }
+                
+            
+            if (hr == S_OK)
+               DoAddRef();
+#endif
             if (SUCCEEDED(hr) && _weakReference)
             {
                 _weakReference->AddStrongRef();
index 913dd53..38e40d1 100644 (file)
@@ -225,14 +225,17 @@ namespace ComWrappersTests
         {
             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)
index 35d1e5d..1b04519 100644 (file)
@@ -1,8 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <!-- Test unsupported outside of windows -->
-    <CLRTestTargetUnsupported Condition="'$(TargetsWindows)' != 'true'">true</CLRTestTargetUnsupported>
     <!-- Registers global instances of ComWrappers -->
     <UnloadabilityIncompatible>true</UnloadabilityIncompatible>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
index 93ae4a3..70c316e 100644 (file)
@@ -2,17 +2,19 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 #pragma once
-
+#ifdef _WIN32
 #include <Windows.h>
 #include <comdef.h>
 #include <cassert>
 #include <exception>
 #include <type_traits>
+#endif
 #include <atomic>
 
 // Common macro for working in COM
 #define RETURN_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { return hr; } }
 
+#ifdef _WIN32   
 namespace Internal
 {
     template<typename I>
@@ -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<I>(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<typename I1, typename ...IR>
     HRESULT DoQueryInterface(
@@ -80,9 +83,15 @@ public:
         }
         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 @@ protected:
     }
 
 private:
-    std::atomic<ULONG> _refCount = 1;
+    std::atomic<ULONG> _refCount;  
 };
 
 // Macro to use for defining ref counting impls
@@ -119,6 +128,7 @@ private:
     STDMETHOD_(ULONG, AddRef)(void) { return UnknownImpl::DoAddRef(); } \
     STDMETHOD_(ULONG, Release)(void) { return UnknownImpl::DoRelease(); }
 
+#ifdef _WIN32
 // Templated class factory
 template<typename T>
 class ClassFactoryBasic : public UnknownImpl, public IClassFactory
@@ -336,6 +346,7 @@ public: // IUnknown
 
     DEFINE_REF_COUNTING();
 };
+#endif
 
 template<typename T>
 struct ComSmartPtr
index 35168b5..7422b70 100644 (file)
@@ -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 <stddef.h>
 
 #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)
index bb72c2b..854204f 100644 (file)
         <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/Reflection/Reflection/**">
             <Issue>https://github.com/dotnet/runtime/issues/34371</Issue>
         </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/ComWrappers/**"> 
+            <Issue>Not supported on Mono</Issue> 
+        </ExcludeList>        
         <ExcludeList Include="$(XunitTestBinBase)/Interop/ICastable/Castable/**">
             <Issue>needs triage</Issue>
         </ExcludeList>