#endif // FEATURE_COMINTEROP
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-VOID NStructFieldTypeToString(FieldMarshaler* pFM, SString& strNStructFieldType)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pFM));
- }
- CONTRACTL_END;
-
- NStructFieldType cls = pFM->GetNStructFieldType();
- LPCWSTR strRetVal;
- CorElementType elemType = pFM->GetFieldDesc()->GetFieldType();
-
- // Some NStruct Field Types have extra information and require special handling.
- if (cls == NFT_FIXEDCHARARRAYANSI)
- {
- strNStructFieldType.Printf(W("fixed array of ANSI char (size = %i bytes)"), pFM->NativeSize());
- return;
- }
- else if (cls == NFT_FIXEDARRAY)
- {
- VARTYPE vtElement = ((FieldMarshaler_FixedArray*)pFM)->GetElementVT();
- TypeHandle thElement = ((FieldMarshaler_FixedArray*)pFM)->GetElementTypeHandle();
- BOOL fElementTypeUserDefined = FALSE;
-
- // Determine if the array type is a user defined type.
- if (vtElement == VT_RECORD)
- {
- fElementTypeUserDefined = TRUE;
- }
- else if (vtElement == VT_UNKNOWN || vtElement == VT_DISPATCH)
- {
- fElementTypeUserDefined = !thElement.IsObjectType();
- }
-
- // Retrieve the string representation for the VARTYPE.
- StackSString strVarType;
- MarshalInfo::VarTypeToString(vtElement, strVarType);
-
- MethodTable *pMT = ((FieldMarshaler_FixedArray*)pFM)->GetElementTypeHandle().GetMethodTable();
- DefineFullyQualifiedNameForClassW();
- WCHAR* szClassName = (WCHAR*)GetFullyQualifiedNameForClassW(pMT);
-
- if (fElementTypeUserDefined)
- {
- strNStructFieldType.Printf(W("fixed array of %s exposed as %s elements (array size = %i bytes)"),
- szClassName,
- strVarType.GetUnicode(), pFM->NativeSize());
- }
- else
- {
- strNStructFieldType.Printf(W("fixed array of %s (array size = %i bytes)"),
- szClassName, pFM->NativeSize());
- }
-
- return;
- }
-#ifdef FEATURE_COMINTEROP
- else if (cls == NFT_INTERFACE)
- {
- MethodTable *pItfMT = NULL;
- DWORD dwFlags = 0;
-
- ((FieldMarshaler_Interface*)pFM)->GetInterfaceInfo(&pItfMT, &dwFlags);
-
- if (dwFlags & ItfMarshalInfo::ITF_MARSHAL_DISP_ITF)
- {
- strNStructFieldType.Set(W("IDispatch "));
- }
- else
- {
- strNStructFieldType.Set(W("IUnknown "));
- }
-
- if (dwFlags & ItfMarshalInfo::ITF_MARSHAL_USE_BASIC_ITF)
- {
- strNStructFieldType.Append(W("(basic) "));
- }
-
-
- if (pItfMT)
- {
- DefineFullyQualifiedNameForClassW();
- GetFullyQualifiedNameForClassW(pItfMT);
-
- strNStructFieldType.Append(GetFullyQualifiedNameForClassW(pItfMT));
- }
-
- return;
- }
-#ifdef FEATURE_CLASSIC_COMINTEROP
- else if (cls == NFT_SAFEARRAY)
- {
- VARTYPE vtElement = ((FieldMarshaler_SafeArray*)pFM)->GetElementVT();
- TypeHandle thElement = ((FieldMarshaler_SafeArray*)pFM)->GetElementTypeHandle();
- BOOL fElementTypeUserDefined = FALSE;
-
- // Determine if the array type is a user defined type.
- if (vtElement == VT_RECORD)
- {
- fElementTypeUserDefined = TRUE;
- }
- else if (vtElement == VT_UNKNOWN || vtElement == VT_DISPATCH)
- {
- fElementTypeUserDefined = !thElement.IsObjectType();
- }
-
- // Retrieve the string representation for the VARTYPE.
- StackSString strVarType;
- MarshalInfo::VarTypeToString(vtElement, strVarType);
-
-
- StackSString strClassName;
- if (!thElement.IsNull())
- {
- DefineFullyQualifiedNameForClassW();
- MethodTable *pMT = ((FieldMarshaler_SafeArray*)pFM)->GetElementTypeHandle().GetMethodTable();
- strClassName.Set((WCHAR*)GetFullyQualifiedNameForClassW(pMT));
- }
- else
- {
- strClassName.Set(W("object"));
- }
-
- if (fElementTypeUserDefined)
- {
- strNStructFieldType.Printf(W("safe array of %s exposed as %s elements (array size = %i bytes)"),
- strClassName.GetUnicode(),
- strVarType.GetUnicode(), pFM->NativeSize());
- }
- else
- {
- strNStructFieldType.Printf(W("safearray of %s (array size = %i bytes)"),
- strClassName.GetUnicode(), pFM->NativeSize());
- }
-
- return;
- }
-#endif // FEATURE_CLASSIC_COMINTEROP
-#endif // FEATURE_COMINTEROP
- else if (cls == NFT_NESTEDLAYOUTCLASS)
- {
- MethodTable *pMT = ((FieldMarshaler_NestedLayoutClass*)pFM)->GetMethodTable();
- DefineFullyQualifiedNameForClassW();
- strNStructFieldType.Printf(W("nested layout class %s"),
- GetFullyQualifiedNameForClassW(pMT));
- return;
- }
- else if (cls == NFT_NESTEDVALUECLASS)
- {
- MethodTable *pMT = ((FieldMarshaler_NestedValueClass*)pFM)->GetMethodTable();
- DefineFullyQualifiedNameForClassW();
- strNStructFieldType.Printf(W("nested value class %s"),
- GetFullyQualifiedNameForClassW(pMT));
- return;
- }
- else if (cls == NFT_COPY1)
- {
- // The following CorElementTypes are the only ones handled with FieldMarshaler_Copy1.
- switch (elemType)
- {
- case ELEMENT_TYPE_I1:
- strRetVal = W("SByte");
- break;
-
- case ELEMENT_TYPE_U1:
- strRetVal = W("Byte");
- break;
-
- default:
- strRetVal = W("Unknown");
- break;
- }
- }
- else if (cls == NFT_COPY2)
- {
- // The following CorElementTypes are the only ones handled with FieldMarshaler_Copy2.
- switch (elemType)
- {
- case ELEMENT_TYPE_CHAR:
- strRetVal = W("Unicode char");
- break;
-
- case ELEMENT_TYPE_I2:
- strRetVal = W("Int16");
- break;
-
- case ELEMENT_TYPE_U2:
- strRetVal = W("UInt16");
- break;
-
- default:
- strRetVal = W("Unknown");
- break;
- }
- }
- else if (cls == NFT_COPY4)
- {
- // The following CorElementTypes are the only ones handled with FieldMarshaler_Copy4.
- switch (elemType)
- {
- // At this point, ELEMENT_TYPE_I must be 4 bytes long. Same for ELEMENT_TYPE_U.
- case ELEMENT_TYPE_I:
- case ELEMENT_TYPE_I4:
- strRetVal = W("Int32");
- break;
-
- case ELEMENT_TYPE_U:
- case ELEMENT_TYPE_U4:
- strRetVal = W("UInt32");
- break;
-
- case ELEMENT_TYPE_R4:
- strRetVal = W("Single");
- break;
-
- case ELEMENT_TYPE_PTR:
- strRetVal = W("4-byte pointer");
- break;
-
- default:
- strRetVal = W("Unknown");
- break;
- }
- }
- else if (cls == NFT_COPY8)
- {
- // The following CorElementTypes are the only ones handled with FieldMarshaler_Copy8.
- switch (elemType)
- {
- // At this point, ELEMENT_TYPE_I must be 8 bytes long. Same for ELEMENT_TYPE_U.
- case ELEMENT_TYPE_I:
- case ELEMENT_TYPE_I8:
- strRetVal = W("Int64");
- break;
-
- case ELEMENT_TYPE_U:
- case ELEMENT_TYPE_U8:
- strRetVal = W("UInt64");
- break;
-
- case ELEMENT_TYPE_R8:
- strRetVal = W("Double");
- break;
-
- case ELEMENT_TYPE_PTR:
- strRetVal = W("8-byte pointer");
- break;
-
- default:
- strRetVal = W("Unknown");
- break;
- }
- }
- else if (cls == NFT_FIXEDSTRINGUNI)
- {
- int nativeSize = pFM->NativeSize();
- int strLength = nativeSize / sizeof(WCHAR);
-
- strNStructFieldType.Printf(W("embedded LPWSTR (length %d)"), strLength);
-
- return;
- }
- else if (cls == NFT_FIXEDSTRINGANSI)
- {
- int nativeSize = pFM->NativeSize();
- int strLength = nativeSize / sizeof(CHAR);
-
- strNStructFieldType.Printf(W("embedded LPSTR (length %d)"), strLength);
-
- return;
- }
- else
- {
- // All other NStruct Field Types which do not require special handling.
- switch (cls)
- {
- case NFT_BSTR:
- strRetVal = W("BSTR");
- break;
-#ifdef FEATURE_COMINTEROP
- case NFT_HSTRING:
- strRetVal = W("HSTRING");
- break;
-#endif // FEATURE_COMINTEROP
- case NFT_STRINGUNI:
- strRetVal = W("LPWSTR");
- break;
- case NFT_STRINGANSI:
- strRetVal = W("LPSTR");
- break;
- case NFT_DELEGATE:
- strRetVal = W("Delegate");
- break;
-#ifdef FEATURE_COMINTEROP
- case NFT_VARIANT:
- strRetVal = W("VARIANT");
- break;
-#endif // FEATURE_COMINTEROP
- case NFT_ANSICHAR:
- strRetVal = W("ANSI char");
- break;
- case NFT_WINBOOL:
- strRetVal = W("Windows Bool");
- break;
- case NFT_CBOOL:
- strRetVal = W("CBool");
- break;
- case NFT_DECIMAL:
- strRetVal = W("DECIMAL");
- break;
- case NFT_DATE:
- strRetVal = W("DATE");
- break;
-#ifdef FEATURE_COMINTEROP
- case NFT_VARIANTBOOL:
- strRetVal = W("VARIANT Bool");
- break;
- case NFT_CURRENCY:
- strRetVal = W("CURRENCY");
- break;
-#endif // FEATURE_COMINTEROP
- case NFT_ILLEGAL:
- strRetVal = W("illegal type");
- break;
- case NFT_SAFEHANDLE:
- strRetVal = W("SafeHandle");
- break;
- case NFT_CRITICALHANDLE:
- strRetVal = W("CriticalHandle");
- break;
- default:
- strRetVal = W("<UNKNOWN>");
- break;
- }
- }
-
- strNStructFieldType.Set(strRetVal);
-
- return;
-}
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
#endif // CROSSGEN_COMPILE
}
//
-// MdaMarshaling
-//
-void MdaMarshaling::Initialize(MdaXmlElement* pXmlInput)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_pMethodFilter = new MdaQuery::CompiledQueries();
- m_pFieldFilter = new MdaQuery::CompiledQueries();
-
- MdaXmlElement* pXmlMethodFilter = pXmlInput->GetChild(MdaElemDecl(MethodFilter));
- if (pXmlMethodFilter)
- MdaQuery::Compile(pXmlMethodFilter, m_pMethodFilter);
-
- MdaXmlElement* pXmlFieldFilter = pXmlInput->GetChild(MdaElemDecl(FieldFilter));
- if (pXmlFieldFilter)
- MdaQuery::Compile(pXmlFieldFilter, m_pFieldFilter);
-}
-
-void MdaMarshaling::ReportFieldMarshal(FieldMarshaler* pFM)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pFM));
- }
- CONTRACTL_END;
-
- FieldDesc* pFD = pFM->GetFieldDesc();
-
- if (!pFD || !m_pFieldFilter->Test(pFD))
- return;
-
- MdaXmlElement* pXml;
- MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
-
- MdaXmlElement* pField = pXml->AddChild(MdaElemDecl(MarshalingField));
- AsMdaAssistant()->OutputFieldDesc(pFD, pField);
-
- StackSString sszField;
- SString managed;
- SString unmanaged;
-
- GetManagedSideForField(managed, pFD);
- GetUnmanagedSideForField(unmanaged, pFM);
-
- msg.SendMessagef(MDARC_MARSHALING_FIELD, AsMdaAssistant()->ToString(sszField, pFD).GetUnicode(), managed.GetUnicode(), unmanaged.GetUnicode());
-}
-
-
-void MdaMarshaling::GetManagedSideForField(SString& strManagedMarshalType, FieldDesc* pFD)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!CheckForPrimitiveType(pFD->GetFieldType(), strManagedMarshalType))
- {
- // The following workaround is added to avoid a recursion caused by calling GetTypeHandle on
- // the m_value field of the UIntPtr class.
- LPCUTF8 szNamespace, szClassName;
- IfFailThrow(pFD->GetMDImport()->GetNameOfTypeDef(pFD->GetApproxEnclosingMethodTable()->GetCl(), &szClassName, &szNamespace));
-
- if (strcmp(szNamespace, "System") == 0 && strcmp(szClassName, "UIntPtr") == 0)
- {
- static LPWSTR strRetVal = W("Void*");
- strManagedMarshalType.Set(strRetVal);
- }
- else
- {
- MetaSig fSig(pFD);
- fSig.NextArgNormalized();
- TypeHandle th = fSig.GetLastTypeHandleNT();
- if (th.IsNull())
- {
- static const WCHAR strErrorMsg[] = W("<error>");
- strManagedMarshalType.Set(strErrorMsg);
- }
- else
- {
- SigFormat sigFmt;
- sigFmt.AddType(th);
- UINT iManagedTypeLen = (UINT)strlen(sigFmt.GetCString()) + 1;
-
- WCHAR* buffer = strManagedMarshalType.OpenUnicodeBuffer(iManagedTypeLen);
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sigFmt.GetCString(), -1, buffer, iManagedTypeLen);
- strManagedMarshalType.CloseBuffer();
- }
- }
- }
-}
-
-void MdaMarshaling::GetUnmanagedSideForField(SString& strUnmanagedMarshalType, FieldMarshaler* pFM)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- NStructFieldTypeToString(pFM, strUnmanagedMarshalType);
-}
-
-
-void MdaMarshaling::GetManagedSideForMethod(SString& strManagedMarshalType, Module* pModule, SigPointer sig, CorElementType elemType)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!CheckForPrimitiveType(elemType, strManagedMarshalType))
- {
- // an empty type context is sufficient: all methods should be non-generic
- SigTypeContext emptyTypeContext;
-
- TypeHandle th = sig.GetTypeHandleNT(pModule, &emptyTypeContext);
- if (th.IsNull())
- {
- strManagedMarshalType.Set(W("<error>"));
- }
- else
- {
- SigFormat sigfmt;
- sigfmt.AddType(th);
- UINT iManagedMarshalTypeLength = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sigfmt.GetCString(), -1, NULL, 0);
-
- WCHAR* str = strManagedMarshalType.OpenUnicodeBuffer(iManagedMarshalTypeLength);
- MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sigfmt.GetCString(), -1, str, iManagedMarshalTypeLength);
- strManagedMarshalType.CloseBuffer();
- }
- }
-}
-
-
-void MdaMarshaling::GetUnmanagedSideForMethod(SString& strNativeMarshalType, MarshalInfo* mi, BOOL fSizeIsSpecified)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- mi->MarshalTypeToString(strNativeMarshalType, fSizeIsSpecified);
-}
-
-BOOL MdaMarshaling::CheckForPrimitiveType(CorElementType elemType, SString& strPrimitiveType)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- }
- CONTRACTL_END;
-
- LPWSTR strRetVal;
-
- switch (elemType)
- {
- case ELEMENT_TYPE_VOID:
- strRetVal = W("Void");
- break;
- case ELEMENT_TYPE_BOOLEAN:
- strRetVal = W("Boolean");
- break;
- case ELEMENT_TYPE_I1:
- strRetVal = W("SByte");
- break;
- case ELEMENT_TYPE_U1:
- strRetVal = W("Byte");
- break;
- case ELEMENT_TYPE_I2:
- strRetVal = W("Int16");
- break;
- case ELEMENT_TYPE_U2:
- strRetVal = W("UInt16");
- break;
- case ELEMENT_TYPE_CHAR:
- strRetVal = W("Char");
- break;
- case ELEMENT_TYPE_I:
- strRetVal = W("IntPtr");
- break;
- case ELEMENT_TYPE_U:
- strRetVal = W("UIntPtr");
- break;
- case ELEMENT_TYPE_I4:
- strRetVal = W("Int32");
- break;
- case ELEMENT_TYPE_U4:
- strRetVal = W("UInt32");
- break;
- case ELEMENT_TYPE_I8:
- strRetVal = W("Int64");
- break;
- case ELEMENT_TYPE_U8:
- strRetVal = W("UInt64");
- break;
- case ELEMENT_TYPE_R4:
- strRetVal = W("Single");
- break;
- case ELEMENT_TYPE_R8:
- strRetVal = W("Double");
- break;
- default:
- return FALSE;
- }
-
- strPrimitiveType.Set(strRetVal);
- return TRUE;
-}
-
-//
// MdaLoaderLock
//
void MdaLoaderLock::ReportViolation(HINSTANCE hInst)