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);
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        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;
            }
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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));
        }
Ejemplo n.º 8
0
        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);
            }
        }