Beispiel #1
0
        /// <summary>
        /// If the type is aliased, return the ultimated non-aliased type if the type is user-defined, otherwise, return
        /// the aliased type directly. So the result could still be aliased to a built-in type.
        /// If the type is not aliased, just return the type directly
        /// </summary>
        public static void ResolveAlias(TypeInfo type, TypeDesc typeDesc, out TypeInfo realType, out TypeAttr realAttr)
        {
            if (type == null) throw new ArgumentNullException(nameof(type));
            if (typeDesc == null) throw new ArgumentNullException(nameof(typeDesc));
            if ((VarEnum)typeDesc.vt != VarEnum.VT_USERDEFINED)
            {
                // Already resolved
                realType = type;
                realAttr = type.GetTypeAttr();
                return;
            }
            else
            {
                TypeInfo refType = type.GetRefTypeInfo(typeDesc.hreftype);
                TypeAttr refAttr = refType.GetTypeAttr();

                // If the userdefined typeinfo is not itself an alias, then it is what the alias aliases.
                // Also, if the userdefined typeinfo is an alias to a builtin type, then the builtin
                // type is what the alias aliases.
                if (refAttr.typekind != TypeLibTypes.Interop.TYPEKIND.TKIND_ALIAS || (VarEnum)refAttr.tdescAlias.vt != VarEnum.VT_USERDEFINED)
                {
                    // Resolved
                    realType = refType;
                    realAttr = refAttr;
                }
                else
                {
                    // Continue resolving the type
                    ResolveAlias(refType, refAttr.tdescAlias, out realType, out realAttr);
                }
            }
        }
 public TypeInfoMatchTarget(TypeLib typeLib, TypeInfo typeInfo, TYPEKIND typeKind)
 {
     if (typeInfo == null) throw new ArgumentNullException(nameof(typeInfo));
     m_typeLib = typeLib;
     m_typeInfo = typeInfo;
     m_typeKind = typeKind;
     m_typeString = TypeLibUtility.TypeKind2String(m_typeKind);
     m_guid = typeInfo.GetTypeAttr().Guid;
 }
 private static void ProcessFields(TypeInfo parentTypeInfo, TreeNode parentTreeNode)
 {
     //
     // Walk through all vars (including elements from structs and disp interface, ...)
     //
     using (TypeAttr attr = parentTypeInfo.GetTypeAttr())
     {
         for (int i = 0; i < attr.cVars; ++i)
         {
             FieldInfoMatchTarget variableInfo = new FieldInfoMatchTarget(parentTypeInfo, i);
             TreeNode dispVarTreeNode = new TreeNode();
             dispVarTreeNode.Text = variableInfo.Name + ": " + variableInfo.Type;
             dispVarTreeNode.Tag = variableInfo;
             SetTlbTreeNodeImage(dispVarTreeNode);
             parentTreeNode.Nodes.Add(dispVarTreeNode);
         }
     }
 }
 private static void ProcessFunctions(TypeInfo parentTypeInfo, TreeNode parentTreeNode)
 {
     using (TypeAttr attr = parentTypeInfo.GetTypeAttr())
     {
         //
         // Walk through all the function/propput/propget/propref properties
         //
         for (int i = ConvCommon2.GetIndexOfFirstMethod(parentTypeInfo, attr);
              i < attr.cFuncs; ++i)
         {
             FunctionInfoMatchTarget functionInfo =
                 new FunctionInfoMatchTarget(parentTypeInfo, (short) i);
             TreeNode funcTreeNode = new TreeNode();
             if (functionInfo.FuncDesc.IsPropertyGet)
             {
                 funcTreeNode.Text = functionInfo.Name + " (getter)" + ": " + functionInfo.Type;
             }
             else if (functionInfo.FuncDesc.IsPropertyPut || functionInfo.FuncDesc.IsPropertyPutRef)
             {
                 funcTreeNode.Text = functionInfo.Name + " (setter)" + ": " + functionInfo.Type;
             }
             else
             {
                 funcTreeNode.Text = functionInfo.Name + ": " + functionInfo.Type;
             }
             funcTreeNode.Tag = functionInfo;
             SetTlbTreeNodeImage(funcTreeNode);
             parentTreeNode.Nodes.Add(funcTreeNode);
             ProcessFuncParams(parentTypeInfo, functionInfo.Index, funcTreeNode);
         }
     }
 }
Beispiel #5
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;
        }
Beispiel #6
0
        private bool RuleEngineResolveRedirection(RuleSet ruleSet, TypeInfo typeInfo,
            out Type convertedType)
        {
            convertedType = null;
            if (ruleSet != null)
            {
                ICategory category = TypeCategory.GetInstance();
                TypeLibTypes.Interop.TYPEKIND typeKind;
                using (TypeAttr attr = typeInfo.GetTypeAttr())
                {
                    typeKind = attr.typekind;
                }
                TypeInfoMatchTarget target = new TypeInfoMatchTarget(typeInfo.GetContainingTypeLib(),
                    typeInfo, typeKind);
                AbstractActionManager actionManager = RuleEngine.GetActionManager();
                List<Rule> resolveToRules = ruleSet.GetRule(
                    category, ResolveToActionDef.GetInstance(), target);
                if (resolveToRules.Count != 0)
                {
                    if (resolveToRules.Count > 1)
                    {
                        Output.WriteWarning(Resource.FormatString("Wrn_RuleMultipleMatch",
                                            ResolveToActionDef.GetInstance().GetActionName()),
                            WarningCode.Wrn_RuleMultipleMatch);
                    }
                    Rule resolveToRule =
                        resolveToRules[resolveToRules.Count - 1];

                    ResolveToAction action =
                        resolveToRule.Action as ResolveToAction;
                    try
                    {
                        Assembly assembly = Assembly.ReflectionOnlyLoad(action.AssemblyName);
                        convertedType = assembly.GetType(action.ManagedTypeFullName);
                        return true;
                    }
                    catch (Exception)
                    {
                        Output.WriteWarning(Resource.FormatString("Wrn_CannotLoadResolveToType",
                                            action.ManagedTypeFullName, action.AssemblyName),
                            WarningCode.Wrn_CannotLoadResolveToType);
                    }
                }
            }
            return false;
        }
Beispiel #7
0
        public static TypeInfo GetDefaultInterface(TypeInfo coclass)
        {
            TypeInfo typeInfo = coclass;
            TypeAttr typeAttr = coclass.GetTypeAttr();

            TypeInfo defaultInterface = null;

            for (int i = 0; i < typeAttr.cImplTypes; ++i)
            {
                TypeLibTypes.Interop.IMPLTYPEFLAGS flags = typeInfo.GetImplTypeFlags(i);

                // Non-source default interface?
                if ((flags & (TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE | TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT)) == TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT)
                {
                    return typeInfo.GetRefType(i);
                }
                else if ((flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) == 0 && defaultInterface == null)
                {
                    defaultInterface = typeInfo.GetRefType(i);
                }
            }

            return defaultInterface;
        }
Beispiel #8
0
        /// <summary>
        /// Whether the ITypeInfo is derived from IDispatch. 
        /// </summary>
        /// <return>True if ITypeInfo is derive from IID, false otherwise (including when ITypeInfo is IID)</return>
        public static bool IsDerivedFromIID(TypeInfo typeInfo, Guid iid)
        {
            using (TypeAttr attr = typeInfo.GetTypeAttr())
            {
                // Return false if the ITypeInfo is IID
                if (attr.Guid == iid)
                    return false;

                return IsDerivedFromIIDInternal(typeInfo, iid);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Common code shared by struct, enum, and union type creation 
        /// </summary>
        public static TypeBuilder DefineTypeHelper(ConverterInfo info, TypeInfo typeInfo, TypeInfo nonAliasedTypeInfo, TypeAttributes attributes, Type typeParent, ConvType convType)
        {
            using (TypeAttr typeAttr = nonAliasedTypeInfo.GetTypeAttr())
            {
                string name = info.GetUniqueManagedName(typeInfo, convType);

                TypeBuilder typeBuilder = info.ModuleBuilder.DefineType(name, attributes, typeParent);

                DefineGuid(typeInfo, nonAliasedTypeInfo, typeBuilder);

                // We only emit TypeLibType attribute for class/interface, according to MSDN
                // typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)attr.wTypeFlags));

                return typeBuilder;
            }
        }
Beispiel #10
0
        /// <summary>
        /// Gets the non-aliased type if it is a alias
        /// </summary>
        public static TypeInfo GetAlias(TypeInfo typeInfo)
        {
            //
            // Support for alias
            // If it is an alias, then it must be an alias to a user defined type, which we'll duplicate
            // all the definitions under the alias' name
            //
            using (TypeAttr typeAttr = typeInfo.GetTypeAttr())
            {
                if (typeAttr.IsAlias)
                {
                    TypeInfo resolvedTypeInfo;
                    TypeAttr resolvedTypeAttr;

                    ConvCommon.ResolveAlias(typeInfo, typeAttr.tdescAlias, out resolvedTypeInfo, out resolvedTypeAttr);

                    // If we resolved to an alias, this means this is an alias of built-in type and should never be
                    // passed in
                    Debug.Assert(!resolvedTypeAttr.IsAlias);

                    return resolvedTypeInfo;
                }
                else
                    return typeInfo;
            }
        }
Beispiel #11
0
        /// <summary>
        /// Define guid for a certain type. Prefer the GUID on aliased type, otherwise the aliased type
        /// </summary>
        /// <param name="typeInfo"></param>
        /// <param name="nonAliasedTypeInfo"></param>
        /// <param name="typeBuilder"></param>
        public static void DefineGuid(TypeInfo typeInfo, TypeInfo nonAliasedTypeInfo, TypeBuilder typeBuilder)
        {
            // Prefer the GUID on the alias, otherwise the aliased type
            Guid guid = typeInfo.GetTypeAttr().Guid;
            if (guid == Guid.Empty)
                guid = nonAliasedTypeInfo.GetTypeAttr().Guid;

            if (guid != Guid.Empty)
            {
                // Handle the [Guid(...)] attribute
                typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForGuid(guid));
            }
        }
Beispiel #12
0
        private static bool IsDerivedFromIIDInternal(TypeInfo typeInfo, Guid iid)
        {
            using (TypeAttr attr = typeInfo.GetTypeAttr())
            {
                if (attr.Guid == iid)
                    return true;

                // If we've seen a IUnknown (note that if the iid is IUnknown, we've tested that already)),
                // we've recused far enough
                if (attr.Guid == WellKnownGuids.IID_IUnknown)
                    return false;

                if (attr.cImplTypes == 1)
                {
                    TypeInfo parent = typeInfo.GetRefType(0);
                    return IsDerivedFromIIDInternal(parent, iid);
                }
            }

            return false;
        }
Beispiel #13
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);
                    }
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Test whether the specified VT_RECORD contains any field that can be converted to a managed reference type
        /// </summary>
        private bool HasObjectFields(TypeInfo typeInfo)
        {
            TypeAttr typeAttr = typeInfo.GetTypeAttr();
            for (int i = 0; i < typeAttr.cVars; ++i)
            {
                VarDesc var = typeInfo.GetVarDesc(i);
                if (IsObjectType(typeInfo, var.elemdescVar.tdesc))
                    return true;
            }

            return false;
        }
Beispiel #15
0
        public static int GetPointerSize(TypeInfo typeInfo)
        {
            using (TypeAttr attr = typeInfo.GetTypeAttr())
            {
                if (attr.Guid == WellKnownGuids.IID_IUnknown || attr.Guid == WellKnownGuids.IID_IDispatch)
                {
                    return attr.cbSizeInstance;
                }

                if (attr.cImplTypes == 1)
                {
                    TypeInfo parent = typeInfo.GetRefType(0);
                    return GetPointerSize(parent);
                }

                return attr.cbSizeInstance;
            }
        }
Beispiel #16
0
        /// <summary>
        /// Implement methods in parent interfaces
        /// </summary>
        private void HandleParentInterface(TypeInfo type, bool bSource, ref bool isConversionLoss, bool isDefault)
        {
            using (TypeAttr attr = type.GetTypeAttr())
            {
                InterfaceInfo interfaceInfo = new InterfaceInfo(m_info, m_typeBuilder, ConvCommon.InterfaceSupportsDispatch(type, attr), type, attr, true, bSource, type);
                interfaceInfo.IsDefaultInterface = isDefault;

                if (bSource)
                    // When adding override methods to the interface, we need to use the event interface for source interfaces
                    ConvCommon.CreateEventInterfaceCommon(interfaceInfo);
                else
                    ConvCommon.CreateInterfaceCommon(interfaceInfo);

                isConversionLoss |= interfaceInfo.IsConversionLoss;
            }
        }
Beispiel #17
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();
                }
            }
        }