public SignatureInfoMatchTarget(TypeInfo interfaceTypeInfo, int functionIndex, ElemDesc elemDesc, int parameterIndex) { if (interfaceTypeInfo == null) throw new ArgumentNullException(nameof(interfaceTypeInfo)); m_interfaceTypeInfo = interfaceTypeInfo; m_functionIndex = functionIndex; m_funcDesc = interfaceTypeInfo.GetFuncDesc(m_functionIndex); m_elemDesc = elemDesc; m_parameterIndex = parameterIndex; if (m_parameterIndex == 0) { m_name = "return"; } else { // the name of the parameter. string[] signatureNames = m_interfaceTypeInfo.GetNames(m_funcDesc.memid, m_funcDesc.cParams + 1); m_name = signatureNames[m_parameterIndex]; if (m_name == null || m_name.Trim().Equals("")) m_name = "_unnamed_arg_" + m_parameterIndex; } // NativeParentFunctionName m_nativeParentFunctionName = m_interfaceTypeInfo.GetDocumentation(m_funcDesc.memid); // NativeSignature m_nativeSignature = (new TlbType2String(interfaceTypeInfo, m_elemDesc.tdesc)).GetTypeString(); }
public FieldInfoMatchTarget(TypeInfo parentTypeInfo, int index) { if (parentTypeInfo == null) throw new ArgumentNullException(nameof(parentTypeInfo)); m_parentTypeInfo = parentTypeInfo; m_index = index; m_varDesc = m_parentTypeInfo.GetVarDesc(m_index); m_nativeParentTypeName = m_parentTypeInfo.GetDocumentation(); }
public FunctionInfoMatchTarget(TypeInfo parentTypeInfo, int index) { if (parentTypeInfo == null) throw new ArgumentNullException(nameof(parentTypeInfo)); m_interfaceTypeInfo = parentTypeInfo; m_index = index; m_funcDesc = parentTypeInfo.GetFuncDesc(m_index); m_nativeParentTypeName = m_interfaceTypeInfo.GetDocumentation(); }
/// <summary> /// This function is used to workaround around the fact that the TypeInfo might return IUnknown/IDispatch methods (in the case of dual interfaces) /// So we should always call this function to get the first index for different TypeInfo and never save the id /// </summary> public static int GetIndexOfFirstMethod(TypeInfo type, TypeAttr attr) { if (type == null) throw new ArgumentNullException(nameof(type)); if (attr == null) throw new ArgumentNullException(nameof(attr)); if (attr.typekind != TypeLibTypes.Interop.TYPEKIND.TKIND_DISPATCH) return 0; int nIndex = 0; if (attr.cFuncs >= 3) { // Check for IUnknown first using (FuncDesc func = type.GetFuncDesc(0)) { if (func.memid == 0x60000000 && func.elemdescFunc.tdesc.vt == (int)VarEnum.VT_VOID && func.cParams == 2 && func.GetElemDesc(0).tdesc.vt == (int)VarEnum.VT_PTR && func.GetElemDesc(1).tdesc.vt == (int)VarEnum.VT_PTR && "QueryInterface" == type.GetDocumentation(func.memid)) { nIndex = 3; } } if (attr.cFuncs >= 7) { using (FuncDesc func = type.GetFuncDesc(3)) { // Check IDispatch if (func.memid == 0x60010000 && func.elemdescFunc.tdesc.vt == (int)VarEnum.VT_VOID && func.cParams == 1 && func.GetElemDesc(0).tdesc.vt == (int)VarEnum.VT_PTR && "GetTypeInfoCount" == type.GetDocumentation(func.memid)) { nIndex = 7; } } } } return nIndex; }
private void CreateField(TypeInfo type, TypeAttr attr, VarDesc var, ref bool isConversionLoss) { TypeDesc fieldTypeDesc = var.elemdescVar.tdesc; TypeConverter typeConverter = new TypeConverter(m_info, type, fieldTypeDesc, ConversionType.Field); Type fieldType = typeConverter.ConvertedType; string fieldName = type.GetDocumentation(var.memid); FieldBuilder field = m_typeBuilder.DefineField(fieldName, fieldType, FieldAttributes.Public); typeConverter.ApplyAttributes(field); isConversionLoss |= typeConverter.IsConversionLoss; // // Emit ComConversionLossAttribute for fields if necessary // if (typeConverter.IsConversionLoss) { field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss()); // // Emit Wrn_UnconvertableField warning // m_info.ReportEvent( WarningCode.Wrn_UnconvertableField, Resource.FormatString("Wrn_UnconvertableField", m_typeBuilder.FullName, fieldName)); } // // Emit TypeLibVarAttribute if necessary // if (var.wVarFlags != 0) { field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibVar((TypeLibVarFlags)var.wVarFlags)); } }
public bool GetExclusiveDefaultInterfaceForCoclass(TypeInfo coclassTypeInfo, out TypeInfo exclusiveDefaultInterfaceTypeInfo) { exclusiveDefaultInterfaceTypeInfo = null; string expectedName = coclassTypeInfo.GetDocumentation(); foreach (DefaultInterfaceInfo defaultInterfaceInfo in m_defaultInterfaceInfoList) { if (defaultInterfaceInfo.isExclusive) { if (defaultInterfaceInfo.coclassName == expectedName) { exclusiveDefaultInterfaceTypeInfo = defaultInterfaceInfo.defaultInterface; return true; } } } return false; }
private void CreateField(TypeInfo type, TypeAttr attr, VarDesc var, ref bool isConversionLoss) { if (IsObjectType(type, var.elemdescVar.tdesc)) { isConversionLoss = true; } else { TypeConverter typeConverter = new TypeConverter(m_info, type, var.elemdescVar.tdesc, ConversionType.Field); Type fieldType = typeConverter.ConvertedType; // TlbImp2 will only skip reference types, instead of skipping every field // Also, TlbImp1 will skip ValueType *, which doesn't make any sense. TlbImp2 will keep ValueType * as IntPtr string fieldName = type.GetDocumentation(var.memid); // Generates the [FieldOffset(0)] layout declarations that approximate unions in managed code FieldBuilder field = m_typeBuilder.DefineField(fieldName, fieldType, FieldAttributes.Public); field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForFieldOffset(0)); typeConverter.ApplyAttributes(field); isConversionLoss |= typeConverter.IsConversionLoss; // // Emit ComConversionLossAttribute for fields if necessary // if (typeConverter.IsConversionLoss) { field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss()); // // Emit Wrn_UnconvertableField warning // m_info.ReportEvent( WarningCode.Wrn_UnconvertableField, Resource.FormatString("Wrn_UnconvertableField", m_typeBuilder.FullName, fieldName)); } } }
/// <summary> /// Is this type a StdOle2.Guid? The test is done using the GUID of type library /// </summary> /// <param name="type">The type</param> /// <returns>True if this type is a StdOle2.Guid</returns> private bool _IsStdOleGuid(TypeInfo type) { TypeLib typeLib = type.GetContainingTypeLib(); using (TypeLibAttr typeLibAttr = typeLib.GetLibAttr()) { if (type.GetDocumentation() == "GUID" && typeLibAttr.guid == WellKnownGuids.TYPELIBID_STDOLE2) return true; } return false; }
public static bool HasNewEnumMember(ConverterInfo info, TypeInfo typeInfo, string fullName) { bool hasNewEnumMember = false; bool hasDuplicateNewEnumMember = false; int firstNewEnum = -1; using (TypeAttr attr = typeInfo.GetTypeAttr()) { if (attr.IsDispatch || (attr.IsInterface && ConvCommon.IsDerivedFromIDispatch(typeInfo))) { // Check to see if the interface has a function with a DISPID of DISPID_NEWENUM. for (int i = 0; i < attr.cFuncs; ++i) { using(FuncDesc func = typeInfo.GetFuncDesc(i)) { if (IsNewEnumFunc(info, typeInfo, func, i)) { if (!hasNewEnumMember) firstNewEnum = func.memid; if (hasNewEnumMember) hasDuplicateNewEnumMember = true; // The interface has a function with a DISPID of DISPID_NEWENUM. hasNewEnumMember = true; } } } // Check to see if the interface as a property with a DISPID of DISPID_NEWENUM. for (int i = 0; i < attr.cVars; ++i) { using (VarDesc varDesc = typeInfo.GetVarDesc(i)) { if (IsNewEnumDispatchProperty(info, typeInfo, varDesc, i)) { if (!hasNewEnumMember) firstNewEnum = varDesc.memid; if (hasNewEnumMember) hasDuplicateNewEnumMember = true; // The interface has a property with a DISPID of DISPID_NEWENUM. hasNewEnumMember = true; } } } // Check to see if the ForceIEnumerable custom value exists on the type if (HasForceIEnumerableCustomAttribute(typeInfo)) hasNewEnumMember = true; if (hasDuplicateNewEnumMember) { info.ReportEvent( WarningCode.Wrn_MultiNewEnum, Resource.FormatString("Wrn_MultiNewEnum", fullName, typeInfo.GetDocumentation(firstNewEnum))); } } else { // Check to see if the ForceIEnumerable custom value exists on the type // If it does, spit out a warning. if (HasForceIEnumerableCustomAttribute(typeInfo)) { string msg = Resource.FormatString( "Wrn_IEnumCustomAttributeOnIUnknown", CustomAttributeGuids.GUID_ForceIEnumerable.ToString().ToUpper(), typeInfo.GetDocumentation()); info.ReportEvent(WarningCode.Wrn_IEnumCustomAttributeOnIUnknown, msg); } } } return hasNewEnumMember; }
/// <summary> /// Override the dispid if Guid_DispIdOverride is present /// </summary> /// <param name="index">The index of the func/var, not the disp id</param> /// <returns>Whether we have Guid_DispIdOverride or not</returns> public static bool GetOverrideDispId(ConverterInfo info, TypeInfo typeInfo, int index, InterfaceMemberType memberType, ref int dispid, bool isSet) { bool hasOverride = false; object data; if (memberType == InterfaceMemberType.Method) data = typeInfo.GetFuncCustData(index, CustomAttributeGuids.GUID_DispIdOverride); else { Debug.Assert(memberType == InterfaceMemberType.Variable); data = typeInfo.GetVarCustData(index, CustomAttributeGuids.GUID_DispIdOverride); } if (data is short) { dispid = (short)data; hasOverride = true; } else if (data is int) { dispid = (int)data; hasOverride = true; } else if (data != null) { // We only emit Wrn_NonIntegralCustomAttributeType when we set the id if (isSet) { // // Emit Wrn_NonIntegralCustomAttributeType warning // info.ReportEvent( WarningCode.Wrn_NonIntegralCustomAttributeType, Resource.FormatString("Wrn_NonIntegralCustomAttributeType", "{" + CustomAttributeGuids.GUID_DispIdOverride.ToString().ToUpper() + "}", typeInfo.GetDocumentation(dispid))); } } return hasOverride; }
/// <summary> /// Create the constant fields on the TypeBuilder according to the VarDesc in the type /// </summary> public static void CreateConstantFields(ConverterInfo info, TypeInfo type, TypeBuilder typeBuilder, ConvType convType) { using (TypeAttr attr = type.GetTypeAttr()) { int cVars = attr.cVars; for (int n = 0; n < cVars; ++n) { using (VarDesc var = type.GetVarDesc(n)) { string fieldName = type.GetDocumentation(var.memid); // We don't want the same conversion rules as Field for VT_BOOL and VT_ARRAY, so use Element instead // Basically Element is the same as Field except that it doesn't have special rules for VT_BOOL/VT_ARRAY TypeConverter typeConverter = new TypeConverter(info, type, var.elemdescVar.tdesc, ConversionType.Element); if (typeConverter.ConvertedType == typeof(DateTime)) typeConverter = new TypeConverter(typeof(float)); Type fieldType = typeConverter.ConvertedType; if (typeConverter.IsConversionLoss) { // // Emit Wrn_UnconvertableField warning // info.ReportEvent( WarningCode.Wrn_UnconvertableField, Resource.FormatString("Wrn_UnconvertableField", typeBuilder.FullName, fieldName)); } Type targetType; if (convType == ConvType.Enum) targetType = typeBuilder; // use enum type as the field type for enum else targetType = fieldType; // use the real type as the field type FieldBuilder fieldBuilder = typeBuilder.DefineField(fieldName, targetType, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); typeConverter.ApplyAttributes(fieldBuilder); // // Emit TypeLibVarAttribute if necessary // if (var.wVarFlags != 0) { fieldBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibVar((TypeLibVarFlags)var.wVarFlags)); } // Emit constant for static fields ConvCommon.SetDefaultValue(var, fieldType, fieldBuilder); } } } }
/// <summary> /// Check whether the interface, which the type "extendedType" wants to implement, is a class interface /// exported by TlbExp. /// We do not support this scenario, and an exception will be thrown. /// </summary> internal static void ThrowIfImplementingExportedClassInterface( TypeInfo extendedType, IConvInterface parentInterface) { TypeInfo parentType = parentInterface.RefTypeInfo; TypeLib parentTypeLib = parentType.GetContainingTypeLib(); TypeLib thisTypeLib = extendedType.GetContainingTypeLib(); var asmName = parentTypeLib.GetCustData(CustomAttributeGuids.GUID_ExportedFromComPlus) as string; if (asmName != null) { var parentName = parentType.GetCustData(CustomAttributeGuids.GUID_ManagedName) as string; Type parentManagedType = parentInterface.RealManagedType; if (parentName != null && parentManagedType != null && parentManagedType.IsClass) { string msg = Resource.FormatString("Err_ImplementExportedClassInterface", new object[] { extendedType.GetDocumentation(), thisTypeLib.GetDocumentation(), parentType.GetDocumentation(), parentTypeLib.GetDocumentation() }); throw new TlbImpGeneralException(msg, ErrorCode.Err_ImplementExportedClassInterface); } } }
protected void DefineType(ConverterInfo info, TypeInfo typeInfo, bool dealWithAlias) { m_info = info; m_typeInfo = typeInfo; if (dealWithAlias) m_nonAliasedTypeInfo = ConvCommon.GetAlias(typeInfo); else m_nonAliasedTypeInfo = typeInfo; try { OnDefineType(); // // Emit SuppressUnmanagedCodeSecurityAttribute for /unsafe switch // if ((m_info.Settings.m_flags & TypeLibImporterFlags.UnsafeInterfaces) != 0) { if (ConvType != ConvType.ClassInterface && ConvType != ConvType.EventInterface) m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForSuppressUnmanagedCodeSecurity()); } // Rule Engine AddAttributeAction if (m_info.Settings.m_ruleSet != null) { ICategory category = TypeCategory.GetInstance(); TypeInfoMatchTarget target = null; using (TypeAttr attr = m_typeInfo.GetTypeAttr()) { TypeLibTypes.Interop.TYPEKIND kind = attr.typekind; target = new TypeInfoMatchTarget(m_typeInfo.GetContainingTypeLib(), m_typeInfo, kind); } AbstractActionManager actionManager = RuleEngine.GetActionManager(); List<Rule> addAttributeRules = m_info.Settings.m_ruleSet.GetRule( category, AddAttributeActionDef.GetInstance(), target); foreach (Rule rule in addAttributeRules) { var addAttributeAction = rule.Action as AddAttributeAction; ConstructorInfo attributeCtor; byte[] blob; bool success = true; if (addAttributeAction.GetCustomAttribute(out attributeCtor, out blob)) { try { m_typeBuilder.SetCustomAttribute(attributeCtor, blob); } catch (Exception) { success = false; } } else { success = false; } if (!success) { string name = m_typeInfo.GetDocumentation(); string msg = Resource.FormatString("Wrn_AddCustomAttributeFailed", addAttributeAction.TypeName, name); m_info.ReportEvent(WarningCode.Wrn_AddCustomAttributeFailed, msg); } } } } catch (ReflectionTypeLoadException) { throw; // Fatal failure. Throw } catch (TlbImpResolveRefFailWrapperException) { throw; // Fatal failure. Throw } catch (TlbImpGeneralException) { throw; // Fatal failure. Throw } catch (Exception) { string name = String.Empty; if (m_typeInfo != null) { try { name = m_typeInfo.GetDocumentation(); } catch (Exception) { } } if (name != String.Empty) { string msg = Resource.FormatString("Wrn_InvalidTypeInfo", name); m_info.ReportEvent(WarningCode.Wrn_InvalidTypeInfo, msg); } else { string msg = Resource.FormatString("Wrn_InvalidTypeInfo_Unnamed"); m_info.ReportEvent(WarningCode.Wrn_InvalidTypeInfo_Unnamed, msg); } // When failure, try to create the type anyway if (m_typeBuilder != null) { m_type = m_typeBuilder.CreateType(); } } }