Ejemplo n.º 1
0
        /// <summary>
        /// Returns whether the interface supports calling by IDispatch
        /// </summary>
        /// <param name="interfaceType">The interface</param>
        /// <returns>True if the interface supports calling by IDispatch, false otherwise</returns>
        bool InterfaceSupportsDispatch(Type type)
        {
            IConvBase convBase = m_info.LookupType(type);

            if (convBase == null)
            {
                return(false);
            }

            if (convBase as IConvInterface != null)
            {
                IConvInterface convInterface = convBase as IConvInterface;

                // dispinterface?
                if (convInterface.RefTypeInfo.GetTypeAttr().IsDispatch)
                {
                    return(true);
                }
                else
                {
                    return(ConvCommon.IsDerivedFromIDispatch(convInterface.RefTypeInfo));
                }
            }
            else if (convBase as IConvClassInterface != null || convBase as IConvEventInterface != null)
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 2
0
        // Helpers to perform actual definitions for types.
        public IConvBase GetInterface(TypeInfo type, TypeAttr attr)
        {
            IConvInterface convInterface = (IConvInterface)GetTypeRef(ConvType.Interface, type);

            convInterface.Create();
            return(convInterface);
        }
Ejemplo n.º 3
0
        private readonly TypeInfo m_typeInfo; // Corresponding type info

        #endregion Fields

        #region Constructors

        public ConvCoClassExternal(ConverterInfo info, TypeInfo typeInfo, Type managedType, ConverterAssemblyInfo converterAssemblyInfo)
        {
            m_typeInfo = typeInfo;
            m_managedType = managedType;

            info.RegisterType(managedType, this);

            TypeInfo defaultTypeInfo = ConvCommon.GetDefaultInterface(ConvCommon.GetAlias(typeInfo));
            if (defaultTypeInfo != null)
                m_defaultInterface = info.GetTypeRef(ConvType.Interface, defaultTypeInfo) as IConvInterface;
        }
Ejemplo n.º 4
0
        public ConvClassInterfaceExternal(ConverterInfo info, TypeInfo typeInfo, Type managedType, ConverterAssemblyInfo converterAssemblyInfo)
        {
            m_typeInfo    = typeInfo;
            m_managedType = managedType;

            info.RegisterType(managedType, this);

            //
            // Associate the default interface with the class interface
            //
            TypeInfo defaultInterfaceTypeInfo;

            if (converterAssemblyInfo.ClassInterfaceMap.GetExclusiveDefaultInterfaceForCoclass(typeInfo, out defaultInterfaceTypeInfo))
            {
                IConvInterface convInterface = info.GetTypeRef(ConvType.Interface, defaultInterfaceTypeInfo) as IConvInterface;
                convInterface.AssociateWithExclusiveClassInterface(this);
            }
        }
Ejemplo n.º 5
0
        protected override void OnDefineType()
        {
            TypeInfo typeInfo = RefNonAliasedTypeInfo;

            using (TypeAttr attr = typeInfo.GetTypeAttr())
            {
                string name = m_info.GetUniqueManagedName(RefTypeInfo, ConvType.CoClass);

                //
                // Collect information for a list of interfaces & event interface types
                //
                List <Type> intfList                 = new List <Type>(); // interface list
                List <Type> eventIntfList            = new List <Type>(); // event interface list
                TypeInfo    defaultInterfaceTypeInfo = null;

                int nCount = attr.cImplTypes;

                string sourceInterfaceNames  = String.Empty;
                bool   hasDefaultInterface   = false;
                bool   implementsIEnumerable = ConvCommon.ExplicitlyImplementsIEnumerable(typeInfo, attr);

                for (int n = 0; n < nCount; ++n)
                {
                    IMPLTYPEFLAGS flags     = typeInfo.GetImplTypeFlags(n);
                    bool          isDefault = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0;
                    bool          isSource  = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0;

                    TypeInfo typeImpl = typeInfo.GetRefType(n);

                    using (TypeAttr attrImpl = typeImpl.GetTypeAttr())
                    {
                        // Skip IUnknown & IDispatch
                        if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown)
                        {
                            continue;
                        }

                        // Skip non-dispatch interfaces that doesn't derive from IUnknown
                        if (!attrImpl.IsDispatch && !ConvCommon.IsDerivedFromIUnknown(typeImpl))
                        {
                            continue;
                        }

                        IConvInterface convInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, typeImpl);

                        // For source interfaces, try create the event interface
                        // Could be already created if it is the default source interface
                        if (isSource)
                        {
                            convInterface.DefineEventInterface();
                        }

                        // Use the RealManagedType (avoid getting the class interface)
                        Type typeRef = convInterface.RealManagedType;

                        // Append the source interface name to the list for the ComSourceInterfacesAttribute
                        if (isSource)
                        {
                            string interfaceName;
                            if (convInterface.ConvScope == ConvScope.External)
                            {
                                interfaceName = typeRef.AssemblyQualifiedName + "\0";
                            }
                            else
                            {
                                interfaceName = typeRef.FullName + "\0";
                            }

                            // Insert default source interface to the beginning
                            if (isDefault)
                            {
                                sourceInterfaceNames = interfaceName + sourceInterfaceNames;
                            }
                            else
                            {
                                sourceInterfaceNames = sourceInterfaceNames + interfaceName;
                            }
                        }

                        if (isDefault)
                        {
                            // Add the real interface first
                            if (isSource)
                            {
                                // For source interface, use the event interface instead
                                // Insert to the beginning
                                eventIntfList.Insert(0, convInterface.EventInterface.ManagedType);
                            }
                            else
                            {
                                m_defaultInterface = convInterface;

                                // Insert to the beginning
                                intfList.Insert(0, typeRef);
                                hasDefaultInterface      = true;
                                defaultInterfaceTypeInfo = typeImpl;
                            }
                        }
                        else
                        {
                            if (isSource)
                            {
                                // For source interface, add the event interface instead
                                eventIntfList.Add(convInterface.EventInterface.ManagedType);
                            }
                            else
                            {
                                if (m_defaultInterface == null)
                                {
                                    m_defaultInterface       = convInterface;
                                    defaultInterfaceTypeInfo = typeImpl;
                                }

                                intfList.Add(typeRef);
                            }
                        }
                    }
                }

                //
                // Get class interface
                //
                m_classInterface = m_info.GetTypeRef(ConvType.ClassInterface, RefTypeInfo) as IConvClassInterface;
                if (m_classInterface == null)
                {
                    throw new TlbImpInvalidTypeConversionException(RefTypeInfo);
                }

                //
                // Build implemented type list in a specific order
                //
                List <Type> implTypeList = new List <Type>();
                if (hasDefaultInterface)
                {
                    implTypeList.Add(intfList[0]);
                    intfList.RemoveAt(0);

                    implTypeList.Add(m_classInterface.ManagedType);
                }
                else
                {
                    implTypeList.Add(m_classInterface.ManagedType);
                    if (intfList.Count > 0)
                    {
                        implTypeList.Add(intfList[0]);
                        intfList.RemoveAt(0);
                    }
                }

                if (eventIntfList.Count > 0)
                {
                    implTypeList.Add(eventIntfList[0]);
                    eventIntfList.RemoveAt(0);
                }

                implTypeList.AddRange(intfList);
                implTypeList.AddRange(eventIntfList);

                // Check to see if the default interface has a member with a DISPID of DISPID_NEWENUM.
                if (defaultInterfaceTypeInfo != null)
                {
                    if (!implementsIEnumerable && ConvCommon.HasNewEnumMember(m_info, defaultInterfaceTypeInfo))
                    {
                        implTypeList.Add(typeof(System.Collections.IEnumerable));
                    }
                }

                // Check to see if the IEnumerable Custom Value exists on the CoClass if doesn't inherit from IEnumerable yet
                if (!implTypeList.Contains(typeof(System.Collections.IEnumerable)))
                {
                    if (ConvCommon.HasForceIEnumerableCustomAttribute(typeInfo))
                    {
                        implTypeList.Add(typeof(System.Collections.IEnumerable));
                    }
                }

                // Define the type
                m_typeBuilder = m_info.ModuleBuilder.DefineType(name,
                                                                TypeAttributes.Public | TypeAttributes.Import,
                                                                typeof(Object),
                                                                implTypeList.ToArray());

                // Handle [Guid(...)] custom attribute
                ConvCommon.DefineGuid(RefTypeInfo, RefNonAliasedTypeInfo, m_typeBuilder);

                // Handle [ClassInterface(ClassInterfaceType.None)]
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForClassInterface(ClassInterfaceType.None));

                // Handle [TypeLibType(...)] if evaluate to non-0
                using (TypeAttr refTypeAttr = RefTypeInfo.GetTypeAttr())
                {
                    if (refTypeAttr.wTypeFlags != 0)
                    {
                        m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)refTypeAttr.wTypeFlags));
                    }
                }

                // Handle [ComSourceInterfacesAttribute]
                if (sourceInterfaceNames != String.Empty)
                {
                    sourceInterfaceNames += "\0";
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComSourceInterfaces(sourceInterfaceNames));
                }

                // Add to symbol table automatically
                m_info.AddToSymbolTable(RefTypeInfo, ConvType.CoClass, this);

                // Register type
                m_info.RegisterType(m_typeBuilder, this);
            }
        }
Ejemplo n.º 6
0
        protected override void OnDefineType()
        {
            TypeInfo typeInfo = RefNonAliasedTypeInfo;
            using (TypeAttr attr = typeInfo.GetTypeAttr())
            {
                string name = m_info.GetUniqueManagedName(RefTypeInfo, ConvType.CoClass);

                //
                // Collect information for a list of interfaces & event interface types
                //
                var intfList = new List<Type>();         // interface list
                var eventIntfList = new List<Type>();    // event interface list
                TypeInfo defaultInterfaceTypeInfo = null;

                int nCount = attr.cImplTypes;

                string sourceInterfaceNames = String.Empty;
                bool hasDefaultInterface = false;
                bool implementsIEnumerable = ConvCommon.ExplicitlyImplementsIEnumerable(typeInfo, attr);

                for (int n = 0; n < nCount; ++n)
                {
                    TypeLibTypes.Interop.IMPLTYPEFLAGS flags = typeInfo.GetImplTypeFlags(n);
                    bool isDefault = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0;
                    bool isSource = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0;

                    TypeInfo typeImpl = typeInfo.GetRefType(n);

                    using (TypeAttr attrImpl = typeImpl.GetTypeAttr())
                    {
                        // Skip IUnknown & IDispatch
                        if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown)
                            continue;

                        // Skip non-dispatch interfaces that doesn't derive from IUnknown
                        if (!attrImpl.IsDispatch && !ConvCommon.IsDerivedFromIUnknown(typeImpl))
                            continue;

                        IConvInterface convInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, typeImpl);

                        ConvCommon.ThrowIfImplementingExportedClassInterface(RefTypeInfo, convInterface);

                        // For source interfaces, try create the event interface
                        // Could be already created if it is the default source interface
                        if (isSource)
                        {
                            convInterface.DefineEventInterface();
                        }

                        // Use the RealManagedType (avoid getting the class interface)
                        Type typeRef = convInterface.RealManagedType;

                        // Append the source interface name to the list for the ComSourceInterfacesAttribute
                        if (isSource)
                        {
                            string interfaceName;
                            if (convInterface.ConvScope == ConvScope.External)
                                interfaceName = typeRef.AssemblyQualifiedName + "\0";
                            else
                                interfaceName = typeRef.FullName + "\0";

                            // Insert default source interface to the beginning
                            if (isDefault)
                                sourceInterfaceNames = interfaceName + sourceInterfaceNames;
                            else
                                sourceInterfaceNames = sourceInterfaceNames + interfaceName;
                        }

                        if (isDefault)
                        {
                            // Add the real interface first
                            if (isSource)
                            {
                                // For source interface, use the event interface instead
                                // Insert to the beginning
                                eventIntfList.Insert(0, convInterface.EventInterface.ManagedType);
                            }
                            else
                            {
                                m_defaultInterface = convInterface;

                                // Insert to the beginning
                                intfList.Insert(0, typeRef);
                                hasDefaultInterface = true;
                                defaultInterfaceTypeInfo = typeImpl;
                            }
                        }
                        else
                        {
                            if (isSource)
                            {
                                // For source interface, add the event interface instead
                                eventIntfList.Add(convInterface.EventInterface.ManagedType);
                            }
                            else
                            {
                                if (m_defaultInterface == null)
                                {
                                    m_defaultInterface = convInterface;
                                    defaultInterfaceTypeInfo = typeImpl;
                                }

                                intfList.Add(typeRef);
                            }
                        }
                    }
                }

                //
                // Get class interface
                //
                m_classInterface = m_info.GetTypeRef(ConvType.ClassInterface, RefTypeInfo) as IConvClassInterface;
                if (m_classInterface == null) throw new TlbImpInvalidTypeConversionException(RefTypeInfo);

                //
                // Build implemented type list in a specific order
                //
                var implTypeList = new List<Type>();
                if (hasDefaultInterface)
                {
                    implTypeList.Add(intfList[0]);
                    intfList.RemoveAt(0);

                    implTypeList.Add(m_classInterface.ManagedType);
                }
                else
                {
                    implTypeList.Add(m_classInterface.ManagedType);
                    if (intfList.Count > 0)
                    {
                        implTypeList.Add(intfList[0]);
                        intfList.RemoveAt(0);
                    }
                }

                if (eventIntfList.Count > 0)
                {
                    implTypeList.Add(eventIntfList[0]);
                    eventIntfList.RemoveAt(0);
                }

                implTypeList.AddRange(intfList);
                implTypeList.AddRange(eventIntfList);

                // Check to see if the default interface has a member with a DISPID of DISPID_NEWENUM.
                if (defaultInterfaceTypeInfo != null)
                    if (!implementsIEnumerable && ConvCommon.HasNewEnumMember(m_info, defaultInterfaceTypeInfo, name))
                        implTypeList.Add(typeof(System.Collections.IEnumerable));

                // Check to see if the IEnumerable Custom Value exists on the CoClass if doesn't inherit from IEnumerable yet
                if (!implTypeList.Contains(typeof(System.Collections.IEnumerable)))
                {
                    if (ConvCommon.HasForceIEnumerableCustomAttribute(typeInfo))
                        implTypeList.Add(typeof(System.Collections.IEnumerable));
                }

                // Define the type
                m_typeBuilder = m_info.ModuleBuilder.DefineType(name,
                    TypeAttributes.Public | TypeAttributes.Import,
                    typeof(Object),
                    implTypeList.ToArray());

                // Handle [Guid(...)] custom attribute
                ConvCommon.DefineGuid(RefTypeInfo, RefNonAliasedTypeInfo, m_typeBuilder);

                // Handle [ClassInterface(ClassInterfaceType.None)]
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForClassInterface(ClassInterfaceType.None));

                // Handle [TypeLibType(...)] if evaluate to non-0
                using (TypeAttr refTypeAttr = RefTypeInfo.GetTypeAttr())
                {
                    if (refTypeAttr.wTypeFlags != 0)
                        m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)refTypeAttr.wTypeFlags));
                }

                // Handle [ComSourceInterfacesAttribute]
                if (sourceInterfaceNames != String.Empty)
                {
                    sourceInterfaceNames += "\0";
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComSourceInterfaces(sourceInterfaceNames));
                }

                // Add to symbol table automatically
                m_info.AddToSymbolTable(RefTypeInfo, ConvType.CoClass, this);

                // Register type
                m_info.RegisterType(m_typeBuilder, this);
            }
        }
Ejemplo n.º 7
0
        public AssemblyBuilder DoProcess(
            Object typeLib,
            string asmFilename,
            TypeLibImporterFlags flags,
            ITypeLibImporterNotifySink notifySink,
            byte[] publicKey,
            StrongNameKeyPair keyPair,
            string asmNamespace,
            Version asmVersion,
            bool isVersion2,
            bool isPreserveSig,
            bool isRemoveEnumPrefix)
        {
            m_resolver = notifySink;

            TypeLib tlb = new TypeLib((ITypeLib)typeLib);

            if (asmNamespace == null)
            {
                asmNamespace = tlb.GetDocumentation();

                string fileName = System.IO.Path.GetFileNameWithoutExtension(asmFilename);
                if (fileName != asmNamespace)
                {
                    asmNamespace = fileName;
                }

                //
                // Support for GUID_ManagedName (for namespace)
                //
                string customManagedNamespace = tlb.GetCustData(CustomAttributeGuids.GUID_ManagedName) as string;
                if (customManagedNamespace != null)
                {
                    customManagedNamespace = customManagedNamespace.Trim();
                    if (customManagedNamespace.ToUpper().EndsWith(".DLL"))
                    {
                        customManagedNamespace = customManagedNamespace.Substring(0, customManagedNamespace.Length - 4);
                    }
                    else if (customManagedNamespace.ToUpper().EndsWith(".EXE"))
                    {
                        customManagedNamespace = customManagedNamespace.Substring(0, customManagedNamespace.Length - 4);
                    }

                    asmNamespace = customManagedNamespace;
                }
            }

            //
            // Check for GUID_ExportedFromComPlus
            //
            object value = tlb.GetCustData(CustomAttributeGuids.GUID_ExportedFromComPlus);

            if (value != null)
            {
                // Make this a critical failure, instead of returning null which will be ignored.
                throw new TlbImpGeneralException(Resource.FormatString("Err_CircularImport", asmNamespace), ErrorCode.Err_CircularImport);
            }

            string strModuleName = asmFilename;

            if (asmFilename.Contains("\\"))
            {
                int nIndex;
                for (nIndex = strModuleName.Length; strModuleName[nIndex - 1] != '\\'; --nIndex)
                {
                    ;
                }
                strModuleName = strModuleName.Substring(nIndex);
            }

            // If the version information was not specified, then retrieve it from the typelib.
            if (asmVersion == null)
            {
                using (TypeLibAttr attr = tlb.GetLibAttr())
                {
                    asmVersion = new Version(attr.wMajorVerNum, attr.wMinorVerNum, 0, 0);
                }
            }

            // Assembly name should not have .DLL
            // while module name must contain the .DLL
            string strAsmName = String.Copy(strModuleName);

            if (strAsmName.EndsWith(".DLL", StringComparison.InvariantCultureIgnoreCase))
            {
                strAsmName = strAsmName.Substring(0, strAsmName.Length - 4);
            }

            AssemblyName assemblyName = new AssemblyName();

            assemblyName.Name = strAsmName;
            assemblyName.SetPublicKey(publicKey);
            assemblyName.Version = asmVersion;
            assemblyName.KeyPair = keyPair;

            m_assemblyBuilder = CreateAssemblyBuilder(assemblyName, tlb, flags);

            m_moduleBuilder = CreateModuleBuilder(m_assemblyBuilder, strModuleName);

            // Add a listener for the reflection load only resolve events.
            AppDomain           currentDomain     = Thread.GetDomain();
            ResolveEventHandler asmResolveHandler = new ResolveEventHandler(ReflectionOnlyResolveAsmEvent);

            currentDomain.ReflectionOnlyAssemblyResolve += asmResolveHandler;

            ConverterSettings settings;

            settings.m_isGenerateClassInterfaces = true;
            settings.m_namespace          = asmNamespace;
            settings.m_flags              = flags;
            settings.m_isVersion2         = isVersion2;
            settings.m_isPreserveSig      = isPreserveSig;
            settings.m_isRemoveEnumPrefix = isRemoveEnumPrefix;

            m_converterInfo = new ConverterInfo(m_moduleBuilder, tlb, m_resolver, settings);

            //
            // Generate class interfaces
            // NOTE:
            // We have to create class interface ahead of time because of the need to convert default interfaces to
            // class interfafces. However, this creates another problem that the event interface is always named first
            // before the other interfaces, because we need to create the type builder for the event interface first
            // so that we can create a class interface that implement it. But in the previous version of TlbImp,
            // it doesn't have to do that because it can directly create a typeref with the class interface name,
            // without actually creating anything like the TypeBuilder. The result is that the name would be different
            // with interop assemblies generated by old tlbimp in this case.
            // Given the nature of reflection API, this cannot be easily workarounded unless we switch to metadata APIs.
            // I believe this is acceptable because this only happens when:
            // 1. People decide to migrate newer .NET framework
            // 2. The event interface name conflicts with a normal interface
            //
            // In this case the problem can be easily fixed with a global refactoring, so I wouldn't worry about that
            //
            if (m_converterInfo.GenerateClassInterfaces)
            {
                CreateClassInterfaces();
            }

            //
            // Generate the remaining types except coclass
            // Because during creating coclass, we require every type, including all the referenced type to be created
            // This is a restriction of reflection API that when you override a method in parent interface, the method info
            // is needed so the type must be already created and loaded
            //
            List <TypeInfo> coclassList = new List <TypeInfo>();
            int             nCount      = tlb.GetTypeInfoCount();

            for (int n = 0; n < nCount; ++n)
            {
                TypeInfo type = null;
                try
                {
                    type = tlb.GetTypeInfo(n);
                    string strType = type.GetDocumentation();

                    TypeInfo typeToProcess;
                    TypeAttr attrToProcess;

                    using (TypeAttr attr = type.GetTypeAttr())
                    {
                        TYPEKIND kind = attr.typekind;
                        if (kind == TYPEKIND.TKIND_ALIAS)
                        {
                            ConvCommon.ResolveAlias(type, attr.tdescAlias, out typeToProcess, out attrToProcess);
                            if (attrToProcess.typekind == TYPEKIND.TKIND_ALIAS)
                            {
                                continue;
                            }
                            else
                            {
                                // We need to duplicate the definition of the user defined type in the name of the alias
                                kind          = attrToProcess.typekind;
                                typeToProcess = type;
                                attrToProcess = attr;
                            }
                        }
                        else
                        {
                            typeToProcess = type;
                            attrToProcess = attr;
                        }

                        switch (kind)
                        {
                        // Process coclass later because of reflection API requirements
                        case TYPEKIND.TKIND_COCLASS:
                            coclassList.Add(typeToProcess);
                            break;

                        case TYPEKIND.TKIND_ENUM:
                            m_converterInfo.GetEnum(typeToProcess, attrToProcess);
                            break;

                        case TYPEKIND.TKIND_DISPATCH:
                        case TYPEKIND.TKIND_INTERFACE:
                            m_converterInfo.GetInterface(typeToProcess, attrToProcess);
                            break;

                        case TYPEKIND.TKIND_MODULE:
                            m_converterInfo.GetModule(typeToProcess, attrToProcess);
                            break;

                        case TYPEKIND.TKIND_RECORD:
                            m_converterInfo.GetStruct(typeToProcess, attrToProcess);
                            break;

                        case TYPEKIND.TKIND_UNION:
                            m_converterInfo.GetUnion(typeToProcess, attrToProcess);
                            break;
                        }

                        m_converterInfo.ReportEvent(
                            MessageCode.Msg_TypeInfoImported,
                            Resource.FormatString("Msg_TypeInfoImported", typeToProcess.GetDocumentation()));
                    }
                }
                catch (ReflectionTypeLoadException)
                {
                    throw; // Fatal failure. Throw
                }
                catch (TlbImpResolveRefFailWrapperException)
                {
                    throw; // Fatal failure. Throw
                }
                catch (TlbImpGeneralException)
                {
                    throw; // Fatal failure. Throw
                }
                catch (TypeLoadException)
                {
                    throw; // TypeLoadException is critical. Throw.
                }
                catch (Exception)
                {
                }
            }

            // Process coclass after processing all the other types
            foreach (TypeInfo type in coclassList)
            {
                using (TypeAttr attr = type.GetTypeAttr())
                {
                    try
                    {
                        m_converterInfo.GetCoClass(type, attr);
                    }
                    catch (ReflectionTypeLoadException)
                    {
                        throw; // Fatal failure. Throw
                    }
                    catch (TlbImpResolveRefFailWrapperException)
                    {
                        throw; // Fatal failure. Throw
                    }
                    catch (TlbImpGeneralException)
                    {
                        throw; // Fatal failure. Throw
                    }
                    catch (TypeLoadException)
                    {
                        throw; // TypeLoadException is critical. Throw.
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            //
            // Build an array of EventItfInfo & generate event provider / event sink helpers
            //

            Event.TCEAdapterGenerator eventAdapterGenerator = new Event.TCEAdapterGenerator();
            List <Event.EventItfInfo> eventItfList          = new List <Event.EventItfInfo>();

            foreach (IConvBase symbol in m_converterInfo.GetAllConvBase)
            {
                IConvInterface convInterface = symbol as IConvInterface;
                if (convInterface != null)
                {
                    if (convInterface.EventInterface != null)
                    {
                        Debug.Assert(convInterface.EventInterface is ConvEventInterfaceLocal);
                        ConvEventInterfaceLocal local = convInterface.EventInterface as ConvEventInterfaceLocal;

                        Type eventInterfaceType = convInterface.EventInterface.ManagedType;

                        // Build EventItfInfo and add to the list
                        Type               sourceInterfaceType = convInterface.ManagedType;
                        string             sourceInterfaceName = sourceInterfaceType.FullName;
                        Event.EventItfInfo eventItfInfo        = new Event.EventItfInfo(
                            eventInterfaceType.FullName,
                            sourceInterfaceName,
                            local.EventProviderName,
                            eventInterfaceType,
                            convInterface.ManagedType);
                        eventItfList.Add(eventItfInfo);
                    }
                }
            }

            eventAdapterGenerator.Process(m_moduleBuilder, eventItfList);

            return(m_assemblyBuilder);
        }
Ejemplo n.º 8
0
        protected override void OnDefineType()
        {
            string classInterfaceName = m_info.GetUniqueManagedName(m_coclassTypeInfo, ConvType.ClassInterface);

            Type defaultInterfaceType = null;
            Type defaultSourceInterfaceType = null;

            m_convInterface = null;
            m_convSourceInterface = null;

            //
            // Convert default interface
            //
            if (m_defaultInterfaceTypeInfo != null)
            {
                m_convInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, m_defaultInterfaceTypeInfo);
                // Don't create the interface because we haven't associated the default interface with the class interface yet
                // We don't want to create anything in the "Define" stage
                //m_convInterface.Create();
                defaultInterfaceType = m_convInterface.ManagedType;
            }

            //
            // Convert default source interface
            //
            if (m_defaultSourceInterfaceTypeInfo != null)
            {
                m_convSourceInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, m_defaultSourceInterfaceTypeInfo);
                // Don't create the interface because we haven't associated the default interface with the class interface yet
                // We don't want to create anything in the "Define" stage
                // m_convSourceInterface.Create();
                Type sourceInterfaceType = m_convSourceInterface.RealManagedType;
                IConvEventInterface convEventInterface = m_convSourceInterface.DefineEventInterface();
                // Don't create the interface because we haven't associated the default interface with the class interface yet
                // We don't want to create anything in the "Define" stage
                // convEventInterface.Create();
                defaultSourceInterfaceType = m_convSourceInterface.EventInterface.ManagedType;
            }

            //
            // Prepare list of implemented interfaces
            //
            var implTypes = new List<Type>();
            if (defaultInterfaceType != null)
                implTypes.Add(defaultInterfaceType);
            if (defaultSourceInterfaceType != null)
                implTypes.Add(defaultSourceInterfaceType);

            // Create the class interface
            m_typeBuilder = m_info.ModuleBuilder.DefineType(
                    classInterfaceName,
                    TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Import,
                    null,
                    implTypes.ToArray());

            // Link to it so that ManagedType will return the class interface while GetWrappedInterfaceType will return the
            // real interface
            // This must be done before creating the coclass because coclass needs this information
            // Only do so when the default interface is exclusively belongs to one coclass

            if (m_convInterface != null && m_isExclusive)
            {
                // Check if the default interface -> class interface relationship exists in the default
                // interface's type lib. That means we only need to check if the default interface and
                // the coclass are in the same type library.
                TypeLib typeLib = m_convInterface.RefTypeInfo.GetContainingTypeLib();
                Guid libIdOfDefaultInterface;
                using (TypeLibAttr libAttr = typeLib.GetLibAttr())
                {
                    libIdOfDefaultInterface = libAttr.guid;
                }
                Guid libIdOfCoclass;
                TypeLib coclassTypeLib = m_coclassTypeInfo.GetContainingTypeLib();
                using (TypeLibAttr libAttr = coclassTypeLib.GetLibAttr())
                {
                    libIdOfCoclass = libAttr.guid;
                }
                if (libIdOfDefaultInterface.Equals(libIdOfCoclass))
                {
                    m_convInterface.AssociateWithExclusiveClassInterface(this as IConvClassInterface);
                }
            }

            // Emit GuidAttribute, which is the same as the default interface, if it exists
            // If there is no default Interface here, and the coclass implements IDispatch or IUnknown as non-source
            // interface, we use the IDispatch or IUnknown's guid.
            if (defaultInterfaceType != null)
            {
                ConvCommon.DefineGuid(m_convInterface.RefTypeInfo, m_convInterface.RefNonAliasedTypeInfo, m_typeBuilder);
            }
            else
            {
                TypeInfo ImplementedIDispatchOrIUnknownTypeInfo = null;
                using (TypeAttr attr = m_coclassTypeInfo.GetTypeAttr())
                {
                    for (int m = 0; m < attr.cImplTypes; ++m)
                    {
                        TypeLibTypes.Interop.IMPLTYPEFLAGS flags = m_coclassTypeInfo.GetImplTypeFlags(m);
                        bool bDefault = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0;
                        bool bSource = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0;

                        TypeInfo typeImpl = m_coclassTypeInfo.GetRefType(m);
                        using (TypeAttr attrImpl = typeImpl.GetTypeAttr())
                        {
                            if (attrImpl.Guid == WellKnownGuids.IID_IDispatch ||
                                attrImpl.Guid == WellKnownGuids.IID_IUnknown)
                            {
                                // If more than one IDispatch or IUnknown exist, we will pick the default one;
                                // If none of them is with the default flag, pick the first one.
                                if (!bSource && (bDefault || ImplementedIDispatchOrIUnknownTypeInfo == null))
                                {
                                    ImplementedIDispatchOrIUnknownTypeInfo = typeImpl;
                                }
                            }
                        }
                    }
                }
                if (ImplementedIDispatchOrIUnknownTypeInfo != null)
                {
                    ConvCommon.DefineGuid(ImplementedIDispatchOrIUnknownTypeInfo,
                        ImplementedIDispatchOrIUnknownTypeInfo, m_typeBuilder);
                }
            }

            // Make sure we know about the class interface before we go to define the coclass in the next statement
            m_info.RegisterType(m_typeBuilder, this);
            m_info.AddToSymbolTable(m_coclassTypeInfo, ConvType.ClassInterface, this);

            // Handle [CoClass(typeof(...))]
            Type typeRefCoClass = m_info.GetTypeRef(ConvType.CoClass, m_coclassTypeInfo).ManagedType;
            ConstructorInfo ctorCoClassAttribute = typeof(CoClassAttribute).GetConstructor(
                    new Type[] { typeof(Type) });
            // For back compatibility, use full name to create CoClassAttribute, instead of assembly qualified name.
            CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder();
            blobBuilder.AddFixedArg(typeRefCoClass.FullName);
            m_typeBuilder.SetCustomAttribute(ctorCoClassAttribute, blobBuilder.GetBlob());
        }
Ejemplo n.º 9
0
        public ConvEventInterfaceLocal(IConvInterface convInterface, ConverterInfo info)
        {
            m_convInterface = convInterface;

            DefineType(info, convInterface.RefTypeInfo, false);
        }
Ejemplo n.º 10
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);
                }
            }
        }
Ejemplo n.º 11
0
        public ConvEventInterfaceLocal(IConvInterface convInterface, ConverterInfo info)
        {
            m_convInterface = convInterface;

            DefineType(info, convInterface.RefTypeInfo, false);
        }