Esempio n. 1
0
        public CppBuilder(string exportDir, string stubDir, CLRAssemblyCollection assemblies, IDictionary<CLRAssembly, string> pdbPaths)
        {
            m_assemblies = assemblies;
            m_exportPath = exportDir;
            m_stubDir = stubDir;
            m_typeSpecClasses = new Dictionary<CLRTypeSpec, CppClass>();
            m_fullNameClasses = new Dictionary<string, CppClass>();
            m_pdbs = new Dictionary<CLRAssembly, PdbDebugInfo>();

            foreach (KeyValuePair<CLRAssembly, string> pdbPath in pdbPaths)
            {
                using (System.IO.FileStream fs = new FileStream(pdbPath.Value, FileMode.Open, FileAccess.Read))
                {
                    PdbDebugInfo pdbDebugInfo = new PdbDebugInfo(fs);
                    m_pdbs.Add(pdbPath.Key, pdbDebugInfo);
                }
            }

            // Generate type def cache
            foreach (CLRAssembly assm in assemblies)
            {
                CLRMetaDataTables tables = assm.MetaData.MetaDataTables;
                ICLRTable typeDefs = tables.GetTable(CLRMetaDataTables.TableIndex.TypeDef);

                for (uint i = 0; i < typeDefs.NumRows; i++)
                {
                    CLRTypeDefRow typeDef = (CLRTypeDefRow)typeDefs.GetRow(i);
                    CacheTypeDef(typeDef);
                }
            }

            // Export everything
            foreach (CLRAssembly assm in assemblies)
            {
                CLRMetaDataTables tables = assm.MetaData.MetaDataTables;
                ICLRTable typeDefs = tables.GetTable(CLRMetaDataTables.TableIndex.TypeDef);

                ICLRTable assemblyTable = tables.GetTable(CLRMetaDataTables.TableIndex.Assembly);
                CLRAssemblyRow assemblyRow = (CLRAssemblyRow)assemblyTable.GetRow(0);

                Clarity.Rpa.HighFileBuilder fileBuilder = new Clarity.Rpa.HighFileBuilder();

                using (FileStream fs = new FileStream(exportDir + assemblyRow.Name + ".rpa", FileMode.Create))
                {
                    using (BinaryWriter writer = new BinaryWriter(fs))
                    {
                        using (MemoryStream objDataStream = new MemoryStream())
                        {
                            using (BinaryWriter objDataWriter = new BinaryWriter(objDataStream))
                            {
                                uint numUsableTypes = 0;

                                for (uint i = 0; i < typeDefs.NumRows; i++)
                                {
                                    CLRTypeDefRow typeDef = (CLRTypeDefRow)typeDefs.GetRow(i);
                                    if (typeDef.Extends == null)
                                    {
                                        if (typeDef.TypeNamespace == "" && typeDef.TypeName == "<Module>")
                                            continue;

                                        if (typeDef.Semantics != CLRTypeDefRow.TypeSemantics.Interface && (typeDef.TypeNamespace != "System" || typeDef.TypeName != "Object"))
                                            throw new Exception("Unexpected parentless type");
                                    }
                                    numUsableTypes++;
                                }

                                objDataWriter.Write(numUsableTypes);

                                for (uint i = 0; i < typeDefs.NumRows; i++)
                                {
                                    CLRTypeDefRow typeDef = (CLRTypeDefRow)typeDefs.GetRow(i);

                                    if (typeDef.Extends == null && typeDef.TypeNamespace == "" && typeDef.TypeName == "<Module>")
                                        continue;

                                    ExportTypeDef(fileBuilder, objDataWriter, typeDef);
                                }

                                uint assemblyNameIndex = fileBuilder.IndexString(assemblyRow.Name);

                                writer.Write(0x41503252);   // R2PA
                                fileBuilder.FlushAndWriteCatalogs(writer);
                                writer.Write(assemblyNameIndex);
                                writer.Flush();

                                objDataWriter.Flush();
                                objDataStream.WriteTo(fs);
                            }
                        }
                    }
                }
            }
        }