Exemplo n.º 1
0
        public static long Rebuild(Stream input, long offset, List <ArchiveFileInfo> files, string root)
        {
            root = (root.Last() == '\\') ? root.Remove(root.Length - 1, 1) : root;
            var ROOT = ParseFileTree(files, root);

            //Create MetaData Tree
            var metaData = new MetaData();
            var rootDir  = new MetaData.DirEntry
            {
                MetaOffset          = 0,
                ParentOffset        = 0,
                NextSiblingOffset   = UnusedEntry,
                FirstChildOffset    = ROOT.GetDirectories().Length <= 0 ? UnusedEntry : 0x18,
                FirstFileOffset     = 0,
                NextDirInSameBucket = UnusedEntry,
                name = ""
            };

            metaData.DirMetaOffset = ROOT.GetDirectories().Length <= 0 ? UnusedEntry : 0x18;
            metaData.Dirs.Add(rootDir);

            PopulateMetaData(metaData, ROOT, rootDir);

            //Creating hashbuckets
            metaData.DirHashTable = new uint[GetHashTableEntryCount((uint)metaData.Dirs.Count)];
            for (int i = 0; i < metaData.DirHashTable.Length; i++)
            {
                metaData.DirHashTable[i] = 0xFFFFFFFF;
            }
            PopulateDirHashTable(metaData.Dirs, metaData.DirHashTable);

            metaData.FileHashTable = new uint[GetHashTableEntryCount((uint)metaData.Files.Count)];
            for (int i = 0; i < metaData.FileHashTable.Length; i++)
            {
                metaData.FileHashTable[i] = 0xFFFFFFFF;
            }
            PopulateFileHashTable(metaData.Files, metaData.FileHashTable);

            //Write MetaData
            var romMeta      = File.Create("romMeta_tmp.bin");
            var rawRomFSSize = WriteMetaData(romMeta, metaData, 0x1000);

            //Creating IVFC Hash Levels
            var ivfcLvls = CreateIVFCLevels(romMeta, 3, 0x1000);

            //Write all levels and IVFC Header
            var start = input.Position;

            WriteRomFSData(input, romMeta, rawRomFSSize, ivfcLvls, 0x1000);
            var fullFomFSSize = input.Position - start;

            romMeta.Close();
            if (File.Exists("romMeta_tmp.bin"))
            {
                File.Delete("romMeta_tmp.bin");
            }

            return(fullFomFSSize);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Populates the meta data tree.
        /// </summary>
        /// <param name="metaData">The meta data to populate.</param>
        /// <param name="dir">The directory to populate the meta data with.</param>
        /// <param name="parentDir">The parent directory meta data.</param>
        private static void PopulateMetaData(MetaData metaData, RomFsDirectoryNode dir, MetaData.DirEntry parentDir)
        {
            // Adding files
            var files = dir.Files;

            for (var i = 0; i < files.Count; i++)
            {
                var newFileEntry = new MetaData.FileEntry
                {
                    MetaOffset = metaData.FileMetaOffset,
                    Hash       = CalculatePathHash((uint)parentDir.MetaOffset, Encoding.Unicode.GetBytes(files[i].FilePath.GetName())),

                    FileData = files[i].GetFileData().Result,

                    ParentDirOffset = parentDir.MetaOffset,
                    DataOffset      = metaData.FileOffset,
                    DataSize        = files[i].FileSize,
                    Name            = files[i].FilePath.GetName()
                };
                metaData.FileOffset = (metaData.FileOffset + files[i].FileSize + 0xF) & ~0xF;

                metaData.FileMetaOffset += MetaData.FileEntry.Size + files[i].FilePath.GetName().Length * 2;
                if (metaData.FileMetaOffset % 4 != 0)
                {
                    metaData.FileMetaOffset += 2;
                }

                newFileEntry.NextSiblingOffset = i + 1 == files.Count ? UnusedEntry_ : metaData.FileMetaOffset;

                metaData.Files.Add(newFileEntry);
            }

            // Adding sub directories
            var dirs           = dir.Directories;
            var metaDirIndices = new List <int>();

            for (var i = 0; i < dirs.Count; i++)
            {
                var newDirEntry = new MetaData.DirEntry
                {
                    //Parent = parentDir,

                    MetaOffset = metaData.DirMetaOffset,
                    Hash       = CalculatePathHash((uint)parentDir.MetaOffset, Encoding.Unicode.GetBytes(dirs[i].Name)),

                    ParentOffset = parentDir.MetaOffset,

                    Name = dirs[i].Name
                };

                metaData.DirMetaOffset += MetaData.DirEntry.Size + dirs[i].Name.Length * 2;
                if (metaData.DirMetaOffset % 4 != 0)
                {
                    metaData.DirMetaOffset += 2;
                }

                newDirEntry.NextSiblingOffset = i + 1 < dirs.Count ? metaData.DirMetaOffset : UnusedEntry_;

                metaData.Dirs.Add(newDirEntry);
                metaDirIndices.Add(metaData.Dirs.Count - 1);
            }

            // Adding children of sub directories
            for (var i = 0; i < dirs.Count; i++)
            {
                metaData.Dirs[metaDirIndices[i]].FirstChildOffset = dirs[i].Directories.Count > 0 ? metaData.DirMetaOffset : UnusedEntry_;
                metaData.Dirs[metaDirIndices[i]].FirstFileOffset  = dirs[i].Files.Count > 0 ? metaData.FileMetaOffset : UnusedEntry_;

                PopulateMetaData(metaData, dirs[i], metaData.Dirs[metaDirIndices[i]]);
            }
        }