Example #1
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
            //
            List <Type> 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());
        }
        /// <summary>
        /// Create the event interface
        /// </summary>
        public override void OnCreate()
        {
            if (m_type != null)
            {
                return;
            }

            string name = m_convInterface.ManagedName;

            m_convInterface.Create();

            using (TypeAttr attr = m_convInterface.RefTypeInfo.GetTypeAttr())
            {
                //
                // Emit attributes
                //

                //
                // Emit [ComEventInterfaceAttribute(...)]
                //
                ConstructorInfo ctorComEventInterface = typeof(ComEventInterfaceAttribute).GetConstructor(
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                    null,
                    new Type[] { typeof(Type), typeof(Type) },
                    null);

                //
                // Build the blob manually before creating the event interface / provider types.
                // We only need to give the name of the types, in order to simplify creation logic and avoid dependency
                //
                CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder();

                string eventInterfaceFullyQualifiedName = name;
                if (m_convInterface.ConvScope == ConvScope.External)
                {
                    eventInterfaceFullyQualifiedName = m_convInterface.ManagedType.AssemblyQualifiedName;
                }

                blobBuilder.AddFixedArg(eventInterfaceFullyQualifiedName);                      // source interface

                // Handle event provider name generation collision scenario
                m_eventProviderName = m_info.GetUniqueManagedName(
                    m_info.GetRecommendedManagedName(m_convInterface.RefTypeInfo, ConvType.Interface, true) + "_EventProvider");

                blobBuilder.AddFixedArg(m_eventProviderName);   // corresponding event provider
                m_typeBuilder.SetCustomAttribute(ctorComEventInterface, blobBuilder.GetBlob());

                //
                // Emit ComVisibleAttribute(false)
                //
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComVisible(false));

                //
                // Emit TypeLibTypeAttribute for TYPEFLAG_FHIDDEN
                //
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType(TypeLibTypeFlags.FHidden));

                bool isConversionLoss = false;

                //
                // Verify if the type has any properties
                //
                Type interfaceType = m_convInterface.RealManagedType;
                if (interfaceType.GetProperties().Length > 0)
                {
                    // Emit a warning and we'll skip the properties
                    m_info.ReportEvent(
                        WarningCode.Wrn_NoPropsInEvents,
                        Resource.FormatString("Wrn_NoPropsInEvents", RefTypeInfo.GetDocumentation()));

                    isConversionLoss = true;
                }

                //
                // Create event interface
                //

                InterfaceInfo eventInterfaceInfo = new InterfaceInfo(m_info, m_typeBuilder, false, m_convInterface.RefTypeInfo, attr, false, true);

                ConvCommon.CreateEventInterfaceCommon(eventInterfaceInfo);
                isConversionLoss |= eventInterfaceInfo.IsConversionLoss;

                //
                // Emit ComConversionLossAttribute if necessary
                //
                if (eventInterfaceInfo.IsConversionLoss)
                {
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss());
                }
            }

            m_type = m_typeBuilder.CreateType();
        }
        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());
        }
        /// <summary>
        /// Create the event interface
        /// </summary>
        public override void OnCreate()
        {
            if (m_type != null) return;

            string name = m_convInterface.ManagedName;

            m_convInterface.Create();

            using (TypeAttr attr = m_convInterface.RefTypeInfo.GetTypeAttr())
            {

                //
                // Emit attributes
                //

                //
                // Emit [ComEventInterfaceAttribute(...)]
                //
                ConstructorInfo ctorComEventInterface = typeof(ComEventInterfaceAttribute).GetConstructor(
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                    null,
                    new Type[] { typeof(Type), typeof(Type) },
                    null);

                //
                // Build the blob manually before creating the event interface / provider types.
                // We only need to give the name of the types, in order to simplify creation logic and avoid dependency
                //
                CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder();

                string eventInterfaceFullyQualifiedName = name;
                if (m_convInterface.ConvScope == ConvScope.External)
                    eventInterfaceFullyQualifiedName = m_convInterface.ManagedType.AssemblyQualifiedName;

                blobBuilder.AddFixedArg(eventInterfaceFullyQualifiedName);                      // source interface

                // Handle event provider name generation collision scenario
                m_eventProviderName = m_info.GetUniqueManagedName(
                    m_info.GetRecommendedManagedName(m_convInterface.RefTypeInfo, ConvType.Interface, true) + "_EventProvider");

                blobBuilder.AddFixedArg(m_eventProviderName);   // corresponding event provider
                m_typeBuilder.SetCustomAttribute(ctorComEventInterface, blobBuilder.GetBlob());

                //
                // Emit ComVisibleAttribute(false)
                //
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComVisible(false));

                //
                // Emit TypeLibTypeAttribute for TYPEFLAG_FHIDDEN
                //
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType(TypeLibTypeFlags.FHidden));

                bool isConversionLoss = false;

                //
                // Verify if the type has any properties
                //
                Type interfaceType = m_convInterface.RealManagedType;
                if (interfaceType.GetProperties().Length > 0)
                {
                    // Emit a warning and we'll skip the properties
                    m_info.ReportEvent(
                        WarningCode.Wrn_NoPropsInEvents,
                        Resource.FormatString("Wrn_NoPropsInEvents", RefTypeInfo.GetDocumentation()));

                    isConversionLoss = true;
                }

                //
                // Create event interface
                //

                InterfaceInfo eventInterfaceInfo = new InterfaceInfo(m_info, m_typeBuilder, false, m_convInterface.RefTypeInfo, attr, false, true);

                ConvCommon.CreateEventInterfaceCommon(eventInterfaceInfo);
                isConversionLoss |= eventInterfaceInfo.IsConversionLoss;

                //
                // Emit ComConversionLossAttribute if necessary
                //
                if (eventInterfaceInfo.IsConversionLoss)
                {
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss());
                }
            }

            m_type = m_typeBuilder.CreateType();
        }