public override ArcFile TryOpen(ArcView file) { long index_end = file.MaxOffset - 4; uint index_size = file.View.ReadUInt32 (index_end); if (0 == index_size || index_size >= index_end) return null; long index_offset = index_end - index_size; if (index_size > file.View.Reserve (index_offset, index_size)) return null; var dir = new List<Entry>(); while (index_offset < index_end) { uint name_len = file.View.ReadByte (index_offset++); if (0 == name_len) break; if (name_len+14 > index_end-index_offset) return null; string name = file.View.ReadString (index_offset, name_len); index_offset += name_len+6; var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Size = file.View.ReadUInt32 (index_offset); entry.Offset = file.View.ReadUInt32 (index_offset+4); if (!entry.CheckPlacement (index_offset)) return null; dir.Add (entry); index_offset += 8; } if (0 == dir.Count) return null; return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.EndsWith (".pb", StringComparison.InvariantCultureIgnoreCase)) return null; int count = file.View.ReadInt32 (0); if (count <= 0 || count > 0xfff) return null; var dir = new List<Entry> (count); int index_offset = 0x10; bool is_voice = Path.GetFileName (file.Name).Equals ("voice.pb", StringComparison.InvariantCultureIgnoreCase); int data_offset = index_offset + 8 * count; for (int i = 0; i < count; ++i) { uint offset = file.View.ReadUInt32 (index_offset); Entry entry; if (!is_voice) entry = AutoEntry.Create (file, offset, i.ToString ("D4")); else entry = new Entry { Name = string.Format ("{0:D4}.pb", i), Type = "archive", Offset = offset }; entry.Size = file.View.ReadUInt32 (index_offset + 4); if (offset < data_offset || !entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 8; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32 (0); if (!IsSaneCount (count)) return null; long index_offset = 4; const int name_length = 0x20; uint index_size = (uint)(count * (name_length + 8)); if (index_size > file.View.Reserve (index_offset, index_size)) return null; var dir = new List<Entry>(); for (int i = 0; i < count; ++i) { string name = file.View.ReadString (index_offset, (uint)name_length); if (0 == name.Length) return null; index_offset += name_length; var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = file.View.ReadUInt32 (index_offset); entry.Size = file.View.ReadUInt32 (index_offset+4); if (entry.Offset < index_size+4 || !entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 8; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { uint index_offset = file.View.ReadUInt32 (4); if (index_offset >= file.MaxOffset) return null; int count = file.View.ReadInt32 (index_offset); if (!IsSaneCount (count)) return null; index_offset += 4; uint index_size = (uint)(count * 0x88); if (index_size > file.View.Reserve (index_offset, index_size)) return null; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { string name = file.View.ReadString (index_offset+8, 0x80); var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = file.View.ReadUInt32 (index_offset); entry.Size = file.View.ReadUInt32 (index_offset+4); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 0x88; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.EndsWith (".vpk", StringComparison.InvariantCultureIgnoreCase)) return null; var vtb_name = Path.ChangeExtension (file.Name, "vtb"); if (!VFS.FileExists (vtb_name)) return null; var vtb_entry = VFS.FindFile (vtb_name); int count = (int)(vtb_entry.Size / 0x0C) - 1; if (!IsSaneCount (count)) return null; using (var vtb = VFS.OpenView (vtb_entry)) { vtb.View.Reserve (0, (uint)vtb.MaxOffset); uint index_offset = 0; uint next_offset = vtb.View.ReadUInt32 (8); var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { string name = vtb.View.ReadString (index_offset, 8) + ".vaw"; var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = next_offset; index_offset += 0xC; next_offset = vtb.View.ReadUInt32 (index_offset+8); entry.Size = next_offset - (uint)entry.Offset; if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); } return new ArcFile (file, this, dir); } }
public override ArcFile TryOpen(ArcView file) { int signature = file.View.ReadInt16 (0); if (0x4656 != signature && 0x4C56 != signature) return null; int version = file.View.ReadInt16 (2); int count = file.View.ReadInt16 (4); if (!IsSaneCount (count)) return null; int entry_size = file.View.ReadInt16 (6); int index_size = file.View.ReadInt32 (8); if (entry_size <= 0 || index_size <= 0 || file.MaxOffset != file.View.ReadUInt32 (0xC)) return null; if (version >= 0x0200) return OpenV2 (file, count, entry_size, index_size); int index_offset = 0x10; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString (index_offset, 0x13); var entry = FormatCatalog.Instance.Create<PackedEntry> (name); entry.Offset = file.View.ReadUInt32 (index_offset+0x13); entry.Size = file.View.ReadUInt32 (index_offset+0x17); entry.UnpackedSize = file.View.ReadUInt32 (index_offset+0x1B); entry.IsPacked = 0 != file.View.ReadByte (index_offset+0x1F); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += entry_size; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { uint height = file.View.ReadUInt32 (4); uint width = file.View.ReadUInt32 (8); int count = file.View.ReadInt32 (12); if (!IsSaneCount (count)) return null; uint dir_size = file.View.ReadUInt32 (20); uint cur_offset = 24; uint data_offset = cur_offset + dir_size; uint data_size = file.View.ReadUInt32 (data_offset); data_offset += 4; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var entry = new LwgImageEntry(); entry.PosX = file.View.ReadInt32 (cur_offset); entry.PosY = file.View.ReadInt32 (cur_offset+4); entry.BPP = file.View.ReadByte (cur_offset+8); entry.Offset = data_offset + file.View.ReadUInt32 (cur_offset+9); entry.Size = file.View.ReadUInt32 (cur_offset+13); uint name_length = file.View.ReadByte (cur_offset+17); string name = file.View.ReadString (cur_offset+18, name_length); entry.Name = name + ".wcg"; cur_offset += 18+name_length; if (cur_offset > dir_size+24) return null; if (entry.CheckPlacement (data_offset + data_size)) dir.Add (entry); } 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; var base_name = Path.GetFileNameWithoutExtension (file.Name); var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var offset = file.View.ReadUInt32 (index_offset); var size = file.View.ReadUInt32 (index_offset+4); if (0 != size) { var name = string.Format ("{0}#{1:D4}", base_name, i); var entry = AutoEntry.Create (file, offset, name); entry.Size = size; if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); } index_offset += 8; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual (4, "OggS")) return null; uint current_offset = 0; uint first_size = file.View.ReadUInt32 (current_offset); if (first_size >= file.MaxOffset) return null; var dir = new List<Entry>(); int n = 0; while (current_offset < file.MaxOffset) { uint size = file.View.ReadUInt32 (current_offset); if (current_offset + 4 + (long)size > file.MaxOffset) return null; if (file.View.AsciiEqual (current_offset+4, "OggS")) { var entry = new Entry { Name = string.Format ("{0:D5}.ogg", n++), Type = "audio", Offset = current_offset + 4, Size = size, }; dir.Add (entry); } current_offset += 4+size; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { #pragma warning disable 219 string type; if (file.View.AsciiEqual (0, "M2TYPE_WAV")) type = "wave"; else if (file.View.AsciiEqual (0, "M2T_BMP")) type = "bmp_"; else if (file.View.AsciiEqual (0, "M2T_WORD")) type = "word"; else return null; #pragma warning restore 219 uint index_size = file.View.ReadUInt32 (file.MaxOffset-12); long index_offset = file.MaxOffset-0x14-index_size; int count = file.View.ReadInt32 (file.MaxOffset-8); if (index_offset <= 0 || count <= 0 || count > 0xfffff) return null; file.View.Reserve (index_offset, index_size); var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString (index_offset, 0x10); var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = file.View.ReadUInt32 (index_offset+0x10); entry.Size = file.View.ReadUInt32 (index_offset+0x14); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 0x18; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { int version = file.View.ReadByte (4) - '0'; if (version < 0 || !file.View.AsciiEqual (5, "0__")) return null; int count = file.View.ReadInt32 (0xC); if (!IsSaneCount (count)) return null; uint index_offset = 0x10; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString (index_offset, 0x100); if (string.IsNullOrWhiteSpace (name)) return null; index_offset += 0x100; var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = file.View.ReadInt64 (index_offset); entry.Size = file.View.ReadUInt32 (index_offset+8); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 0x10; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32 (4); if (!IsSaneCount (count)) return null; uint data_offset = file.View.ReadUInt32 (8); if (data_offset < 0x10 + count * 0x20) return null; if (data_offset > file.View.Reserve (0, data_offset)) return null; uint index_offset = 0x10; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString (index_offset, 0x18); var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Size = file.View.ReadUInt32 (index_offset+0x18); entry.Offset = file.View.ReadUInt32 (index_offset+0x1C); if (entry.Offset < data_offset || !entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 0x20; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { uint signature = file.View.ReadUInt32 (0); if (0x44474d != (signature & 0xffffff)) // 'MGD' return null; int count = file.View.ReadInt16 (0x20); if (count <= 0) return null; int flag = file.View.ReadUInt16 (3); var dir = new List<Entry> (count); int index_offset = 0x22; byte[] name_buf = new byte[16]; for (uint i = 0; i < count; ++i) { int name_size = file.View.ReadByte (index_offset+1); if (0 == name_size) return null; if (name_size > name_buf.Length) Array.Resize (ref name_buf, name_size); file.View.Read (index_offset+2, name_buf, 0, (uint)name_size); if (100 == flag) Decrypt (name_buf, 0, name_size); string name = Encodings.cp932.GetString (name_buf, 0, name_size); index_offset += 2 + name_size; uint offset = file.View.ReadUInt32 (index_offset+4); var entry = AutoEntry.Create (file, offset, name); entry.Size = file.View.ReadUInt32 (index_offset); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 8; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual (0, "BSS-Composition\0")) return null; int count = file.View.ReadByte (0x11); if (0 == count) return null; string base_name = Path.GetFileNameWithoutExtension (file.Name); var dir = new List<Entry> (count); uint current_offset = 0x20; for (int i = 0; i < count; ++i) { var entry = new Entry { Name = string.Format ("{0}#{1:D3}.bsg", base_name, i), Type = "image", Offset = current_offset, Size = 0x40 + file.View.ReadUInt32 (current_offset+0x36), }; if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); current_offset += entry.Size; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32 (8); if (!IsSaneCount (count)) return null; uint base_offset = file.View.ReadUInt32 (0x0c); uint index_offset = 0x10; uint index_size = 4u * (uint)count; if (base_offset >= file.MaxOffset || base_offset < (index_offset+index_size)) return null; if (index_size > file.View.Reserve (index_offset, index_size)) return null; var index = new List<uint> (count); for (int i = 0; i < count; ++i) { uint offset = file.View.ReadUInt32 (index_offset); if (offset != 0xffffffff) index.Add (base_offset + offset); index_offset += 4; } var dir = new List<Entry> (index.Count); for (int i = 0; i < index.Count; ++i) { long offset = index[i]; string name = file.View.ReadString (offset, 0x20); var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = offset + 0x24; entry.Size = file.View.ReadUInt32 (offset+0x20); dir.Add (entry); } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { uint index_offset = file.View.ReadUInt32 (0); int count = file.View.ReadInt32 (4); if (index_offset < 8 || index_offset >= file.MaxOffset || !IsSaneCount (count)) return null; uint index_size = (uint)count * 0x28u; if (index_size > file.MaxOffset - index_offset) return null; var index = file.View.ReadBytes (index_offset, index_size); // last byte of the first filename presumably is zero byte key = index[0x1F]; for (int i = 0; i < index.Length; ++i) index[i] ^= key; int current = 0; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { int name_offset = '\\' == index[current] ? 1 : 0; var name = Binary.GetCString (index, current+name_offset, 0x20-name_offset); if (0 == name.Length) return null; var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = LittleEndian.ToUInt32 (index, current+0x20); entry.Size = LittleEndian.ToUInt32 (index, current+0x24); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); current += 0x28; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { uint skip = file.View.ReadUInt32 (4); if (skip >= file.MaxOffset) return null; var dir = new List<Entry> (1); dir.Add (new Entry { Name = Path.GetFileNameWithoutExtension (file.Name)+".mpg", Type = "video", Offset = 8+skip, Size = (uint)(file.MaxOffset-(8+skip)), }); return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt16 (0); if (!IsSaneCount (count)) return null; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var entry = FormatCatalog.Instance.Create<Entry> (name); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (file.MaxOffset > uint.MaxValue) return null; int dir_size = file.View.ReadUInt16 (0); if (dir_size < 0x20 || 0 != (dir_size & 0xf) || dir_size + 2 >= file.MaxOffset) return null; byte first = file.View.ReadByte (2); if (0 == first) return null; file.View.Reserve (0, (uint)dir_size + 2); int dir_offset = 2; uint next_offset = file.View.ReadUInt32 (dir_offset+12); if (next_offset > file.MaxOffset || next_offset < dir_size+2) return null; var encoding = Encodings.cp932.WithFatalFallback(); byte[] name_raw = new byte[12]; int count = dir_size / 0x10 - 1; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { file.View.Read (dir_offset, name_raw, 0, 12); int name_length = name_raw.Length; while (name_length > 0 && 0 == name_raw[name_length-1]) --name_length; if (0 == name_length) return null; uint offset = next_offset; dir_offset += 0x10; next_offset = file.View.ReadUInt32 (dir_offset+12); if (next_offset > file.MaxOffset || next_offset < offset) return null; string name = encoding.GetString (name_raw, 0, name_length).ToLowerInvariant(); var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = offset; entry.Size = next_offset - offset; dir.Add (entry); } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32 (0); if (count <= 0 || count > 0xfffff) return null; long index_offset = 4; uint index_size = (uint)(0xc * count); if (index_size > file.View.Reserve (index_offset, index_size)) return null; var dir = new List<Entry>(); for (int i = 0; i < count; ++i) { var entry = new Entry { Offset = file.View.ReadUInt32 (index_offset+4), Size = file.View.ReadUInt32 (index_offset+8) }; if (entry.Offset < index_size || !entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 12; } byte[] name_buf = new byte[260]; foreach (var entry in dir) { uint max_len = Math.Min (260u, file.View.Reserve (index_offset, 260)); uint n; for (n = 0; n < max_len; ++n) { byte b = file.View.ReadByte (index_offset+n); if (0 == b) break; name_buf[n] = b; } if (0 == n || max_len == n) return null; entry.Name = Encodings.cp932.GetString (name_buf, 0, (int)n); entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name); index_offset += n+1; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { var first_offset = file.View.ReadUInt32 (8); if (first_offset <= 0x14 || first_offset >= file.MaxOffset || first_offset > int.MaxValue) return null; int index_size = (int)(first_offset - 4); var count = index_size / 0x10; if (count * 0x10 != index_size) return null; string base_name = Path.GetFileNameWithoutExtension (file.Name); uint index_offset = 4; uint last_offset = 0; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var offset = file.View.ReadUInt32 (index_offset+4); if (0 == offset) break; if (offset <= last_offset) return null; string name = string.Format ("{0}#{1:D4}", base_name, i); var entry = new AutoEntry (name, () => { uint signature = file.View.ReadUInt32 (offset); if (0 == signature) return null; return FormatCatalog.Instance.LookupSignature (signature).FirstOrDefault(); }); entry.Offset = offset; entry.Size = file.View.ReadUInt32 (index_offset); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); last_offset = offset; index_offset += 0x10; } if (0 == dir.Count) return null; return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (file.View.ReadUInt16 (4) != '7') return null; string base_name = Path.GetFileNameWithoutExtension (file.Name); uint offset = 0xC; var dir = new List<Entry>(); uint size = file.View.ReadUInt32 (offset); offset += 4; var entry = new Entry { Name = string.Format ("{0}#0.dat", base_name), Offset = offset, Size = size, }; if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); offset += size; int n = 1; while (offset < file.MaxOffset) { size = file.View.ReadUInt32 (offset); if (0 == size) break; offset += 4; entry = new Entry { Name = string.Format ("{0}#{1}", base_name, n++), Type = "image", Offset = offset, Size = size, }; if (!entry.CheckPlacement (file.MaxOffset)) break; DetectFileType (file, entry); dir.Add (entry); offset += size; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.EndsWith (".vol", StringComparison.InvariantCultureIgnoreCase)) return null; uint first_offset = file.View.ReadUInt32 (0); if (first_offset < 0x10 || 0 != (first_offset & 0xF) || first_offset >= file.MaxOffset) return null; int count = (int)(first_offset /4); if (!IsSaneCount (count)) return null; var offset_table = new List<uint> (count); offset_table.Add (first_offset); uint index_offset = 4; for (int i = 1; i < count; ++i) { uint offset = file.View.ReadUInt32 (index_offset); if (offset < offset_table[i-1] || offset > file.MaxOffset) return null; offset_table.Add (offset); if (offset == file.MaxOffset) break; index_offset += 4; } var base_name = Path.GetFileNameWithoutExtension (file.Name); var dir = new List<Entry> (offset_table.Count-1); for (int i = 0; i < offset_table.Count-1; ++i) { uint size = offset_table[i+1] - offset_table[i]; if (0 == size) continue; var name = string.Format ("{0}#{1:D4}", base_name, i); var entry = AutoEntry.Create (file, offset_table[i], name); entry.Size = size; dir.Add (entry); } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen (ArcView file) { int count = file.View.ReadInt32 (0); if (!IsSaneCount (count) || count * 10 >= file.MaxOffset) return null; uint index_offset = 4; byte[] name_buffer = new byte[0x100]; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { byte name_length = file.View.ReadByte (index_offset++); if (0 == name_length) return null; if (name_length != file.View.Read (index_offset, name_buffer, 0, name_length)) return null; index_offset += name_length; byte key = (byte)(name_length+1); for (int j = 0; j < name_length; ++j) { name_buffer[j] -= key--; if (name_buffer[j] < 0x20) return null; } string name = Encodings.cp932.GetString (name_buffer, 0, name_length); var entry = FormatCatalog.Instance.Create<PackedEntry> (name); entry.Offset = Binary.BigEndian (file.View.ReadUInt32 (index_offset)); entry.Size = Binary.BigEndian (file.View.ReadUInt32 (index_offset+4)); index_offset += 8; if (entry.Offset < index_offset || !entry.CheckPlacement (file.MaxOffset)) return null; if (name.EndsWith (".scr", StringComparison.InvariantCultureIgnoreCase)) entry.IsPacked = true; dir.Add (entry); } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual (4, "ARCHIVED")) return null; int count = file.View.ReadInt16 (0x0c); if (count <= 0) return null; file.View.Reserve (0x10, (uint)count*0x20u); int index_offset = 0x10; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString (index_offset, 0x0c); var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = file.View.ReadUInt32 (index_offset+0x10); entry.Size = file.View.ReadUInt32 (index_offset+0x14); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 0x20; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { if ('c' != file.View.ReadInt16 (4)) return null; int version = file.View.ReadInt16 (8); if (version < 1 || version > 3) return null; int count = file.View.ReadInt16 (0xA); if (!IsSaneCount (count)) return null; uint index_offset = file.View.ReadUInt32 (0xC); if (index_offset >= file.MaxOffset) return null; var reader = new IndexReader (file); List<Entry> dir = null; if (version > 1) dir = reader.ReadV2 (count, index_offset); if (null == dir) dir = reader.ReadV1 (count, index_offset); if (null == dir) return null; 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 * 0x20; if (index_size > file.View.Reserve (4, (uint)index_size)) return null; int first_offset = file.View.ReadInt32 (0x1C); byte key = (byte)count; first_offset ^= key | key << 8 | key << 16 | key << 24; if (first_offset != 0) return null; var index = new byte[index_size]; file.View.Read (4, index, 0, index_size); for (int i = 0; i < index.Length; ++i) index[i] ^= key; long base_offset = 4 + index_size; int index_offset = 0; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var name = Binary.GetCString (index, index_offset, 0x18); var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = base_offset + LittleEndian.ToUInt32 (index, index_offset+0x18); entry.Size = LittleEndian.ToUInt32 (index, index_offset+0x1C); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 0x20; } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { string index_name = Path.ChangeExtension (file.Name, ".dll"); if (index_name == file.Name || !VFS.FileExists (index_name)) return null; var index_entry = VFS.FindFile (index_name); if (index_entry.Size < 12) return null; int count = file.View.ReadInt32 (0); if (!IsSaneCount (count) || (count & 0xFFFF) == 0x5A4D) // 'MZ' return null; var base_name = Path.GetFileNameWithoutExtension (file.Name); using (var idx = VFS.OpenView (index_entry)) { var dir = new List<Entry> (count); uint index_offset = 4; int i = 0; uint last_offset = 3; while (index_offset+8 <= idx.MaxOffset) { uint offset = idx.View.ReadUInt32 (index_offset); if (offset <= last_offset) return null; var name = string.Format ("{0}#{1:D5}", base_name, i++); var entry = AutoEntry.Create (file, offset, name); entry.Size = idx.View.ReadUInt32(index_offset+4); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); last_offset = offset; index_offset += 8; } 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 * 12; uint name_index_size = file.View.ReadUInt32(4); if (8L + index_size + name_index_size >= file.MaxOffset) { return(null); } uint index_offset = 8; file.View.Reserve(index_offset, index_size + name_index_size); uint names_base = index_offset + index_size; var dir = new List <Entry> (count); string entry_type = null; string arc_name = Path.GetFileNameWithoutExtension(file.Name).ToLowerInvariant(); if ("voice" == arc_name || "bgm" == arc_name) { entry_type = "audio"; } for (int i = 0; i < count; ++i) { uint filename_offset = file.View.ReadUInt32(index_offset); if (filename_offset >= name_index_size) { return(null); } var name = file.View.ReadString(names_base + filename_offset, name_index_size - filename_offset); if (0 == name.Length) { return(null); } var entry = new Entry { Name = name, Offset = file.View.ReadUInt32(index_offset + 4), Size = file.View.ReadUInt32(index_offset + 8), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } if (entry_type != null) { entry.Type = entry_type; } dir.Add(entry); index_offset += 12; } if (null == entry_type) { foreach (var entry in dir) { var signature = file.View.ReadUInt32(entry.Offset); if (0 == signature) { continue; } var res = FormatCatalog.Instance.LookupSignature(signature).FirstOrDefault(); if (null == res) { continue; } entry.Type = res.Type; var ext = res.Extensions.FirstOrDefault(); if (!string.IsNullOrEmpty(ext)) { entry.Name += '.' + ext; } } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0x14); if (!IsSaneCount(count)) { return(null); } long index_offset = 0x2A; if (!file.View.AsciiEqual(index_offset, "NAME")) { return(null); } var addr_offset = file.View.ReadInt64(index_offset + 4); index_offset += 0xE; if (!file.View.AsciiEqual(index_offset, "NIDX")) { return(null); } index_offset += 4; var nidx_offsets = new uint[count]; // name offsets for (int i = 0; i < count; ++i) { nidx_offsets[i] = file.View.ReadUInt32(index_offset + 2); index_offset += 8; } if (!file.View.AsciiEqual(index_offset, "EIDX")) { return(null); } index_offset += 4 + 8 * count; if (!file.View.AsciiEqual(index_offset, "CINF")) { return(null); } index_offset += 4; var name_buffer = new byte[0x40]; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { index_offset += 6; ushort name_length = file.View.ReadUInt16(index_offset); if (name_length > name_buffer.Length) { name_buffer = new byte[name_length]; } file.View.Read(index_offset + 4, name_buffer, 0, name_length); index_offset += 6 + name_length; var name = DecryptName(name_buffer, name_length); var entry = FormatCatalog.Instance.Create <Entry> (name); dir.Add(entry); } index_offset = addr_offset; if (!file.View.AsciiEqual(index_offset, "ADDR")) { return(null); } index_offset += 4; for (int i = 0; i < count; ++i) { dir[i].Offset = file.View.ReadInt64(index_offset + 2); index_offset += 12; } foreach (var entry in dir) { if (!file.View.AsciiEqual(entry.Offset, "FILE")) { continue; } entry.Size = file.View.ReadUInt32(entry.Offset + 0x18); entry.Offset += 0x22; } dir = dir.Where(entry => entry.Size != 0).ToList(); if (0 == dir.Count) { return(null); } return(new ArcFile(file, this, dir)); }
public NitroPak(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, int version) : base(arc, impl, dir) { Version = version; }
public DatIndexReader(byte[] toc, ArcView file) : base(toc, file) { }
public IndexReader(ArcView file) { m_file = file; }
public LibPReader(ArcView file, IMalieDecryptor decryptor, byte[] header, LibScheme scheme) : base(file, decryptor, header) { m_base_offset = 0; m_scheme = scheme; }
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, }; 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 ResourcesAssetsDeserializer(ArcView file) { m_res_name = file.Name; }
public UnityResourcesAsset(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, IDictionary <string, ArcView> res_map) : base(arc, impl, dir) { ResourceMap = res_map; }
public IndexReader(byte[] toc, ArcView file) { m_index = new BinMemoryStream(toc); m_max_offset = file.MaxOffset; }
public SteinsGateEncryptedStream(ArcView file, long offset, uint size) { m_stream = file.CreateStream(offset, size); m_should_dispose = true; m_base_pos = 0; }
public CherryPak(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir) : base(arc, impl, dir) { }
public override ArcFile TryOpen(ArcView file) { if (0 != file.View.ReadUInt32 (4) || 0xCCAE01FF != file.View.ReadUInt32 (0xA)) return null; uint first_offset = file.View.ReadUInt32 (0x12); int count = (int)(first_offset - 0x12) / 6; if (!IsSaneCount (count)) return null; var base_name = Path.GetFileNameWithoutExtension (file.Name); uint next_offset = first_offset; uint index_offset = 0x12; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var entry = new Entry { Name = string.Format ("{0}#{1:D4}.ogg", base_name, i), Type = "audio", Offset = next_offset, }; index_offset += 6; next_offset = i+1 == count ? (uint)file.MaxOffset : file.View.ReadUInt32 (index_offset); entry.Size = (uint)(next_offset - entry.Offset); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); } return new ArcFile (file, this, dir); }
public YpfArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, uint script_key) : base(arc, impl, dir) { ScriptKey = script_key; }
public AstArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir) : base(arc, impl, dir) { }
public PckArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, byte[] key) : base(arc, impl, dir) { Encryption = new Blowfish(key); }
public Reader(ArcView file) { m_view = file.View; }
public TocUnpacker(ArcView file, bool should_dispose = false) { m_file = file; m_should_dispose = should_dispose; }
public MalieArchive(ArcView file, ArchiveFormat format, ICollection <Entry> dir, IMalieDecryptor decr) : base(file, format, dir) { Decryptor = decr; }
public override ArcFile TryOpen(ArcView file) { int format_count = file.View.ReadUInt16(4); int count = file.View.ReadUInt16(6); if (0 == format_count || 0 == count) { return(null); } uint index_offset = 8; long base_offset = index_offset + format_count * 0x14 + count * 0x18; if (base_offset >= file.MaxOffset) { return(null); } var formats = new List <WaveFormat> (format_count); for (int i = 0; i < format_count; ++i) { var format = new WaveFormat { FormatTag = file.View.ReadUInt16(index_offset), Channels = file.View.ReadUInt16(index_offset + 2), SamplesPerSecond = file.View.ReadUInt32(index_offset + 4), AverageBytesPerSecond = file.View.ReadUInt32(index_offset + 8), BitsPerSample = file.View.ReadUInt16(index_offset + 12), BlockAlign = file.View.ReadUInt16(index_offset + 14), }; index_offset += 0x14; formats.Add(format); } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int fmt_index = file.View.ReadUInt16(index_offset); if (fmt_index > formats.Count) { return(null); } string name = file.View.ReadString(index_offset + 2, 0x0A); var entry = new PkwEntry { Name = name + ".wav", Type = "audio", Offset = base_offset + file.View.ReadInt64(index_offset + 0x10), Size = file.View.ReadUInt32(index_offset + 0x0C), IsPacked = true, Format = formats[fmt_index], }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.UnpackedSize = entry.Size + WaveHeaderSize; dir.Add(entry); index_offset += 0x18; } return(new ArcFile(file, this, dir)); }
public BellArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, AImageScheme scheme) : base(arc, impl, dir) { Scheme = scheme; }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".dat")) { return(null); } var arc_name = Path.GetFileName(file.Name); var match = IndexNameRe.Match(arc_name); if (!match.Success) { return(null); } var base_name = match.Groups[2].Value; base_name = VFS.ChangeFileName(file.Name, base_name); var index_name = base_name + ".pcg"; if (!VFS.FileExists(index_name)) { index_name = base_name + ".spf"; if (!VFS.FileExists(index_name)) { return(null); } } arc_name = match.Groups[1].Value; using (var index = VFS.OpenView(index_name)) { int parts_count = index.View.ReadInt32(0); int count = index.View.ReadInt32(4); if (parts_count > 10 || !IsSaneCount(count)) { return(null); } int entry_size = (int)(index.MaxOffset - 0x198) / count; if (entry_size < 0x30) { return(null); } int first_index = -1, last_index = -1; for (int i = 0; i < parts_count; ++i) { int name_pos = 8 + i * 0x20; var name = index.View.ReadString(name_pos, 0x20); if (name == arc_name) { int first_index_pos = 0x148 + i * 4; int last_index_pos = 0x170 + i * 4; first_index = index.View.ReadInt32(first_index_pos); last_index = index.View.ReadInt32(last_index_pos); break; } } if (first_index < 0 || first_index >= last_index || last_index > count) { return(null); } uint name_size = entry_size >= 0x48 ? 0x40u : 0x20u; int index_offset = 0x198 + entry_size * first_index; var dir = new List <Entry> (last_index - first_index); for (int i = first_index; i < last_index; ++i) { var name = index.View.ReadString(index_offset, name_size); var entry = FormatCatalog.Instance.Create <Entry> (name); entry.Size = index.View.ReadUInt32(index_offset + name_size); entry.Offset = index.View.ReadUInt32(index_offset + name_size + 4); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += entry_size; } return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { long base_offset = 0; if (0x5a4d == file.View.ReadUInt16(0)) // 'MZ' { base_offset = SkipExeHeader(file); } if (!file.View.AsciiEqual(base_offset, SignatureBytes)) { return(null); } long dir_offset = base_offset + file.View.ReadInt64(base_offset + 0x0b); if (dir_offset < 0x13 || dir_offset >= file.MaxOffset) { return(null); } if (0x80 == file.View.ReadUInt32(dir_offset)) { dir_offset = base_offset + file.View.ReadInt64(dir_offset + 9); if (dir_offset < 0x13 || dir_offset >= file.MaxOffset) { return(null); } } int header_type = file.View.ReadByte(dir_offset); if (0 != header_type && 1 != header_type) { return(null); } Stream header_stream; if (0 == header_type) // read unpacked header { long header_size = file.View.ReadInt64(dir_offset + 1); if (header_size > uint.MaxValue) { return(null); } header_stream = file.CreateStream(dir_offset + 9, (uint)header_size); } else // read packed header { long packed_size = file.View.ReadInt64(dir_offset + 1); if (packed_size > uint.MaxValue) { return(null); } long header_size = file.View.ReadInt64(dir_offset + 9); using (var input = file.CreateStream(dir_offset + 17, (uint)packed_size)) header_stream = ZLibCompressor.DeCompress(input); } var crypt_algorithm = new Lazy <ICrypt> (() => QueryCryptAlgorithm(file), false); var dir = new List <Entry>(); dir_offset = 0; using (var header = new BinaryReader(header_stream, Encoding.Unicode)) using (var filename_map = new FilenameMap()) { while (-1 != header.PeekChar()) { uint entry_signature = header.ReadUInt32(); long entry_size = header.ReadInt64(); if (entry_size < 0) { return(null); } dir_offset += 12 + entry_size; if (0x656C6946 == entry_signature) // "File" { var entry = new Xp3Entry(); while (entry_size > 0) { uint section = header.ReadUInt32(); long section_size = header.ReadInt64(); entry_size -= 12; if (section_size > entry_size) { break; } entry_size -= section_size; long next_section_pos = header.BaseStream.Position + section_size; switch (section) { case 0x6f666e69: // "info" if (entry.Size != 0 || !string.IsNullOrEmpty(entry.Name)) { goto NextEntry; // ambiguous entry, ignore } entry.IsEncrypted = 0 != header.ReadUInt32(); long file_size = header.ReadInt64(); long packed_size = header.ReadInt64(); if (file_size >= uint.MaxValue || packed_size > uint.MaxValue || packed_size > file.MaxOffset) { goto NextEntry; } entry.IsPacked = file_size != packed_size; entry.Size = (uint)packed_size; entry.UnpackedSize = (uint)file_size; int name_size = header.ReadInt16(); if (name_size > 0x100 || name_size <= 0) { goto NextEntry; } if (entry.IsEncrypted || ForceEncryptionQuery) { entry.Cipher = crypt_algorithm.Value; } else { entry.Cipher = NoCryptAlgorithm; } var name = new string (header.ReadChars(name_size)); if (entry.Cipher.ObfuscatedIndex && ObfuscatedPathRe.IsMatch(name)) { goto NextEntry; } if (filename_map.Count > 0) { name = filename_map.Get(entry.Hash, name); } if (name.Length > 0x100) { goto NextEntry; } entry.Name = name; entry.Type = FormatCatalog.Instance.GetTypeFromName(name); entry.IsEncrypted = !(entry.Cipher is NoCrypt) && !(entry.Cipher.StartupTjsNotEncrypted && "startup.tjs" == name); break; case 0x6d676573: // "segm" int segment_count = (int)(section_size / 0x1c); if (segment_count > 0) { for (int i = 0; i < segment_count; ++i) { bool compressed = 0 != header.ReadInt32(); long segment_offset = base_offset + header.ReadInt64(); long segment_size = header.ReadInt64(); long segment_packed_size = header.ReadInt64(); if (segment_offset > file.MaxOffset || segment_packed_size > file.MaxOffset) { goto NextEntry; } var segment = new Xp3Segment { IsCompressed = compressed, Offset = segment_offset, Size = (uint)segment_size, PackedSize = (uint)segment_packed_size }; entry.Segments.Add(segment); } entry.Offset = entry.Segments.First().Offset; } break; case 0x726c6461: // "adlr" if (4 == section_size) { entry.Hash = header.ReadUInt32(); } break; default: // unknown section break; } header.BaseStream.Position = next_section_pos; } if (!string.IsNullOrEmpty(entry.Name) && entry.Segments.Any()) { if (entry.Cipher.ObfuscatedIndex) { DeobfuscateEntry(entry); } dir.Add(entry); } } else if (entry_size > 7) { // 0x6E666E68 == entry_signature // "hnfn" // 0x6C696D73 == entry_signature // "smil" // 0x46696C65 == entry_signature // "eliF" // 0x757A7559 == entry_signature // "Yuzu" uint hash = header.ReadUInt32(); int name_size = header.ReadInt16(); if (name_size > 0) { entry_size -= 6; if (name_size * 2 <= entry_size) { var filename = new string (header.ReadChars(name_size)); filename_map.Add(hash, filename); } } } NextEntry: header.BaseStream.Position = dir_offset; } } if (0 == dir.Count) { return(null); } var arc = new ArcFile(file, this, dir); try { if (crypt_algorithm.IsValueCreated) { crypt_algorithm.Value.Init(arc); } return(arc); } catch { arc.Dispose(); throw; } }
public ArcIndexReader(byte[] toc, ArcView file, int arc_number, string game_name = null) : base(toc, file) { m_arc_number = arc_number; m_game_name = game_name; m_ignore_b_files = m_game_name == "ドキドキ母娘レッスン ~教えて♪Hなお勉強~"; }
public NpkArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, Aes enc) : base(arc, impl, dir) { Encryption = enc; }
private List <Entry> OpenPakV3(ArcView file) { if (0x110 > file.View.Reserve(4, 0x110)) { return(null); } uint size_xor = file.View.ReadUInt32(0x104); if (0x64 != size_xor) { return(null); } byte[] name_buf = file.View.ReadBytes(4, 0x100); int name_len = 0; for (int i = 0; i < name_buf.Length; ++i) { if (0 == name_buf[i]) { break; } if (name_buf[i] >= 0x80 || name_buf[i] < 0x20) { return(null); } ++name_len; } if (0 == name_len || name_len > 0x10) { return(null); } uint header_key = GetKey(name_buf, name_len); uint unpacked = file.View.ReadUInt32(0x108) ^ header_key; int count = (int)(file.View.ReadUInt32(0x10c) ^ header_key); if (!IsSaneCount(count)) { return(null); } var dir = new List <Entry> (count); uint header_size = file.View.ReadUInt32(0x110) ^ size_xor; long base_offset = 0x114 + header_size; using (var input = file.CreateStream(0x114, header_size)) using (var header_stream = new ZLibStream(input, CompressionMode.Decompress)) using (var header = new BinaryReader(header_stream, Encoding.ASCII, true)) { for (int i = 0; i < count; ++i) { name_len = header.ReadInt32(); if (name_len <= 0 || name_len > name_buf.Length) { return(null); } if (name_len != header.Read(name_buf, 0, name_len)) { return(null); } uint key = GetKey(name_buf, name_len); var name = Encodings.cp932.GetString(name_buf, 0, name_len); var entry = FormatCatalog.Instance.Create <PakEntry> (name); entry.Offset = (header.ReadUInt32() ^ key) + base_offset; entry.UnpackedSize = (header.ReadUInt32() ^ key); uint ignored = (header.ReadUInt32() ^ key); entry.IsPacked = (header.ReadUInt32() ^ key) != 0; uint packed_size = (header.ReadUInt32() ^ key); entry.Key = key; entry.Size = entry.IsPacked ? packed_size : entry.UnpackedSize; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(dir); } }
public ArchiveFile(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, int offset, byte[] key) : base(arc, impl, dir) { HeaderOffset = offset; Key = key; }
protected List <Entry> ReadIndex(ArcView index, int index_offset, int count, long base_offset, ArcView file) { uint index_size = (uint)count * 0x18u; if (index_size > index.View.Reserve(index_offset, index_size)) { return(null); } string arc_name = Path.GetFileNameWithoutExtension(file.Name); bool is_grp = arc_name.EndsWith("GRP", StringComparison.InvariantCultureIgnoreCase); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { string name = index.View.ReadString(index_offset, 0x10); if (0 == name.Length) { return(null); } var offset = base_offset + index.View.ReadUInt32(index_offset + 0x10); Entry entry; if (is_grp) { entry = new Entry { Name = Path.ChangeExtension(name, "grp"), Type = "image", Offset = offset }; } else { entry = AutoEntry.Create(file, offset, name); } entry.Size = index.View.ReadUInt32(index_offset + 0x14); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 0x18; } return(dir); }
public NoaArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, string password = null) : base(arc, impl, dir) { Password = password; }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(8, "AlicArch")) { return(null); } if (!file.View.AsciiEqual(0x1C, "INFO")) { return(null); } int version = file.View.ReadInt32(0x10); long base_offset = file.View.ReadUInt32(0x18); uint packed_size = file.View.ReadUInt32(0x20); int unpacked_size = file.View.ReadInt32(0x24); int count = file.View.ReadInt32(0x28); if (!IsSaneCount(count)) { return(null); } var dir = new List <Entry> (count); var name_buf = new byte[0x40]; using (var input = file.CreateStream(0x2C, packed_size)) using (var zstream = new ZLibStream(input, CompressionMode.Decompress)) using (var index = new BinaryReader(zstream)) { for (int i = 0; i < count; ++i) { int name_length = index.ReadInt32(); int index_step = index.ReadInt32(); if (name_length <= 0 || name_length > index_step || index_step > unpacked_size) { return(null); } if (index_step > name_buf.Length) { name_buf = new byte[index_step]; } if (index_step != index.Read(name_buf, 0, index_step)) { return(null); } var name = Encodings.cp932.GetString(name_buf, 0, name_length); var entry = FormatCatalog.Instance.Create <Entry> (name); index.ReadInt32(); index.ReadInt32(); if (version < 2) { index.ReadInt32(); } entry.Offset = index.ReadUInt32() + base_offset; entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { var header = file.View.ReadBytes (0, 0x5C); if (header.Length != 0x5C) return null; header = HeaderEncryption.Decrypt (header); if (!Binary.AsciiEqual (header, "GLibArchiveData2.") || header[0x12] != 0) return null; int version = header[0x11] - '0'; if (version != 0 && version != 1) return null; uint index_offset = LittleEndian.ToUInt32 (header, 0x54); uint index_size = LittleEndian.ToUInt32 (header, 0x58); byte[][] encrypted_index = new byte[2][]; encrypted_index[0] = file.View.ReadBytes (index_offset, index_size); if (encrypted_index[0].Length != index_size) return null; encrypted_index[1] = new byte[index_size]; uint[] keys = { LittleEndian.ToUInt32 (header, 0x44), LittleEndian.ToUInt32 (header, 0x34), LittleEndian.ToUInt32 (header, 0x24), LittleEndian.ToUInt32 (header, 0x14), }; int i = 0; foreach (var key in keys) { var decoder = G2MetaScheme.CreateInstance (key); decoder.Decrypt (encrypted_index[i], encrypted_index[i^1]); i ^= 1; } byte[] index = encrypted_index[i]; if (!Binary.AsciiEqual (index, "CDBD")) return null; int count = LittleEndian.ToInt32 (index, 4); int current_offset = 0x10; int info_base = current_offset + LittleEndian.ToInt32 (index, 8); int names_base = current_offset + count * 0x18; var dir = new List<Entry> (count); for (i = 0; i < count; ++i) { int name_offset = names_base + LittleEndian.ToInt32 (index, current_offset); int parent_dir = LittleEndian.ToInt32 (index, current_offset+8); int attr = LittleEndian.ToInt32 (index, current_offset+0xC); var name = Binary.GetCString (index, name_offset, info_base-name_offset); if (parent_dir != -1) name = Path.Combine (dir[parent_dir].Name, name); var entry = new G2Entry { Name = name }; if (0x100 == attr) { int info_offset = info_base + LittleEndian.ToInt32 (index, current_offset+0x10); entry.Size = LittleEndian.ToUInt32 (index, info_offset+8); entry.Offset = LittleEndian.ToUInt32 (index, info_offset+0xC); entry.Type = FormatCatalog.Instance.GetTypeFromName (name); for (int j = 0; j < 4; ++j) { info_offset += 0x10; entry.Keys[j] = LittleEndian.ToUInt32 (index, info_offset); } } dir.Add (entry); current_offset += 0x18; } return new ArcFile (file, this, dir.Where (e => e.Offset != -1).ToList()); }
public AdvReader(ArcView file) { m_file = file; }