未验证 提交 8a20ae03 编写于 作者: A Aaron Robinson 提交者: GitHub

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.
上级 eb57372f
......@@ -464,8 +464,15 @@ public static IntPtr CreateAggregatedObject(IntPtr pOuter, object o)
/// <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.
......
......@@ -460,8 +460,17 @@ internal RuntimeMethodHandleInternal GetInterfaceMethodImplementation(RuntimeTyp
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);
......
......@@ -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)
......
......@@ -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)
{
......
......@@ -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);
......
......@@ -946,30 +946,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,
......
......@@ -103,11 +103,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,
......
......@@ -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;
......
......@@ -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);
......
......@@ -21,6 +21,12 @@ static void ValidateNativeOuter()
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()));
......
......@@ -24,6 +24,9 @@ static void Validate_Activation()
// 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()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册