public static bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header) { header = new ZipCentralDirectoryFileHeader(); if (reader.ReadUInt32() != 33639248u) { 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 num = 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 readUncompressedSize = num2 == 4294967295u; bool readCompressedSize = num == 4294967295u; bool readLocalHeaderOffset = num4 == 4294967295u; bool readStartDiskNumber = num3 == 65535; long position = reader.BaseStream.Position + (long)((ulong)header.ExtraFieldLength); Zip64ExtraField zip64ExtraField; using (Stream stream = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, (long)((ulong)header.ExtraFieldLength))) { if (saveExtraFieldsAndComments) { header.ExtraFields = ZipGenericExtraField.ParseExtraField(stream); zip64ExtraField = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields, readUncompressedSize, readCompressedSize, readLocalHeaderOffset, readStartDiskNumber); } else { header.ExtraFields = null; zip64ExtraField = Zip64ExtraField.GetJustZip64Block(stream, readUncompressedSize, readCompressedSize, readLocalHeaderOffset, readStartDiskNumber); } } ZipHelper.AdvanceToPosition(reader.BaseStream, position); if (saveExtraFieldsAndComments) { header.FileComment = reader.ReadBytes((int)header.FileCommentLength); } else { reader.BaseStream.Position += (long)((ulong)header.FileCommentLength); header.FileComment = null; } header.UncompressedSize = (long)((!zip64ExtraField.UncompressedSize.HasValue) ? ((ulong)num2) : ((ulong)zip64ExtraField.UncompressedSize.Value)); header.CompressedSize = (long)((!zip64ExtraField.CompressedSize.HasValue) ? ((ulong)num) : ((ulong)zip64ExtraField.CompressedSize.Value)); header.RelativeOffsetOfLocalHeader = (long)((!zip64ExtraField.LocalHeaderOffset.HasValue) ? ((ulong)num4) : ((ulong)zip64ExtraField.LocalHeaderOffset.Value)); header.DiskNumberStart = ((!zip64ExtraField.StartDiskNumber.HasValue) ? ((int)num3) : zip64ExtraField.StartDiskNumber.Value); return(true); }
private void ReadEndOfCentralDirectory() { try { this._archiveStream.Seek(-18L, SeekOrigin.End); if (!ZipHelper.SeekBackwardsToSignature(this._archiveStream, 101010256U)) { throw new InvalidDataException(CompressionConstants.EOCDNotFound); } long position = this._archiveStream.Position; ZipEndOfCentralDirectoryBlock eocdBlock; ZipEndOfCentralDirectoryBlock.TryReadBlock(this._archiveReader, out eocdBlock); if ((int)eocdBlock.NumberOfThisDisk != (int)eocdBlock.NumberOfTheDiskWithTheStartOfTheCentralDirectory) { throw new InvalidDataException(CompressionConstants.SplitSpanned); } this._numberOfThisDisk = (uint)eocdBlock.NumberOfThisDisk; this._centralDirectoryStart = (long)eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber; if ((int)eocdBlock.NumberOfEntriesInTheCentralDirectory != (int)eocdBlock.NumberOfEntriesInTheCentralDirectoryOnThisDisk) { throw new InvalidDataException(CompressionConstants.SplitSpanned); } this._expectedNumberOfEntries = (long)eocdBlock.NumberOfEntriesInTheCentralDirectory; if (this._mode == ZipArchiveMode.Update) { this._archiveComment = eocdBlock.ArchiveComment; } if ((int)eocdBlock.NumberOfThisDisk == (int)ushort.MaxValue || (int)eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber == -1 || (int)eocdBlock.NumberOfEntriesInTheCentralDirectory == (int)ushort.MaxValue) { this._archiveStream.Seek(position - 16L, SeekOrigin.Begin); if (ZipHelper.SeekBackwardsToSignature(this._archiveStream, 117853008U)) { Zip64EndOfCentralDirectoryLocator zip64EOCDLocator; Zip64EndOfCentralDirectoryLocator.TryReadBlock(this._archiveReader, out zip64EOCDLocator); if (zip64EOCDLocator.OffsetOfZip64EOCD > 9223372036854775807UL) { throw new InvalidDataException(CompressionConstants.FieldTooBigOffsetToZip64EOCD); } this._archiveStream.Seek((long)zip64EOCDLocator.OffsetOfZip64EOCD, SeekOrigin.Begin); Zip64EndOfCentralDirectoryRecord zip64EOCDRecord; if (!Zip64EndOfCentralDirectoryRecord.TryReadBlock(this._archiveReader, out zip64EOCDRecord)) { throw new InvalidDataException(CompressionConstants.Zip64EOCDNotWhereExpected); } this._numberOfThisDisk = zip64EOCDRecord.NumberOfThisDisk; if (zip64EOCDRecord.NumberOfEntriesTotal > 9223372036854775807UL) { throw new InvalidDataException(CompressionConstants.FieldTooBigNumEntries); } if (zip64EOCDRecord.OffsetOfCentralDirectory > 9223372036854775807UL) { throw new InvalidDataException(CompressionConstants.FieldTooBigOffsetToCD); } if ((long)zip64EOCDRecord.NumberOfEntriesTotal != (long)zip64EOCDRecord.NumberOfEntriesOnThisDisk) { throw new InvalidDataException(CompressionConstants.SplitSpanned); } this._expectedNumberOfEntries = (long)zip64EOCDRecord.NumberOfEntriesTotal; this._centralDirectoryStart = (long)zip64EOCDRecord.OffsetOfCentralDirectory; } } if (this._centralDirectoryStart > this._archiveStream.Length) { throw new InvalidDataException(CompressionConstants.FieldTooBigOffsetToCD); } } catch (EndOfStreamException ex) { throw new InvalidDataException(CompressionConstants.CDCorrupt, (Exception)ex); } catch (IOException ex) { throw new InvalidDataException(CompressionConstants.CDCorrupt, (Exception)ex); } }
private static void DoCreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, bool includeBaseDirectory, bool includeSubDirectories, Encoding entryNameEncoding) { if (sourceDirectoryName == null) { throw new ArgumentNullException("sourceDirectoryName"); } if (destinationArchiveFileName == null) { throw new ArgumentNullException("destinationArchiveFileName"); } sourceDirectoryName = Path.GetFullPath(sourceDirectoryName); if (!Directory.Exists(sourceDirectoryName)) { throw new DirectoryNotFoundException(sourceDirectoryName); } destinationArchiveFileName = Path.GetFullPath(destinationArchiveFileName); using (ZipArchive destination = ZipFile.Open(destinationArchiveFileName, ZipArchiveMode.Create, entryNameEncoding)) { bool flag = true; DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirectoryName); string fullName = directoryInfo.FullName; if (includeBaseDirectory && directoryInfo.Parent != null) { fullName = directoryInfo.Parent.FullName; } List <FileSystemInfo> list = new List <FileSystemInfo>(); if (includeSubDirectories) { list.AddRange(directoryInfo.GetDirectories("*", SearchOption.AllDirectories)); list.AddRange(directoryInfo.GetFiles("*", SearchOption.AllDirectories)); } else { list.AddRange(directoryInfo.GetFiles("*", SearchOption.TopDirectoryOnly)); } foreach (FileSystemInfo fileSystemInfo in list) { flag = false; int length = fileSystemInfo.FullName.Length - fullName.Length; string entryName = fileSystemInfo.FullName.Substring(fullName.Length, length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (fileSystemInfo is FileInfo) { destination.CreateEntryFromFile(fileSystemInfo.FullName, entryName); } else { DirectoryInfo possiblyEmptyDir = fileSystemInfo as DirectoryInfo; if (possiblyEmptyDir != null && ZipHelper.IsDirEmpty(possiblyEmptyDir)) { destination.CreateEntryFromDirectory(possiblyEmptyDir.FullName, entryName + Path.DirectorySeparatorChar); } } } if (!includeBaseDirectory || !flag) { return; } destination.CreateEntryFromDirectory(directoryInfo.FullName, directoryInfo.Name + Path.DirectorySeparatorChar); } }
/// <summary> /// Archives the files and directories from the specified directory, uses the specified compression level, and optionally includes the base directory. /// </summary> /// <param name="sourceDirectoryName">The path to the directory to be archived, specified as a relative or absolute path. A relative path is interpreted as relative to the current working directory.</param> /// <param name="includeBaseDirectory">true to include the directory name from <paramref name="sourceDirectoryName"/> at the root of the archive; false to include only the contents of the directory.</param> /// <param name="includeSubDirectories">true to include all subdirectories from <paramref name="sourceDirectoryName"/>; false to include only the contents of the top directory.</param> /// <exception cref="T:System.ArgumentException"><paramref name="sourceDirectoryName"/> is <see cref="F:System.String.Empty"/>, contains only white space, or contains at least one invalid character.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="sourceDirectoryName"/> is null.</exception> /// <exception cref="T:System.IO.PathTooLongException">In <paramref name="sourceDirectoryName"/> the specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must not exceed 248 characters, and file names must not exceed 260 characters.</exception> /// <exception cref="T:System.IO.DirectoryNotFoundException"><paramref name="sourceDirectoryName"/> is invalid or does not exist (for example, it is on an unmapped drive).</exception> /// <exception cref="T:System.NotSupportedException"><paramref name="sourceDirectoryName"/> contains an invalid format.-or-The zip archive does not support writing.</exception> public void CreateEntriesFromDirectory(string sourceDirectoryName, bool includeBaseDirectory, bool includeSubDirectories) { this.ThrowIfDisposed(); if (sourceDirectoryName == null) { throw new ArgumentNullException("sourceDirectoryName"); } if (this._mode == ZipArchiveMode.Read) { throw new NotSupportedException(CompressionConstants.CreateInReadMode); } sourceDirectoryName = Path.GetFullPath(sourceDirectoryName); if (!Directory.Exists(sourceDirectoryName)) { throw new DirectoryNotFoundException(sourceDirectoryName); } bool flag = true; DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirectoryName); string fullName = directoryInfo.FullName; if (includeBaseDirectory && directoryInfo.Parent != null) { fullName = directoryInfo.Parent.FullName; } List <FileSystemInfo> list = new List <FileSystemInfo>(); if (includeSubDirectories) { list.AddRange(directoryInfo.GetDirectories("*", SearchOption.AllDirectories)); list.AddRange(directoryInfo.GetFiles("*", SearchOption.AllDirectories)); } else { list.AddRange(directoryInfo.GetFiles("*", SearchOption.TopDirectoryOnly)); } foreach (FileSystemInfo fileSystemInfo in list) { flag = false; int length = fileSystemInfo.FullName.Length - fullName.Length; string entryName = fileSystemInfo.FullName.Substring(fullName.Length, length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (fileSystemInfo is FileInfo) { this.CreateEntryFromFile(fileSystemInfo.FullName, entryName); } else { DirectoryInfo possiblyEmptyDir = fileSystemInfo as DirectoryInfo; if (possiblyEmptyDir != null && ZipHelper.IsDirEmpty(possiblyEmptyDir)) { this.CreateEntryFromDirectory(possiblyEmptyDir.FullName, entryName + Path.DirectorySeparatorChar); } } } if (!includeBaseDirectory || !flag) { return; } this.CreateEntryFromDirectory(directoryInfo.FullName, directoryInfo.Name + Path.DirectorySeparatorChar); }
private void Init(Stream stream, ZipArchiveMode mode, bool leaveOpen) { Stream stream1 = null; try { this._backingStream = null; switch (mode) { case ZipArchiveMode.Read: if (!stream.CanRead) { throw new ArgumentException(CompressionConstants.ReadModeCapabilities); } if (!stream.CanSeek) { this._backingStream = stream; stream1 = stream = new MemoryStream(); ZipHelper.CopyStreamTo(this._backingStream, stream); stream.Seek(0L, SeekOrigin.Begin); break; } break; case ZipArchiveMode.Create: if (!stream.CanWrite) { throw new ArgumentException(CompressionConstants.CreateModeCapabilities); } break; case ZipArchiveMode.Update: if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek) { throw new ArgumentException(CompressionConstants.UpdateModeCapabilities); } break; default: throw new ArgumentOutOfRangeException("mode"); } this._mode = mode; this._archiveStream = stream; this._archiveStreamOwner = null; this._archiveReader = mode != ZipArchiveMode.Create ? new BinaryReader(stream) : null; this._entries = new List <ZipArchiveEntry>(); this._entriesCollection = new ReadOnlyCollection <ZipArchiveEntry>(this._entries); this._entriesDictionary = new Dictionary <string, ZipArchiveEntry>(); this._readEntries = false; this._leaveOpen = leaveOpen; this._centralDirectoryStart = 0L; this._isDisposed = false; this._numberOfThisDisk = 0U; this._archiveComment = null; switch (mode) { case ZipArchiveMode.Read: this.ReadEndOfCentralDirectory(); break; case ZipArchiveMode.Create: this._readEntries = true; break; default: if (this._archiveStream.Length == 0L) { this._readEntries = true; break; } this.ReadEndOfCentralDirectory(); this.EnsureCentralDirectoryRead(); using (List <ZipArchiveEntry> .Enumerator enumerator = this._entries.GetEnumerator()) { while (enumerator.MoveNext()) { enumerator.Current.ThrowIfNotOpenable(false, true); } break; } } } catch { if (stream1 != null) { stream1.Close(); } throw; } }
private bool WriteLocalFileHeader(bool isEmptyFile) { BinaryWriter binaryWriter = new BinaryWriter(this._archive.ArchiveStream); Zip64ExtraField zip64ExtraField = new Zip64ExtraField(); bool flag = false; uint num1; uint num2; if (isEmptyFile) { this.CompressionMethod = ZipArchiveEntry.CompressionMethodValues.Stored; num1 = 0U; num2 = 0U; } else if (this._archive.Mode == ZipArchiveMode.Create && !this._archive.ArchiveStream.CanSeek && !isEmptyFile) { this._generalPurposeBitFlag = this._generalPurposeBitFlag | ZipArchiveEntry.BitFlagValues.DataDescriptor; flag = false; num1 = 0U; num2 = 0U; } else if (this.SizesTooLarge()) { flag = true; num1 = uint.MaxValue; num2 = uint.MaxValue; zip64ExtraField.CompressedSize = new long?(this._compressedSize); zip64ExtraField.UncompressedSize = new long?(this._uncompressedSize); this.VersionToExtractAtLeast(ZipVersionNeededValues.Zip64); } else { flag = false; num1 = (uint)this._compressedSize; num2 = (uint)this._uncompressedSize; } this._offsetOfLocalHeader = binaryWriter.BaseStream.Position; int num3 = (flag ? (int)zip64ExtraField.TotalSize : 0) + (this._lhUnknownExtraFields != null ? ZipGenericExtraField.TotalSize(this._lhUnknownExtraFields) : 0); ushort num4; if (num3 > (int)ushort.MaxValue) { num4 = flag ? zip64ExtraField.TotalSize : (ushort)0; this._lhUnknownExtraFields = null; } else { num4 = (ushort)num3; } binaryWriter.Write(67324752U); binaryWriter.Write((ushort)this._versionToExtract); binaryWriter.Write((ushort)this._generalPurposeBitFlag); binaryWriter.Write((ushort)this.CompressionMethod); binaryWriter.Write(ZipHelper.DateTimeToDosTime(this._lastModified.DateTime)); binaryWriter.Write(this._crc32); binaryWriter.Write(num1); binaryWriter.Write(num2); binaryWriter.Write((ushort)this._storedEntryNameBytes.Length); binaryWriter.Write(num4); binaryWriter.Write(this._storedEntryNameBytes); if (flag) { zip64ExtraField.WriteBlock(this._archive.ArchiveStream); } if (this._lhUnknownExtraFields != null) { ZipGenericExtraField.WriteAllBlocks(this._lhUnknownExtraFields, this._archive.ArchiveStream); } return(flag); }
private byte[] EncodeEntryName(string entryName, out bool isUTF8) { Encoding encoding = this._archive == null || this._archive.EntryNameEncoding == null ? (ZipHelper.RequiresUnicode(entryName) ? Encoding.UTF8 : Encoding.GetEncoding(0)) : this._archive.EntryNameEncoding; isUTF8 = encoding is UTF8Encoding && encoding.Equals(Encoding.UTF8); return(encoding.GetBytes(entryName)); }
internal void WriteCentralDirectoryFileHeader() { BinaryWriter binaryWriter = new BinaryWriter(this._archive.ArchiveStream); Zip64ExtraField zip64ExtraField = new Zip64ExtraField(); bool flag = false; uint num1; uint num2; if (this.SizesTooLarge()) { flag = true; num1 = uint.MaxValue; num2 = uint.MaxValue; zip64ExtraField.CompressedSize = new long?(this._compressedSize); zip64ExtraField.UncompressedSize = new long?(this._uncompressedSize); } else { num1 = (uint)this._compressedSize; num2 = (uint)this._uncompressedSize; } uint num3; if (this._offsetOfLocalHeader > (long)uint.MaxValue) { flag = true; num3 = uint.MaxValue; zip64ExtraField.LocalHeaderOffset = new long?(this._offsetOfLocalHeader); } else { num3 = (uint)this._offsetOfLocalHeader; } if (flag) { this.VersionToExtractAtLeast(ZipVersionNeededValues.Zip64); } int num4 = (flag ? (int)zip64ExtraField.TotalSize : 0) + (this._cdUnknownExtraFields != null ? ZipGenericExtraField.TotalSize(this._cdUnknownExtraFields) : 0); ushort num5; if (num4 > (int)ushort.MaxValue) { num5 = flag ? zip64ExtraField.TotalSize : (ushort)0; this._cdUnknownExtraFields = null; } else { num5 = (ushort)num4; } binaryWriter.Write(33639248U); binaryWriter.Write((ushort)this._versionToExtract); binaryWriter.Write((ushort)this._versionToExtract); binaryWriter.Write((ushort)this._generalPurposeBitFlag); binaryWriter.Write((ushort)this.CompressionMethod); binaryWriter.Write(ZipHelper.DateTimeToDosTime(this._lastModified.DateTime)); binaryWriter.Write(this._crc32); binaryWriter.Write(num1); binaryWriter.Write(num2); binaryWriter.Write((ushort)this._storedEntryNameBytes.Length); binaryWriter.Write(num5); binaryWriter.Write(this._fileComment != null ? (ushort)this._fileComment.Length : (ushort)0); binaryWriter.Write((ushort)0); binaryWriter.Write((ushort)0); binaryWriter.Write((uint)this._externalFileAttributes); binaryWriter.Write(num3); binaryWriter.Write(this._storedEntryNameBytes); if (flag) { zip64ExtraField.WriteBlock(this._archive.ArchiveStream); } if (this._cdUnknownExtraFields != null) { ZipGenericExtraField.WriteAllBlocks(this._cdUnknownExtraFields, this._archive.ArchiveStream); } if (this._fileComment != null) { binaryWriter.Write(this._fileComment); } }