コード例 #1
0
ファイル: GT3Vol.cs プロジェクト: adeyblue/GTVolTools
        private static VolHeader BuildHeader(string directory)
        {
            VolHeader      header       = new VolHeader();
            MemoryStream   stringStream = new MemoryStream();
            BinaryWriter   nameString   = new BinaryWriter(stringStream);
            VolHeaderEntry root         = new VolHeaderEntry();

            root.entryOffset = 0x14;
            root.parent      = null;
            AppendVolHeaderFileName(nameString, ".", out root.nameOffset);
            uint runningFileDataOffset = 0;
            uint dirEntryIter          = 0x14;
            uint fileInfoSize          = 0;

            root.dataOffset  = 0x14;
            root.entryOffset = 0x14;
            root.children    = DirectoryToHeaderEntries(directory, nameString, ref dirEntryIter, ref runningFileDataOffset, ref fileInfoSize);
            nameString.Flush();
#if DEBUG
            Console.WriteLine(
                "Sizes: fileInfoOffset = {0:x}, fileInfoSize = {1:x}, runningFDO = {2:x}, nameString Length {3:x}",
                dirEntryIter,
                fileInfoSize,
                runningFileDataOffset,
                stringStream.Position
                );
#endif
            header.nameString     = stringStream.ToArray();
            header.fileInfoOffset = dirEntryIter;
            header.volEntries     = root;
            header.nameOffset     = header.fileInfoOffset + fileInfoSize;
            header.headerSize     = header.nameOffset + (uint)header.nameString.Length;
            return(header);
        }
コード例 #2
0
ファイル: GT3Vol.cs プロジェクト: adeyblue/GTVolTools
        private static void WriteDirectory(
            BinaryWriter directoryWriter,
            BinaryWriter fileInfoWriter,
            uint fileInfoOffset,
            uint nameStringOffset,
            uint fileDataOffset,
            VolHeaderEntry dirEntry
            )
        {
            directoryWriter.Write(0x01000000 | (dirEntry.nameOffset + nameStringOffset));
            directoryWriter.Write(dirEntry.children.Count + 1); // +1 for the parent
            if (dirEntry.parent != null)
            {
                directoryWriter.Write(dirEntry.parent.entryOffset);
            }
            else
            {
                directoryWriter.Write(0);
            }
            List <MemoryStream> childDirDirectoryEntries = new List <MemoryStream>();

            foreach (VolHeaderEntry child in dirEntry.children)
            {
                if (child.children != null)
                {
                    directoryWriter.Write(child.dataOffset);
                    MemoryStream childDirEntries = new MemoryStream();
                    BinaryWriter childDirWriter  = new BinaryWriter(childDirEntries);
                    WriteDirectory(childDirWriter, fileInfoWriter, fileInfoOffset, nameStringOffset, fileDataOffset, child);
                    childDirDirectoryEntries.Add(childDirEntries);
                }
                else
                {
                    directoryWriter.Write(child.fileInfoOffset + fileInfoOffset);
                    uint highByte     = 0;
                    bool isCompressed = (child.decompFileSize != 0);
                    if (isCompressed)
                    {
                        highByte = 0x02000000;
                    }
                    fileInfoWriter.Write(highByte | (child.nameOffset + nameStringOffset));
                    fileInfoWriter.Write((fileDataOffset + child.dataOffset) / 0x800);
                    if (isCompressed)
                    {
                        fileInfoWriter.Write(child.decompFileSize);
                    }
                    fileInfoWriter.Write(child.fileSize);
                }
            }
            byte[] buffer = new byte[8192];
            directoryWriter.Flush();
            foreach (MemoryStream ms in childDirDirectoryEntries)
            {
                ms.Position = 0;
                StreamUtils.Copy(ms, directoryWriter.BaseStream, buffer);
            }
        }
コード例 #3
0
ファイル: GT3Vol.cs プロジェクト: adeyblue/GTVolTools
        private static List <VolHeaderEntry> DirectoryToHeaderEntries(
            string fsDirectory,
            BinaryWriter sb,
            ref uint nextDirStartOffset,
            ref uint fileDataRunningOffset,
            ref uint fileInfoSize
            )
        {
            string[] entries = Directory.GetFileSystemEntries(fsDirectory);
            for (int i = 0; i < entries.Length; ++i)
            {
                if (entries[i].EndsWith(GT2Vol.VolFile.DecompDir, StringComparison.InvariantCultureIgnoreCase))
                {
                    string thisEntry = entries[i];
                    string last      = entries[entries.Length - 1];
                    entries[i] = last;
                    Array.Resize(ref entries, entries.Length - 1);
                    --i;
                    break;
                }
            }
            Array.Sort(entries);
            byte[] decompBuffer = new byte[65536];
            // the 3 is for:
            // the name entry for this directory
            // the count that comes after the name offset
            // the offset to the parent directory
            //
            // running dir offset is for entries in this directory
            // nextDirStartOffset is where the next child directory will start
            uint runningDirOffset = nextDirStartOffset + (3 * sizeof(uint));

            nextDirStartOffset += (uint)((entries.Length + 3) * sizeof(uint));
            List <VolHeaderEntry> dirEntries = new List <VolHeaderEntry>();

            char[] slashChars = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
            foreach (string fileOrDir in entries)
            {
                int            lastSlash    = fileOrDir.LastIndexOfAny(slashChars);
                string         lastPathPart = fileOrDir.Remove(0, lastSlash + 1);
                string         fullFsPath   = fileOrDir;
                VolHeaderEntry vhe          = new VolHeaderEntry();
                vhe.entryOffset = runningDirOffset;
                vhe.filePath    = fullFsPath;
                AppendVolHeaderFileName(sb, lastPathPart, out vhe.nameOffset);
                if (Directory.Exists(fullFsPath))
                {
                    vhe.dataOffset = vhe.fileInfoOffset = nextDirStartOffset;
                    vhe.children   = DirectoryToHeaderEntries(
                        fullFsPath,
                        sb,
                        ref nextDirStartOffset,
                        ref fileDataRunningOffset,
                        ref fileInfoSize
                        );
                    foreach (VolHeaderEntry child in vhe.children)
                    {
                        child.parent = vhe;
                    }
                }
                else
                {
                    vhe.fileInfoOffset = fileInfoSize;
                    fileInfoSize      += (sizeof(uint) * 2); // name offset + fileSize
                    vhe.dataOffset     = fileDataRunningOffset;
                    long fileSize   = 0;
                    uint decompSize = 0;
                    using (FileStream fs = new FileStream(fullFsPath, FileMode.Open, FileAccess.Read))
                    {
                        fileSize = fs.Length;
                        // try to decompress if it looks like a gzip file
                        if ((fs.ReadByte() == 0x1f) && (fs.ReadByte() == 0x8B))
                        {
                            try
                            {
                                using (GZipInputStream gzIn = new GZipInputStream(fs))
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        StreamUtils.Copy(gzIn, ms, decompBuffer);
                                        decompSize    = (uint)ms.Position;
                                        fileInfoSize += sizeof(uint); // decomp size
                                    }
                            }
                            catch (Exception)
                            {
                                ; // probably isn't a gzip file afterall
                            }
                        }
                    }
                    vhe.fileSize       = (uint)fileSize;
                    vhe.decompFileSize = decompSize;
                    // round up to next sector multiple
                    fileSize = (fileSize + 0x7FF) & ~0x7FF;
                    fileDataRunningOffset += (uint)fileSize;

                    vhe.children = null;
                }
                runningDirOffset += sizeof(uint);
                dirEntries.Add(vhe);
            }
            return(dirEntries);
        }
コード例 #4
0
ファイル: GT3Vol.cs プロジェクト: adeyblue/GTVolTools
            public byte[] nameString;   // already bitwise notted

            public VolHeader()
            {
                volEntries = new VolHeaderEntry();
            }