Exemplo n.º 1
0
        public NcchRomFs(Stream instream)
        {
            using var br = new BinaryReaderX(instream, true);

            // Read header
            var romFsOffset = br.BaseStream.Position;

            header     = br.ReadType <NcchRomFsHeader>();
            masterHash = br.ReadBytes(header.masterHashSize);

            // Read Level 3
            lv3Offset = romFsOffset + 0x1000;
            br.BaseStream.Position = lv3Offset;
            lv3Header = br.ReadType <NcchRomFsLevelHeader>();

            // Resolve file and directory tree
            br.BaseStream.Position = lv3Offset + lv3Header.dirMetaTableOffset;
            Files = new List <FinalFileInfo>();
            ResolveDirectories(br);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Write meta data tree.
        /// </summary>
        /// <param name="output">The stream to write to.</param>
        /// <param name="metaData">The meta data tree to write.</param>
        /// <returns>The size of the written meta data.</returns>
        private static long WriteMetaData(Stream output, MetaData metaData)
        {
            var startPosition = output.Position;

            using var bw = new BinaryWriterX(output, true);

            var header = new NcchRomFsLevelHeader
            {
                headerLength       = 0x28,
                dirHashTableOffset = 0x28,
                dirHashTableSize   = metaData.DirHashTable.Length * sizeof(uint),
                dirMetaTableSize   = metaData.Dirs.Sum(dir => dir.GetSize(4)),
                fileHashTableSize  = metaData.FileHashTable.Length * sizeof(uint),
                fileMetaTableSize  = metaData.Files.Sum(file => file.GetSize(4)),
            };

            bw.BaseStream.Position = startPosition + 0x28;

            // Write directory hash table
            foreach (var hash in metaData.DirHashTable)
            {
                bw.Write(hash);
            }

            // Write directory entries
            header.dirMetaTableOffset = (int)(bw.BaseStream.Position - startPosition);
            foreach (var dir in metaData.Dirs)
            {
                bw.Write(dir.ParentOffset);
                bw.Write(dir.NextSiblingOffset);
                bw.Write(dir.FirstChildOffset);
                bw.Write(dir.FirstFileOffset);
                bw.Write(dir.NextDirInSameBucket ?? UnusedEntry_);
                bw.Write(Encoding.Unicode.GetByteCount(dir.Name));
                bw.Write(Encoding.Unicode.GetBytes(dir.Name));

                bw.WriteAlignment(4);
            }

            // Write file hash table
            header.fileHashTableOffset = (int)(bw.BaseStream.Position - startPosition);
            foreach (var hash in metaData.FileHashTable)
            {
                bw.Write(hash);
            }

            // Write file entries
            header.fileMetaTableOffset = (int)(bw.BaseStream.Position - startPosition);
            foreach (var file in metaData.Files)
            {
                bw.Write(file.ParentDirOffset);
                bw.Write(file.NextSiblingOffset);
                bw.Write(file.DataOffset);
                bw.Write(file.DataSize);
                bw.Write(file.NextFileInSameBucket ?? UnusedEntry_);
                bw.Write(Encoding.Unicode.GetByteCount(file.Name));
                bw.Write(Encoding.Unicode.GetBytes(file.Name));

                bw.WriteAlignment(4);
            }

            // Write files
            header.fileDataOffset = (int)((bw.BaseStream.Position - startPosition + 0xF) & ~0xF);
            foreach (var file in metaData.Files)
            {
                bw.WriteAlignment();
                file.FileData.CopyTo(bw.BaseStream);
            }

            var level3Size = bw.BaseStream.Position - startPosition;

            bw.WriteAlignment(BlockSize_);

            bw.BaseStream.Position = startPosition;
            bw.WriteType(header);

            return(level3Size);
        }