private void B_Go_Click(object sender, EventArgs e) { // Continue only if a string path is loaded. if (textBox1.Text.Length < 1) { return; } // Fetch file extension (first 4 bytes) to check if it is a GARC BinaryReader brz = new BinaryReader(System.IO.File.OpenRead(textBox1.Text)); try { string s = new string(Reverse(brz.ReadChars(4))); if (s != "GARC") { RTB.Text += "Input file is not a .GARC"; return; } RTB.Text = s; } catch (EncoderFallbackException) { RTB.Text += "Invalid File."; return; } brz.Close(); // Unpack the GARC GARC garc = ARC.Unpack(textBox1.Text); RTB.Text += "\r\nCount: " + garc.otaf.nFiles; ProgressInit(garc.otaf.nFiles); if (garc.otaf.nFiles > 50) { CHK_NoPrint.Checked = true; } // Get file path infos for exporting FileInfo fileInfo = new FileInfo(textBox1.Text); string path = fileInfo.DirectoryName; string parentName = fileInfo.Name; string basepath = path + "\\" + parentName + "_"; BinaryReader br = new BinaryReader(System.IO.File.OpenRead(textBox1.Text)); // Create Extraction folder if it does not exist. if (!Directory.Exists(basepath)) { DirectoryInfo di = Directory.CreateDirectory(basepath); } // Pull out all the files for (int i = 0; i < garc.otaf.nFiles; i++) { string ext = "bin"; bool compressed = false; string newext; br.BaseStream.Position = garc.btaf.entries[i].start_offset + garc.data_offset; try { newext = TrimFromZero(new string(br.ReadChars(4))); if ((System.Text.RegularExpressions.Regex.IsMatch(newext, @"^[a-zA-Z0-9]+$")) && (!CHK_ForceBIN.Checked)) { ext = newext; } else { compressed = true; } } catch { newext = null; } // Set File Name string filename = i.ToString("D" + Math.Ceiling(Math.Log10(garc.otaf.nFiles))); string fileout = basepath + "\\" + filename + "." + ext; BinaryWriter bw = new BinaryWriter(File.OpenWrite(fileout)); // Write out the data for the file br.BaseStream.Position = garc.btaf.entries[i].start_offset + garc.data_offset; for (int x = 0; x < garc.btaf.entries[i].length; x++) { bw.Write(br.ReadByte()); } bw.Flush(); bw.Close(); printout("\r\nWrote to " + fileout); // See if decompression should be attempted. if (compressed && !CHK_SkipDecompress.Checked) { string decout = path + "\\" + parentName + "_\\" + "dec_" + filename; string result = LZSS.Decompress11LZS(fileout, decout); if (result != null) { printout("\r\n" + result); if (CHK_delAfterD.Checked) { try { File.Delete(fileout); } catch { } } } } pBar1.PerformStep(); } br.Close(); RTB.Text += "\r\nDone!"; RTB.Select(RTB.Text.Length - 1, 0); RTB.ScrollToCaret(); }
public sFolder Unpack(sFile file) { ARC arc = new ARC(); BinaryReader br = new BinaryReader(System.IO.File.OpenRead(file.path)); // Nitro generic header arc.id = br.ReadChars(4); arc.id_endian = br.ReadUInt16(); if (arc.id_endian == 0xFFFE) arc.id.Reverse<Char>(); arc.constant = br.ReadUInt16(); arc.file_size = br.ReadUInt32(); arc.header_size = br.ReadUInt16(); arc.nSections = br.ReadUInt16(); // BTAF (File Allocation TaBle) arc.btaf.id = br.ReadChars(4); arc.btaf.section_size = br.ReadUInt32(); arc.btaf.nFiles = br.ReadUInt32(); arc.btaf.entries = new BTAF_Entry[arc.btaf.nFiles]; for (int i = 0; i < arc.btaf.nFiles; i++) { arc.btaf.entries[i].start_offset = br.ReadUInt32(); arc.btaf.entries[i].end_offset = br.ReadUInt32(); } // BTNF (File Name TaBle) arc.btnf.id = br.ReadChars(4); arc.btnf.section_size = br.ReadUInt32(); arc.btnf.entries = new List<BTNF_MainEntry>(); long mainTables_offset = br.BaseStream.Position; uint gmif_offset = (uint)br.BaseStream.Position + arc.btnf.section_size; #region Get root folder br.BaseStream.Position += 6; ushort num_mains = br.ReadUInt16(); br.BaseStream.Position -= 8; for (int m = 0; m < num_mains; m++) { BTNF_MainEntry main = new BTNF_MainEntry(); main.offset = br.ReadUInt32(); main.first_pos = br.ReadUInt16(); main.parent = br.ReadUInt16(); uint idFile = main.first_pos; if (main.offset < 0x8) // There aren't names (in Pokemon games) { for (int i = 0; i < arc.btaf.nFiles; i++) { sFile currFile = new sFile(); currFile.name = Path.GetFileNameWithoutExtension(file.name) + '_' + idFile.ToString(); currFile.id = (ushort)idFile++; // FAT data currFile.path = file.path; currFile.offset = arc.btaf.entries[currFile.id].start_offset + gmif_offset; currFile.size = (arc.btaf.entries[currFile.id].end_offset - arc.btaf.entries[currFile.id].start_offset); // Get the extension long currPos = br.BaseStream.Position; br.BaseStream.Position = currFile.offset; char[] ext; if (currFile.size < 4) ext = Encoding.ASCII.GetChars(br.ReadBytes((int)currFile.size)); else ext = Encoding.ASCII.GetChars(br.ReadBytes(4)); String extS = "."; for (int s = 0; s < ext.Length; s++) if (Char.IsLetterOrDigit(ext[s]) || ext[s] == 0x20) extS += ext[s]; if (extS != "." && extS.Length == 5 && currFile.size >= 4) currFile.name += extS; else currFile.name += ".bin"; br.BaseStream.Position = currPos; if (!(main.files is List<sFile>)) main.files = new List<sFile>(); main.files.Add(currFile); } arc.btnf.entries.Add(main); continue; } long posmain = br.BaseStream.Position; br.BaseStream.Position = main.offset + mainTables_offset; int id = br.ReadByte(); while (id != 0x0) // Indicate the end of the subtable { if ((id & 0x80) == 0) // File { sFile currFile = new sFile(); currFile.id = (ushort)idFile++; currFile.name = new String(br.ReadChars(id)); // FAT data currFile.path = file.path; currFile.offset = arc.btaf.entries[currFile.id].start_offset + gmif_offset; currFile.size = (arc.btaf.entries[currFile.id].end_offset - arc.btaf.entries[currFile.id].start_offset); if (!(main.files is List<sFile>)) main.files = new List<sFile>(); main.files.Add(currFile); } else // Directory { sFolder currFolder = new sFolder(); currFolder.name = new String(br.ReadChars(id - 0x80)); currFolder.id = br.ReadUInt16(); if (!(main.folders is List<sFolder>)) main.folders = new List<sFolder>(); main.folders.Add(currFolder); } id = br.ReadByte(); } arc.btnf.entries.Add(main); br.BaseStream.Position = posmain; } sFolder root = Create_TreeFolders(arc.btnf.entries, 0xF000, "root"); #endregion // GMIF (File IMaGe) br.BaseStream.Position = gmif_offset - 8; arc.gmif.id = br.ReadChars(4); arc.gmif.section_size = br.ReadUInt32(); // Files data br.Close(); narc = arc; return root; }
public sFolder Unpack(sFile file) { ARC arc = new ARC(); BinaryReader br = new BinaryReader(System.IO.File.OpenRead(file.path)); // Nitro generic header arc.id = br.ReadChars(4); arc.id_endian = br.ReadUInt16(); if (arc.id_endian == 0xFFFE) { arc.id.Reverse <Char>(); } arc.constant = br.ReadUInt16(); arc.file_size = br.ReadUInt32(); arc.header_size = br.ReadUInt16(); arc.nSections = br.ReadUInt16(); // BTAF (File Allocation TaBle) arc.btaf.id = br.ReadChars(4); arc.btaf.section_size = br.ReadUInt32(); arc.btaf.nFiles = br.ReadUInt32(); arc.btaf.entries = new BTAF_Entry[arc.btaf.nFiles]; for (int i = 0; i < arc.btaf.nFiles; i++) { arc.btaf.entries[i].start_offset = br.ReadUInt32(); arc.btaf.entries[i].end_offset = br.ReadUInt32(); } // BTNF (File Name TaBle) arc.btnf.id = br.ReadChars(4); arc.btnf.section_size = br.ReadUInt32(); arc.btnf.entries = new List <BTNF_MainEntry>(); long mainTables_offset = br.BaseStream.Position; uint gmif_offset = (uint)br.BaseStream.Position + arc.btnf.section_size; #region Get root folder br.BaseStream.Position += 6; ushort num_mains = br.ReadUInt16(); br.BaseStream.Position -= 8; for (int m = 0; m < num_mains; m++) { BTNF_MainEntry main = new BTNF_MainEntry(); main.offset = br.ReadUInt32(); main.first_pos = br.ReadUInt16(); main.parent = br.ReadUInt16(); uint idFile = main.first_pos; if (main.offset < 0x8) // There aren't names (in Pokemon games) { for (int i = 0; i < arc.btaf.nFiles; i++) { sFile currFile = new sFile(); currFile.name = Path.GetFileNameWithoutExtension(file.name) + '_' + idFile.ToString(); currFile.id = (ushort)idFile++; // FAT data currFile.path = file.path; currFile.offset = arc.btaf.entries[currFile.id].start_offset + gmif_offset; currFile.size = (arc.btaf.entries[currFile.id].end_offset - arc.btaf.entries[currFile.id].start_offset); // Get the extension long currPos = br.BaseStream.Position; br.BaseStream.Position = currFile.offset; char[] ext; if (currFile.size < 4) { ext = Encoding.ASCII.GetChars(br.ReadBytes((int)currFile.size)); } else { ext = Encoding.ASCII.GetChars(br.ReadBytes(4)); } String extS = "."; for (int s = 0; s < ext.Length; s++) { if (Char.IsLetterOrDigit(ext[s]) || ext[s] == 0x20) { extS += ext[s]; } } if (extS != "." && extS.Length == 5 && currFile.size >= 4) { currFile.name += extS; } else { currFile.name += ".bin"; } br.BaseStream.Position = currPos; if (!(main.files is List <sFile>)) { main.files = new List <sFile>(); } main.files.Add(currFile); } arc.btnf.entries.Add(main); continue; } long posmain = br.BaseStream.Position; br.BaseStream.Position = main.offset + mainTables_offset; int id = br.ReadByte(); while (id != 0x0) // Indicate the end of the subtable { if ((id & 0x80) == 0) // File { sFile currFile = new sFile(); currFile.id = (ushort)idFile++; currFile.name = new String(br.ReadChars(id)); // FAT data currFile.path = file.path; currFile.offset = arc.btaf.entries[currFile.id].start_offset + gmif_offset; currFile.size = (arc.btaf.entries[currFile.id].end_offset - arc.btaf.entries[currFile.id].start_offset); if (!(main.files is List <sFile>)) { main.files = new List <sFile>(); } main.files.Add(currFile); } else // Directory { sFolder currFolder = new sFolder(); currFolder.name = new String(br.ReadChars(id - 0x80)); currFolder.id = br.ReadUInt16(); if (!(main.folders is List <sFolder>)) { main.folders = new List <sFolder>(); } main.folders.Add(currFolder); } id = br.ReadByte(); } arc.btnf.entries.Add(main); br.BaseStream.Position = posmain; } sFolder root = Create_TreeFolders(arc.btnf.entries, 0xF000, "root"); #endregion // GMIF (File IMaGe) br.BaseStream.Position = gmif_offset - 8; arc.gmif.id = br.ReadChars(4); arc.gmif.section_size = br.ReadUInt32(); // Files data br.Close(); narc = arc; return(root); }
public sFolder Unpack(string archivo) { ARC arc = new ARC(); utilityFile = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + "utility_" + Path.GetRandomFileName(); File.Copy(archivo, utilityFile, true); BinaryReader br = new BinaryReader(System.IO.File.OpenRead(archivo)); uint fntOffset = br.ReadUInt32(); uint fntSize = br.ReadUInt32(); uint fatOffset = br.ReadUInt32(); uint fatSize = br.ReadUInt32(); // FAT (File Allocation TaBle) br.BaseStream.Position = fatOffset; arc.btaf.nFiles = fatSize / 0x08; arc.btaf.entries = new BTAF_Entry[arc.btaf.nFiles]; for (int i = 0; i < arc.btaf.nFiles; i++) { arc.btaf.entries[i].start_offset = br.ReadUInt32(); arc.btaf.entries[i].end_offset = br.ReadUInt32(); } // FNT (File Name TaBle) br.BaseStream.Position = fntOffset; arc.btnf.entries = new List <BTNF_MainEntry>(); #region Get root directory do { BTNF_MainEntry main = new BTNF_MainEntry(); main.offset = br.ReadUInt32(); main.first_pos = br.ReadUInt16(); main.parent = br.ReadUInt16(); uint idFile = main.first_pos; long currOffset = br.BaseStream.Position; br.BaseStream.Position = main.offset + fntOffset; int id = br.ReadByte(); while (id != 0x0) // End of subtable { if ((id & 0x80) == 0) // File { sFile currFile = new sFile(); currFile.id = (ushort)idFile; idFile++; currFile.name = new String(br.ReadChars(id)); // Add the fat data currFile.path = utilityFile; currFile.offset = arc.btaf.entries[currFile.id].start_offset; currFile.size = (arc.btaf.entries[currFile.id].end_offset - currFile.offset); if (!(main.files is List <sFile>)) { main.files = new List <sFile>(); } main.files.Add(currFile); } else // Directory { sFolder currFolder = new sFolder(); currFolder.name = new String(br.ReadChars(id - 0x80)); currFolder.id = br.ReadUInt16(); if (!(main.folders is List <sFolder>)) { main.folders = new List <sFolder>(); } main.folders.Add(currFolder); } id = br.ReadByte(); } arc.btnf.entries.Add(main); br.BaseStream.Position = currOffset; } while (fntOffset + arc.btnf.entries[0].offset != br.BaseStream.Position); sFolder root = Create_TreeFolders(arc.btnf.entries, 0xF000, "root"); #endregion br.Close(); return(root); }
public sFolder Unpack(string archivo) { ARC arc = new ARC(); utilityFile = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + "utility_" + Path.GetRandomFileName(); File.Copy(archivo, utilityFile, true); BinaryReader br = new BinaryReader(System.IO.File.OpenRead(archivo)); uint fntOffset = br.ReadUInt32(); uint fntSize = br.ReadUInt32(); uint fatOffset = br.ReadUInt32(); uint fatSize = br.ReadUInt32(); // FAT (File Allocation TaBle) br.BaseStream.Position = fatOffset; arc.btaf.nFiles = fatSize / 0x08; arc.btaf.entries = new BTAF_Entry[arc.btaf.nFiles]; for (int i = 0; i < arc.btaf.nFiles; i++) { arc.btaf.entries[i].start_offset = br.ReadUInt32(); arc.btaf.entries[i].end_offset = br.ReadUInt32(); } // FNT (File Name TaBle) br.BaseStream.Position = fntOffset; arc.btnf.entries = new List<BTNF_MainEntry>(); #region Get root directory do { BTNF_MainEntry main = new BTNF_MainEntry(); main.offset = br.ReadUInt32(); main.first_pos = br.ReadUInt16(); main.parent = br.ReadUInt16(); uint idFile = main.first_pos; long currOffset = br.BaseStream.Position; br.BaseStream.Position = main.offset + fntOffset; int id = br.ReadByte(); while (id != 0x0) // End of subtable { if ((id & 0x80) == 0) // File { sFile currFile = new sFile(); currFile.id = (ushort)idFile; idFile++; currFile.name = new String(br.ReadChars(id)); // Add the fat data currFile.path = utilityFile; currFile.offset = arc.btaf.entries[currFile.id].start_offset; currFile.size = (arc.btaf.entries[currFile.id].end_offset - currFile.offset); if (!(main.files is List<sFile>)) main.files = new List<sFile>(); main.files.Add(currFile); } else // Directory { sFolder currFolder = new sFolder(); currFolder.name = new String(br.ReadChars(id - 0x80)); currFolder.id = br.ReadUInt16(); if (!(main.folders is List<sFolder>)) main.folders = new List<sFolder>(); main.folders.Add(currFolder); } id = br.ReadByte(); } arc.btnf.entries.Add(main); br.BaseStream.Position = currOffset; } while (fntOffset + arc.btnf.entries[0].offset != br.BaseStream.Position); sFolder root = Create_TreeFolders(arc.btnf.entries, 0xF000, "root"); #endregion br.Close(); return root; }