public List <Entry> ReadIndex() { using (var index = OpenIndex()) { int name_size = m_record_size - 0x10; var dir = new List <Entry> (m_count); for (int i = 0; i < m_count; ++i) { var entry = new AgsiEntry(); entry.UnpackedSize = index.ReadUInt32(); entry.Size = index.ReadUInt32(); entry.Method = index.ReadInt32(); entry.Offset = index.ReadUInt32() + m_data_offset; if (!entry.CheckPlacement(m_file.MaxOffset)) { return(null); } var name = index.ReadCString(name_size); if (string.IsNullOrEmpty(name)) { return(null); } entry.Name = name; entry.Type = FormatCatalog.Instance.GetTypeFromName(name); entry.IsPacked = entry.Method != 0 && entry.Method != 3; entry.IsSpecial = name.Equals("Copyright.Dat", StringComparison.OrdinalIgnoreCase); dir.Add(entry); } return(dir); } }
internal Stream OpenEncryptedEntry(AgsiArchive arc, AgsiEntry entry) { uint enc_size = entry.Size; if (enc_size > 1024) { enc_size = 1032; } using (var des = DES.Create()) { des.Key = arc.Key; des.Mode = CipherMode.ECB; des.Padding = PaddingMode.Zeros; using (var enc = arc.File.CreateStream(entry.Offset, enc_size)) using (var dec = new InputCryptoStream(enc, des.CreateDecryptor())) { var output = new byte[enc_size]; dec.Read(output, 0, output.Length); int header_size; if (!entry.IsSpecial) { header_size = output.ToInt32(output.Length - 4); if (header_size > entry.UnpackedSize) { throw new InvalidEncryptionScheme(); } } else { header_size = (int)entry.UnpackedSize; } if (!entry.IsSpecial && entry.Size > enc_size) { var header = new byte[header_size]; Buffer.BlockCopy(output, 0, header, 0, header_size); var input = arc.File.CreateStream(entry.Offset + enc_size, entry.Size - enc_size); return(new PrefixStream(header, input)); } else { return(new BinMemoryStream(output, 0, header_size, entry.Name)); } } } }