Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaron Robinson <arobins@microsoft.com>2021-06-22 09:44:16 +0300
committerGitHub <noreply@github.com>2021-06-22 09:44:16 +0300
commit8a20ae03566e3aabb0c95d2bb206a9ee780db4fd (patch)
tree8f298a07ac9fa0bfda9ef8af25476eaee98e8d31 /src
parenteb57372f7eb239c301ddbff0b1314e5a8f7d66ae (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.cs11
-rw-r--r--src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs13
-rw-r--r--src/coreclr/vm/ecalllist.h2
-rw-r--r--src/coreclr/vm/interoputil.cpp19
-rw-r--r--src/coreclr/vm/interoputil.h4
-rw-r--r--src/coreclr/vm/marshalnative.cpp24
-rw-r--r--src/coreclr/vm/marshalnative.h5
-rw-r--r--src/coreclr/vm/runtimehandles.cpp28
-rw-r--r--src/coreclr/vm/runtimehandles.h1
-rw-r--r--src/tests/Interop/COM/NETClients/Aggregation/Program.cs6
-rw-r--r--src/tests/Interop/COM/NETClients/ConsumeNETServer/Program.cs3
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()