예제 #1
0
        /// <summary>
        /// Collect information
        /// </summary>
        private void Collect()
        {
            // Remember all the interface name to coclass name mapping
            Hashtable interfaceToCoClassMapping = new Hashtable();

            //
            // For every coclass
            //
            int nCount = m_typeLib.GetTypeInfoCount();
            for (int n = 0; n < nCount; ++n)
            {
                TypeInfo type = m_typeLib.GetTypeInfo(n);
                //
                // Walk the list of implemented interfaces
                //
                using (TypeAttr attr = type.GetTypeAttr())
                {
                    if (attr.typekind == TypeLibTypes.Interop.TYPEKIND.TKIND_COCLASS)
                    {
                        DefaultInterfaceInfo defaultInterfaceInfo = new DefaultInterfaceInfo();
                        defaultInterfaceInfo.coclass = type;
                        defaultInterfaceInfo.coclassName = type.GetDocumentation();

                        for (int m = 0; m < attr.cImplTypes; ++m)
                        {
                            TypeLibTypes.Interop.IMPLTYPEFLAGS flags = type.GetImplTypeFlags(m);
                            bool bDefault = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0;

                            // For invalid default interfaces, such as
                            // coclass MyObj
                            // {
                            //     [default] interface IUnknown;
                            //     interface IA;
                            // }
                            // to use the first valid interface, which is IA;
                            // if (!bDefault) continue;

                            bool bSource = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0;

                            TypeInfo typeImpl = type.GetRefType(m);

                            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;

                                string name = typeImpl.GetDocumentation();

                                if (bSource)
                                {
                                    // Default source interface
                                    if (bDefault ||                                             // If explicitly stated as default, use that
                                        defaultInterfaceInfo.defaultSourceInterface == null)    // otherwise, try to use the first one
                                    {
                                        defaultInterfaceInfo.defaultSourceInterface = typeImpl;
                                        defaultInterfaceInfo.defaultSourceInterfaceName = name;
                                    }
                                }
                                else
                                {
                                    // Default interface
                                    if (bDefault ||                                     // If explicitly stated as default, use that
                                        defaultInterfaceInfo.defaultInterface == null)  // otherwise, try to use the first one
                                    {
                                        defaultInterfaceInfo.defaultInterface = typeImpl;
                                        defaultInterfaceInfo.defaultInterfaceName = name;
                                    }
                                }
                            }

                        }

                        //
                        // Walk through the list of implemented interfaces again. This time we remember all the implemented interfaces (including base)
                        //
                        for (int m = 0; m < attr.cImplTypes; ++m)
                        {
                            TypeInfo typeImpl = type.GetRefType(m);
                            string name = typeImpl.GetDocumentation();

                            while (typeImpl != null)
                            {
                                // If we arleady seen this interface
                                if (interfaceToCoClassMapping.Contains(name))
                                {
                                    // and if it is for a different interface
                                    if ((string)interfaceToCoClassMapping[name] != defaultInterfaceInfo.coclassName)
                                    {
                                        // Set the name to null so that we know we've seen other interfaces
                                        interfaceToCoClassMapping[name] = null;
                                    }
                                }
                                else
                                {
                                    interfaceToCoClassMapping.Add(name, defaultInterfaceInfo.coclassName);
                                }

                                TypeAttr attrImpl = typeImpl.GetTypeAttr();
                                if (attrImpl.cImplTypes == 1)
                                    typeImpl = typeImpl.GetRefType(0);
                                else
                                    typeImpl = null;
                            }
                        }

                        // We do allow coclass that doesn't have any 'valid' default interfaces to have a class interface
                        // For example,
                        // coclass MyObject {
                        //     [default] interface IUnknown;
                        // }
                        m_defaultInterfaceInfoList.Add(defaultInterfaceInfo);
                    }
                }
            }

            foreach (DefaultInterfaceInfo defaultInterfaceInfo in m_defaultInterfaceInfoList)
            {
                bool isExclusive = true;
                if (defaultInterfaceInfo.defaultInterface != null)
                {
                    if (interfaceToCoClassMapping.Contains(defaultInterfaceInfo.defaultInterfaceName))
                    {
                        if (interfaceToCoClassMapping[defaultInterfaceInfo.defaultInterfaceName] == null)
                        {
                            isExclusive = false;
                        }
                    }
                    defaultInterfaceInfo.isExclusive = isExclusive;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Collect information
        /// </summary>
        private void Collect()
        {
            // Remember all the interface name to coclass name mapping
            Hashtable interfaceToCoClassMapping = new Hashtable();

            //
            // For every coclass
            //
            int nCount = m_typeLib.GetTypeInfoCount();

            for (int n = 0; n < nCount; ++n)
            {
                TypeInfo type = m_typeLib.GetTypeInfo(n);
                //
                // Walk the list of implemented interfaces
                //
                using (TypeAttr attr = type.GetTypeAttr())
                {
                    if (attr.typekind == TYPEKIND.TKIND_COCLASS)
                    {
                        DefaultInterfaceInfo defaultInterfaceInfo = new DefaultInterfaceInfo();
                        defaultInterfaceInfo.coclass     = type;
                        defaultInterfaceInfo.coclassName = type.GetDocumentation();

                        for (int m = 0; m < attr.cImplTypes; ++m)
                        {
                            IMPLTYPEFLAGS flags    = type.GetImplTypeFlags(m);
                            bool          bDefault = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0;

                            // For invalid default interfaces, such as
                            // coclass MyObj
                            // {
                            //     [default] interface IUnknown;
                            //     interface IA;
                            // }
                            // to use the first valid interface, which is IA;
                            // if (!bDefault) continue;

                            bool bSource = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0;

                            TypeInfo typeImpl = type.GetRefType(m);

                            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;
                                }

                                string name = typeImpl.GetDocumentation();

                                if (bSource)
                                {
                                    // Default source interface
                                    if (bDefault ||                                             // If explicitly stated as default, use that
                                        defaultInterfaceInfo.defaultSourceInterface == null)    // otherwise, try to use the first one
                                    {
                                        defaultInterfaceInfo.defaultSourceInterface     = typeImpl;
                                        defaultInterfaceInfo.defaultSourceInterfaceName = name;
                                    }
                                }
                                else
                                {
                                    // Default interface
                                    if (bDefault ||                                     // If explicitly stated as default, use that
                                        defaultInterfaceInfo.defaultInterface == null)  // otherwise, try to use the first one
                                    {
                                        defaultInterfaceInfo.defaultInterface     = typeImpl;
                                        defaultInterfaceInfo.defaultInterfaceName = name;
                                    }
                                }
                            }
                        }

                        //
                        // Walk through the list of implemented interfaces again. This time we remember all the implemented interfaces (including base)
                        //
                        for (int m = 0; m < attr.cImplTypes; ++m)
                        {
                            TypeInfo typeImpl = type.GetRefType(m);
                            string   name     = typeImpl.GetDocumentation();

                            while (typeImpl != null)
                            {
                                // If we arleady seen this interface
                                if (interfaceToCoClassMapping.Contains(name))
                                {
                                    // and if it is for a different interface
                                    if ((string)interfaceToCoClassMapping[name] != defaultInterfaceInfo.coclassName)
                                    {
                                        // Set the name to null so that we know we've seen other interfaces
                                        interfaceToCoClassMapping[name] = null;
                                    }
                                }
                                else
                                {
                                    interfaceToCoClassMapping.Add(name, defaultInterfaceInfo.coclassName);
                                }

                                TypeAttr attrImpl = typeImpl.GetTypeAttr();
                                if (attrImpl.cImplTypes == 1)
                                {
                                    typeImpl = typeImpl.GetRefType(0);
                                }
                                else
                                {
                                    typeImpl = null;
                                }
                            }
                        }

                        // We do allow coclass that doesn't have any 'valid' default interfaces to have a class interface
                        // For example,
                        // coclass MyObject {
                        //     [default] interface IUnknown;
                        // }
                        m_defaultInterfaceInfoList.Add(defaultInterfaceInfo);
                    }
                }
            }

            foreach (DefaultInterfaceInfo defaultInterfaceInfo in m_defaultInterfaceInfoList)
            {
                bool isExclusive = true;
                if (defaultInterfaceInfo.defaultInterface != null)
                {
                    if (interfaceToCoClassMapping.Contains(defaultInterfaceInfo.defaultInterfaceName))
                    {
                        if (interfaceToCoClassMapping[defaultInterfaceInfo.defaultInterfaceName] == null)
                        {
                            isExclusive = false;
                        }
                    }
                    defaultInterfaceInfo.isExclusive = isExclusive;
                }
            }
        }