public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); int index_offset = 4; int index_end = 4 + 8 * count; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry { Offset = file.View.ReadUInt32(index_offset), Size = file.View.ReadUInt32(index_offset + 4), }; if (entry.Offset < index_end || !entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.Name = string.Format("{0}#{1:D5}", base_name, i); dir.Add(entry); index_offset += 8; } foreach (PackedEntry entry in dir) { var n = file.View.ReadInt32(entry.Offset); if (n <= 0) { return(null); } var offset = file.View.ReadUInt32(entry.Offset + 4); var size = file.View.ReadUInt32(entry.Offset + 8); entry.Offset += offset; entry.Size = size & 0x3FFFFFFF; entry.IsPacked = 2 != (size >> 30); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } var res = AutoEntry.DetectFileType(file.View.ReadUInt32(entry.Offset)); if (res != null) { entry.ChangeType(res); } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); var dir = new List <Entry> (count); int index_offset = 8; long data_offset = count * 4 + 8; uint next_offset = file.View.ReadUInt32(index_offset); for (int i = 0; i < count; ++i) { index_offset += 4; var entry = new PackedEntry { Offset = next_offset }; next_offset = i + 1 < count?file.View.ReadUInt32(index_offset) : (uint)file.MaxOffset; entry.Size = next_offset - (uint)entry.Offset; if (entry.Offset < data_offset || !entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.Name = string.Format("{0}#{1:D4}", base_name, i); dir.Add(entry); } DetectFileTypes(file, dir); return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { var arc_name = Path.GetFileName(file.Name); var parsed = ArcNameParser.ParseName(arc_name); if (null == parsed) { return(null); } var toc_name = VFS.CombinePath(VFS.GetDirectoryName(file.Name), parsed.Item1); var toc = ReadToc(toc_name, 4); if (null == toc) { return(null); } bool has_images = false; var dir = new List <Entry>(); using (var toc_stream = new MemoryStream(toc)) using (var index = new StreamReader(toc_stream)) { string line; while ((line = index.ReadLine()) != null) { var fields = line.Split(','); if (fields.Length != 5) { return(null); } var name = Path.ChangeExtension(fields[0], fields[4]); string type = ""; if ("b" == fields[4]) { type = "image"; has_images = true; } else if ("k" == fields[4] || "j" == fields[4]) { type = "audio"; } var entry = new PackedEntry { Name = name, Type = type, Offset = UInt32.Parse(fields[3]), Size = UInt32.Parse(fields[2]), UnpackedSize = UInt32.Parse(fields[1]), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.IsPacked = entry.UnpackedSize != entry.Size; dir.Add(entry); } } return(ArchiveFromDir(file, dir, has_images)); }
bool ReadV1(Stream input) { // NOTE CryptoStream will close an input stream using (var xored = new CryptoStream(input, new NotTransform(), CryptoStreamMode.Read)) using (var lzss = new LzssStream(xored)) lzss.Read(m_index, 0, m_index.Length); int index_offset = Array.IndexOf(m_index, (byte)0); if (-1 == index_offset || 0 == index_offset) { return(false); } Password = m_index.Take(index_offset++).ToArray(); long base_offset = 0x20 + m_packed_size; for (int i = 0; i < m_count; ++i) { var entry = new PackedEntry(); entry.Offset = LittleEndian.ToUInt32(m_index, index_offset) + base_offset; entry.Size = LittleEndian.ToUInt32(m_index, index_offset + 4); entry.UnpackedSize = LittleEndian.ToUInt32(m_index, index_offset + 8); entry.IsPacked = entry.UnpackedSize != 0; if (!entry.CheckPlacement(m_file.MaxOffset)) { return(false); } int name_len = LittleEndian.ToInt32(m_index, index_offset + 0xC); entry.Name = Encodings.cp932.GetString(m_index, index_offset + 0x18, name_len); entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); m_dir.Value.Add(entry); index_offset += 0x18 + name_len; } return(true); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0x10); if (!IsSaneCount(count)) { return(null); } uint index_offset = file.View.ReadUInt32(8); if (index_offset >= file.MaxOffset) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry { Name = string.Format("{0}#{1:D4}", base_name, i), Size = file.View.ReadUInt32(index_offset), Offset = file.View.ReadUInt32(index_offset + 4), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 8; } DetectFileTypes(dir, file); return(new ArcFile(file, this, dir)); }
bool ReadV0(Stream input) { long current_offset = 0x20 + m_packed_size; uint offset_table_size = (uint)m_count * 0x10; if (offset_table_size > m_file.View.Reserve(current_offset, offset_table_size)) { return(false); } using (var lzss = new LzssStream(input, LzssMode.Decompress, true)) if (m_index.Length != lzss.Read(m_index, 0, m_index.Length)) { return(false); } for (int i = 0; i < m_index.Length; ++i) { m_index[i] = (byte)(~m_index[i] - 5); } int index_offset = Array.IndexOf <byte> (m_index, 0); if (-1 == index_offset || 0 == index_offset) { return(false); } index_offset++; // Password = m_index.Take (index_offset++).ToArray(); for (int i = 0; i < m_count && index_offset < m_index.Length; ++i) { int name_end = Array.IndexOf <byte> (m_index, 0, index_offset); if (-1 == name_end) { name_end = m_index.Length; } if (index_offset == name_end) { return(false); } var entry = new PackedEntry(); entry.Offset = m_file.View.ReadUInt32(current_offset); entry.Size = m_file.View.ReadUInt32(current_offset + 4); entry.UnpackedSize = m_file.View.ReadUInt32(current_offset + 8); entry.IsPacked = entry.UnpackedSize != 0; if (!entry.CheckPlacement(m_file.MaxOffset)) { return(false); } entry.Name = Encodings.cp932.GetString(m_index, index_offset, name_end - index_offset); entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); m_dir.Value.Add(entry); index_offset = name_end + 1; current_offset += 0x10; } return(true); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(4, "KO ARC20")) { return(null); } int count = file.View.ReadInt32(12); if (!IsSaneCount(count)) { return(null); } uint index_size = 0x80 * (uint)count; if (index_size > file.View.Reserve(0x10, index_size)) { return(null); } var dir = new List <Entry> (count); long index_offset = 0x10; long base_offset = index_offset + index_size; for (uint i = 0; i < count; ++i) { string name = file.View.ReadString(index_offset, 0x60); var offset = base_offset + file.View.ReadUInt32(index_offset + 0x60); var entry = new PackedEntry { Name = name, Offset = offset }; entry.Size = file.View.ReadUInt32(index_offset + 0x64); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 0x80; } foreach (var entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); var res = AutoEntry.DetectFileType(signature); if (res != null) { entry.Type = res.Type; } else if (file.View.AsciiEqual(entry.Offset, "BSE 1.")) { entry.Type = "image"; } else if (file.View.AsciiEqual(entry.Offset + 4, "bw ")) { entry.Type = "audio"; } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(0, "PAC") || 'K' == file.View.ReadByte(3)) { return(null); } int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } int pack_type = file.View.ReadInt32(8); uint index_size = file.View.ReadUInt32(file.MaxOffset - 4); if (index_size >= file.MaxOffset) { return(null); } byte[] index_packed = new byte[index_size]; file.View.Read(file.MaxOffset - 4 - index_size, index_packed, 0, index_size); for (int i = 0; i < index_packed.Length; ++i) { index_packed[i] = (byte)~index_packed[i]; } var index = HuffmanDecode(index_packed, count * 0x4c); var dir = new List <Entry> (count); int offset = 0; for (int i = 0; i < count; ++i, offset += 0x4c) { var name = Binary.GetCString(index, offset, 0x40); var entry = new PackedEntry { Name = name, Type = FormatCatalog.Instance.GetTypeFromName(name), Offset = LittleEndian.ToUInt32(index, offset + 0x40), UnpackedSize = LittleEndian.ToUInt32(index, offset + 0x44), Size = LittleEndian.ToUInt32(index, offset + 0x48), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.IsPacked = pack_type != 0 && (pack_type != 4 || entry.Size != entry.UnpackedSize); dir.Add(entry); } if (0 == pack_type) { return(new ArcFile(file, this, dir)); } return(new PacArchive(file, this, dir, (Compression)pack_type)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if ((count & 0xFFFF) != 0) { return(null); } count = (count >> 16) - 1; if (!IsSaneCount(count)) { return(null); } uint index_offset = 0xC; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadUInt32(index_offset).ToString("D5"); var entry = new PackedEntry { Name = name, Offset = file.View.ReadUInt32(index_offset + 4) << 11, Size = file.View.ReadUInt32(index_offset + 8), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 12; } foreach (PackedEntry entry in dir) { uint signature; if (entry.Size > 13 && file.View.AsciiEqual(entry.Offset + 2, "ike")) { int unpacked_size = IkeReader.DecodeSize(file.View.ReadByte(entry.Offset + 10), file.View.ReadByte(entry.Offset + 11), file.View.ReadByte(entry.Offset + 12)); entry.IsPacked = true; entry.UnpackedSize = (uint)unpacked_size; signature = file.View.ReadUInt32(entry.Offset + 0xF); entry.Offset += 13; entry.Size -= 13; } else { signature = file.View.ReadUInt32(entry.Offset); } entry.ChangeType(AutoEntry.DetectFileType(signature)); } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { var arc_list = new List <Entry>(); long max_offset = file.MaxOffset; for (int i = 1; i < 100; ++i) { var part_name = Path.ChangeExtension(file.Name, string.Format("a{0:D02}", i)); if (!VFS.FileExists(part_name)) { break; } var part = VFS.FindFile(part_name); arc_list.Add(part); max_offset += part.Size; } uint index_length = file.View.ReadUInt32(8); uint data_offset = file.View.ReadUInt32(0x10); using (var zindex = file.CreateStream(0x20, index_length)) using (var uindex = new ZLibStream(zindex, CompressionMode.Decompress)) using (var index = new BinaryStream(uindex, file.Name)) { var buffer = new byte[500]; var dir = new List <Entry>(); while (index.PeekByte() != -1) { int entry_length = index.ReadInt32(); if (entry_length <= 528) { return(null); } bool is_deleted = index.ReadUInt32() != 0; var entry = new PackedEntry(); entry.Offset = index.ReadInt64() + data_offset; index.ReadUInt32(); entry.Size = index.ReadUInt32(); entry.UnpackedSize = index.ReadUInt32(); entry.IsPacked = entry.Size != entry.UnpackedSize; index.Read(buffer, 0, 500); int name_length = index.Read(buffer, 0, entry_length - 528); if (!is_deleted && entry.CheckPlacement(max_offset)) { entry.Name = Encoding.Unicode.GetString(buffer, 0, name_length); entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); dir.Add(entry); } } return(new Mpf2Archive(file, this, dir, arc_list)); } }
public override ArcFile TryOpen(ArcView file) { uint first_offset = file.View.ReadUInt32(0); if (first_offset < 8 || first_offset >= file.MaxOffset || 0 != (first_offset & 3)) { return(null); } int count = (int)(first_offset - 4) / 4; if (!IsSaneCount(count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); uint index_offset = 0; uint next_offset = first_offset; var dir = new List <Entry> (count); for (int i = 0; i < count && next_offset < file.MaxOffset; ++i) { var entry = new PackedEntry { Offset = next_offset }; index_offset += 4; next_offset = file.View.ReadUInt32(index_offset); if (next_offset < entry.Offset) { return(null); } entry.Size = (uint)(next_offset - entry.Offset); entry.UnpackedSize = entry.Size; if (entry.Size != 0) { if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.Name = string.Format("{0}#{1:D4}", base_name, i); dir.Add(entry); } } if (0 == dir.Count) { return(null); } DetectFileTypes(file, dir); return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } uint index_offset = 8; long base_offset = count * 0x20 + 8; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { string name = file.View.ReadString(index_offset, 0x10); uint size = file.View.ReadUInt32(index_offset + 0x10); var entry = new PackedEntry { Name = name }; if (name.HasExtension(".scp")) { entry.Type = "script"; entry.IsPacked = size > 12 && file.View.AsciiEqual(index_offset + 0x14, "CMP1"); } else { entry.Type = FormatCatalog.Instance.GetTypeFromName(name); entry.IsPacked = false; } if (entry.IsPacked) { entry.UnpackedSize = file.View.ReadUInt32(index_offset + 0x18); } else { entry.UnpackedSize = size; } entry.Offset = base_offset; entry.Size = size; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); base_offset += size; index_offset += 0x20; } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(0, "KOTORI") || 0x1A1A00 != file.View.ReadInt32(6)) { return(null); } int count = file.View.ReadUInt16(0x14); if (0x0100A618 != file.View.ReadInt32(0x10) || !IsSaneCount(count)) { return(null); } string base_name = Path.GetFileNameWithoutExtension(file.Name); uint current_offset = 0x18; long next_offset = file.View.ReadUInt32(current_offset); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry { Name = string.Format("{0}#{1:D4}.ogg", base_name, i), Type = "audio", Offset = next_offset, }; if (i + 1 != count) { current_offset += 6; next_offset = file.View.ReadUInt32(current_offset); } else { next_offset = file.MaxOffset; } entry.Size = (uint)(next_offset - entry.Offset); if (entry.Size >= 0x32) { entry.IsPacked = true; entry.UnpackedSize = entry.Size - 0x32; } if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } uint first_offset = file.View.ReadUInt32(4); if (first_offset != 4 + (uint)count * 12) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name).ToUpperInvariant(); string default_type = base_name == "SCR" ? "script" : base_name == "VOICE" || base_name == "SE" ? "audio" : base_name == "PICT" ? "image" : ""; uint index_offset = 4; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { uint offset = file.View.ReadUInt32(index_offset); var entry = new PackedEntry { Name = string.Format("{0}#{1:D4}", base_name, i), Type = default_type, Offset = file.View.ReadUInt32(index_offset), UnpackedSize = file.View.ReadUInt32(index_offset + 4), Size = file.View.ReadUInt32(index_offset + 8), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.IsPacked = entry.UnpackedSize != entry.Size; dir.Add(entry); index_offset += 12; } if (string.IsNullOrEmpty(default_type)) { DetectFileTypes(file, dir); } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } var index = Him5Opener.ReadIndex(file, 0x20, count); var dir = new List <Entry>(); foreach (var section in index) { int index_offset = section.Item1; for (int section_size = section.Item2; section_size > 0;) { int entry_size = file.View.ReadByte(index_offset); if (entry_size < 17) { break; } var entry = new PackedEntry { Offset = file.View.ReadUInt32(index_offset + 1), UnpackedSize = file.View.ReadUInt32(index_offset + 5), Size = file.View.ReadUInt32(index_offset + 9), Name = file.View.ReadString(index_offset + 17, (uint)entry_size - 17), }; entry.IsPacked = entry.Size != 0; if (!entry.IsPacked) { entry.Size = entry.UnpackedSize; } if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } index_offset += entry_size; section_size -= entry_size; dir.Add(entry); } } DetectFileTypes(file, dir); return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".arc")) { return(null); } var bin_name = Path.ChangeExtension(file.Name, "BIN"); if (!VFS.FileExists(bin_name)) { return(null); } using (var bin = VFS.OpenView(bin_name)) { if (!bin.View.AsciiEqual(0, "LSDARC V.100")) { return(null); } int count = bin.View.ReadInt32(0xC); if (!IsSaneCount(count)) { return(null); } using (var index = bin.CreateStream()) { index.Position = 0x10; var dir = new List <Entry>(count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry(); entry.IsPacked = index.ReadInt32() != 0; entry.Offset = index.ReadUInt32(); entry.UnpackedSize = index.ReadUInt32(); entry.Size = index.ReadUInt32(); entry.Name = index.ReadCString(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new ArcFile(file, this, dir)); } } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".dm")) { return(null); } int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } var arc_name = Path.GetFileNameWithoutExtension(file.Name).ToLowerInvariant(); string type = arc_name == "image" ? "image" : arc_name == "sound" ? "audio" : ""; uint index_offset = 4; uint data_offset = 4 + (uint)count * 0x2C; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString(index_offset, 0x20); if (string.IsNullOrWhiteSpace(name)) { return(null); } var entry = new PackedEntry { Name = name, Type = type, UnpackedSize = file.View.ReadUInt32(index_offset + 0x20), Size = file.View.ReadUInt32(index_offset + 0x24), Offset = file.View.ReadUInt32(index_offset + 0x28), IsPacked = true, }; if (entry.Offset < data_offset || !entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 0x2C; } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { uint index_offset = file.View.ReadUInt32(8); int count = file.View.ReadInt32(0xC); if (!IsSaneCount(count) || index_offset >= file.MaxOffset) { return(null); } var dir = new List <Entry> (count); Func <uint, bool> ReadIndex = entry_size => { uint current_offset = index_offset; for (int i = 0; i < count; ++i) { var entry = new PackedEntry { Name = i.ToString("D5") }; entry.Offset = file.View.ReadUInt32(current_offset); entry.Size = file.View.ReadUInt32(current_offset + 4); if (0 == entry.Size || !entry.CheckPlacement(file.MaxOffset)) { return(false); } dir.Add(entry); current_offset += entry_size; } return(true); }; if (!ReadIndex(8)) { dir.Clear(); if (!ReadIndex(0x10)) { return(null); } } using (var stream = file.CreateStream()) DetectFileTypes(stream, dir); return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0xC); if (!IsSaneCount(count)) { return(null); } uint index_offset = file.View.ReadUInt32(4); if (index_offset >= file.MaxOffset) { return(null); } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry { UnpackedSize = file.View.ReadUInt32(index_offset), Size = file.View.ReadUInt32(index_offset + 4), Offset = file.View.ReadUInt32(index_offset + 8), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } uint name_length = file.View.ReadUInt32(index_offset + 0xC); if (0 == name_length || name_length > 0x100) { return(null); } entry.Name = file.View.ReadString(index_offset + 0x10, name_length); entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); entry.IsPacked = entry.UnpackedSize != entry.Size; dir.Add(entry); index_offset += 0x10 + name_length; } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { if (file.View.ReadInt16(4) != 1) { return(null); } uint unpacked_size = file.View.ReadUInt32(0x16); uint width = file.View.ReadUInt32(0x1A); uint height = file.View.ReadUInt32(0x1E); int count = file.View.ReadInt32(0x2A); if (!IsSaneCount(count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); uint offset = 0x32; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { uint size = file.View.ReadUInt32(offset); var entry = new PackedEntry { Name = string.Format("{0}#{1:D4}.bmp", base_name, i), Type = "image", Offset = offset + 4, Size = size, IsPacked = true, UnpackedSize = unpacked_size + 0x36, }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); offset += 4 + size; } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count) || !file.Name.HasExtension(".dat")) { return(null); } uint first_offset = file.View.ReadUInt32(0x14); if (first_offset != 4 + count * 0x14) { return(null); } uint index_offset = 4; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString(index_offset, 0xC); if (string.IsNullOrEmpty(name)) { return(null); } var entry = new PackedEntry { Name = name, Size = file.View.ReadUInt32(index_offset + 0xC), Offset = file.View.ReadUInt32(index_offset + 0x10), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 0x14; } DetectFileTypes(file, dir); return(new ArcFile(file, this, dir)); }
internal List <Entry> ReadIndex(ArcView file, uint index_offset, int count) { var base_name = Path.GetFileNameWithoutExtension(file.Name); long offset = index_offset + count * 4; if (offset >= file.MaxOffset) { return(null); } var dir = new List <Entry> (count / 2); for (int i = 0; i < count; ++i) { uint size = file.View.ReadUInt32(index_offset); if (size != 0 && size != uint.MaxValue) { var entry = new PackedEntry { Name = string.Format("{0}#{1:D5}", base_name, i), Offset = offset, Size = size, IsPacked = false, }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); offset += size; } index_offset += 4; } if (0 == dir.Count || (file.MaxOffset - offset) > 0x80000) { return(null); } DetectFileTypes(file, dir); return(dir); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); uint index_offset = 0x20; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry { Offset = file.View.ReadUInt32(index_offset), UnpackedSize = file.View.ReadUInt32(index_offset + 4), Size = file.View.ReadUInt32(index_offset + 8), Name = string.Format("{0}#{1:D5}", base_name, i), }; entry.IsPacked = entry.Size != 0; if (!entry.IsPacked) { entry.Size = entry.UnpackedSize; } if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } index_offset += 0x10; dir.Add(entry); } DetectFileTypes(file, dir); return(new ArcFile(file, this, dir)); }
public List <Entry> ReadIndex() { uint section_size = ReadSectionSize("Fver"); m_offset += section_size; section_size = ReadSectionSize("Fcdr"); /* * int Mcdr_size; * var Mcdr = ZlibUnpack (m_offset, section_size, out Mcdr_size); */ m_offset += section_size; uint abmp_size = ReadSectionSize("ABMP"); int max_count = m_file.View.Read(m_offset, m_size_buffer, 0, Math.Min(10, abmp_size)); int size_offset = 0; ReadValue(m_size_buffer, ref size_offset, max_count); max_count -= size_offset; int bmp_unpacked_size = (int)ReadValue(m_size_buffer, ref size_offset, max_count); m_offset += size_offset; abmp_size -= (uint)size_offset; int index_size; var index = ZlibUnpack(m_offset, abmp_size, out index_size, bmp_unpacked_size); m_offset += abmp_size; section_size = ReadSectionSize("FGEI"); if (0 != section_size) { throw new NotSupportedException(); } int index_offset = 0; ReadValue(index, ref index_offset, index_size - index_offset); ReadValue(index, ref index_offset, index_size - index_offset); int entry_count = (int)ReadValue(index, ref index_offset, index_size - index_offset); if (entry_count <= 0 || entry_count > 0xfffff) { return(null); } var type_buf = new char[4]; var dir = new List <Entry> (entry_count); for (int i = 0; i < entry_count; ++i) { uint id = ReadValue(index, ref index_offset, index_size - index_offset); uint offset = ReadValue(index, ref index_offset, index_size - index_offset); uint size = ReadValue(index, ref index_offset, index_size - index_offset); uint unpacked_size = ReadValue(index, ref index_offset, index_size - index_offset); uint flag = ReadValue(index, ref index_offset, index_size - index_offset); if (index_size - index_offset < 4) { return(null); } uint type_id = LittleEndian.ToUInt32(index, index_offset); index_offset += 4; if (0 == type_id || uint.MaxValue == offset) { continue; } Encoding.ASCII.GetChars(index, index_offset - 4, 4, type_buf, 0); var entry = new PackedEntry { Name = CreateName(id, type_buf), Offset = (long)m_offset + offset, Size = size, UnpackedSize = unpacked_size, IsPacked = 0 == flag, }; if (entry.CheckPlacement(m_file.MaxOffset)) { dir.Add(entry); } } return(dir); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } uint first_offset = file.View.ReadUInt32(4); if (4 + count * 8 != first_offset) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); bool is_msg = base_name == "msg"; uint index_offset = 4; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { uint offset = file.View.ReadUInt32(index_offset); uint size = file.View.ReadUInt32(index_offset + 4); var entry = new PackedEntry { Name = string.Format("{0}#{1:D5}", base_name, i), Offset = offset, Size = size, }; if (!is_msg && !entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 8; } foreach (PackedEntry entry in dir) { if (is_msg) { uint size = file.View.ReadUInt32(entry.Offset); entry.Offset += 4; entry.UnpackedSize = entry.Size; entry.Size = size; entry.IsPacked = true; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } continue; } uint pos = file.View.ReadUInt32(entry.Offset + 4); if (pos > entry.Size) { continue; } uint unpacked_size = file.View.ReadUInt32(entry.Offset + 8); uint flags = unpacked_size >> 30; unpacked_size &= 0x3FFFFFFF; entry.IsPacked = 0 == flags; uint signature = 0; if (entry.IsPacked) { entry.UnpackedSize = unpacked_size; entry.Size = file.View.ReadUInt32(entry.Offset + pos); entry.Offset += pos + 4; if ((file.View.ReadByte(entry.Offset) & 0xF) == 0xF) { signature = file.View.ReadUInt32(entry.Offset + 1); } } else { entry.Size = unpacked_size; entry.Offset += pos; signature = file.View.ReadUInt32(entry.Offset); } var res = AutoEntry.DetectFileType(signature); if (res != null) { entry.ChangeType(res); } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } long offset = 4 + count * 4; if (offset >= file.MaxOffset) { return(null); } uint index_offset = 4; var dir = new List <Entry>(); for (int i = 0; i < count; ++i) { uint size = file.View.ReadUInt32(index_offset); if (0 != size) { var entry = new PackedEntry { Name = i.ToString("D5"), Offset = offset, Size = size, IsPacked = false, }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); offset += size; } index_offset += 4; } if (offset != file.MaxOffset || 0 == dir.Count) { return(null); } byte[] preview = new byte[16]; byte[] sign_buf = new byte[4]; foreach (PackedEntry entry in dir) { uint extra = 6; if (extra > entry.Size) { continue; } int label = file.View.ReadUInt16(entry.Offset); if (1 == label) { entry.IsPacked = true; entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 2); } entry.Offset += extra; entry.Size -= extra; uint signature; if (entry.IsPacked) { file.View.Read(entry.Offset, preview, 0, (uint)preview.Length); using (var input = new MemoryStream(preview)) { LzssUnpack(input, sign_buf); signature = LittleEndian.ToUInt32(sign_buf, 0); } } else { signature = file.View.ReadUInt32(entry.Offset); } if (0 != signature) { SetEntryType(entry, signature); } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { uint first_offset = file.View.ReadUInt32 (0); if (first_offset < 8 || first_offset >= file.MaxOffset) return null; int count = (int)(first_offset - 8) / 4; if (!IsSaneCount (count)) return null; var base_name = Path.GetFileNameWithoutExtension (file.Name); uint index_offset = 0; uint next_offset = first_offset; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry { Offset = next_offset }; index_offset += 4; next_offset = file.View.ReadUInt32 (index_offset); if (next_offset < entry.Offset) return null; entry.Size = (uint)(next_offset - entry.Offset); entry.UnpackedSize = entry.Size; if (entry.Size != 0) { if (!entry.CheckPlacement (file.MaxOffset)) return null; entry.Name = string.Format ("{0}#{1:D4}", base_name, i); dir.Add (entry); } } if (0 == dir.Count) return null; foreach (PackedEntry entry in dir) { if (entry.Size < 4) continue; uint unpacked_size = file.View.ReadUInt32 (entry.Offset); if (entry.Size > 8 && file.View.AsciiEqual (entry.Offset+4, "HDJ\0")) { if (file.View.AsciiEqual (entry.Offset+12, "BM")) { entry.Name = Path.ChangeExtension (entry.Name, "bmp"); entry.Type = "image"; } entry.UnpackedSize = unpacked_size; entry.IsPacked = true; } else if (entry.Size > 12 && file.View.AsciiEqual (entry.Offset+8, "RIFF")) { entry.Name = Path.ChangeExtension (entry.Name, "wav"); entry.Type = "audio"; entry.UnpackedSize = unpacked_size; entry.IsPacked = true; } else if (0x4D42 == (unpacked_size & 0xFFFF)) { entry.Name = Path.ChangeExtension (entry.Name, "bmp"); entry.Type = "image"; } } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(4, "OFST")) { return(null); } int index_size = file.View.ReadInt32(8); int count = index_size / 4; if (!IsSaneCount(count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); string content_ext = "", content_type = ""; if (base_name.EndsWith("flac", StringComparison.InvariantCultureIgnoreCase)) { content_ext = "flac"; content_type = "audio"; base_name = base_name.Substring(0, base_name.Length - 4); } else if (base_name.EndsWith("ogg", StringComparison.InvariantCultureIgnoreCase)) { content_ext = "ogg"; content_type = "audio"; base_name = base_name.Substring(0, base_name.Length - 3); } var filenames = GetFileNames(VFS.GetDirectoryName(file.Name), base_name); if (null == filenames) { filenames = new List <string> (count); } for (int i = filenames.Count; i < count; ++i) { filenames.Add(string.Format("{0}#{1:D5}", base_name, i)); } uint index_offset = 0xC; var dir = new List <Entry> (count); uint next_offset = file.View.ReadUInt32(index_offset); for (int i = 0; i < count; ++i) { index_offset += 4; var entry = new PackedEntry { Name = filenames[i] }; entry.Offset = next_offset; next_offset = i + 1 < count?file.View.ReadUInt32(index_offset) : (uint)file.MaxOffset; entry.Size = next_offset - (uint)entry.Offset; if (entry.Size > 0 && !entry.CheckPlacement(file.MaxOffset)) { return(null); } if (!string.IsNullOrEmpty(content_type)) { entry.Type = content_type; entry.Name = Path.ChangeExtension(entry.Name, content_ext); } dir.Add(entry); } foreach (PackedEntry entry in dir.Where(e => e.Size > 4)) { entry.IsPacked = file.View.AsciiEqual(entry.Offset, "DFLT"); if (entry.IsPacked) { entry.Size = file.View.ReadUInt32(entry.Offset + 4); entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 8); entry.Offset += 12; } else if (file.View.AsciiEqual(entry.Offset, "DATA")) { entry.Size = file.View.ReadUInt32(entry.Offset + 4); entry.UnpackedSize = entry.Size; entry.Offset += 8; if (string.IsNullOrEmpty(entry.Type)) { uint signature = file.View.ReadUInt32(entry.Offset); if (0x43614C66 == signature) // 'fLaC' { entry.Type = "audio"; entry.Name = Path.ChangeExtension(entry.Name, "flac"); } else { var res = AutoEntry.DetectFileType(signature); if (null != res) { entry.ChangeType(res); } } } } } return(new ArcFile(file, this, dir)); }
bool ReadV1(Stream input) { // NOTE CryptoStream will close an input stream using (var xored = new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read)) using (var lzss = new LzssStream (xored)) lzss.Read (m_index, 0, m_index.Length); int index_offset = Array.IndexOf (m_index, (byte)0); if (-1 == index_offset || 0 == index_offset) return false; Password = m_index.Take (index_offset++).ToArray(); long base_offset = 0x20 + m_packed_size; for (int i = 0; i < m_count; ++i) { var entry = new PackedEntry(); entry.Offset = LittleEndian.ToUInt32 (m_index, index_offset) + base_offset; entry.Size = LittleEndian.ToUInt32 (m_index, index_offset + 4); entry.UnpackedSize = LittleEndian.ToUInt32 (m_index, index_offset + 8); entry.IsPacked = entry.UnpackedSize != 0; if (!entry.CheckPlacement (m_file.MaxOffset)) return false; int name_len = LittleEndian.ToInt32 (m_index, index_offset + 0xC); entry.Name = Encodings.cp932.GetString (m_index, index_offset+0x18, name_len); entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name); m_dir.Value.Add (entry); index_offset += 0x18 + name_len; } return true; }
public override ArcFile TryOpen(ArcView file) { int version = file.View.ReadByte(3) - 0x30; int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } var name_buf = new byte[32]; var dir = new List <Entry> (count); long index_offset = 8; uint next_offset = file.View.ReadUInt32(index_offset); for (int i = 0; i < count; ++i) { uint offset = next_offset; uint size = file.View.ReadUInt32(index_offset + 4); int name_length = file.View.ReadByte(index_offset + 8); if (name_length > name_buf.Length) { name_buf = new byte[name_length]; } file.View.Read(index_offset + 9, name_buf, 0, (uint)name_length); if (i + 1 == count) { next_offset = (uint)file.MaxOffset; } else { next_offset = file.View.ReadUInt32(index_offset + 9 + name_length); } if (0 != offset && offset != file.MaxOffset) { if (2 == version) { for (int j = 0; j < name_length; ++j) { name_buf[j] ^= 0xff; } } uint packed_size; if (0 == next_offset) { packed_size = size; } else if (next_offset >= offset) { packed_size = next_offset - offset; } else { return(null); } string name = Encodings.cp932.GetString(name_buf, 0, name_length); var entry = new PackedEntry { Name = name, Type = FormatCatalog.Instance.GetTypeFromName(name), Offset = offset, Size = packed_size, UnpackedSize = size, IsPacked = packed_size != size, }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } index_offset += 9 + name_length; } if (2 == version) { return(new AstArchive(file, this, dir)); } else { return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } uint index_size = (uint)count * 4 + 8; if (index_size > file.View.Reserve(0, index_size)) { return(null); } uint index_offset = 4; uint offset = file.View.ReadUInt32(index_offset); if (offset != index_size) { return(null); } uint last_offset = file.View.ReadUInt32(index_size - 4); if (last_offset != file.MaxOffset) { return(null); } string default_type = ""; if (file.Name.HasExtension("fx")) { default_type = "audio"; } else if (file.Name.HasExtension("gx")) { default_type = "image"; } var base_name = Path.GetFileNameWithoutExtension(file.Name); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { index_offset += 4; var entry = new PackedEntry { Name = string.Format("{0}#{1:D4}", base_name, i), Type = default_type, Offset = offset, }; offset = file.View.ReadUInt32(index_offset); entry.Size = (uint)(offset - entry.Offset); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } if (string.IsNullOrEmpty(default_type)) { foreach (var entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); entry.ChangeType(AutoEntry.DetectFileType(signature)); } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32 (0); if (!IsSaneCount (count)) return null; long offset = 4+count*4; if (offset >= file.MaxOffset) return null; uint index_offset = 4; var dir = new List<Entry>(); for (int i = 0; i < count; ++i) { uint size = file.View.ReadUInt32 (index_offset); if (0 != size) { var entry = new PackedEntry { Name = i.ToString ("D5"), Offset = offset, Size = size, IsPacked = false, }; if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); offset += size; } index_offset += 4; } if (offset != file.MaxOffset || 0 == dir.Count) return null; byte[] preview = new byte[16]; byte[] sign_buf = new byte[4]; foreach (PackedEntry entry in dir) { uint extra = 6; if (extra > entry.Size) continue; int label = file.View.ReadUInt16 (entry.Offset); if (1 == label) { entry.IsPacked = true; entry.UnpackedSize = file.View.ReadUInt32 (entry.Offset+2); } entry.Offset += extra; entry.Size -= extra; uint signature; if (entry.IsPacked) { file.View.Read (entry.Offset, preview, 0, (uint)preview.Length); using (var input = new MemoryStream (preview)) { LzssUnpack (input, sign_buf); signature = LittleEndian.ToUInt32 (sign_buf, 0); } } else { signature = file.View.ReadUInt32 (entry.Offset); } if (0 != signature) SetEntryType (entry, signature); } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (0 != file.View.ReadInt32(4)) { return(null); } long index_offset = file.View.ReadInt64(8); if (index_offset >= file.MaxOffset) { return(null); } if (!file.View.AsciiEqual(index_offset, "GCE3")) { return(null); } int count = file.View.ReadInt32(index_offset + 0x18); if (!IsSaneCount(count)) { return(null); } bool index_packed = 0x11 == file.View.ReadInt32(index_offset + 4); uint index_size = file.View.ReadUInt32(index_offset + 8); byte[] index = null; if (index_packed) { index_size -= 0x28; int unpacked_size = file.View.ReadInt32(index_offset + 0x20); using (var input = file.CreateStream(index_offset + 0x28, index_size)) using (var reader = new GceReader(input, unpacked_size)) index = reader.Data; } else { index_size -= 0x20; index = new byte[index_size]; if (index.Length != file.View.Read(index_offset + 0x20, index, 0, index_size)) { return(null); } } int current_index = 0; int current_filename = 0x20 * count; long current_offset = 0x10; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int name_length = LittleEndian.ToUInt16(index, current_filename); if (current_filename + 2 + name_length > index.Length) { return(null); } uint size = LittleEndian.ToUInt32(index, current_index + 0x18); if (size != 0) { string name = Encodings.cp932.GetString(index, current_filename + 2, name_length); var entry = new PackedEntry { Name = name, Type = FormatCatalog.Instance.GetTypeFromName(name), Offset = current_offset, Size = size, UnpackedSize = LittleEndian.ToUInt32(index, current_index + 0x10), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.IsPacked = entry.Size != entry.UnpackedSize; current_offset += entry.Size; dir.Add(entry); } current_index += 0x20; current_filename += 2 + name_length; } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32 (4); if (!IsSaneCount (count)) return null; var base_name = Path.GetFileNameWithoutExtension (file.Name); var dir = new List<Entry> (count); int index_offset = 8; long data_offset = count * 4 + 8; uint next_offset = file.View.ReadUInt32 (index_offset); for (int i = 0; i < count; ++i) { index_offset += 4; var entry = new PackedEntry { Offset = next_offset }; next_offset = i + 1 < count ? file.View.ReadUInt32 (index_offset) : (uint)file.MaxOffset; entry.Size = next_offset - (uint)entry.Offset; if (entry.Offset < data_offset || !entry.CheckPlacement (file.MaxOffset)) return null; entry.Name = string.Format ("{0}#{1:D4}", base_name, i); dir.Add (entry); } DetectFileTypes (file, dir); return new ArcFile (file, this, dir); }
bool ReadV0(Stream input) { long current_offset = 0x20 + m_packed_size; uint offset_table_size = (uint)m_count * 0x10; if (offset_table_size > m_file.View.Reserve (current_offset, offset_table_size)) return false; using (var lzss = new LzssStream (input, LzssMode.Decompress, true)) lzss.Read (m_index, 0, m_index.Length); for (int i = 0; i < m_index.Length; ++i) { m_index[i] = (byte)(~m_index[i] - 5); } int index_offset = Array.IndexOf (m_index, (byte)0); if (-1 == index_offset || 0 == index_offset) return false; index_offset++; // Password = m_index.Take (index_offset++).ToArray(); for (int i = 0; i < m_count && index_offset < m_index.Length; ++i) { int name_end = Array.IndexOf (m_index, (byte)0, index_offset); if (-1 == name_end) name_end = m_index.Length; if (index_offset == name_end) return false; var entry = new PackedEntry(); entry.Offset = m_file.View.ReadUInt32 (current_offset); entry.Size = m_file.View.ReadUInt32 (current_offset+4); entry.UnpackedSize = m_file.View.ReadUInt32 (current_offset+8); entry.IsPacked = entry.UnpackedSize != 0; if (!entry.CheckPlacement (m_file.MaxOffset)) return false; entry.Name = Encodings.cp932.GetString (m_index, index_offset, name_end-index_offset); entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name); m_dir.Value.Add (entry); index_offset = name_end+1; current_offset += 0x10; } return true; }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual (0, "KOTORI") || 0x1A1A00 != file.View.ReadInt32 (6)) return null; int count = file.View.ReadUInt16 (0x14); if (0x0100A618 != file.View.ReadInt32 (0x10) || !IsSaneCount (count)) return null; string base_name = Path.GetFileNameWithoutExtension (file.Name); uint current_offset = 0x18; long next_offset = file.View.ReadUInt32 (current_offset); var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry { Name = string.Format ("{0}#{1:D4}.ogg", base_name, i), Type = "audio", Offset = next_offset, }; if (i+1 != count) { current_offset += 6; next_offset = file.View.ReadUInt32 (current_offset); } else next_offset = file.MaxOffset; entry.Size = (uint)(next_offset - entry.Offset); if (entry.Size >= 0x32) { entry.IsPacked = true; entry.UnpackedSize = entry.Size - 0x32; } if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); } return new ArcFile (file, this, dir); }