public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } List <Entry> dir = null; foreach (var name_size in NameSizes) { uint index_size = (uint)((name_size + 8) * count); uint first_offset = file.View.ReadUInt32(4 + name_size + 4); if (first_offset == (4 + index_size) && first_offset < file.MaxOffset) { if (null == dir) { dir = new List <Entry> (count); } else { dir.Clear(); } long index_offset = 4; for (int i = 0; i < count; ++i) { string name = file.View.ReadString(index_offset, name_size); if (string.IsNullOrWhiteSpace(name)) { goto CheckNextLength; } index_offset += name_size; uint offset = file.View.ReadUInt32(index_offset + 4); var entry = new AutoEntry(name, () => { uint signature = file.View.ReadUInt32(offset); if (1 == signature) { return(s_GraFormat.Value); } return(AutoEntry.DetectFileType(signature)); }); entry.Offset = offset; entry.Size = file.View.ReadUInt32(index_offset); if (offset <= index_size || !entry.CheckPlacement(file.MaxOffset)) { goto CheckNextLength; } dir.Add(entry); index_offset += 8; } return(new ArcFile(file, this, dir)); } CheckNextLength: ; } return(null); }
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.AsciiEqual(0, "MD")) { return(null); } uint entry_length = file.View.ReadUInt16(4); int count = file.View.ReadUInt16(6); if (entry_length <= 8 || !IsSaneCount(count)) { return(null); } uint name_length = entry_length - 8; uint index_offset = 0x10; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString(index_offset, name_length); index_offset += name_length; uint offset = file.View.ReadUInt32(index_offset + 4); var entry = new AutoEntry(name, () => { uint signature = file.View.ReadUInt32(offset); if (0x4259 == (signature & 0xFFFF)) // 'YB' { return(PrsFormat.Value); } return(AutoEntry.DetectFileType(signature)); }); entry.Size = file.View.ReadUInt32(index_offset); entry.Offset = offset; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 8; } var base_name = Path.GetFileNameWithoutExtension(file.Name); if (base_name.EndsWith("_scr", StringComparison.OrdinalIgnoreCase) && KnownSchemes.Count > 0) { var encryption = QueryEncryption(file.Name); if (encryption != null) { return(new ScrMedArchive(file, this, dir, encryption)); } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { uint file_size = file.View.ReadUInt32(4); if (file_size != file.MaxOffset) { return(null); } int count = file.View.ReadInt32(8); if (count <= 0 || count > 0xfffff) { return(null); } int dir_level = file.View.ReadByte(0x0d); int dir_entries = file.View.ReadUInt16(0x0e); uint index_offset = 0x10; uint index_size = (uint)(count * 0x18 + dir_entries * 8); if (index_size > file.View.Reserve(index_offset, index_size)) { return(null); } List <DirEntry> folders = null; if (0 != dir_entries && 2 == dir_level) { folders = new List <DirEntry> (dir_entries); uint dir_offset = index_offset + (uint)count * 0x18; for (int i = 0; i < dir_entries; ++i) { folders.Add(new DirEntry { Name = file.View.ReadString(dir_offset, 4), Index = file.View.ReadInt32(dir_offset + 4) }); dir_offset += 8; } } bool is_mask_arc = VFS.IsPathEqualsToFileName(file.Name, "mask.arc"); var dir = new List <Entry> (count); int next_folder = null == folders ? count : folders[0].Index; int folder = 0; string current_folder = ""; for (int i = 0; i < count; ++i) { while (i >= next_folder && folder < folders.Count) { current_folder = folders[folder++].Name; if (folders.Count == folder) { next_folder = count; } else { next_folder = folders[folder].Index; } } string name = file.View.ReadString(index_offset, 0x10); if (0 == name.Length) { return(null); } var offset = file.View.ReadUInt32(index_offset + 0x10); var entry = new AutoEntry(Path.Combine(current_folder, name), () => { if (is_mask_arc) { return(s_MskFormat.Value); } uint signature = file.View.ReadUInt32(offset); switch (signature & 0xFFFF) { case 0x4D43: return(s_CmFormat.Value); case 0x4D41: return(s_AmFormat.Value); case 0x4D42: return(ImageFormat.Bmp); default: return(AutoEntry.DetectFileType(signature)); } }); entry.Offset = offset; 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) { 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.AsciiEqual (0, "MD")) return null; uint entry_length = file.View.ReadUInt16 (4); int count = file.View.ReadUInt16 (6); if (entry_length <= 8 || !IsSaneCount (count)) return null; uint name_length = entry_length - 8; uint index_offset = 0x10; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString (index_offset, name_length); index_offset += name_length; uint offset = file.View.ReadUInt32 (index_offset+4); var entry = new AutoEntry (name, () => { uint signature = file.View.ReadUInt32 (offset); if (0x4259 == (signature & 0xFFFF)) // 'YB' return PrsFormat.Value; return AutoEntry.DetectFileType (signature); }); entry.Size = file.View.ReadUInt32 (index_offset); entry.Offset = offset; if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); index_offset += 8; } var base_name = Path.GetFileNameWithoutExtension (file.Name); if (base_name.EndsWith ("_scr", StringComparison.InvariantCultureIgnoreCase) && KnownSchemes.Count > 0) { var options = Query<MedOptions> (arcStrings.ArcEncryptedNotice); if (options.Encryption != null) return new ScrMedArchive (file, this, dir, options.Encryption); } return new ArcFile (file, this, dir); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32 (0); if (!IsSaneCount (count)) return null; List<Entry> dir = null; foreach (var name_size in NameSizes) { uint index_size = (uint)((name_size+8) * count); uint first_offset = file.View.ReadUInt32 (4+name_size+4); if (first_offset == (4 + index_size) && first_offset < file.MaxOffset) { if (null == dir) dir = new List<Entry> (count); long index_offset = 4; for (int i = 0; i < count; ++i) { string name = file.View.ReadString (index_offset, name_size); if (string.IsNullOrWhiteSpace (name)) goto CheckNextLength; index_offset += name_size; uint offset = file.View.ReadUInt32 (index_offset+4); var entry = new AutoEntry (name, () => { uint signature = file.View.ReadUInt32 (offset); if (1 == signature) return s_GraFormat.Value; return AutoEntry.DetectFileType (signature); }); entry.Offset = offset; entry.Size = file.View.ReadUInt32 (index_offset); if (offset <= index_size || !entry.CheckPlacement (file.MaxOffset)) goto CheckNextLength; dir.Add (entry); index_offset += 8; } return new ArcFile (file, this, dir); } CheckNextLength: ; } return null; }
public override ArcFile TryOpen(ArcView file) { uint file_size = file.View.ReadUInt32(4); if (file_size != file.MaxOffset) { return(null); } int count = file.View.ReadInt32(8); if (count <= 0 || count > 0xfffff) { return(null); } int dir_level = file.View.ReadByte(0x0d); int dir_entries = file.View.ReadUInt16(0x0e); uint index_offset = 0x10; uint index_size = (uint)(count * 0x18 + dir_entries * 8); if (index_size > file.View.Reserve(index_offset, index_size)) { return(null); } List <DirEntry> folders = null; if (0 != dir_entries && 2 == dir_level) { folders = new List <DirEntry> (dir_entries); uint dir_offset = index_offset + (uint)count * 0x18; for (int i = 0; i < dir_entries; ++i) { folders.Add(new DirEntry { Name = file.View.ReadString(dir_offset, 4), Index = file.View.ReadInt32(dir_offset + 4) }); dir_offset += 8; } } bool is_mask_arc = "mask.arc" == Path.GetFileName(file.Name).ToLowerInvariant(); var dir = new List <Entry> (count); int next_folder = null == folders ? count : folders[0].Index; int folder = 0; string current_folder = ""; for (int i = 0; i < count; ++i) { while (i >= next_folder && folder < folders.Count) { current_folder = folders[folder++].Name; if (folders.Count == folder) { next_folder = count; } else { next_folder = folders[folder].Index; } } string name = file.View.ReadString(index_offset, 0x10); if (0 == name.Length) { return(null); } var offset = file.View.ReadUInt32(index_offset + 0x10); var entry = new AutoEntry(Path.Combine(current_folder, name), () => { uint signature = file.View.ReadUInt32(offset); if (is_mask_arc) { return(ImageFormat.FindByTag("MSK/MAI")); } else if (0x4d43 == (signature & 0xffff)) // 'CM' { return(ImageFormat.FindByTag("CM/MAI")); } else if (0x4d41 == (signature & 0xffff)) // 'AM' { return(ImageFormat.FindByTag("AM/MAI")); } else if (0x4d42 == (signature & 0xffff)) // 'BM' { return(ImageFormat.Bmp); } else if (signature != 0) { return(FormatCatalog.Instance.LookupSignature(signature).FirstOrDefault()); } else { return(null); } }); entry.Offset = offset; 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)); }