From 21e691b7ede2a9497d4b0090177a45d1287eb147 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 28 Jun 2021 15:13:38 +0000 Subject: [PATCH 01/22] Product changes to enable comwrappers on linux --- src/coreclr/clr.featuredefines.props | 1 + src/coreclr/clrfeatures.cmake | 4 +++ src/coreclr/debug/daccess/enummem.cpp | 16 +++++++++++- src/coreclr/interop/comwrappers.cpp | 25 ++++++++++--------- src/coreclr/interop/comwrappers.hpp | 13 ++++++++++ src/coreclr/interop/interoplib.cpp | 4 +-- src/coreclr/interop/platform.h | 9 +++++++ src/coreclr/interop/referencetrackertypes.hpp | 6 +++++ src/coreclr/interop/trackerobjectmanager.cpp | 18 +++++++------ src/coreclr/vm/interoplibinterface.cpp | 17 +++++++++++-- 10 files changed, 89 insertions(+), 24 deletions(-) diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props index 67a5eab17c8684..5e0b9d88e55807 100644 --- a/src/coreclr/clr.featuredefines.props +++ b/src/coreclr/clr.featuredefines.props @@ -20,6 +20,7 @@ true true true + true diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index 5a9a161821c852..c1e710cce222af 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -39,3 +39,7 @@ endif() if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) set(FEATURE_OBJCMARSHAL 1) endif() + +if (CLR_CMAKE_TARGET_UNIX) + set(FEATURE_COMWRAPPERS 1) +endif() \ No newline at end of file diff --git a/src/coreclr/debug/daccess/enummem.cpp b/src/coreclr/debug/daccess/enummem.cpp index 2c7445bf99cf91..e006a457ec545e 100644 --- a/src/coreclr/debug/daccess/enummem.cpp +++ b/src/coreclr/debug/daccess/enummem.cpp @@ -26,6 +26,20 @@ #include #endif // FEATURE_COMWRAPPERS +#if TARGET_UNIX +#include "assemblyspec.hpp" +#define TEAR_OFF_SLOT 1 +typedef struct _MINIDUMP_EXCEPTION { + ULONG32 ExceptionCode; + ULONG32 ExceptionFlags; + ULONG64 ExceptionRecord; + ULONG64 ExceptionAddress; + ULONG32 NumberParameters; + ULONG32 __unusedAlignment; + ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ]; +} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION; +#endif + extern HRESULT GetDacTableAddress(ICorDebugDataTarget* dataTarget, ULONG64 baseAddress, PULONG64 dacTableAddress); #if defined(DAC_MEASURE_PERF) @@ -1405,7 +1419,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/interop/comwrappers.cpp b/src/coreclr/interop/comwrappers.cpp index 90c366cead4b9b..544ce99661e80b 100644 --- a/src/coreclr/interop/comwrappers.cpp +++ b/src/coreclr/interop/comwrappers.cpp @@ -5,7 +5,7 @@ #include #include -#include // placement new +//#include // placement new using OBJECTHANDLE = InteropLib::OBJECTHANDLE; using AllocScenario = InteropLibImports::AllocScenario; @@ -344,9 +344,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 +393,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 <= sizeof(runtimeDefinedLocal)/sizeof(runtimeDefinedLocal[0])); // Compute size for ManagedObjectWrapper instance. const size_t totalRuntimeDefinedSize = runtimeDefinedCount * sizeof(ABI::ComInterfaceEntry); @@ -436,7 +436,7 @@ HRESULT ManagedObjectWrapper::Create( { userDefined, userDefinedCount } }; - ABI::ComInterfaceDispatch* dispSection = ABI::PopulateDispatchSection(wrapperMem, dispatchSectionOffset, ARRAYSIZE(AllEntries), AllEntries); + ABI::ComInterfaceDispatch* dispSection = ABI::PopulateDispatchSection(wrapperMem, dispatchSectionOffset, sizeof(AllEntries)/sizeof(AllEntries[0]), AllEntries); ManagedObjectWrapper* wrapper = new (wrapperMem) ManagedObjectWrapper { @@ -465,7 +465,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 +547,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 @@ -664,8 +664,6 @@ HRESULT ManagedObjectWrapper::QueryInterface( _ASSERTE(*ppvObject == nullptr); return E_NOINTERFACE; - default: - _ASSERTE(false && "Unknown result value"); case TryInvokeICustomQueryInterfaceResult::FailedToInvoke: // Set the 'lacks' flag since our attempt to use ICustomQueryInterface // indicated the object lacks an implementation. @@ -680,6 +678,9 @@ HRESULT ManagedObjectWrapper::QueryInterface( // the same way that would occur if the managed object lacked // an ICustomQueryInterface implementation. break; + + default: + _ASSERTE(false && "Unknown result value"); } } @@ -744,7 +745,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..fb75c0f12f93a0 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, diff --git a/src/coreclr/interop/interoplib.cpp b/src/coreclr/interop/interoplib.cpp index 70063e16d51f2a..5680e8f06ba641 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..ddb990ecc3996c 100644 --- a/src/coreclr/interop/platform.h +++ b/src/coreclr/interop/platform.h @@ -22,6 +22,15 @@ #endif // _WIN32 +#ifdef 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 // HOST_UNIX + #define ABI_ASSERT(abi_definition) static_assert((abi_definition), "ABI is being invalidated.") // Runtime headers diff --git a/src/coreclr/interop/referencetrackertypes.hpp b/src/coreclr/interop/referencetrackertypes.hpp index a5887df802dc26..5b4276fe21c680 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, 0x36} }; + 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..e0b7a0ba8b3230 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/vm/interoplibinterface.cpp b/src/coreclr/vm/interoplibinterface.cpp index b027d6b9d4bbdc..51b2529821a489 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,6 +19,17 @@ using CreateObjectFlags = InteropLib::Com::CreateObjectFlags; using CreateComInterfaceFlags = InteropLib::Com::CreateComInterfaceFlags; +void* GetCurrentCtxCookieWrapper() +{ + +#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT + RETURN GetCurrentCtxCookie(); +#else + RETURN NULL; +#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT + +} + namespace { // This class is used to track the external object within the runtime. @@ -837,7 +850,7 @@ namespace ExternalObjectContext::Construct( resultHolder.GetContext(), identity, - GetCurrentCtxCookie(), + GetCurrentCtxCookieWrapper(), gc.objRefMaybe->GetSyncBlockIndex(), wrapperId, eocFlags); @@ -1056,7 +1069,7 @@ namespace InteropLibImports ExtObjCxtCache* cache = ExtObjCxtCache::GetInstanceNoThrow(); gc.objsEnumRef = cache->CreateManagedEnumerable( ExternalObjectContext::Flags_ReferenceTracker, - GetCurrentCtxCookie()); + GetCurrentCtxCookieWrapper()); CallReleaseObjects(&gc.implRef, &gc.objsEnumRef); From 480622cf165c3f946ed601ae0f700f2c84885842 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 29 Jun 2021 14:37:56 +0000 Subject: [PATCH 02/22] Some enhancement (ArraySize, Stowed exception exclusion, etc.) --- src/coreclr/clrfeatures.cmake | 6 +---- src/coreclr/debug/daccess/dacimpl.h | 2 +- src/coreclr/debug/daccess/enummem.cpp | 18 ++------------ src/coreclr/interop/comwrappers.cpp | 25 +++++++++++--------- src/coreclr/interop/interoplib.cpp | 4 ++-- src/coreclr/interop/platform.h | 15 +++++------- src/coreclr/interop/trackerobjectmanager.cpp | 2 +- src/coreclr/vm/interoplibinterface.cpp | 22 ++++++++++------- 8 files changed, 40 insertions(+), 54 deletions(-) diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index c1e710cce222af..f82ff1aa4e73e9 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -32,14 +32,10 @@ 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() if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) set(FEATURE_OBJCMARSHAL 1) endif() - -if (CLR_CMAKE_TARGET_UNIX) - set(FEATURE_COMWRAPPERS 1) -endif() \ No newline at end of file diff --git a/src/coreclr/debug/daccess/dacimpl.h b/src/coreclr/debug/daccess/dacimpl.h index 165dcb47fb1ad5..0a0a8c6e731825 100644 --- a/src/coreclr/debug/daccess/dacimpl.h +++ b/src/coreclr/debug/daccess/dacimpl.h @@ -1312,7 +1312,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 e006a457ec545e..577fdcbc6b2e44 100644 --- a/src/coreclr/debug/daccess/enummem.cpp +++ b/src/coreclr/debug/daccess/enummem.cpp @@ -26,20 +26,6 @@ #include #endif // FEATURE_COMWRAPPERS -#if TARGET_UNIX -#include "assemblyspec.hpp" -#define TEAR_OFF_SLOT 1 -typedef struct _MINIDUMP_EXCEPTION { - ULONG32 ExceptionCode; - ULONG32 ExceptionFlags; - ULONG64 ExceptionRecord; - ULONG64 ExceptionAddress; - ULONG32 NumberParameters; - ULONG32 __unusedAlignment; - ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ]; -} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION; -#endif - extern HRESULT GetDacTableAddress(ICorDebugDataTarget* dataTarget, ULONG64 baseAddress, PULONG64 dacTableAddress); #if defined(DAC_MEASURE_PERF) @@ -1079,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) @@ -1312,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. diff --git a/src/coreclr/interop/comwrappers.cpp b/src/coreclr/interop/comwrappers.cpp index 544ce99661e80b..7936addfce32ac 100644 --- a/src/coreclr/interop/comwrappers.cpp +++ b/src/coreclr/interop/comwrappers.cpp @@ -5,7 +5,10 @@ #include #include -//#include // placement new +#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 = (void*) ManagedObjectWrapper_IUnknownImpl.QueryInterface; - *fpAddRef = (void*) ManagedObjectWrapper_IUnknownImpl.AddRef; - *fpRelease = (void*) 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 @@ -396,8 +399,8 @@ HRESULT ManagedObjectWrapper::Create( curr.IID = IID_IReferenceTrackerTarget; curr.Vtable = &ManagedObjectWrapper_IReferenceTrackerTargetImpl; } - - _ASSERTE(runtimeDefinedCount <= sizeof(runtimeDefinedLocal)/sizeof(runtimeDefinedLocal[0])); + + _ASSERTE(runtimeDefinedCount <= ARRAYSIZE(runtimeDefinedLocal)); // Compute size for ManagedObjectWrapper instance. const size_t totalRuntimeDefinedSize = runtimeDefinedCount * sizeof(ABI::ComInterfaceEntry); @@ -664,6 +667,9 @@ HRESULT ManagedObjectWrapper::QueryInterface( _ASSERTE(*ppvObject == nullptr); return E_NOINTERFACE; + 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. @@ -677,10 +683,7 @@ HRESULT ManagedObjectWrapper::QueryInterface( // Instead of returning immediately, we handle the case // the same way that would occur if the managed object lacked // an ICustomQueryInterface implementation. - break; - - default: - _ASSERTE(false && "Unknown result value"); + break; } } @@ -745,7 +748,7 @@ HRESULT NativeObjectWrapperContext::Create( ComHolder trackerObject; if (flags & InteropLib::Com::CreateObjectFlags_TrackerObject) { - hr = external->QueryInterface(IID_IReferenceTracker,(void**) &trackerObject); + hr = external->QueryInterface(IID_IReferenceTracker, (void**)&trackerObject); if (SUCCEEDED(hr)) RETURN_IF_FAILED(TrackerObjectManager::OnIReferenceTrackerFound(trackerObject)); } diff --git a/src/coreclr/interop/interoplib.cpp b/src/coreclr/interop/interoplib.cpp index 5680e8f06ba641..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(IID_IReferenceTracker,(void **) &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(IID_IUnknown,(void **) &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 ddb990ecc3996c..01c5a26d948201 100644 --- a/src/coreclr/interop/platform.h +++ b/src/coreclr/interop/platform.h @@ -12,24 +12,21 @@ #define _ASSERTE(x) assert((x)) #endif +#ifndef ARRAYSIZE +#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) +#endif // !ARRAYSIZE + #ifdef _WIN32 #include -#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 -#ifdef HOST_UNIX +#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 // HOST_UNIX +#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/trackerobjectmanager.cpp b/src/coreclr/interop/trackerobjectmanager.cpp index e0b7a0ba8b3230..6f7ee970717b49 100644 --- a/src/coreclr/interop/trackerobjectmanager.cpp +++ b/src/coreclr/interop/trackerobjectmanager.cpp @@ -10,7 +10,7 @@ using RuntimeCallContext = InteropLibImports::RuntimeCallContext; namespace { - //29a71c6a-3c42-4416-a39d-e2825a07a773" + //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 diff --git a/src/coreclr/vm/interoplibinterface.cpp b/src/coreclr/vm/interoplibinterface.cpp index 51b2529821a489..47f8b26a6251f7 100644 --- a/src/coreclr/vm/interoplibinterface.cpp +++ b/src/coreclr/vm/interoplibinterface.cpp @@ -19,19 +19,23 @@ using CreateObjectFlags = InteropLib::Com::CreateObjectFlags; using CreateComInterfaceFlags = InteropLib::Com::CreateComInterfaceFlags; -void* GetCurrentCtxCookieWrapper() -{ - -#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT - RETURN GetCurrentCtxCookie(); -#else - RETURN NULL; -#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT -} 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 { From d6dcd0e32d53e73256189a16f1c85000e6a49c08 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 30 Jun 2021 09:16:43 +0000 Subject: [PATCH 03/22] Further enhancements + gcenv.ee.cpp change for build failures --- src/coreclr/interop/comwrappers.cpp | 4 ++-- src/coreclr/interop/trackerobjectmanager.cpp | 2 +- src/coreclr/vm/gcenv.ee.cpp | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/coreclr/interop/comwrappers.cpp b/src/coreclr/interop/comwrappers.cpp index 7936addfce32ac..ba78cbc19db987 100644 --- a/src/coreclr/interop/comwrappers.cpp +++ b/src/coreclr/interop/comwrappers.cpp @@ -439,7 +439,7 @@ HRESULT ManagedObjectWrapper::Create( { userDefined, userDefinedCount } }; - ABI::ComInterfaceDispatch* dispSection = ABI::PopulateDispatchSection(wrapperMem, dispatchSectionOffset, sizeof(AllEntries)/sizeof(AllEntries[0]), AllEntries); + ABI::ComInterfaceDispatch* dispSection = ABI::PopulateDispatchSection(wrapperMem, dispatchSectionOffset, ARRAYSIZE(AllEntries), AllEntries); ManagedObjectWrapper* wrapper = new (wrapperMem) ManagedObjectWrapper { @@ -683,7 +683,7 @@ HRESULT ManagedObjectWrapper::QueryInterface( // Instead of returning immediately, we handle the case // the same way that would occur if the managed object lacked // an ICustomQueryInterface implementation. - break; + break; } } diff --git a/src/coreclr/interop/trackerobjectmanager.cpp b/src/coreclr/interop/trackerobjectmanager.cpp index 6f7ee970717b49..6f4bebc8b57e1a 100644 --- a/src/coreclr/interop/trackerobjectmanager.cpp +++ b/src/coreclr/interop/trackerobjectmanager.cpp @@ -124,7 +124,7 @@ namespace // QI for IUnknown to get the identity unknown ComHolder identity; - RETURN_IF_FAILED(obj->QueryInterface(IID_IUnknown, (void**) &identity)); + RETURN_IF_FAILED(obj->QueryInterface(IID_IUnknown, (void**)&identity)); // Get or create an existing implementation for this external. ComHolder target; diff --git a/src/coreclr/vm/gcenv.ee.cpp b/src/coreclr/vm/gcenv.ee.cpp index 5be5bc2d9ecf96..faeb30418c8de2 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; From 703a59ce65b3d6412b92677459f44bc0ca13cbc7 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 1 Jul 2021 09:59:27 +0000 Subject: [PATCH 04/22] Array size definition moved below windows.h --- src/coreclr/interop/platform.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/interop/platform.h b/src/coreclr/interop/platform.h index 01c5a26d948201..351b5ebf6ec486 100644 --- a/src/coreclr/interop/platform.h +++ b/src/coreclr/interop/platform.h @@ -12,14 +12,14 @@ #define _ASSERTE(x) assert((x)) #endif -#ifndef ARRAYSIZE -#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) -#endif // !ARRAYSIZE - #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 From 550ae661967f17f7e84e8ef21675f7822be73d0b Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 1 Jul 2021 13:05:03 +0000 Subject: [PATCH 05/22] MockReferenceTrackerRuntime test project changes for Linux --- src/tests/Interop/CMakeLists.txt | 5 + .../ReferenceTrackerRuntime.cpp | 47 +++- src/tests/Interop/common/xplatform.h | 261 +++++++++++++++++- 3 files changed, 294 insertions(+), 19 deletions(-) diff --git a/src/tests/Interop/CMakeLists.txt b/src/tests/Interop/CMakeLists.txt index b8f39f741985f6..428d8747b91db5 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/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp index bfe96dcebb689d..aa4e4605b166c5 100644 --- a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp +++ b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp @@ -2,15 +2,22 @@ // The .NET Foundation licenses this file to you under the MIT license. #include +#ifdef _WIN32 #include +#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/common/xplatform.h b/src/tests/Interop/common/xplatform.h index 35168b575bbecf..9da90641a30982 100644 --- a/src/tests/Interop/common/xplatform.h +++ b/src/tests/Interop/common/xplatform.h @@ -8,6 +8,94 @@ #ifndef WINDOWS +#include +#define __RPC_FAR +#define DECLSPEC_UUID(x) +#define DECLSPEC_NOVTABLE +#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE +#define interface struct +#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 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 0x80004001 + +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 & +#else +#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 & +#else +#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) + +// Common macro for working in COM +#define RETURN_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { return hr; } } + +#define __uuidof(type) IID_##type + +#ifndef assert +#define assert(e) ((void)0) +#endif // assert + #include #undef INT_MIN @@ -88,12 +176,177 @@ 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 +{ + +}; + +// Implementation of IUnknown operations +class UnknownImpl { public: - virtual int QueryInterface(void* riid,void** ppvObject) = 0; - virtual unsigned long AddRef() = 0; - virtual unsigned long Release() = 0; + UnknownImpl() : _refCount{ 1 } {}; + virtual ~UnknownImpl() = default; + + UnknownImpl(const UnknownImpl&) = delete; + UnknownImpl& operator=(const UnknownImpl&) = delete; + + UnknownImpl(UnknownImpl&&) : _refCount{ 1 } {}; + UnknownImpl& operator=(UnknownImpl&&) = delete; + + template + HRESULT DoQueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void **ppvObject, + /* [in] */ I1 i1, + /* [in] */ IR... remain) + { + if (ppvObject == nullptr) + return E_POINTER; + + if (riid == __uuidof(IUnknown)) + { + *ppvObject = static_cast(i1); + } + else + { + //Temporary commented: to be managed with templates (_uuidof(T) needed) or with + // dedicated if-logic over well-know types + //HRESULT hr = Internal::__QueryInterfaceImpl(riid, ppvObject, i1, remain...); + //if (hr != S_OK) + // return hr; + } + + DoAddRef(); + return S_OK; + } + + ULONG DoAddRef() + { + assert(_refCount > 0); + return (++_refCount); + } + + ULONG DoRelease() + { + assert(_refCount > 0); + ULONG c = (--_refCount); + if (c == 0) + delete this; + return c; + } + +protected: + ULONG GetRefCount() + { + return _refCount; + } + +private: + //std::atomic _refCount = 1; + //Initizialization moved ad constructor level + std::atomic _refCount; +}; + + +// Macro to use for defining ref counting impls +#define DEFINE_REF_COUNTING() \ + STDMETHOD_(ULONG, AddRef)(void) { return UnknownImpl::DoAddRef(); } \ + STDMETHOD_(ULONG, Release)(void) { return UnknownImpl::DoRelease(); } + +template +struct ComSmartPtr +{ + T* p; + + ComSmartPtr() + : p{ nullptr } + { } + + ComSmartPtr(_In_ T* t) + : p{ t } + { + if (p != nullptr) + (void)p->AddRef(); + } + + ComSmartPtr(_In_ const ComSmartPtr&) = delete; + + ComSmartPtr(_Inout_ ComSmartPtr&& other) + : p{ other.Detach() } + { } + + ~ComSmartPtr() + { + Release(); + } + + ComSmartPtr& operator=(_In_ const ComSmartPtr&) = delete; + + ComSmartPtr& operator=(_Inout_ ComSmartPtr&& other) + { + Attach(other.Detach()); + return (*this); + } + + operator T*() + { + return p; + } + + T** operator&() + { + return &p; + } + + T* operator->() + { + return p; + } + + void Attach(_In_opt_ T* t) noexcept + { + Release(); + p = t; + } + + T* Detach() noexcept + { + T* tmp = p; + p = nullptr; + return tmp; + } + + void Release() noexcept + { + if (p != nullptr) + { + (void)p->Release(); + p = nullptr; + } + } }; #define DECIMAL_NEG ((BYTE)0x80) From f3cf7867ee33c859ed51cb9b1bde6b9b70e5e0c1 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 1 Jul 2021 16:23:48 +0000 Subject: [PATCH 06/22] Use FALLTHROUGH macro in place of [[fallthrough]] --- src/coreclr/interop/comwrappers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/interop/comwrappers.cpp b/src/coreclr/interop/comwrappers.cpp index ba78cbc19db987..3b77fef6d67c5c 100644 --- a/src/coreclr/interop/comwrappers.cpp +++ b/src/coreclr/interop/comwrappers.cpp @@ -669,7 +669,7 @@ HRESULT ManagedObjectWrapper::QueryInterface( default: _ASSERTE(false && "Unknown result value"); - [[fallthrough]]; + FALLTHROUGH; case TryInvokeICustomQueryInterfaceResult::FailedToInvoke: // Set the 'lacks' flag since our attempt to use ICustomQueryInterface // indicated the object lacks an implementation. From d0b90ecdcefc9557ecd7cc1321461c87b02dd5eb Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 7 Jul 2021 16:06:45 +0000 Subject: [PATCH 07/22] WeakReference test project changes for Linux --- src/tests/Interop/CMakeLists.txt | 2 +- .../WeakReference/WeakReferenceNative.cpp | 2 + src/tests/Interop/common/xplatform.h | 115 +++++++++++++++++- 3 files changed, 113 insertions(+), 6 deletions(-) diff --git a/src/tests/Interop/CMakeLists.txt b/src/tests/Interop/CMakeLists.txt index 428d8747b91db5..226e5d128dacd3 100644 --- a/src/tests/Interop/CMakeLists.txt +++ b/src/tests/Interop/CMakeLists.txt @@ -96,7 +96,7 @@ endif(CLR_CMAKE_TARGET_WIN32) if(CLR_CMAKE_TARGET_UNIX) add_subdirectory(COM/ComWrappers/MockReferenceTrackerRuntime) - #add_subdirectory(COM/ComWrappers/WeakReference) + 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) diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp index 0d9de17306b35a..b82466c40fd4d0 100644 --- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp +++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp @@ -2,9 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. #include +#ifdef _WIN32 #include #include #include +#endif //_WIN32 namespace { diff --git a/src/tests/Interop/common/xplatform.h b/src/tests/Interop/common/xplatform.h index 9da90641a30982..7dff05f0b30fbb 100644 --- a/src/tests/Interop/common/xplatform.h +++ b/src/tests/Interop/common/xplatform.h @@ -28,6 +28,12 @@ #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) @@ -36,6 +42,14 @@ #define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000EL) #define E_NOTIMPL 0x80004001 +// 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; @@ -203,6 +217,99 @@ 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 HRESULT STDMETHODCALLTYPE GetWeakReference( + /* [retval][out] */ __RPC__deref_out_opt IWeakReference * *weakReference) = 0; +}; + + +namespace Internal +{ + template + HRESULT __QueryInterfaceImpl( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject, + /* [in] */ I obj) + { + //__uuidof(I) doesn't work on linux, so needed types are checked + if (riid == __uuidof(IInspectable) || riid == __uuidof(IWeakReference) || riid == __uuidof(IWeakReferenceSource)) + { + *ppvObject = static_cast(obj); + } + else + { + *ppvObject = nullptr; + return E_NOINTERFACE; + } + + return S_OK; + } + + template + HRESULT __QueryInterfaceImpl( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject, + /* [in] */ I1 i1, + /* [in] */ IR... remain) + { + //__uuidof(I1) doesn't work on linux, so needed types are checked + if (riid == __uuidof(IInspectable) || riid == __uuidof(IWeakReference) || riid == __uuidof(IWeakReferenceSource) ) + { + *ppvObject = static_cast(i1); + return S_OK; + } + + return __QueryInterfaceImpl(riid, ppvObject, remain...); + } +} + + // Implementation of IUnknown operations class UnknownImpl { @@ -232,11 +339,9 @@ class UnknownImpl } else { - //Temporary commented: to be managed with templates (_uuidof(T) needed) or with - // dedicated if-logic over well-know types - //HRESULT hr = Internal::__QueryInterfaceImpl(riid, ppvObject, i1, remain...); - //if (hr != S_OK) - // return hr; + HRESULT hr = Internal::__QueryInterfaceImpl(riid, ppvObject, i1, remain...); + if (hr != S_OK) + return hr; } DoAddRef(); From 3b5ed871e4e7e4f898cdb1d1eab46a8bcb8c1f0e Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 12 Jul 2021 13:32:31 +0000 Subject: [PATCH 08/22] Moved back comhelpers.h code from xplatform.h --- .../ReferenceTrackerRuntime.cpp | 2 +- .../WeakReference/WeakReferenceNative.cpp | 2 +- src/tests/Interop/common/ComHelpers.h | 30 ++- src/tests/Interop/common/xplatform.h | 190 ------------------ 4 files changed, 31 insertions(+), 193 deletions(-) diff --git a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp index aa4e4605b166c5..e25ded451cd40a 100644 --- a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp +++ b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. #include -#ifdef _WIN32 #include +#ifdef _WIN32 #include #else #include diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp index b82466c40fd4d0..3a2e05118af595 100644 --- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp +++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. #include -#ifdef _WIN32 #include +#ifdef _WIN32 #include #include #endif //_WIN32 diff --git a/src/tests/Interop/common/ComHelpers.h b/src/tests/Interop/common/ComHelpers.h index 93ae4a3a09fdce..c3db3f849b60c8 100644 --- a/src/tests/Interop/common/ComHelpers.h +++ b/src/tests/Interop/common/ComHelpers.h @@ -2,12 +2,13 @@ // 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 @@ -21,7 +22,12 @@ namespace Internal /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject, /* [in] */ I obj) { +#ifdef _WIN32 if (riid == __uuidof(I)) +#else + //__uuidof(I) doesn't work on linux, so needed types are checked + if (riid == __uuidof(IInspectable) || riid == __uuidof(IWeakReference) || riid == __uuidof(IWeakReferenceSource)) +#endif { *ppvObject = static_cast(obj); } @@ -41,7 +47,12 @@ namespace Internal /* [in] */ I1 i1, /* [in] */ IR... remain) { +#ifdef _WIN32 if (riid == __uuidof(I1)) +#else + //__uuidof(I1) doesn't work on linux, so needed types are checked + if (riid == __uuidof(IInspectable) || riid == __uuidof(IWeakReference) || riid == __uuidof(IWeakReferenceSource) ) +#endif { *ppvObject = static_cast(i1); return S_OK; @@ -55,14 +66,24 @@ namespace Internal class UnknownImpl { public: +#ifdef _WIN32 UnknownImpl() = default; +#else + UnknownImpl() : _refCount{ 1 } {}; +#endif virtual ~UnknownImpl() = default; UnknownImpl(const UnknownImpl&) = delete; UnknownImpl& operator=(const UnknownImpl&) = delete; +#ifdef _WIN32 UnknownImpl(UnknownImpl&&) = default; UnknownImpl& operator=(UnknownImpl&&) = default; + #else + UnknownImpl(UnknownImpl&&) : _refCount{ 1 } {}; + UnknownImpl& operator=(UnknownImpl&&) = delete; + #endif + template HRESULT DoQueryInterface( @@ -111,7 +132,12 @@ class UnknownImpl } private: +#ifdef _WIN32 std::atomic _refCount = 1; +#else + //Initizialization moved ad constructor level + std::atomic _refCount; +#endif }; // Macro to use for defining ref counting impls @@ -119,6 +145,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 +363,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 7dff05f0b30fbb..e5077d7cabbf10 100644 --- a/src/tests/Interop/common/xplatform.h +++ b/src/tests/Interop/common/xplatform.h @@ -8,7 +8,6 @@ #ifndef WINDOWS -#include #define __RPC_FAR #define DECLSPEC_UUID(x) #define DECLSPEC_NOVTABLE @@ -101,9 +100,6 @@ typedef GUID IID; #define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -// Common macro for working in COM -#define RETURN_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { return hr; } } - #define __uuidof(type) IID_##type #ifndef assert @@ -268,192 +264,6 @@ IWeakReferenceSource : public IUnknown /* [retval][out] */ __RPC__deref_out_opt IWeakReference * *weakReference) = 0; }; - -namespace Internal -{ - template - HRESULT __QueryInterfaceImpl( - /* [in] */ REFIID riid, - /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject, - /* [in] */ I obj) - { - //__uuidof(I) doesn't work on linux, so needed types are checked - if (riid == __uuidof(IInspectable) || riid == __uuidof(IWeakReference) || riid == __uuidof(IWeakReferenceSource)) - { - *ppvObject = static_cast(obj); - } - else - { - *ppvObject = nullptr; - return E_NOINTERFACE; - } - - return S_OK; - } - - template - HRESULT __QueryInterfaceImpl( - /* [in] */ REFIID riid, - /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject, - /* [in] */ I1 i1, - /* [in] */ IR... remain) - { - //__uuidof(I1) doesn't work on linux, so needed types are checked - if (riid == __uuidof(IInspectable) || riid == __uuidof(IWeakReference) || riid == __uuidof(IWeakReferenceSource) ) - { - *ppvObject = static_cast(i1); - return S_OK; - } - - return __QueryInterfaceImpl(riid, ppvObject, remain...); - } -} - - -// Implementation of IUnknown operations -class UnknownImpl -{ -public: - UnknownImpl() : _refCount{ 1 } {}; - virtual ~UnknownImpl() = default; - - UnknownImpl(const UnknownImpl&) = delete; - UnknownImpl& operator=(const UnknownImpl&) = delete; - - UnknownImpl(UnknownImpl&&) : _refCount{ 1 } {}; - UnknownImpl& operator=(UnknownImpl&&) = delete; - - template - HRESULT DoQueryInterface( - /* [in] */ REFIID riid, - /* [iid_is][out] */ _COM_Outptr_ void **ppvObject, - /* [in] */ I1 i1, - /* [in] */ IR... remain) - { - if (ppvObject == nullptr) - return E_POINTER; - - if (riid == __uuidof(IUnknown)) - { - *ppvObject = static_cast(i1); - } - else - { - HRESULT hr = Internal::__QueryInterfaceImpl(riid, ppvObject, i1, remain...); - if (hr != S_OK) - return hr; - } - - DoAddRef(); - return S_OK; - } - - ULONG DoAddRef() - { - assert(_refCount > 0); - return (++_refCount); - } - - ULONG DoRelease() - { - assert(_refCount > 0); - ULONG c = (--_refCount); - if (c == 0) - delete this; - return c; - } - -protected: - ULONG GetRefCount() - { - return _refCount; - } - -private: - //std::atomic _refCount = 1; - //Initizialization moved ad constructor level - std::atomic _refCount; -}; - - -// Macro to use for defining ref counting impls -#define DEFINE_REF_COUNTING() \ - STDMETHOD_(ULONG, AddRef)(void) { return UnknownImpl::DoAddRef(); } \ - STDMETHOD_(ULONG, Release)(void) { return UnknownImpl::DoRelease(); } - -template -struct ComSmartPtr -{ - T* p; - - ComSmartPtr() - : p{ nullptr } - { } - - ComSmartPtr(_In_ T* t) - : p{ t } - { - if (p != nullptr) - (void)p->AddRef(); - } - - ComSmartPtr(_In_ const ComSmartPtr&) = delete; - - ComSmartPtr(_Inout_ ComSmartPtr&& other) - : p{ other.Detach() } - { } - - ~ComSmartPtr() - { - Release(); - } - - ComSmartPtr& operator=(_In_ const ComSmartPtr&) = delete; - - ComSmartPtr& operator=(_Inout_ ComSmartPtr&& other) - { - Attach(other.Detach()); - return (*this); - } - - operator T*() - { - return p; - } - - T** operator&() - { - return &p; - } - - T* operator->() - { - return p; - } - - void Attach(_In_opt_ T* t) noexcept - { - Release(); - p = t; - } - - T* Detach() noexcept - { - T* tmp = p; - p = nullptr; - return tmp; - } - - void Release() noexcept - { - if (p != nullptr) - { - (void)p->Release(); - p = nullptr; - } - } -}; - #define DECIMAL_NEG ((BYTE)0x80) #define DECIMAL_SCALE(dec) ((dec).u.u.scale) #define DECIMAL_SIGN(dec) ((dec).u.u.sign) From ebc4fd2375bd78e76b4752e8889466b0b328d3dc Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 16 Jul 2021 08:52:33 +0000 Subject: [PATCH 09/22] OBJC_TEST logic to avoid OSX errors --- src/coreclr/vm/interoplibinterface.cpp | 1 - src/tests/Interop/common/xplatform.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/interoplibinterface.cpp b/src/coreclr/vm/interoplibinterface.cpp index 47f8b26a6251f7..1b46b0de1b2208 100644 --- a/src/coreclr/vm/interoplibinterface.cpp +++ b/src/coreclr/vm/interoplibinterface.cpp @@ -20,7 +20,6 @@ using CreateObjectFlags = InteropLib::Com::CreateObjectFlags; using CreateComInterfaceFlags = InteropLib::Com::CreateComInterfaceFlags; - namespace { diff --git a/src/tests/Interop/common/xplatform.h b/src/tests/Interop/common/xplatform.h index e5077d7cabbf10..01a22b6d171a6c 100644 --- a/src/tests/Interop/common/xplatform.h +++ b/src/tests/Interop/common/xplatform.h @@ -12,7 +12,9 @@ #define DECLSPEC_UUID(x) #define DECLSPEC_NOVTABLE #define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE +#ifndef OBJC_TESTS #define interface struct +#endif #define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method #define STDMETHOD_(type,method) virtual type STDMETHODCALLTYPE method #undef _In_ From c0a8dae6cc69ff47737b79be29c869fee17cd46a Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 20 Jul 2021 10:19:13 +0000 Subject: [PATCH 10/22] Fix for GCC pipeline errors --- src/coreclr/interop/comwrappers.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/interop/comwrappers.hpp b/src/coreclr/interop/comwrappers.hpp index fb75c0f12f93a0..bd383beabc5dce 100644 --- a/src/coreclr/interop/comwrappers.hpp +++ b/src/coreclr/interop/comwrappers.hpp @@ -45,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 { @@ -172,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, From 4d4761ea8c376ad422795527364ae08fc918aeec Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 20 Jul 2021 14:39:30 +0000 Subject: [PATCH 11/22] Arraysize result comparison error --- src/coreclr/interop/comwrappers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/interop/comwrappers.cpp b/src/coreclr/interop/comwrappers.cpp index 3b77fef6d67c5c..a4afa67f96abed 100644 --- a/src/coreclr/interop/comwrappers.cpp +++ b/src/coreclr/interop/comwrappers.cpp @@ -400,7 +400,7 @@ HRESULT ManagedObjectWrapper::Create( 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); From e07ee91ff6ab002d0f31e6ba1d75a49466535c61 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 21 Jul 2021 09:53:38 +0000 Subject: [PATCH 12/22] Fix IID_IReferenceTracker GUID typo --- src/coreclr/interop/referencetrackertypes.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/interop/referencetrackertypes.hpp b/src/coreclr/interop/referencetrackertypes.hpp index 5b4276fe21c680..6e703a936413cd 100644 --- a/src/coreclr/interop/referencetrackertypes.hpp +++ b/src/coreclr/interop/referencetrackertypes.hpp @@ -47,7 +47,7 @@ class DECLSPEC_UUID("04b3486c-4687-4229-8d14-505ab584dd88") IFindReferenceTarget }; //11d3b13a-180e-4789-a8be-7712882893e6 -const GUID IID_IReferenceTracker = { 0x11d3b13a, 0x180e, 0x4789, { 0xa8, 0xbe, 0x77, 0x12, 0x88, 0x28, 0x93, 0x36} }; +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 { From dad8d0d8fe626ae5af8b60cae59dec037c13adf6 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 26 Jul 2021 13:11:34 +0000 Subject: [PATCH 13/22] QueryInterface implementation and other minor changes --- .../ReferenceTrackerRuntime.cpp | 2 +- .../WeakReference/WeakReferenceNative.cpp | 54 +++++++++++++++++++ src/tests/Interop/common/ComHelpers.h | 20 ++++--- src/tests/Interop/common/xplatform.h | 7 +-- 4 files changed, 66 insertions(+), 17 deletions(-) diff --git a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp index e25ded451cd40a..1af8b0ca095da9 100644 --- a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp +++ b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp @@ -212,7 +212,7 @@ namespace (void)tgt->AddRefFromReferenceTracker(); if (FAILED(tgt->Peg())) { - throw std::runtime_error("Peg failure"); + throw std::runtime_error{ "Peg failure" }; } } } diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp index 3a2e05118af595..b0bf9b7f73e1a5 100644 --- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp +++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp @@ -48,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() @@ -91,7 +116,36 @@ 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; + + //IUnknown not checked due to ambiguous coversion from IWeakReferenceSource and IInspectable + + if (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/common/ComHelpers.h b/src/tests/Interop/common/ComHelpers.h index c3db3f849b60c8..85cfe3219fdab8 100644 --- a/src/tests/Interop/common/ComHelpers.h +++ b/src/tests/Interop/common/ComHelpers.h @@ -14,6 +14,7 @@ // Common macro for working in COM #define RETURN_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { return hr; } } +#ifdef _WIN32 namespace Internal { template @@ -21,13 +22,8 @@ namespace Internal /* [in] */ REFIID riid, /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject, /* [in] */ I obj) - { -#ifdef _WIN32 + { if (riid == __uuidof(I)) -#else - //__uuidof(I) doesn't work on linux, so needed types are checked - if (riid == __uuidof(IInspectable) || riid == __uuidof(IWeakReference) || riid == __uuidof(IWeakReferenceSource)) -#endif { *ppvObject = static_cast(obj); } @@ -47,12 +43,7 @@ namespace Internal /* [in] */ I1 i1, /* [in] */ IR... remain) { -#ifdef _WIN32 if (riid == __uuidof(I1)) -#else - //__uuidof(I1) doesn't work on linux, so needed types are checked - if (riid == __uuidof(IInspectable) || riid == __uuidof(IWeakReference) || riid == __uuidof(IWeakReferenceSource) ) -#endif { *ppvObject = static_cast(i1); return S_OK; @@ -61,6 +52,7 @@ namespace Internal return __QueryInterfaceImpl(riid, ppvObject, remain...); } } + #endif // Implementation of IUnknown operations class UnknownImpl @@ -101,9 +93,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_NOINTERFACE; +#endif } DoAddRef(); diff --git a/src/tests/Interop/common/xplatform.h b/src/tests/Interop/common/xplatform.h index 01a22b6d171a6c..7422b7076f4957 100644 --- a/src/tests/Interop/common/xplatform.h +++ b/src/tests/Interop/common/xplatform.h @@ -12,6 +12,7 @@ #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 @@ -41,7 +42,7 @@ #define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002L) #define S_FALSE _HRESULT_TYPEDEF_(0x00000001L) #define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000EL) -#define E_NOTIMPL 0x80004001 +#define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001L) // Declaring a handle dummy struct for HSTRING the same way DECLARE_HANDLE does. typedef struct HSTRING__{ @@ -71,8 +72,6 @@ typedef const GUID *LPCGUID; #ifdef __cplusplus #define REFGUID const GUID & -#else -#define REFGUID const GUID * #endif @@ -94,8 +93,6 @@ inline int operator!=(REFGUID guidOne, REFGUID guidOther) typedef GUID IID; #ifdef __cplusplus #define REFIID const IID & -#else -#define REFIID const IID * #endif #define IID_NULL { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} From f09372b8da8a308c9888dfb162894c7be5631806 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 26 Jul 2021 15:24:47 +0000 Subject: [PATCH 14/22] UnknowImpl fix to remove WIN32 constructor cases --- src/tests/Interop/common/ComHelpers.h | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/tests/Interop/common/ComHelpers.h b/src/tests/Interop/common/ComHelpers.h index 85cfe3219fdab8..02d559db6452ab 100644 --- a/src/tests/Interop/common/ComHelpers.h +++ b/src/tests/Interop/common/ComHelpers.h @@ -57,26 +57,16 @@ namespace Internal // Implementation of IUnknown operations class UnknownImpl { -public: -#ifdef _WIN32 - UnknownImpl() = default; -#else +public: UnknownImpl() : _refCount{ 1 } {}; -#endif virtual ~UnknownImpl() = default; UnknownImpl(const UnknownImpl&) = delete; UnknownImpl& operator=(const UnknownImpl&) = delete; -#ifdef _WIN32 - UnknownImpl(UnknownImpl&&) = default; - UnknownImpl& operator=(UnknownImpl&&) = default; - #else UnknownImpl(UnknownImpl&&) : _refCount{ 1 } {}; - UnknownImpl& operator=(UnknownImpl&&) = delete; - #endif - - + UnknownImpl& operator=(UnknownImpl&&) = default; + template HRESULT DoQueryInterface( /* [in] */ REFIID riid, @@ -130,12 +120,7 @@ class UnknownImpl } private: -#ifdef _WIN32 - std::atomic _refCount = 1; -#else - //Initizialization moved ad constructor level - std::atomic _refCount; -#endif + std::atomic _refCount; }; // Macro to use for defining ref counting impls From 371d6a2e9e5089fdba3a3e2e36a87ed8913588f3 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 26 Jul 2021 16:22:35 +0000 Subject: [PATCH 15/22] UnknownImpl error fix --- src/tests/Interop/common/ComHelpers.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/Interop/common/ComHelpers.h b/src/tests/Interop/common/ComHelpers.h index 02d559db6452ab..fa3ee501207259 100644 --- a/src/tests/Interop/common/ComHelpers.h +++ b/src/tests/Interop/common/ComHelpers.h @@ -65,7 +65,11 @@ class UnknownImpl UnknownImpl& operator=(const UnknownImpl&) = delete; UnknownImpl(UnknownImpl&&) : _refCount{ 1 } {}; + #ifdef _WIN32 UnknownImpl& operator=(UnknownImpl&&) = default; + #else + UnknownImpl& operator=(UnknownImpl&&) = delete; + #endif template HRESULT DoQueryInterface( From ce9806c3e7a3c4d209038b667afc6521ee248a41 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 26 Jul 2021 16:42:33 +0000 Subject: [PATCH 16/22] Included ComWrappers Managed tests --- .../COM/ComWrappers/Directory.Build.props | 9 +++++ .../GlobalInstance.TrackerSupport.cs | 7 ++-- .../GlobalInstanceMarshallingTests.csproj | 2 ++ ...eMarshallingTestsBuiltInComDisabled.csproj | 2 ++ ...anceTrackerSupportTests_TargetUnix.csproj} | 3 +- ...ceTrackerSupportTests_TargetWindows.csproj | 33 +++++++++++++++++++ 6 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 src/tests/Interop/COM/ComWrappers/Directory.Build.props rename src/tests/Interop/COM/ComWrappers/GlobalInstance/{GlobalInstanceTrackerSupportTests.csproj => GlobalInstanceTrackerSupportTests_TargetUnix.csproj} (84%) create mode 100644 src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetWindows.csproj 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.csproj b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj similarity index 84% rename from src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests.csproj rename to src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj index 40529e85eab8bd..955d4d17cee057 100644 --- a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests.csproj +++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj @@ -5,6 +5,8 @@ true true true + + true @@ -15,7 +17,6 @@ - false Content diff --git a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetWindows.csproj b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetWindows.csproj new file mode 100644 index 00000000000000..44a5bde6f2acfa --- /dev/null +++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetWindows.csproj @@ -0,0 +1,33 @@ + + + Exe + App.manifest + true + true + true + $(DefineConstants);Windows + + true + + + + + + + + + + + + + false + Content + Always + + + + + PreserveNewest + + + From 85db0ed0d3347b5d7e983a0cd31c23dfd824dd76 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 27 Jul 2021 16:38:54 +0000 Subject: [PATCH 17/22] Excluded Unix ComWrappers test for Mono --- src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj | 1 + .../ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj | 1 + .../GlobalInstanceTrackerSupportTests_TargetUnix.csproj | 1 + 3 files changed, 3 insertions(+) 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/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj index 955d4d17cee057..56634404240db7 100644 --- a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj +++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstanceTrackerSupportTests_TargetUnix.csproj @@ -7,6 +7,7 @@ true true + true From 2d93161c68d7d94859ae1fe4dbc5c2f6ae81b536 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 28 Jul 2021 08:34:55 +0000 Subject: [PATCH 18/22] Disabled comwrappers test for mono + other code enhancements --- src/tests/Interop/common/ComHelpers.h | 2 +- src/tests/issues.targets | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/Interop/common/ComHelpers.h b/src/tests/Interop/common/ComHelpers.h index fa3ee501207259..bb389e907b1e5f 100644 --- a/src/tests/Interop/common/ComHelpers.h +++ b/src/tests/Interop/common/ComHelpers.h @@ -94,7 +94,7 @@ class UnknownImpl return hr; #else *ppvObject = nullptr; - return E_NOINTERFACE; + return E_NOTIMPL; #endif } 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 From bff18a98763edef9d22958e69cb2561e0f448cfd Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 27 Jul 2021 18:36:56 -0700 Subject: [PATCH 19/22] Enable interop info sync block cleanup under FEATURE_COMWRAPPERS --- src/coreclr/vm/interoputil.cpp | 13 +++++++++++-- src/coreclr/vm/interoputil.h | 9 +++++++++ src/coreclr/vm/syncblk.cpp | 8 ++++---- 3 files changed, 24 insertions(+), 6 deletions(-) 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) From 52587fc7bfb501b8ea975fa6af6df09408f70747 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 27 Jul 2021 18:54:12 -0700 Subject: [PATCH 20/22] Fix local instance ComWrappers WeakReference tests --- .../WeakReference/WeakReferenceNative.cpp | 4 +--- .../ComWrappers/WeakReference/WeakReferenceTest.cs | 13 ++++++++----- .../WeakReference/WeakReferenceTest.csproj | 2 -- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp index b0bf9b7f73e1a5..5643f26bad7074 100644 --- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp +++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp @@ -124,9 +124,7 @@ namespace if (ppvObject == nullptr) hr = E_POINTER; - //IUnknown not checked due to ambiguous coversion from IWeakReferenceSource and IInspectable - - if (riid == __uuidof(IWeakReferenceSource)) + if (riid == __uuidof(IUnknown) || riid == __uuidof(IWeakReferenceSource)) { *ppvObject = static_cast(this); hr = S_OK; diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs index 913dd53f6213ad..1ab7c87eb17628 100644 --- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs +++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs @@ -225,13 +225,16 @@ static int Main(string[] doNotUse) { try { - ValidateNonComWrappers(); + if (OperatingSystem.IsWindows()) + { + ValidateNonComWrappers(); - ComWrappers.RegisterForTrackerSupport(TestComWrappers.TrackerSupportInstance); - ValidateGlobalInstanceTrackerSupport(); + ComWrappers.RegisterForTrackerSupport(TestComWrappers.TrackerSupportInstance); + ValidateGlobalInstanceTrackerSupport(); - ComWrappers.RegisterForMarshalling(TestComWrappers.MarshallingInstance); - ValidateGlobalInstanceMarshalling(); + ComWrappers.RegisterForMarshalling(TestComWrappers.MarshallingInstance); + ValidateGlobalInstanceMarshalling(); + } ValidateLocalInstance(); } 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 From 22ed7de5b0faabf7a57e66e81bba5ffa0e7e9e3a Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 27 Jul 2021 20:20:17 -0700 Subject: [PATCH 21/22] Enable NativeComWeakHandleInfo under FEATURE_COMWRAPPERS --- src/coreclr/dlls/mscorrc/mscorrc.rc | 4 +- src/coreclr/dlls/mscorrc/resource.h | 4 +- src/coreclr/gc/objecthandle.cpp | 4 +- src/coreclr/pal/inc/rt/weakreference.h | 85 +++++++++++++++++++ src/coreclr/vm/appdomain.hpp | 4 +- src/coreclr/vm/gchandleutilities.h | 10 +-- src/coreclr/vm/weakreferencenative.cpp | 52 ++++++------ .../WeakReference/WeakReferenceTest.cs | 6 +- 8 files changed, 129 insertions(+), 40 deletions(-) create mode 100644 src/coreclr/pal/inc/rt/weakreference.h 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/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/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/weakreferencenative.cpp b/src/coreclr/vm/weakreferencenative.cpp index 4d56975daa065d..53178117f33a91 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,13 +139,15 @@ 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)); } @@ -285,11 +287,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 +340,7 @@ NOINLINE Object* LoadComWeakReferenceTarget(WEAKREFERENCEREF weakReference, Type return OBJECTREFToObject(gc.target); } -#endif // FEATURE_COMINTEROP +#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS //************************************************************************ @@ -444,7 +448,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 +466,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 +499,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 +517,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 +554,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 +573,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 +690,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 +699,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 +718,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 +727,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 +766,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 +829,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/COM/ComWrappers/WeakReference/WeakReferenceTest.cs b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs index 1ab7c87eb17628..38e40d129243f6 100644 --- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs +++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs @@ -229,13 +229,13 @@ static int Main(string[] doNotUse) { ValidateNonComWrappers(); - ComWrappers.RegisterForTrackerSupport(TestComWrappers.TrackerSupportInstance); - ValidateGlobalInstanceTrackerSupport(); - ComWrappers.RegisterForMarshalling(TestComWrappers.MarshallingInstance); ValidateGlobalInstanceMarshalling(); } + ComWrappers.RegisterForTrackerSupport(TestComWrappers.TrackerSupportInstance); + ValidateGlobalInstanceTrackerSupport(); + ValidateLocalInstance(); } catch (Exception e) From ac12e83157921d3b672b89010a74d0781b123e78 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 29 Jul 2021 08:31:55 +0000 Subject: [PATCH 22/22] weakreferencenative.cpp and ComHelpers.h code enhancements --- src/coreclr/vm/weakreferencenative.cpp | 5 +++-- src/tests/Interop/common/ComHelpers.h | 8 ++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/coreclr/vm/weakreferencenative.cpp b/src/coreclr/vm/weakreferencenative.cpp index 53178117f33a91..1354f35582fdb5 100644 --- a/src/coreclr/vm/weakreferencenative.cpp +++ b/src/coreclr/vm/weakreferencenative.cpp @@ -147,11 +147,12 @@ NativeComWeakHandleInfo* GetComWeakReferenceInfo(OBJECTREF* pObject) } else #endif -#ifdef FEATURE_COMWRAPPERS { +#ifdef FEATURE_COMWRAPPERS pWeakReferenceSource = reinterpret_cast(ComWrappersNative::GetIdentityForObject(pObject, IID_IWeakReferenceSource, &wrapperId)); +#endif } -#endif + if (pWeakReferenceSource == nullptr) { diff --git a/src/tests/Interop/common/ComHelpers.h b/src/tests/Interop/common/ComHelpers.h index bb389e907b1e5f..70c316e10c1f04 100644 --- a/src/tests/Interop/common/ComHelpers.h +++ b/src/tests/Interop/common/ComHelpers.h @@ -64,13 +64,9 @@ class UnknownImpl UnknownImpl(const UnknownImpl&) = delete; UnknownImpl& operator=(const UnknownImpl&) = delete; - UnknownImpl(UnknownImpl&&) : _refCount{ 1 } {}; - #ifdef _WIN32 - UnknownImpl& operator=(UnknownImpl&&) = default; - #else + UnknownImpl(UnknownImpl&&) = delete; UnknownImpl& operator=(UnknownImpl&&) = delete; - #endif - + template HRESULT DoQueryInterface( /* [in] */ REFIID riid,