public CsafStream(CsafArchive arc) { m_length = arc.File.MaxOffset; m_view = arc.File.CreateFrame(); m_encryption = arc.Encryption; }
public override ArcFile TryOpen(ArcView file) { uint flags = file.View.ReadUInt32(4); if ((flags & 0x7FFFFFFF) != 0x10000) { return(null); } int count = file.View.ReadInt32(8); if (!IsSaneCount(count)) { return(null); } bool is_encrypted = (flags >> 31) != 0; uint index_size = (uint)((count * 24 + 31) & -4096) + 0xFE0u; uint names_size = file.View.ReadUInt32(12); var arc_md5 = file.View.ReadBytes(0x10, 0x10); var index = new byte[index_size + names_size]; CsafEncryption enc = null; try { if (is_encrypted) { file.View.Read(0x20, index, 0, index_size); enc = new CsafEncryption(DefaultKey, DefaultIV); using (var decryptor = enc.CreateDecryptor(0)) using (var enc_names = file.CreateStream(0x20 + index_size, names_size)) using (var dec_names = new InputCryptoStream(enc_names, decryptor)) { dec_names.Read(index, (int)index_size, (int)names_size); } } else { file.View.Read(0x20, index, 0, index_size + names_size); } using (var md5 = MD5.Create()) { var hash = md5.ComputeHash(index); if (!hash.SequenceEqual(arc_md5)) { return(null); } int index_pos = 0x10; int name_pos = (int)index_size; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int j; for (j = name_pos; j + 1 < index.Length; j += 2) { if (index[j] == 0 && index[j + 1] == 0) { break; } } int name_length = j - name_pos; var name = Encoding.Unicode.GetString(index, name_pos, name_length); // hash = md5.ComputeHash (index, name_pos, name_length); // == [index_pos-0x10] name_pos += name_length + 10; var entry = Create <Entry> (name); entry.Offset = (long)index.ToUInt32(index_pos) << 12; entry.Size = index.ToUInt32(index_pos + 4); index_pos += 0x18; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } if (!is_encrypted) { return(new ArcFile(file, this, dir)); } var arc = new CsafArchive(file, this, dir, enc); enc = null; return(arc); } } finally { if (enc != null) { enc.Dispose(); } } }
public CsafArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, CsafEncryption enc) : base(arc, impl, dir) { Encryption = enc; }