internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd) { this._archive = archive; this._originallyInArchive = true; this._diskNumberStart = cd.DiskNumberStart; this._versionToExtract = (ZipVersionNeededValues)cd.VersionNeededToExtract; this._generalPurposeBitFlag = (ZipArchiveEntry.BitFlagValues)cd.GeneralPurposeBitFlag; this.CompressionMethod = (ZipArchiveEntry.CompressionMethodValues)cd.CompressionMethod; this._lastModified = new DateTimeOffset(ZipHelper.DosTimeToDateTime(cd.LastModified)); this._compressedSize = cd.CompressedSize; this._uncompressedSize = cd.UncompressedSize; this._externalFileAttr = cd.ExternalFileAttributes; this._offsetOfLocalHeader = cd.RelativeOffsetOfLocalHeader; this._storedOffsetOfCompressedData = null; this._crc32 = cd.Crc32; this._compressedBytes = null; this._storedUncompressedData = null; this._currentlyOpenForWrite = false; this._everOpenedForWrite = false; this._outstandingWriteStream = null; this.FullName = this.DecodeEntryName(cd.Filename); this._lhUnknownExtraFields = null; this._cdUnknownExtraFields = cd.ExtraFields; this._fileComment = cd.FileComment; this._compressionLevel = null; }
private void ReadCentralDirectory() { try { //assume ReadEndOfCentralDirectory has been called and has populated _centralDirectoryStart _archiveStream.Seek(_centralDirectoryStart, SeekOrigin.Begin); long numberOfEntries = 0; //read the central directory ZipCentralDirectoryFileHeader currentHeader; bool saveExtraFieldsAndComments = Mode == ZipArchiveMode.Update; while (ZipCentralDirectoryFileHeader.TryReadBlock(_archiveReader, saveExtraFieldsAndComments, out currentHeader)) { AddEntry(new ZipArchiveEntry(this, currentHeader)); numberOfEntries++; } if (numberOfEntries != _expectedNumberOfEntries) { throw new InvalidDataException(SR.NumEntriesWrong); } } catch (EndOfStreamException ex) { throw new InvalidDataException(SR.Format(SR.CentralDirectoryInvalid, ex)); } }
//Initializes, attaches it to archive internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd) { _archive = archive; _originallyInArchive = true; _diskNumberStart = cd.DiskNumberStart; _versionToExtract = (ZipVersionNeededValues)cd.VersionNeededToExtract; _generalPurposeBitFlag = (BitFlagValues)cd.GeneralPurposeBitFlag; CompressionMethod = (CompressionMethodValues)cd.CompressionMethod; _lastModified = new DateTimeOffset(ZipHelper.DosTimeToDateTime(cd.LastModified)); _compressedSize = cd.CompressedSize; _uncompressedSize = cd.UncompressedSize; _offsetOfLocalHeader = cd.RelativeOffsetOfLocalHeader; /* we don't know this yet: should be _offsetOfLocalHeader + 30 + _storedEntryNameBytes.Length + extrafieldlength * but entryname/extra length could be different in LH */ _storedOffsetOfCompressedData = null; _crc32 = cd.Crc32; _compressedBytes = null; _storedUncompressedData = null; _currentlyOpenForWrite = false; _everOpenedForWrite = false; _outstandingWriteStream = null; FullName = DecodeEntryName(cd.Filename); _lhUnknownExtraFields = null; //the cd should have these as null if we aren't in Update mode _cdUnknownExtraFields = cd.ExtraFields; _fileComment = cd.FileComment; _compressionLevel = null; }
//Initializes, attaches it to archive internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd, CompressionLevel compressionLevel) : this(archive, cd) { // Checking of compressionLevel is passed down to DeflateStream and the IDeflater implementation // as it is a pugable component that completely encapsulates the meaning of compressionLevel. _compressionLevel = compressionLevel; }
// Initializes, attaches it to archive internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd) { _archive = archive; _originallyInArchive = true; _diskNumberStart = cd.DiskNumberStart; _versionMadeByPlatform = (ZipVersionMadeByPlatform)cd.VersionMadeByCompatibility; _versionMadeBySpecification = (ZipVersionNeededValues)cd.VersionMadeBySpecification; _versionToExtract = (ZipVersionNeededValues)cd.VersionNeededToExtract; _generalPurposeBitFlag = (BitFlagValues)cd.GeneralPurposeBitFlag; CompressionMethod = (CompressionMethodValues)cd.CompressionMethod; _lastModified = new DateTimeOffset(ZipHelper.DosTimeToDateTime(cd.LastModified)); _compressedSize = cd.CompressedSize; _uncompressedSize = cd.UncompressedSize; _externalFileAttr = cd.ExternalFileAttributes; _offsetOfLocalHeader = cd.RelativeOffsetOfLocalHeader; // we don't know this yet: should be _offsetOfLocalHeader + 30 + _storedEntryNameBytes.Length + extrafieldlength // but entryname/extra length could be different in LH _storedOffsetOfCompressedData = null; _crc32 = cd.Crc32; _compressedBytes = null; _storedUncompressedData = null; _currentlyOpenForWrite = false; _everOpenedForWrite = false; _outstandingWriteStream = null; FullName = DecodeEntryName(cd.Filename); _lhUnknownExtraFields = null; // the cd should have these as null if we aren't in Update mode _cdUnknownExtraFields = cd.ExtraFields; _fileComment = cd.FileComment; _compressionLevel = null; }
private void ReadCentralDirectory() { ZipCentralDirectoryFileHeader zipCentralDirectoryFileHeader; try { this._archiveStream.Seek(this._centralDirectoryStart, SeekOrigin.Begin); long num = (long)0; bool mode = this.Mode == ZipArchiveMode.Update; while (ZipCentralDirectoryFileHeader.TryReadBlock(this._archiveReader, mode, out zipCentralDirectoryFileHeader)) { this.AddEntry(new ZipArchiveEntry(this, zipCentralDirectoryFileHeader)); num += (long)1; } if (num != this._expectedNumberOfEntries) { throw new InvalidDataException(Messages.NumEntriesWrong); } } catch (EndOfStreamException endOfStreamException) { throw new InvalidDataException(Messages.CentralDirectoryInvalid, endOfStreamException); } }
// if saveExtraFieldsAndComments is false, FileComment and ExtraFields will be null // in either case, the zip64 extra field info will be incorporated into other fields public static bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header) { header = new ZipCentralDirectoryFileHeader(); if (reader.ReadUInt32() != SignatureConstant) { return(false); } header.VersionMadeBySpecification = reader.ReadByte(); header.VersionMadeByCompatibility = reader.ReadByte(); header.VersionNeededToExtract = reader.ReadUInt16(); header.GeneralPurposeBitFlag = reader.ReadUInt16(); header.CompressionMethod = reader.ReadUInt16(); header.LastModified = reader.ReadUInt32(); header.Crc32 = reader.ReadUInt32(); uint compressedSizeSmall = reader.ReadUInt32(); uint uncompressedSizeSmall = reader.ReadUInt32(); header.FilenameLength = reader.ReadUInt16(); header.ExtraFieldLength = reader.ReadUInt16(); header.FileCommentLength = reader.ReadUInt16(); ushort diskNumberStartSmall = reader.ReadUInt16(); header.InternalFileAttributes = reader.ReadUInt16(); header.ExternalFileAttributes = reader.ReadUInt32(); uint relativeOffsetOfLocalHeaderSmall = reader.ReadUInt32(); header.Filename = reader.ReadBytes(header.FilenameLength); bool uncompressedSizeInZip64 = uncompressedSizeSmall == ZipHelper.Mask32Bit; bool compressedSizeInZip64 = compressedSizeSmall == ZipHelper.Mask32Bit; bool relativeOffsetInZip64 = relativeOffsetOfLocalHeaderSmall == ZipHelper.Mask32Bit; bool diskNumberStartInZip64 = diskNumberStartSmall == ZipHelper.Mask16Bit; Zip64ExtraField zip64; long endExtraFields = reader.BaseStream.Position + header.ExtraFieldLength; using (Stream str = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, header.ExtraFieldLength)) { if (saveExtraFieldsAndComments) { header.ExtraFields = ZipGenericExtraField.ParseExtraField(str); zip64 = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields, uncompressedSizeInZip64, compressedSizeInZip64, relativeOffsetInZip64, diskNumberStartInZip64); } else { header.ExtraFields = null; zip64 = Zip64ExtraField.GetJustZip64Block(str, uncompressedSizeInZip64, compressedSizeInZip64, relativeOffsetInZip64, diskNumberStartInZip64); } } // There are zip files that have malformed ExtraField blocks in which GetJustZip64Block() silently bails out without reading all the way to the end // of the ExtraField block. Thus we must force the stream's position to the proper place. reader.BaseStream.AdvanceToPosition(endExtraFields); if (saveExtraFieldsAndComments) { header.FileComment = reader.ReadBytes(header.FileCommentLength); } else { reader.BaseStream.Position += header.FileCommentLength; header.FileComment = null; } header.UncompressedSize = zip64.UncompressedSize == null ? uncompressedSizeSmall : zip64.UncompressedSize.Value; header.CompressedSize = zip64.CompressedSize == null ? compressedSizeSmall : zip64.CompressedSize.Value; header.RelativeOffsetOfLocalHeader = zip64.LocalHeaderOffset == null ? relativeOffsetOfLocalHeaderSmall : zip64.LocalHeaderOffset.Value; header.DiskNumberStart = zip64.StartDiskNumber == null ? diskNumberStartSmall : zip64.StartDiskNumber.Value; return(true); }
internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd, CompressionLevel compressionLevel) : this(archive, cd) { this._compressionLevel = new CompressionLevel?(compressionLevel); }
//Initializes, attaches it to archive internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd, CompressionLevel compressionLevel) : this(archive, cd) { _compressionLevel = compressionLevel; }
public static bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header) { Zip64ExtraField justZip64Block; long? uncompressedSize; long value; long num; long value1; header = new ZipCentralDirectoryFileHeader(); if (reader.ReadUInt32() != 33639248) { return(false); } header.VersionMadeBy = reader.ReadUInt16(); header.VersionNeededToExtract = reader.ReadUInt16(); header.GeneralPurposeBitFlag = reader.ReadUInt16(); header.CompressionMethod = reader.ReadUInt16(); header.LastModified = reader.ReadUInt32(); header.Crc32 = reader.ReadUInt32(); uint num1 = reader.ReadUInt32(); uint num2 = reader.ReadUInt32(); header.FilenameLength = reader.ReadUInt16(); header.ExtraFieldLength = reader.ReadUInt16(); header.FileCommentLength = reader.ReadUInt16(); ushort num3 = reader.ReadUInt16(); header.InternalFileAttributes = reader.ReadUInt16(); header.ExternalFileAttributes = reader.ReadUInt32(); uint num4 = reader.ReadUInt32(); header.Filename = reader.ReadBytes((int)header.FilenameLength); bool flag = num2 == -1; bool flag1 = num1 == -1; bool flag2 = num4 == -1; bool flag3 = num3 == 65535; long position = (long)(reader.BaseStream.Position + (ulong)header.ExtraFieldLength); using (Stream subReadStream = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, (long)header.ExtraFieldLength)) { if (!saveExtraFieldsAndComments) { header.ExtraFields = null; justZip64Block = Zip64ExtraField.GetJustZip64Block(subReadStream, flag, flag1, flag2, flag3); } else { header.ExtraFields = ZipGenericExtraField.ParseExtraField(subReadStream); justZip64Block = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields, flag, flag1, flag2, flag3); } } reader.BaseStream.AdvanceToPosition(position); if (!saveExtraFieldsAndComments) { Stream baseStream = reader.BaseStream; baseStream.Position = (long)(baseStream.Position + (ulong)header.FileCommentLength); header.FileComment = null; } else { header.FileComment = reader.ReadBytes((int)header.FileCommentLength); } if (!justZip64Block.UncompressedSize.HasValue) { value = (long)((ulong)num2); } else { uncompressedSize = justZip64Block.UncompressedSize; value = uncompressedSize.Value; } header.UncompressedSize = value; if (!justZip64Block.CompressedSize.HasValue) { num = (long)((ulong)num1); } else { uncompressedSize = justZip64Block.CompressedSize; num = uncompressedSize.Value; } header.CompressedSize = num; if (!justZip64Block.LocalHeaderOffset.HasValue) { value1 = (long)((ulong)num4); } else { uncompressedSize = justZip64Block.LocalHeaderOffset; value1 = uncompressedSize.Value; } header.RelativeOffsetOfLocalHeader = value1; header.DiskNumberStart = (!justZip64Block.StartDiskNumber.HasValue ? (int)num3 : justZip64Block.StartDiskNumber.Value); return(true); }
//if saveExtraFieldsAndComments is false, FileComment and ExtraFields will be null //in either case, the zip64 extra field info will be incorporated into other fields static public bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header) { header = new ZipCentralDirectoryFileHeader(); if (reader.ReadUInt32() != SignatureConstant) return false; header.VersionMadeBySpecification = reader.ReadByte(); header.VersionMadeByCompatibility = reader.ReadByte(); header.VersionNeededToExtract = reader.ReadUInt16(); header.GeneralPurposeBitFlag = reader.ReadUInt16(); header.CompressionMethod = reader.ReadUInt16(); header.LastModified = reader.ReadUInt32(); header.Crc32 = reader.ReadUInt32(); uint compressedSizeSmall = reader.ReadUInt32(); uint uncompressedSizeSmall = reader.ReadUInt32(); header.FilenameLength = reader.ReadUInt16(); header.ExtraFieldLength = reader.ReadUInt16(); header.FileCommentLength = reader.ReadUInt16(); ushort diskNumberStartSmall = reader.ReadUInt16(); header.InternalFileAttributes = reader.ReadUInt16(); header.ExternalFileAttributes = reader.ReadUInt32(); uint relativeOffsetOfLocalHeaderSmall = reader.ReadUInt32(); header.Filename = reader.ReadBytes(header.FilenameLength); bool uncompressedSizeInZip64 = uncompressedSizeSmall == ZipHelper.Mask32Bit; bool compressedSizeInZip64 = compressedSizeSmall == ZipHelper.Mask32Bit; bool relativeOffsetInZip64 = relativeOffsetOfLocalHeaderSmall == ZipHelper.Mask32Bit; bool diskNumberStartInZip64 = diskNumberStartSmall == ZipHelper.Mask16Bit; Zip64ExtraField zip64; long endExtraFields = reader.BaseStream.Position + header.ExtraFieldLength; using (Stream str = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, header.ExtraFieldLength)) { if (saveExtraFieldsAndComments) { header.ExtraFields = ZipGenericExtraField.ParseExtraField(str); zip64 = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields, uncompressedSizeInZip64, compressedSizeInZip64, relativeOffsetInZip64, diskNumberStartInZip64); } else { header.ExtraFields = null; zip64 = Zip64ExtraField.GetJustZip64Block(str, uncompressedSizeInZip64, compressedSizeInZip64, relativeOffsetInZip64, diskNumberStartInZip64); } } // There are zip files that have malformed ExtraField blocks in which GetJustZip64Block() silently bails out without reading all the way to the end // of the ExtraField block. Thus we must force the stream's position to the proper place. reader.BaseStream.AdvanceToPosition(endExtraFields); if (saveExtraFieldsAndComments) header.FileComment = reader.ReadBytes(header.FileCommentLength); else { reader.BaseStream.Position += header.FileCommentLength; header.FileComment = null; } header.UncompressedSize = zip64.UncompressedSize == null ? uncompressedSizeSmall : zip64.UncompressedSize.Value; header.CompressedSize = zip64.CompressedSize == null ? compressedSizeSmall : zip64.CompressedSize.Value; header.RelativeOffsetOfLocalHeader = zip64.LocalHeaderOffset == null ? relativeOffsetOfLocalHeaderSmall : zip64.LocalHeaderOffset.Value; header.DiskNumberStart = zip64.StartDiskNumber == null ? diskNumberStartSmall : zip64.StartDiskNumber.Value; return true; }
//if saveExtraFieldsAndComments is false, FileComment and ExtraFields will be null //in either case, the zip64 extra field info will be incorporated into other fields static public Boolean TryReadBlock(BinaryReader reader, Boolean saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header) { header = new ZipCentralDirectoryFileHeader(); if (reader.ReadUInt32() != SignatureConstant) { return(false); } header.VersionMadeBy = reader.ReadUInt16(); header.VersionNeededToExtract = reader.ReadUInt16(); header.GeneralPurposeBitFlag = reader.ReadUInt16(); header.CompressionMethod = reader.ReadUInt16(); header.LastModified = reader.ReadUInt32(); header.Crc32 = reader.ReadUInt32(); UInt32 compressedSizeSmall = reader.ReadUInt32(); UInt32 uncompressedSizeSmall = reader.ReadUInt32(); header.FilenameLength = reader.ReadUInt16(); header.ExtraFieldLength = reader.ReadUInt16(); header.FileCommentLength = reader.ReadUInt16(); UInt16 diskNumberStartSmall = reader.ReadUInt16(); header.InternalFileAttributes = reader.ReadUInt16(); header.ExternalFileAttributes = reader.ReadUInt32(); UInt32 relativeOffsetOfLocalHeaderSmall = reader.ReadUInt32(); header.Filename = reader.ReadBytes(header.FilenameLength); Boolean uncompressedSizeInZip64 = uncompressedSizeSmall == ZipHelper.Mask32Bit; Boolean compressedSizeInZip64 = compressedSizeSmall == ZipHelper.Mask32Bit; Boolean relativeOffsetInZip64 = relativeOffsetOfLocalHeaderSmall == ZipHelper.Mask32Bit; Boolean diskNumberStartInZip64 = diskNumberStartSmall == ZipHelper.Mask16Bit; Zip64ExtraField zip64; using (Stream str = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, header.ExtraFieldLength)) { if (saveExtraFieldsAndComments) { header.ExtraFields = ZipGenericExtraField.ParseExtraField(str); zip64 = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields, uncompressedSizeInZip64, compressedSizeInZip64, relativeOffsetInZip64, diskNumberStartInZip64); } else { header.ExtraFields = null; zip64 = Zip64ExtraField.GetJustZip64Block(str, uncompressedSizeInZip64, compressedSizeInZip64, relativeOffsetInZip64, diskNumberStartInZip64); } } if (saveExtraFieldsAndComments) { header.FileComment = reader.ReadBytes(header.FileCommentLength); } else { reader.BaseStream.Position += header.FileCommentLength; header.FileComment = null; } header.UncompressedSize = zip64.UncompressedSize == null ? uncompressedSizeSmall : zip64.UncompressedSize.Value; header.CompressedSize = zip64.CompressedSize == null ? compressedSizeSmall : zip64.CompressedSize.Value; header.RelativeOffsetOfLocalHeader = zip64.LocalHeaderOffset == null ? relativeOffsetOfLocalHeaderSmall : zip64.LocalHeaderOffset.Value; header.DiskNumberStart = zip64.StartDiskNumber == null ? diskNumberStartSmall : zip64.StartDiskNumber.Value; return(true); }