Exemple #1
0
        readonly TypeLib m_typeLib; // Corresponding type library

        #endregion Fields

        #region Constructors

        public ClassInterfaceMap(TypeLib typeLib)
        {
            m_typeLib = typeLib;
            m_defaultInterfaceInfoList = new List<DefaultInterfaceInfo>();

            Collect();
        }
 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;
 }
Exemple #3
0
 public void SetTypeLibrary(TypeLib typeLib)
 {
     TreeNode root = TypeLib2TreeNodeProcessor.GetTypeLibNode(typeLib, m_displayLevel);
     TypeLib2TreeNodeProcessor.SetTlbTreeNodeImage(root);
     this.BeginUpdate();
     this.Nodes.Clear();
     this.Nodes.Add(root);
     root.Expand();
     this.EndUpdate();
 }
        internal static TreeNode GetTypeLibNode(TypeLib tlb, DisplayLevel displayLevel)
        {
            string typeLibName = tlb.GetDocumentation();
            TreeNode root = new TreeNode(typeLibName);
            root.Tag = tlb;

            int nCount = tlb.GetTypeInfoCount();
            for (int n = 0; n < nCount; ++n)
            {
                TypeInfo type = tlb.GetTypeInfo(n);
                //string typeTypeName = type.GetDocumentation();
                //NativeType2String.AddNativeUserDefinedType(typeTypeName);

                // For dual interfaces, it has a "funky" TKIND_DISPATCH|TKIND_DUAL interface with a parter of TKIND_INTERFACE|TKIND_DUAL interface
                // The first one is pretty bad and has duplicated all the interface members of its parent, which is not we want
                // We want the second v-table interface
                // So, if we indeed has seen this kind of interface, prefer its partner
                // However, we should not blindly get the partner because those two interfaces partners with each other
                // So we need to first test to see if the interface is both dispatch & dual, and then get its partner interface
                using (TypeAttr attr = type.GetTypeAttr())
                {
                    if (attr.IsDual && attr.IsDispatch)
                    {
                        TypeInfo typeReferencedType = type.GetRefTypeNoComThrow();
                        if (typeReferencedType != null)
                        {
                            type = typeReferencedType;
                        }
                    }
                }
                TreeNode typeInfoNode = new TreeNode();
                TypeInfoMatchTarget typeInfoMatchTarget = null;
                root.Nodes.Add(typeInfoNode);
                using (TypeAttr attr = type.GetTypeAttr())
                {
                    TYPEKIND kind = attr.typekind;
                    typeInfoMatchTarget = new TypeInfoMatchTarget(tlb, type, kind);
                    if (displayLevel == DisplayLevel.All)
                    {
                        ProcessFunctions(type, typeInfoNode);
                        ProcessFields(type, typeInfoNode);
                    }
                }
                typeInfoNode.Text = typeInfoMatchTarget.Name + ": " +
                                typeInfoMatchTarget.Type;
                typeInfoNode.Tag = typeInfoMatchTarget;
                SetTlbTreeNodeImage(typeInfoNode);
            }
            return root;
        }
        private void LoadTlb(string tlbFileName)
        {
            try
            {
                // Load the typelib.
                System.Runtime.InteropServices.ComTypes.ITypeLib TypeLib = null;
                APIHelper.LoadTypeLibEx(tlbFileName, REGKIND.REGKIND_DEFAULT, out TypeLib);

                // Update the tlbTreeView.
                TypeLib tlb = new TypeLib((ITypeLib)TypeLib);
                this.tlbTreeView.SetTypeLibrary(tlb);
            }
            catch (Exception)
            {
                MessageBox.Show("Err_TypeLibLoad");
            }
        }
Exemple #6
0
        public AssemblyBuilder DoProcess(
            Object typeLib,
            string asmFilename,
            TypeLibImporterFlags flags,
            ITypeLibImporterNotifySink notifySink,
            byte[] publicKey,
            StrongNameKeyPair keyPair,
            string asmNamespace,
            Version asmVersion,
            bool isVersion2,
            bool isPreserveSig,
            string ruleSetFileName)
        {
            m_resolver = notifySink;

            TypeLib tlb = new TypeLib((TypeLibTypes.Interop.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 = 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;
            RuleEngine.InitRuleEngine(new TlbImpActionManager(),
                                      new TlbImpCategoryManager(),
                                      new TlbImpConditionManager(),
                                      new TlbImpOperatorManager());
            if (ruleSetFileName != null)
            {
                try
                {
                    RuleFileParser parser = new RuleFileParser(ruleSetFileName);
                    settings.m_ruleSet = parser.Parse();
                }
                catch (Exception ex)
                {
                    Output.WriteWarning(Resource.FormatString("Wrn_LoadRuleFileFailed",
                                                              ruleSetFileName, ex.Message),
                                        WarningCode.Wrn_LoadRuleFileFailed);
                    settings.m_ruleSet = null;
                }
            }
            else
            {
                settings.m_ruleSet = null;
            }

            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
            //
            var coclassList = new List<TypeInfo>();
            int nCount = tlb.GetTypeInfoCount();
            for (int n = 0; n < nCount; ++n)
            {
                try
                {
                    TypeInfo type = tlb.GetTypeInfo(n);
                    string strType = type.GetDocumentation();

                    using (TypeAttr attr = type.GetTypeAttr())
                    {
                        TypeLibTypes.Interop.TYPEKIND kind = attr.typekind;
                        TypeInfo typeToProcess;
                        TypeAttr attrToProcess;
                        if (kind == TypeLibTypes.Interop.TYPEKIND.TKIND_ALIAS)
                        {
                            ConvCommon.ResolveAlias(type, attr.tdescAlias, out typeToProcess, out attrToProcess);
                            if (attrToProcess.typekind == TypeLibTypes.Interop.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 TypeLibTypes.Interop.TYPEKIND.TKIND_COCLASS:
                                coclassList.Add(typeToProcess);
                                break;

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

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

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

                            case TypeLibTypes.Interop.TYPEKIND.TKIND_RECORD:
                                m_converterInfo.GetStruct(typeToProcess, attrToProcess);
                                break;
                            case TypeLibTypes.Interop.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
            //

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

            foreach (IConvBase symbol in m_converterInfo.GetAllConvBase)
            {
                var convInterface = symbol as IConvInterface;
                if (convInterface != null)
                {
                    if (convInterface.EventInterface != null)
                    {
                        Debug.Assert(convInterface.EventInterface is ConvEventInterfaceLocal);
                        var 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;
        }
Exemple #7
0
        public AssemblyBuilder CreateAssemblyBuilder(AssemblyName name, TypeLib tlb, TypeLibImporterFlags flags)
        {
            using (TypeLibAttr attr = tlb.GetLibAttr())
            {
                // New assembly as well as loaded assembly should be all in a ReflectionOnly context as we don't need to run the code
                AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(name, AssemblyBuilderAccess.ReflectionOnly);

                // Handle the type library name
                assemblyBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForImportedFromTypeLib(tlb.GetDocumentation()));

                // Handle the type library version
                assemblyBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibVersion(attr.wMajorVerNum, attr.wMinorVerNum));

                // Handle the LIBID
                assemblyBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForGuid(attr.guid));

                // If we are generating a PIA, then set the PIA custom attribute.
                if ((flags & TypeLibImporterFlags.PrimaryInteropAssembly) != 0)
                    assemblyBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForPrimaryInteropAssembly(attr.wMajorVerNum, attr.wMinorVerNum));

                return assemblyBuilder;
            }
        }
Exemple #8
0
            public int ResolveTypeLib(string simpleName, Guid tlbId, int lcid, ushort majorVersion, ushort minorVersion, TypeLibTypes.Interop.SYSKIND syskind, out string bstrPathName)
            {
                // Remember the type lib info
                s_MissingTypeLibInfo = new TypeLibInfo();
                s_MissingTypeLibInfo.name = simpleName;
                s_MissingTypeLibInfo.guid = tlbId;
                s_MissingTypeLibInfo.majorVersion = majorVersion;
                s_MissingTypeLibInfo.minorVersion = minorVersion;

                //
                // Find this type library in list of referenced type libraries
                //
                foreach (string pathName in s_RefTypeLibraries.Keys)
                {
                TypeLib refTypeLib = new TypeLib(s_RefTypeLibraries[pathName] as TypeLibTypes.Interop.ITypeLib);
                TypeLibAttr libAttr = refTypeLib.GetLibAttr();
                if (libAttr.guid == tlbId)
                {
                    if (libAttr.wMajorVerNum == majorVersion && libAttr.wMinorVerNum == minorVersion)
                    {
                        // Resolved to a matching type lib
                        bstrPathName = pathName;
                        return 0;
                    }
                }
                }

                //
                // Find using GUID
                //
                int hr = TypeLib.QueryPathOfRegTypeLib(ref tlbId, majorVersion, minorVersion, lcid, out bstrPathName);
                if (hr >= 0)
                {
                // Try loading the type library and verify guid/version
                hr = TryLoadTypeLib(bstrPathName, simpleName, tlbId, majorVersion, minorVersion);
                if (hr >= 0) return hr;
                }

                //
                // Try to load current directory
                //
                bstrPathName = Path.Combine(Directory.GetCurrentDirectory(), simpleName);
                if (File.Exists(bstrPathName))
                {
                // Try loading the type library guid/version
                hr = TryLoadTypeLib(bstrPathName, simpleName, tlbId, majorVersion, minorVersion);
                if (hr >= 0) return hr;
                }

                if (TlbImpCode.s_Options.m_bVerboseMode)
                {
                Output.WriteInfo(
                    Resource.FormatString("Msg_TypeLibRefResolveFailed",
                        new object[] { simpleName, majorVersion.ToString() + "." + minorVersion, tlbId.ToString() }),
                    MessageCode.Msg_TypeLibRefResolveFailed);
                }

                return -1;
            }
Exemple #9
0
        /// <summary>
        /// Try to load the type library and verify guid/version
        /// </summary>
        /// <returns>HRESULT. >=0 if succeeds, otherwise failed</returns>
        private static int TryLoadTypeLib(string pathName, string simpleName, Guid tlbId, ushort majorVersion, ushort minorVersion)
        {
            TypeLibTypes.Interop.ITypeLib typeLib;
            int hr = TypeLib.LoadTypeLib(pathName, out typeLib);
            if (hr >= 0)
            {
            s_RefTypeLibraries.Add(pathName, typeLib as System.Runtime.InteropServices.ComTypes.ITypeLib);

            TypeLib refTypeLib = new TypeLib(typeLib);
            TypeLibAttr libAttr = refTypeLib.GetLibAttr();
            if (libAttr.guid == tlbId && libAttr.wMajorVerNum == majorVersion && libAttr.wMinorVerNum == minorVersion)
            {
                if (TlbImpCode.s_Options.m_bVerboseMode)
                {
                    Output.WriteInfo(
                        Resource.FormatString("Msg_TypeLibRefResolved",
                            new object[] { simpleName, majorVersion.ToString() + "." + minorVersion, tlbId.ToString(), pathName }),
                        MessageCode.Msg_TypeLibRefResolved);
                }

                return 0;
            }
            else
            {
                if (TlbImpCode.s_Options.m_bVerboseMode)
                {
                    Output.WriteInfo(
                        Resource.FormatString("Msg_TypeLibRefMismatch",
                            new object[] {
                                        simpleName, majorVersion.ToString() + "." + minorVersion, tlbId.ToString(),
                                        simpleName, libAttr.wMajorVerNum.ToString() + "." + libAttr.wMajorVerNum.ToString(), libAttr.guid,
                                        pathName }),
                        MessageCode.Msg_TypeLibRefMismatch);
                }

                return -1;
            }
            }

            return hr;
        }
        private void LoadTlb(string tlbFileName)
        {
            try
            {
                // Load the typelib.
                System.Runtime.InteropServices.ComTypes.ITypeLib typeLib = null;
                APIHelper.LoadTypeLibEx(tlbFileName, REGKIND.REGKIND_DEFAULT, out typeLib);

                // Update the tlbTreeView.
                m_typeLib = new TypeLib((ITypeLib)typeLib);
                treeViewTypeLib.SetTypeLibrary(m_typeLib);
            }
            catch (Exception)
            {
                MessageBox.Show(Resource.FormatString("Wrn_TypeLibLoadFailed", tlbFileName));
            }
        }