Ejemplo n.º 1
0
        public static void Explode(string[] args, VolFile.ExplodeProgressCallback callback)
        {
            if (!File.Exists(args[1]))
            {
                Console.Error.WriteLine("VOL file '{0}' doesn't exist!", args[1]);
                return;
            }
            GT3Vol volFile = new GT3Vol(args[1]);

            volFile.Extract(args[2], args.Length >= 4, callback);
        }
Ejemplo n.º 2
0
 public void WriteNewVol(string newVol, HeaderInfo hi, List <FSEntry> entries, VolFile.ExplodeProgressCallback callback)
 {
     // the Vol file is massive, about 500 MB
     // I don't want to have to write out the file data section to an actual file and have to read it back in
     // to copy it to the final file. So ~500MB of memory it is
     using (MemoryStream fileData = new MemoryStream(500000000))
     {
         int[]        offsets    = hi.offsets;
         int          nextOffset = hi.fileDataStartPosition;
         byte[]       padBytes   = new byte[0x7ff];
         BinaryWriter bw         = new BinaryWriter(fileData);
         int          fileCount  = 0;
         foreach (FSEntry entry in entries)
         {
             int size = 0;
             if ((entry.tocEntry.flags & TOCFlags_Directory) == 0)
             {
                 // if we recompressed the file, just write its bytes out
                 if (entry.compressedFile != null)
                 {
                     size = entry.compressedFile.Length;
                     bw.Write(entry.compressedFile);
                 }
                 else
                 {
                     // otherwise read it in and write it to the memory
                     using (FileStream fs = new FileStream(entry.diskFile, FileMode.Open, FileAccess.Read))
                     {
                         size = (int)fs.Length;
                         byte[] d    = new byte[0x8000];
                         int    read = 0;
                         while ((read = fs.Read(d, 0, d.Length)) > 0)
                         {
                             bw.Write(d, 0, read);
                         }
                     }
                 }
                 // write the pad bytes
                 int remainder = 0x800 - (size % 0x800);
                 if (remainder == 0x800)
                 {
                     remainder = 0;
                 }
                 bw.Write(padBytes, 0, remainder);
                 callback(String.Format("Wrote {0} at 0x{1:x}, padded with 0x{2:x} bytes", entry.name, nextOffset, remainder));
                 offsets[2 + fileCount] = nextOffset | remainder;
                 nextOffset            += size + remainder;
                 Debug.Assert((nextOffset & 0x7FF) == 0);
                 ++fileCount;
             }
         }
         bw.Flush();
         fileData.Position           = 0;
         offsets[offsets.Length - 1] = nextOffset; // last one is the file size
         using (FileStream newVolFile = new FileStream(newVol, FileMode.Create, FileAccess.Write))
         {
             byte[] offBytes = new byte[offsets.Length * sizeof(int)];
             Buffer.BlockCopy(offsets, 0, offBytes, 0, offBytes.Length);
             // header
             newVolFile.Write(hi.header, 0, hi.header.Length);
             // offsets
             newVolFile.Write(offBytes, 0, offBytes.Length);
             // padding for offsets
             newVolFile.Write(padBytes, 0, offsets[0] & 0x7ff);
             // toc
             hi.toc.Position = 0;
             StreamUtils.Copy(hi.toc, newVolFile, offBytes);
             // toc padding
             newVolFile.Write(padBytes, 0, offsets[1] & 0x7ff);
             // file data
             StreamUtils.Copy(fileData, newVolFile, offBytes);
         }
     }
 }
Ejemplo n.º 3
0
 public void Extract(string path, bool decomp, VolFile.ExplodeProgressCallback callback)
 {
     ExtractDirectory(rootVolEntry.children, path, decomp, callback);
 }
Ejemplo n.º 4
0
        private void ExtractDirectory(List <VolEntryInfo> dirEntries, string dirPath, bool decomp, VolFile.ExplodeProgressCallback callback)
        {
            string decompDir = Path.Combine(dirPath, VolFile.DecompDir);

            foreach (VolEntryInfo inf in dirEntries)
            {
                string localName = Path.Combine(dirPath, inf.name);
                if (inf.children != null)
                {
                    Directory.CreateDirectory(localName);
                    ExtractDirectory(inf.children, localName, decomp, callback);
                }
                else
                {
                    volFile.Seek(inf.fileAddress, SeekOrigin.Begin);
                    byte[] data = new byte[inf.size];
                    volFile.Read(data, 0, (int)inf.size);
                    callback(String.Format("Extracting {0} from {1:x}", inf.name, inf.fileAddress));
                    File.WriteAllBytes(localName, data);
                    if (inf.isCompressed && decomp)
                    {
                        Directory.CreateDirectory(decompDir);
                        string          decompFileName = Path.Combine(decompDir, inf.name);
                        MemoryStream    ms             = new MemoryStream(data, false);
                        GZipInputStream gzIn           = new GZipInputStream(ms);
                        callback(String.Format("Decompressing {0}", inf.name));
                        using (FileStream decompFile = new FileStream(decompFileName, FileMode.Create, FileAccess.Write))
                        {
                            byte[] buffer = new byte[8192];
                            StreamUtils.Copy(gzIn, decompFile, buffer);
                        }
                    }
                }
            }
        }