diff options
author | Aaron Robinson <arobins@microsoft.com> | 2021-06-22 09:44:16 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-22 09:44:16 +0300 |
commit | 8a20ae03566e3aabb0c95d2bb206a9ee780db4fd (patch) | |
tree | 8f298a07ac9fa0bfda9ef8af25476eaee98e8d31 /src | |
parent | eb57372f7eb239c301ddbff0b1314e5a8f7d66ae (diff) |
Convert some COM object checking functions to managed code (#54471)
* Convert COM object checking to managed code
* Convert IsComWrapperClass to a managed "can cast to" implementation.
* Add testing for updates.
Diffstat (limited to 'src')
-rw-r--r-- | src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs | 11 | ||||
-rw-r--r-- | src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs | 13 | ||||
-rw-r--r-- | src/coreclr/vm/ecalllist.h | 2 | ||||
-rw-r--r-- | src/coreclr/vm/interoputil.cpp | 19 | ||||
-rw-r--r-- | src/coreclr/vm/interoputil.h | 4 | ||||
-rw-r--r-- | src/coreclr/vm/marshalnative.cpp | 24 | ||||
-rw-r--r-- | src/coreclr/vm/marshalnative.h | 5 | ||||
-rw-r--r-- | src/coreclr/vm/runtimehandles.cpp | 28 | ||||
-rw-r--r-- | src/coreclr/vm/runtimehandles.h | 1 | ||||
-rw-r--r-- | src/tests/Interop/COM/NETClients/Aggregation/Program.cs | 6 | ||||
-rw-r--r-- | src/tests/Interop/COM/NETClients/ConsumeNETServer/Program.cs | 3 |
11 files changed, 29 insertions, 87 deletions
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 688e4f83908..e064c36746d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs @@ -464,8 +464,15 @@ namespace System.Runtime.InteropServices /// <summary> /// Checks if the object is classic COM component. /// </summary> - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern bool IsComObject(object o); + public static bool IsComObject(object o) + { + if (o is null) + { + throw new ArgumentNullException(nameof(o)); + } + + return o is __ComObject; + } /// <summary> /// Release the COM component and if the reference hits 0 zombie this object. diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 75aff556de7..dd17a2fa744 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -460,8 +460,17 @@ namespace System return GetInterfaceMethodImplementation(new QCallTypeHandle(ref nativeHandle), new QCallTypeHandle(ref nativeInterfaceHandle), interfaceMethodHandle); } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern bool IsComObject(RuntimeType type, bool isGenericCOM); + internal static bool IsComObject(RuntimeType type, bool isGenericCOM) + { +#if FEATURE_COMINTEROP + if (isGenericCOM) + return type == typeof(__ComObject); + + return RuntimeTypeHandle.CanCastTo(type, (RuntimeType)typeof(__ComObject)); +#else + return false; +#endif + } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool IsInterface(RuntimeType type); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 48a2d7d322e..1822422f596 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -209,7 +209,6 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetNumVirtualsAndStaticVirtuals", RuntimeTypeHandle::GetNumVirtualsAndStaticVirtuals) QCFuncElement("VerifyInterfaceIsImplemented", RuntimeTypeHandle::VerifyInterfaceIsImplemented) QCFuncElement("GetInterfaceMethodImplementation", RuntimeTypeHandle::GetInterfaceMethodImplementation) - FCFuncElement("IsComObject", RuntimeTypeHandle::IsComObject) FCFuncElement("IsValueType", RuntimeTypeHandle::IsValueType) FCFuncElement("IsInterface", RuntimeTypeHandle::IsInterface) FCFuncElement("IsByRefLike", RuntimeTypeHandle::IsByRefLike) @@ -768,7 +767,6 @@ FCFuncStart(gInteropMarshalFuncs) #ifdef FEATURE_COMINTEROP FCFuncElement("GetHRForException", MarshalNative::GetHRForException) - FCFuncElement("IsComObject", MarshalNative::IsComObject) FCFuncElement("GetObjectForIUnknownNative", MarshalNative::GetObjectForIUnknownNative) FCFuncElement("GetUniqueObjectForIUnknownNative", MarshalNative::GetUniqueObjectForIUnknownNative) FCFuncElement("GetNativeVariantForObjectNative", MarshalNative::GetNativeVariantForObjectNative) diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index e3797b13d50..2b6697887aa 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -820,25 +820,6 @@ BOOL CanCastComObject(OBJECTREF obj, MethodTable * pTargetMT) } } -// Returns TRUE iff the argument represents the "__ComObject" type or -// any type derived from it (i.e. typelib-imported RCWs). -BOOL IsComWrapperClass(TypeHandle type) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - MethodTable* pMT = type.GetMethodTable(); - if (pMT == NULL) - return FALSE; - - return pMT->IsComObjectType(); -} - // Returns TRUE iff the argument represents the "__ComObject" type. BOOL IsComObjectClass(TypeHandle type) { diff --git a/src/coreclr/vm/interoputil.h b/src/coreclr/vm/interoputil.h index c7209467b4a..b99764688dd 100644 --- a/src/coreclr/vm/interoputil.h +++ b/src/coreclr/vm/interoputil.h @@ -83,10 +83,6 @@ ULONG SafeReleasePreemp(IUnknown* pUnk, RCW* pRCW = NULL); // Determines if a COM object can be cast to the specified type. BOOL CanCastComObject(OBJECTREF obj, MethodTable * pTargetMT); -// includes Types which hold a "ComObject" class -// and types which are imported through typelib -BOOL IsComWrapperClass(TypeHandle type); - // includes Type which hold a "__ComObject" class BOOL IsComObjectClass(TypeHandle type); diff --git a/src/coreclr/vm/marshalnative.cpp b/src/coreclr/vm/marshalnative.cpp index 6d1c38b9d33..b28f34aa266 100644 --- a/src/coreclr/vm/marshalnative.cpp +++ b/src/coreclr/vm/marshalnative.cpp @@ -947,30 +947,6 @@ FCIMPL0(FC_BOOL_RET, MarshalNative::AreComObjectsAvailableForCleanup) FCIMPLEND //==================================================================== -// check if the object is classic COM component -//==================================================================== -FCIMPL1(FC_BOOL_RET, MarshalNative::IsComObject, Object* objUNSAFE) -{ - FCALL_CONTRACT; - - BOOL retVal = FALSE; - OBJECTREF obj = (OBJECTREF) objUNSAFE; - HELPER_METHOD_FRAME_BEGIN_RET_1(obj); - - if(!obj) - COMPlusThrowArgumentNull(W("o")); - - MethodTable* pMT = obj->GetMethodTable(); - PREFIX_ASSUME(pMT != NULL); - retVal = pMT->IsComObjectType(); - - HELPER_METHOD_FRAME_END(); - FC_RETURN_BOOL(retVal); -} -FCIMPLEND - - -//==================================================================== // free the COM component and zombie this object if the ref count hits 0 // further usage of this Object might throw an exception, //==================================================================== diff --git a/src/coreclr/vm/marshalnative.h b/src/coreclr/vm/marshalnative.h index 790c7316d32..8a3615294ff 100644 --- a/src/coreclr/vm/marshalnative.h +++ b/src/coreclr/vm/marshalnative.h @@ -104,11 +104,6 @@ public: static FCDECL2(IUnknown*, CreateAggregatedObjectNative, IUnknown* pOuter, Object* refObjUNSAFE); //==================================================================== - // check if the object is classic COM component - //==================================================================== - static FCDECL1(FC_BOOL_RET, IsComObject, Object* objUNSAFE); - - //==================================================================== // free the COM component and zombie this object // further usage of this Object might throw an exception, //==================================================================== diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index a8851f307ed..d3c21535cc4 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1033,34 +1033,6 @@ RuntimeTypeHandle::IsVisible( return fIsExternallyVisible; } // RuntimeTypeHandle::IsVisible -FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTypeUNSAFE, CLR_BOOL isGenericCOM) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - - BOOL ret = FALSE; - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - TypeHandle typeHandle = refType->GetType(); - - HELPER_METHOD_FRAME_BEGIN_RET_1(refType); - { - if (isGenericCOM) - ret = IsComObjectClass(typeHandle); - else - ret = IsComWrapperClass(typeHandle); - } - HELPER_METHOD_FRAME_END(); - - FC_RETURN_BOOL(ret); -} -FCIMPLEND - FCIMPL1(LPCUTF8, RuntimeTypeHandle::GetUtf8Name, ReflectClassBaseObject* pTypeUNSAFE) { CONTRACTL { FCALL_CHECK; diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index d40b45458af..33645adc3ec 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -191,7 +191,6 @@ public: static BOOL QCALLTYPE IsVisible(QCall::TypeHandle pTypeHandle); - static FCDECL2(FC_BOOL_RET, IsComObject, ReflectClassBaseObject *pType, CLR_BOOL isGenericCOM); static FCDECL2(FC_BOOL_RET, CanCastTo, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); static FCDECL2(FC_BOOL_RET, IsInstanceOfType, ReflectClassBaseObject *pType, Object *object); diff --git a/src/tests/Interop/COM/NETClients/Aggregation/Program.cs b/src/tests/Interop/COM/NETClients/Aggregation/Program.cs index ee1984f5842..2072b41a011 100644 --- a/src/tests/Interop/COM/NETClients/Aggregation/Program.cs +++ b/src/tests/Interop/COM/NETClients/Aggregation/Program.cs @@ -21,6 +21,12 @@ namespace NetClient var managedInner = new ManagedInner(); var nativeOuter = (AggregationTesting)managedInner; + Assert.IsTrue(typeof(ManagedInner).IsCOMObject); + Assert.IsTrue(typeof(AggregationTestingClass).IsCOMObject); + Assert.IsFalse(typeof(AggregationTesting).IsCOMObject); + Assert.IsTrue(Marshal.IsComObject(managedInner)); + Assert.IsTrue(Marshal.IsComObject(nativeOuter)); + Assert.IsTrue(nativeOuter.IsAggregated()); Assert.IsTrue(nativeOuter.AreAggregated(managedInner, nativeOuter)); Assert.IsFalse(nativeOuter.AreAggregated(nativeOuter, new object())); diff --git a/src/tests/Interop/COM/NETClients/ConsumeNETServer/Program.cs b/src/tests/Interop/COM/NETClients/ConsumeNETServer/Program.cs index a78274eb9c8..1bade41b255 100644 --- a/src/tests/Interop/COM/NETClients/ConsumeNETServer/Program.cs +++ b/src/tests/Interop/COM/NETClients/ConsumeNETServer/Program.cs @@ -24,6 +24,9 @@ namespace NetClient // The CoClass should be the activated type, _not_ the activation interface. Assert.AreEqual(test.GetType(), typeof(CoClass.ConsumeNETServerTestingClass)); + Assert.IsTrue(typeof(CoClass.ConsumeNETServerTestingClass).IsCOMObject); + Assert.IsFalse(typeof(CoClass.ConsumeNETServerTesting).IsCOMObject); + Assert.IsTrue(Marshal.IsComObject(test)); } static void Validate_CCW_Wasnt_Unwrapped() |