summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dlls/mscorrc/mscorrc.rc2
-rw-r--r--src/vm/comcallablewrapper.cpp39
-rw-r--r--src/vm/comcallablewrapper.h3
3 files changed, 35 insertions, 9 deletions
diff --git a/src/dlls/mscorrc/mscorrc.rc b/src/dlls/mscorrc/mscorrc.rc
index 20612bbd7c..517c548bd7 100644
--- a/src/dlls/mscorrc/mscorrc.rc
+++ b/src/dlls/mscorrc/mscorrc.rc
@@ -907,7 +907,7 @@ BEGIN
IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_INTERFACE_METHOD_IMPL "Method '%3' on type '%1' from assembly '%2' tried to explicitly implement an interface method with weaker type parameter constraints."
IDS_CLASSLOAD_EXPLICIT_GENERIC "Could not load type '%1' from assembly '%2' because generic types cannot have explicit layout."
- IDS_EE_COM_INVISIBLE_PARENT "This type has a ComVisible(false) parent in its hierarchy, therefore QueryInterface calls for IDispatch or class interfaces are disallowed."
+ IDS_EE_COM_INVISIBLE_PARENT "Type '%1' has a ComVisible(false) parent '%2' in its hierarchy, therefore QueryInterface calls for IDispatch or class interfaces are disallowed."
IDS_EE_COMIMPORT_METHOD_NO_INTERFACE "Method '%1' in ComImport class '%2' must implement an interface method."
IDS_EE_ATTEMPT_TO_CREATE_GENERIC_CCW "Generic types cannot be marshaled to COM interface pointers."
diff --git a/src/vm/comcallablewrapper.cpp b/src/vm/comcallablewrapper.cpp
index 415cfa8232..ec05f00cd3 100644
--- a/src/vm/comcallablewrapper.cpp
+++ b/src/vm/comcallablewrapper.cpp
@@ -5305,7 +5305,16 @@ void ComCallWrapperTemplate::CheckParentComVisibility(BOOL fForIDispatch)
// Throw an exception to report the error.
if (!CheckParentComVisibilityNoThrow(fForIDispatch))
- COMPlusThrow(kInvalidOperationException, IDS_EE_COM_INVISIBLE_PARENT);
+ {
+ ComCallWrapperTemplate *invisParent = FindInvisibleParent();
+ _ASSERTE(invisParent != NULL);
+
+ SString thisType;
+ SString invisParentType;
+ TypeString::AppendType(thisType, m_thClass);
+ TypeString::AppendType(invisParentType, invisParent->m_thClass);
+ COMPlusThrow(kInvalidOperationException, IDS_EE_COM_INVISIBLE_PARENT, thisType.GetUnicode(), invisParentType.GetUnicode());
+ }
}
BOOL ComCallWrapperTemplate::CheckParentComVisibilityNoThrow(BOOL fForIDispatch)
@@ -6173,20 +6182,36 @@ void ComCallWrapperTemplate::DetermineComVisibility()
m_flags &= (~enum_InvisibleParent);
- // If there are no parents...leave it as false.
if (m_pParent == NULL)
return;
- // If our parent has an invisible parent
- if (m_pParent->HasInvisibleParent())
+ // Check if the parent has an invisible parent
+ // or if the parent itself is invisible.
+ if (m_pParent->HasInvisibleParent()
+ || !IsTypeVisibleFromCom(m_pParent->m_thClass))
{
+ _ASSERTE(NULL != FindInvisibleParent());
m_flags |= enum_InvisibleParent;
}
- // If our parent is invisible
- else if (!IsTypeVisibleFromCom(m_pParent->m_thClass))
+}
+
+ComCallWrapperTemplate* ComCallWrapperTemplate::FindInvisibleParent()
+{
+ ComCallWrapperTemplate* invisParentMaybe = m_pParent;
+
+ // Walk up the CCW parent classes and try to find
+ // if one is invisible to COM.
+ while (invisParentMaybe != NULL)
{
- m_flags |= enum_InvisibleParent;
+ // If our parent is invisible, return it.
+ if (!IsTypeVisibleFromCom(invisParentMaybe->m_thClass))
+ return invisParentMaybe;
+
+ invisParentMaybe = invisParentMaybe->m_pParent;
}
+
+ // All classes in hierarchy are COM visible
+ return NULL;
}
//--------------------------------------------------------------------------
diff --git a/src/vm/comcallablewrapper.h b/src/vm/comcallablewrapper.h
index a8cce3dccb..11c057444a 100644
--- a/src/vm/comcallablewrapper.h
+++ b/src/vm/comcallablewrapper.h
@@ -449,7 +449,8 @@ private:
ComMethodTable* CreateComMethodTableForBasic(MethodTable* pClassMT);
ComMethodTable* CreateComMethodTableForDelegate(MethodTable *pDelegateMT);
- void DetermineComVisibility();
+ void DetermineComVisibility();
+ ComCallWrapperTemplate* FindInvisibleParent();
private:
LONG m_cbRefCount;