public ArchiveDatabase ReadDatabase(IPasswordProvider pass) { var db = new ArchiveDatabase(); db.Clear(); db.MajorVersion = _header[6]; db.MinorVersion = _header[7]; if (db.MajorVersion != 0) throw new InvalidOperationException(); uint crcFromArchive = DataReader.Get32(_header, 8); long nextHeaderOffset = (long)DataReader.Get64(_header, 0xC); long nextHeaderSize = (long)DataReader.Get64(_header, 0x14); uint nextHeaderCrc = DataReader.Get32(_header, 0x1C); uint crc = CRC.kInitCRC; crc = CRC.Update(crc, nextHeaderOffset); crc = CRC.Update(crc, nextHeaderSize); crc = CRC.Update(crc, nextHeaderCrc); crc = CRC.Finish(crc); if (crc != crcFromArchive) throw new InvalidOperationException(); db.StartPositionAfterHeader = _streamOrigin + 0x20; // empty header is ok if (nextHeaderSize == 0) { db.Fill(); return db; } if (nextHeaderOffset < 0 || nextHeaderSize < 0 || nextHeaderSize > Int32.MaxValue) throw new InvalidOperationException(); if (nextHeaderOffset > _streamEnding - db.StartPositionAfterHeader) throw new IndexOutOfRangeException(); _stream.Seek(nextHeaderOffset, SeekOrigin.Current); byte[] header = new byte[nextHeaderSize]; _stream.ReadExact(header, 0, header.Length); if (CRC.Finish(CRC.Update(CRC.kInitCRC, header, 0, header.Length)) != nextHeaderCrc) throw new InvalidOperationException(); using (CStreamSwitch streamSwitch = new CStreamSwitch()) { streamSwitch.Set(this, header); BlockType? type = ReadId(); if (type != BlockType.Header) { if (type != BlockType.EncodedHeader) throw new InvalidOperationException(); var dataVector = ReadAndDecodePackedStreams(db.StartPositionAfterHeader, pass); // compressed header without content is odd but ok if (dataVector.Count == 0) { db.Fill(); return db; } if (dataVector.Count != 1) throw new InvalidOperationException(); streamSwitch.Set(this, dataVector[0]); if (ReadId() != BlockType.Header) throw new InvalidOperationException(); } ReadHeader(db, pass); } db.Fill(); return db; }
public ArchiveDatabase ReadDatabase(IPasswordProvider pass) { ArchiveDatabase db = new ArchiveDatabase(); db.Clear(); db.MajorVersion = this._header[6]; db.MinorVersion = this._header[7]; if (db.MajorVersion != 0) { throw new InvalidOperationException(); } uint num = DataReader.Get32(this._header, 8); long num2 = (long) DataReader.Get64(this._header, 12); long num3 = (long) DataReader.Get64(this._header, 20); uint num4 = DataReader.Get32(this._header, 0x1c); uint maxValue = uint.MaxValue; if (CRC.Finish(CRC.Update(CRC.Update(CRC.Update(maxValue, num2), num3), num4)) != num) { throw new InvalidOperationException(); } db.StartPositionAfterHeader = this._streamOrigin + 0x20L; if (num3 == 0L) { db.Fill(); return db; } if (((num2 < 0L) || (num3 < 0L)) || (num3 > 0x7fffffffL)) { throw new InvalidOperationException(); } if (num2 > (this._streamEnding - db.StartPositionAfterHeader)) { throw new IndexOutOfRangeException(); } this._stream.Seek(num2, SeekOrigin.Current); byte[] buffer = new byte[num3]; Utils.ReadExact(this._stream, buffer, 0, buffer.Length); if (CRC.Finish(CRC.Update(uint.MaxValue, buffer, 0, buffer.Length)) != num4) { throw new InvalidOperationException(); } using (CStreamSwitch switch2 = new CStreamSwitch()) { switch2.Set(this, buffer); BlockType? nullable = this.ReadId(); if (((BlockType) nullable) != BlockType.Header) { if (((BlockType) nullable) != BlockType.EncodedHeader) { throw new InvalidOperationException(); } List<byte[]> list = this.ReadAndDecodePackedStreams(db.StartPositionAfterHeader, pass); if (list.Count == 0) { db.Fill(); return db; } if (list.Count != 1) { throw new InvalidOperationException(); } switch2.Set(this, list[0]); if (((BlockType) this.ReadId()) != BlockType.Header) { throw new InvalidOperationException(); } } this.ReadHeader(db, pass); } db.Fill(); return db; }