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();
        }
예제 #2
0
 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();
 }
예제 #4
0
        /// <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;
        }
예제 #5
0
        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));
            }
        }
예제 #6
0
        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;
        }
예제 #7
0
        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));
                }
            }
        }
예제 #8
0
        /// <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;
        }
예제 #9
0
        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;
        }
예제 #10
0
        /// <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;
        }
예제 #11
0
        /// <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);
                    }
                }
            }
        }
예제 #12
0
        /// <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);
                }
            }
        }
예제 #13
0
        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();
                }
            }
        }