public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count) || file.MaxOffset >= ~0xC0000000) { return(null); } uint offset1 = file.View.ReadUInt32(0x14); uint offset2 = file.View.ReadUInt32(0x20); uint entry_size, next_offset; if (4 + (uint)count * 0x14 == (offset1 & ~0xC0000000)) { entry_size = 0x14; next_offset = offset1; } else if (4 + (uint)count * 0x20 == (offset2 & ~0xC0000000)) { entry_size = 0x20; next_offset = offset2; } else { return(null); } uint index_size = entry_size * (uint)count; if (index_size > file.View.Reserve(4, index_size)) { return(null); } uint index_offset = 4; uint size = file.View.ReadUInt32(index_offset + entry_size - 8); offset2 = file.View.ReadUInt32(index_offset + (entry_size * 2) - 4); if (size == (offset2 - next_offset)) // route2 archives shouldn't have entry size { return(null); } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString(index_offset, entry_size - 4); if (!IsValidEntryName(name)) { return(null); } uint flags = next_offset >> 30; Entry entry; if (1 == flags || name.HasExtension(".iaf")) { entry = new Entry(); } else { entry = new CgfEntry { Flags = flags } }; entry.Name = name; entry.Type = "image"; entry.Offset = next_offset & ~0xC0000000; index_offset += entry_size; next_offset = i + 1 == count ? (uint)file.MaxOffset : file.View.ReadUInt32(index_offset + entry_size - 4); if (next_offset < entry.Offset) { return(null); } entry.Size = (next_offset & ~0xC0000000) - (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 count = file.View.ReadInt32(0); if (!IsSaneCount(count) || file.MaxOffset >= ~0xC0000000) { return(null); } uint offset1 = file.View.ReadUInt32(0x14); uint offset2 = file.View.ReadUInt32(0x20); uint entry_size, next_offset; if (4 + (uint)count * 0x14 == (offset1 & ~0xC0000000)) { entry_size = 0x14; next_offset = offset1; } else if (4 + (uint)count * 0x20 == (offset2 & ~0xC0000000)) { entry_size = 0x20; next_offset = offset2; } else { return(null); } uint index_size = entry_size * (uint)count; if (index_size > file.View.Reserve(4, index_size)) { 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, entry_size - 4); uint flags = next_offset >> 30; Entry entry; if (1 == flags || name.EndsWith(".iaf", StringComparison.InvariantCultureIgnoreCase)) { entry = new Entry(); } else { entry = new CgfEntry { Flags = flags } }; entry.Name = name; entry.Type = "image"; entry.Offset = next_offset & ~0xC0000000; index_offset += entry_size; next_offset = i + 1 == count ? (uint)file.MaxOffset : file.View.ReadUInt32(index_offset + entry_size - 4); if (next_offset < entry.Offset) { return(null); } entry.Size = (next_offset & ~0xC0000000) - (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 count = file.View.ReadInt32 (0); if (!IsSaneCount (count) || file.MaxOffset >= ~0xC0000000) return null; uint offset1 = file.View.ReadUInt32 (0x14); uint offset2 = file.View.ReadUInt32 (0x20); uint entry_size, next_offset; if (4+(uint)count*0x14 == (offset1 & ~0xC0000000)) { entry_size = 0x14; next_offset = offset1; } else if (4+(uint)count*0x20 == (offset2 & ~0xC0000000)) { entry_size = 0x20; next_offset = offset2; } else return null; uint index_size = entry_size * (uint)count; if (index_size > file.View.Reserve (4, index_size)) 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, entry_size-4); uint flags = next_offset >> 30; Entry entry; if (1 == flags || name.EndsWith (".iaf", StringComparison.InvariantCultureIgnoreCase)) entry = new Entry(); else entry = new CgfEntry { Flags = flags }; entry.Name = name; entry.Type = "image"; entry.Offset = next_offset & ~0xC0000000; index_offset += entry_size; next_offset = i+1 == count ? (uint)file.MaxOffset : file.View.ReadUInt32 (index_offset+entry_size-4); if (next_offset < entry.Offset) return null; entry.Size = (next_offset & ~0xC0000000) - (uint)entry.Offset; if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); } return new ArcFile (file, this, dir); }