/// <summary> /// Finish compression and write any footer information required to stream /// </summary> public override void Finish() { // If no data has been written a header should be added. if (state_ == OutputState.Header) { WriteHeader(); } if (state_ == OutputState.Footer) { state_ = OutputState.Finished; base.Finish(); var totalin = (uint)(Deflater.TotalIn & 0xffffffff); var crcval = (uint)(crc.Value & 0xffffffff); byte[] gzipFooter; unchecked { gzipFooter = new byte[] { (byte)crcval, (byte)(crcval >> 8), (byte)(crcval >> 16), (byte)(crcval >> 24), (byte)totalin, (byte)(totalin >> 8), (byte)(totalin >> 16), (byte)(totalin >> 24) }; } BaseOutputStream.Write(gzipFooter, 0, gzipFooter.Length); } }
void WriteHeader() { if (state_ == OutputState.Header) { state_ = OutputState.Footer; var mod_time = (int)((DateTime.Now.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000L); // Ticks give back 100ns intervals byte[] gzipHeader = { // The two magic bytes (byte)(GZipConstants.GZIP_MAGIC >> 8), (byte)(GZipConstants.GZIP_MAGIC & 0xff), // The compression type (byte)Deflater.DEFLATED, // The flags (not set) 0, // The modification time (byte)mod_time, (byte)(mod_time >> 8), (byte)(mod_time >> 16), (byte)(mod_time >> 24), // The extra flags 0, // The OS type (unknown) (byte)255 }; BaseOutputStream.Write(gzipHeader, 0, gzipHeader.Length); } }
private void WriteAesHeader(ZipEntry entry) { byte[] buffer; byte[] buffer2; InitializeAesPassword(entry, Password, out buffer, out buffer2); BaseOutputStream.Write(buffer, 0, buffer.Length); BaseOutputStream.Write(buffer2, 0, buffer2.Length); }
private void WriteEncryptionHeader(long crcValue) { _offset += 12L; InitializePassword(Password); byte[] buffer = new byte[12]; new Random().NextBytes(buffer); buffer[11] = (byte)(crcValue >> 0x18); EncryptBlock(buffer, 0, buffer.Length); BaseOutputStream.Write(buffer, 0, buffer.Length); }
void WriteEncryptionHeader(long crcValue) { offset += ZipConstants.CryptoHeaderSize; byte[] cryptBuffer = new byte[ZipConstants.CryptoHeaderSize]; var rnd = new Random(); rnd.NextBytes(cryptBuffer); cryptBuffer[11] = (byte)(crcValue >> 24); BaseOutputStream.Write(cryptBuffer, 0, cryptBuffer.Length); }
private void CopyAndEncrypt(byte[] buffer, int off, int count) { byte[] destinationArray = new byte[0x1000]; while (count > 0) { int length = (count < 0x1000) ? count : 0x1000; Array.Copy(buffer, off, destinationArray, 0, length); EncryptBlock(destinationArray, 0, length); BaseOutputStream.Write(destinationArray, 0, length); count -= length; off += length; } }
void CopyAndEncrypt(byte[] buffer, int offset, int count) { const int CopyBufferSize = 4096; byte[] localBuffer = new byte[CopyBufferSize]; while (count > 0) { int bufferCount = (count < CopyBufferSize) ? count : CopyBufferSize; Array.Copy(buffer, offset, localBuffer, 0, bufferCount); BaseOutputStream.Write(localBuffer, 0, bufferCount); count -= bufferCount; offset += bufferCount; } }
private void WriteHeader() { if (_state == OutputState.Header) { _state = OutputState.Footer; DateTime time2 = new DateTime(0x7b2, 1, 1); int num = (int)((DateTime.Now.Ticks - time2.Ticks) / 0x989680L); byte[] buffer2 = { 0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 0, 0xff }; buffer2[4] = (byte)num; buffer2[5] = (byte)(num >> 8); buffer2[6] = (byte)(num >> 0x10); buffer2[7] = (byte)(num >> 0x18); byte[] buffer = buffer2; BaseOutputStream.Write(buffer, 0, buffer.Length); } }
public override void Finish() { if (_state == OutputState.Header) { WriteHeader(); } if (_state == OutputState.Footer) { _state = OutputState.Finished; base.Finish(); uint num = (uint)(((ulong)Deflater.TotalIn) & 0xffffffffL); uint num2 = (uint)(((ulong)_crc.Value) & 0xffffffffL); byte[] buffer = { (byte)num2, (byte)(num2 >> 8), (byte)(num2 >> 0x10), (byte)(num2 >> 0x18), (byte)num, (byte)(num >> 8), (byte)(num >> 0x10), (byte)(num >> 0x18) }; BaseOutputStream.Write(buffer, 0, buffer.Length); } }
/// <summary> /// Deflates everything in the input buffers. This will call /// <code>def.deflate()</code> until all bytes from the input buffers /// are processed. /// </summary> protected void Deflate() { while (!Deflater.IsNeedingInput) { var deflate_count = Deflater.Deflate(_buffer, 0, _buffer.Length); if (deflate_count <= 0) { break; } BaseOutputStream.Write(_buffer, 0, deflate_count); } if (!Deflater.IsNeedingInput) { throw new SharpZipBaseException("DeflaterOutputStream can't deflate all input?"); } }
public override void Write(byte[] buffer, int off, int count) { if (_curEntry == null) { throw new InvalidOperationException("No open entry."); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (off < 0) { throw new ArgumentOutOfRangeException(nameof(off), "Cannot be negative"); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "Cannot be negative"); } if ((buffer.Length - off) < count) { throw new ArgumentException("Invalid offset/count combination"); } _crc.Update(buffer, off, count); _size += count; switch (_curMethod) { case CompressionMethod.Stored: if (Password != null) { CopyAndEncrypt(buffer, off, count); } else { BaseOutputStream.Write(buffer, off, count); } break; case CompressionMethod.Deflated: Write(buffer, off, count); break; } }
/// <summary> /// Writes the given buffer to the current entry. /// </summary> /// <param name="buffer">The buffer containing data to write.</param> /// <param name="offset">The offset of the first byte to write.</param> /// <param name="count">The number of bytes to write.</param> /// <exception cref="ZipException">Archive size is invalid</exception> /// <exception cref="System.InvalidOperationException">No entry is active.</exception> public override void Write(byte[] buffer, int offset, int count) { if (curEntry == null) { throw new InvalidOperationException("No open entry."); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset), "Cannot be negative"); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "Cannot be negative"); } if ((buffer.Length - offset) < count) { throw new ArgumentException("Invalid offset/count combination"); } crc.Update(new ArraySegment <byte>(buffer, offset, count)); size += count; switch (curMethod) { case CompressionMethod.Deflated: base.Write(buffer, offset, count); break; case CompressionMethod.Stored: BaseOutputStream.Write(buffer, offset, count); break; } }
/// <summary> /// Finishes the stream by calling finish() on the deflater. /// </summary> /// <exception cref="SharpZipBaseException"> /// Not all input is deflated /// </exception> public virtual void Finish() { Deflater.Finish(); while (!Deflater.IsFinished) { int len = Deflater.Deflate(_buffer, 0, _buffer.Length); if (len <= 0) { break; } BaseOutputStream.Write(_buffer, 0, len); } if (!Deflater.IsFinished) { throw new SharpZipBaseException("Can't deflate all input?"); } BaseOutputStream.Flush(); }
/// <summary> /// Deflates everything in the input buffers. This will call. /// <code>def.deflate()</code> until all bytes from the input buffers /// are processed. /// </summary> protected void Deflate() { while (!Deflater.IsNeedingInput) { var deflateCount = Deflater.Deflate(buffer, 0, buffer.Length); if (deflateCount <= 0) { break; } if (CryptoTransform != null) { EncryptBlock(buffer, 0, deflateCount); } BaseOutputStream.Write(buffer, 0, deflateCount); } if (!Deflater.IsNeedingInput) { throw new InvalidDataException("DeflaterOutputStream can't deflate all input?"); } }
/// <summary> /// Starts a new Zip entry. It automatically closes the previous /// entry if present. /// All entry elements bar name are optional, but must be correct if present. /// If the compression method is stored and the output is not patchable /// the compression for that entry is automatically changed to deflate level 0 /// </summary> /// <param name="entry"> /// the entry. /// </param> /// <exception cref="System.ArgumentNullException"> /// if entry passed is null. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O error occured. /// </exception> /// <exception cref="System.InvalidOperationException"> /// if stream was finished /// </exception> /// <exception cref="ZipException"> /// Too many entries in the Zip file<br/> /// Entry name is too long<br/> /// Finish has already been called<br/> /// </exception> public void PutNextEntry(ZipEntry entry) { if (entry == null) { throw new ArgumentNullException(nameof(entry)); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; // Clear flags that the library manages internally entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; // No need to compress - definitely no data. if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc && entry.CompressedSize >= 0; // Switch to deflation if storing isnt possible. if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { // Can't patch entries so storing is not possible. method = CompressionMethod.Deflated; compressionLevel = 0; } } else // entry.size must be > 0 { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { // Only way to record size and compressed size is to append a data descriptor // after compressed data. // Stored entries of this form have already been converted to deflating. entry.Flags |= 8; } else { patchEntryHeader = true; } } entry.Offset = offset; entry.CompressionMethod = (CompressionMethod)method; curMethod = method; sizePatchPos = -1; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } // Write the local file header WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)entry.CompressionMethodForHeader); WriteLeInt((int)entry.DosTime); // TODO: Refactor header writing. Its done in several places. if (headerInfoAvailable) { WriteLeInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader) { crcPatchPos = BaseOutputStream.Position; } WriteLeInt(0); // Crc if (patchEntryHeader) { sizePatchPos = BaseOutputStream.Position; } // For local header both sizes appear in Zip64 Extended Information if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); // Compressed size WriteLeInt(0); // Uncompressed size } } byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } var ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if (!ed.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } if (entry.AESKeySize > 0) { AddExtraDataAES(entry, ed); } byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if (name.Length > 0) { BaseOutputStream.Write(name, 0, name.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += BaseOutputStream.Position; } if (extra.Length > 0) { BaseOutputStream.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; // Fix offsetOfCentraldir for AES if (entry.AESKeySize > 0) { offset += entry.AESOverheadSize; } // Activate the entry. curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { Deflater.Reset(); Deflater.SetLevel(compressionLevel); } size = 0; }
/// <summary> /// Finishes the stream. This will write the central directory at the /// end of the zip file and flush the stream. /// </summary> /// <remarks> /// This is automatically called when the stream is closed. /// </remarks> /// <exception cref="System.IO.IOException"> /// An I/O error occurs. /// </exception> /// <exception cref="ZipException"> /// Comment exceeds the maximum length<br/> /// Entry name exceeds the maximum length /// </exception> public override void Finish() { if (entries == null) { return; } if (curEntry != null) { CloseEntry(); } long numEntries = entries.Count; long sizeEntries = 0; foreach (ZipEntry entry in entries) { WriteLeInt(ZipConstants.CentralHeaderSignature); WriteLeShort(ZipConstants.VersionMadeBy); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((short)entry.CompressionMethodForHeader); WriteLeInt((int)entry.DosTime); WriteLeInt((int)entry.Crc); if (entry.IsZip64Forced() || (entry.CompressedSize >= uint.MaxValue)) { WriteLeInt(-1); } else { WriteLeInt((int)entry.CompressedSize); } if (entry.IsZip64Forced() || (entry.Size >= uint.MaxValue)) { WriteLeInt(-1); } else { WriteLeInt((int)entry.Size); } byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xffff) { throw new ZipException("Name too long."); } var ed = new ZipExtraData(entry.ExtraData); if (entry.CentralHeaderRequiresZip64) { ed.StartNewEntry(); if (entry.IsZip64Forced() || (entry.Size >= 0xffffffff)) { ed.AddLeLong(entry.Size); } if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffff)) { ed.AddLeLong(entry.CompressedSize); } if (entry.Offset >= 0xffffffff) { ed.AddLeLong(entry.Offset); } ed.AddNewEntry(1); } else { ed.Delete(1); } if (entry.AESKeySize > 0) { AddExtraDataAES(entry, ed); } byte[] extra = ed.GetEntryData(); byte[] entryComment = (entry.Comment != null) ? ZipStrings.ConvertToArray(entry.Flags, entry.Comment) : new byte[0]; if (entryComment.Length > 0xffff) { throw new ZipException("Comment too long."); } WriteLeShort(name.Length); WriteLeShort(extra.Length); WriteLeShort(entryComment.Length); WriteLeShort(0); // disk number WriteLeShort(0); // internal file attributes // external file attributes if (entry.ExternalFileAttributes != -1) { WriteLeInt(entry.ExternalFileAttributes); } else { if (entry.IsDirectory) // mark entry as directory (from nikolam.AT.perfectinfo.com) { WriteLeInt(16); } else { WriteLeInt(0); } } if (entry.Offset >= uint.MaxValue) { WriteLeInt(-1); } else { WriteLeInt((int)entry.Offset); } if (name.Length > 0) { BaseOutputStream.Write(name, 0, name.Length); } if (extra.Length > 0) { BaseOutputStream.Write(extra, 0, extra.Length); } if (entryComment.Length > 0) { BaseOutputStream.Write(entryComment, 0, entryComment.Length); } sizeEntries += ZipConstants.CentralHeaderBaseSize + name.Length + extra.Length + entryComment.Length; } using (ZipHelperStream zhs = new ZipHelperStream(BaseOutputStream)) { zhs.WriteEndOfCentralDirectory(numEntries, sizeEntries, offset, zipComment); } entries = null; }
public void PutNextEntry(ZipEntry entry) { bool hasCrc; if (entry == null) { throw new ArgumentNullException(nameof(entry)); } if (_entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (_curEntry != null) { CloseEntry(); } if (_entries.Count == 0x7fffffff) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod compressionMethod = entry.CompressionMethod; int compressionLevel = _defaultCompressionLevel; entry.Flags &= 0x800; _patchEntryHeader = false; if (entry.Size == 0L) { entry.CompressedSize = entry.Size; entry.Crc = 0L; compressionMethod = CompressionMethod.Stored; hasCrc = true; } else { hasCrc = (entry.Size >= 0L) && entry.HasCrc; if (compressionMethod == CompressionMethod.Stored) { if (!hasCrc) { if (!CanPatchEntries) { compressionMethod = CompressionMethod.Deflated; compressionLevel = 0; } } else { entry.CompressedSize = entry.Size; hasCrc = entry.HasCrc; } } } if (!hasCrc) { if (!CanPatchEntries) { entry.Flags |= 8; } else { _patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0L) { entry.Flags |= 8; } } entry.Offset = _offset; entry.CompressionMethod = compressionMethod; _curMethod = compressionMethod; _sizePatchPos = -1L; if ((_useZip64 == UseZip64.On) || ((entry.Size < 0L) && (_useZip64 == UseZip64.Dynamic))) { entry.ForceZip64(); } WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)entry.CompressionMethodForHeader); WriteLeInt((int)entry.DosTime); if (hasCrc) { WriteLeInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (((int)entry.CompressedSize) + 12) : ((int)entry.CompressedSize)); WriteLeInt((int)entry.Size); } } else { if (_patchEntryHeader) { _crcPatchPos = BaseOutputStream.Position; } WriteLeInt(0); if (_patchEntryHeader) { _sizePatchPos = BaseOutputStream.Position; } if (entry.LocalHeaderRequiresZip64 || _patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); WriteLeInt(0); } } byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (buffer.Length > 0xffff) { throw new ZipException("Entry name too long."); } ZipExtraData extraData = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { extraData.StartNewEntry(); if (hasCrc) { extraData.AddLeLong(entry.Size); extraData.AddLeLong(entry.CompressedSize); } else { extraData.AddLeLong(-1L); extraData.AddLeLong(-1L); } extraData.AddNewEntry(1); if (!extraData.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (_patchEntryHeader) { _sizePatchPos = extraData.CurrentReadIndex; } } else { extraData.Delete(1); } if (entry.AesKeySize > 0) { AddExtraDataAes(entry, extraData); } byte[] entryData = extraData.GetEntryData(); WriteLeShort(buffer.Length); WriteLeShort(entryData.Length); if (buffer.Length > 0) { BaseOutputStream.Write(buffer, 0, buffer.Length); } if (entry.LocalHeaderRequiresZip64 && _patchEntryHeader) { _sizePatchPos += BaseOutputStream.Position; } if (entryData.Length > 0) { BaseOutputStream.Write(entryData, 0, entryData.Length); } _offset += (30 + buffer.Length) + entryData.Length; if (entry.AesKeySize > 0) { _offset += entry.AesOverheadSize; } _curEntry = entry; _crc.Reset(); if (compressionMethod == CompressionMethod.Deflated) { Deflater.Reset(); Deflater.SetLevel(compressionLevel); } _size = 0L; if (entry.IsCrypted) { if (entry.AesKeySize > 0) { WriteAesHeader(entry); } else if (entry.Crc < 0L) { WriteEncryptionHeader(entry.DosTime << 0x10); } else { WriteEncryptionHeader(entry.Crc); } } }
public override void Finish() { if (_entries != null) { if (_curEntry != null) { CloseEntry(); } long count = _entries.Count; long sizeEntries = 0L; foreach (ZipEntry entry in _entries) { WriteLeInt(ZipConstants.CentralHeaderSignature); WriteLeShort(0x33); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((short)entry.CompressionMethodForHeader); WriteLeInt((int)entry.DosTime); WriteLeInt((int)entry.Crc); if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL)) { WriteLeInt(-1); } else { WriteLeInt((int)entry.CompressedSize); } if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL)) { WriteLeInt(-1); } else { WriteLeInt((int)entry.Size); } byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (buffer.Length > 0xffff) { throw new ZipException("Name too long."); } ZipExtraData extraData = new ZipExtraData(entry.ExtraData); if (entry.CentralHeaderRequiresZip64) { extraData.StartNewEntry(); if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL)) { extraData.AddLeLong(entry.Size); } if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL)) { extraData.AddLeLong(entry.CompressedSize); } if (entry.Offset >= 0xffffffffL) { extraData.AddLeLong(entry.Offset); } extraData.AddNewEntry(1); } else { extraData.Delete(1); } if (entry.AesKeySize > 0) { AddExtraDataAes(entry, extraData); } byte[] entryData = extraData.GetEntryData(); byte[] buffer3 = (entry.Comment != null) ? ZipConstants.ConvertToArray(entry.Flags, entry.Comment) : new byte[0]; if (buffer3.Length > 0xffff) { throw new ZipException("Comment too long."); } WriteLeShort(buffer.Length); WriteLeShort(entryData.Length); WriteLeShort(buffer3.Length); WriteLeShort(0); WriteLeShort(0); if (entry.ExternalFileAttributes != -1) { WriteLeInt(entry.ExternalFileAttributes); } else if (entry.IsDirectory) { WriteLeInt(0x10); } else { WriteLeInt(0); } if (entry.Offset >= 0xffffffffL) { WriteLeInt(-1); } else { WriteLeInt((int)entry.Offset); } if (buffer.Length > 0) { BaseOutputStream.Write(buffer, 0, buffer.Length); } if (entryData.Length > 0) { BaseOutputStream.Write(entryData, 0, entryData.Length); } if (buffer3.Length > 0) { BaseOutputStream.Write(buffer3, 0, buffer3.Length); } sizeEntries += ((ZipConstants.CentralHeaderBaseSize + buffer.Length) + entryData.Length) + buffer3.Length; } using (ZipHelperStream stream = new ZipHelperStream(BaseOutputStream)) { stream.WriteEndOfCentralDirectory(count, sizeEntries, _offset, _zipComment); } _entries = null; } }
public void CloseEntry() { if (_curEntry == null) { throw new InvalidOperationException("No open entry"); } long compressedSize = _size; if (_curMethod == CompressionMethod.Deflated) { if (_size >= 0L) { Finish(); compressedSize = Deflater.TotalOut; } else { Deflater.Reset(); } } if (_curEntry.AesKeySize > 0) { BaseOutputStream.Write(AesAuthCode, 0, 10); } if (_curEntry.Size < 0L) { _curEntry.Size = _size; } else if (_curEntry.Size != _size) { throw new ZipException(string.Concat("size was ", _size, ", but I expected ", _curEntry.Size)); } if (_curEntry.CompressedSize < 0L) { _curEntry.CompressedSize = compressedSize; } else if (_curEntry.CompressedSize != compressedSize) { throw new ZipException(string.Concat("compressed size was ", compressedSize, ", but I expected ", _curEntry.CompressedSize)); } if (_curEntry.Crc < 0L) { _curEntry.Crc = _crc.Value; } else if (_curEntry.Crc != _crc.Value) { throw new ZipException(string.Concat("crc was ", _crc.Value, ", but I expected ", _curEntry.Crc)); } _offset += compressedSize; if (_curEntry.IsCrypted) { if (_curEntry.AesKeySize > 0) { _curEntry.CompressedSize += _curEntry.AesOverheadSize; } else { _curEntry.CompressedSize += 12L; } } if (_patchEntryHeader) { _patchEntryHeader = false; long position = BaseOutputStream.Position; BaseOutputStream.Seek(_crcPatchPos, SeekOrigin.Begin); WriteLeInt((int)_curEntry.Crc); if (_curEntry.LocalHeaderRequiresZip64) { if (_sizePatchPos == -1L) { throw new ZipException("Entry requires zip64 but this has been turned off"); } BaseOutputStream.Seek(_sizePatchPos, SeekOrigin.Begin); WriteLeLong(_curEntry.Size); WriteLeLong(_curEntry.CompressedSize); } else { WriteLeInt((int)_curEntry.CompressedSize); WriteLeInt((int)_curEntry.Size); } BaseOutputStream.Seek(position, SeekOrigin.Begin); } if ((_curEntry.Flags & 8) != 0) { WriteLeInt(ZipConstants.DataDescriptorSignature); WriteLeInt((int)_curEntry.Crc); if (_curEntry.LocalHeaderRequiresZip64) { WriteLeLong(_curEntry.CompressedSize); WriteLeLong(_curEntry.Size); _offset += 0x18L; } else { WriteLeInt((int)_curEntry.CompressedSize); WriteLeInt((int)_curEntry.Size); _offset += 0x10L; } } _entries.Add(_curEntry); _curEntry = null; }