Пример #1
0
        /// <summary>
        /// Executes the logic for this workflow activity
        /// </summary>
        protected override void InternalExecute()
        {
            if (!string.IsNullOrEmpty(this.UseZip64WhenSaving.Get(this.ActivityContext)))
            {
                this.useZip64WhenSaving = (Zip64Option)Enum.Parse(typeof(Zip64Option), this.UseZip64WhenSaving.Get(this.ActivityContext));
            }

            switch (this.Action)
            {
            case ZipAction.Create:
                this.Create();
                break;

            case ZipAction.Extract:
                this.Extract();
                break;

            case ZipAction.AddFiles:
                this.AddFiles();
                break;

            default:
                throw new ArgumentException("Action not supported");
            }
        }
Пример #2
0
 private void _Init(Stream stream, bool leaveOpen, string name)
 {
     _outputStream              = (stream.CanRead ? stream : new CountingStream(stream));
     CompressionLevel           = CompressionLevel.Default;
     CompressionMethod          = CompressionMethod.Deflate;
     _encryption                = EncryptionAlgorithm.None;
     _entriesWritten            = new Dictionary <string, ZipEntry>(StringComparer.Ordinal);
     _zip64                     = Zip64Option.Default;
     _leaveUnderlyingStreamOpen = leaveOpen;
     Strategy                   = CompressionStrategy.Default;
     _name = (name ?? "(stream)");
 }
Пример #3
0
 private void _Init(Stream stream, bool leaveOpen, string name)
 {
     this._outputStream              = ((!stream.CanRead) ? new CountingStream(stream) : stream);
     this.CompressionLevel           = CompressionLevel.Default;
     this.CompressionMethod          = CompressionMethod.Deflate;
     this._encryption                = EncryptionAlgorithm.None;
     this._entriesWritten            = new Dictionary <string, ZipEntry>(StringComparer.Ordinal);
     this._zip64                     = Zip64Option.Default;
     this._leaveUnderlyingStreamOpen = leaveOpen;
     this.Strategy                   = CompressionStrategy.Default;
     this._name = (name ?? "(stream)");
     this.ParallelDeflateThreshold = -1L;
 }
Пример #4
0
        private void Test_SpannedZip64_Unzip_Compatibility(
            long fileSize,
            long spanSize,
            Zip64Option zip64Option,
            Action <string, string> unzipAction)
        {
            TestContext.WriteLine("Creating fodder files... {0}",
                                  DateTime.Now.ToString("G"));
            CreateSomeFiles();

            var file1Path = Path.Combine(_fodderDir, "1.dat");
            var file2Path = Path.Combine(_fodderDir, "2.dat");

            foreach (var filePath in new[] { file1Path, file2Path })
            {
                using (var file = File.Create(filePath))
                {
                    file.Seek(fileSize, SeekOrigin.Begin);
                    file.Write(new byte[] { 1 }, 0, 1);
                }
            }

            Directory.CreateDirectory("zip-output");
            var zipFilePath = Path.Combine("zip-output", "archive.zip");

            using (var zipFile = new ZipFile())
            {
                zipFile.UseZip64WhenSaving = zip64Option;
                // disable compression to make sure out 0-filled files would keep their size
                zipFile.CompressionLevel       = Zlib.CompressionLevel.None;
                zipFile.MaxOutputSegmentSize64 = spanSize;

                zipFile.AddFile(file1Path, "");
                zipFile.AddFile(file2Path, "");

                zipFile.Save(zipFilePath);
            }

            var extractDir = "extract";

            Directory.CreateDirectory(extractDir);

            unzipAction(zipFilePath, extractDir);

            string[] filesUnzipped = Directory.GetFiles(extractDir);
            Assert.AreEqual(2, filesUnzipped.Length, "Incorrect number of files extracted");
        }
Пример #5
0
        public static bool WriteCentralDirectoryStructure(Stream s,
                                                          ICollection<ZipEntry> entries,
                                                          uint numSegments,
                                                          Zip64Option zip64,
                                                          String comment,
                                                          System.Text.Encoding encoding)
        {
            var zss = s as ZipSegmentedStream;
            if (zss != null)
                zss.ContiguousWrite = true;

            // write to a memory stream in order to keep the
            // CDR contiguous
            var ms = new MemoryStream();

            foreach (ZipEntry e in entries)
            {
                if (e.IncludedInMostRecentSave)
                {
                    // this writes a ZipDirEntry corresponding to the ZipEntry
                    e.WriteCentralDirectoryEntry(ms);
                }
            }
            var a = ms.ToArray();
            s.Write(a, 0, a.Length);

            // We need to keep track of the start and
            // Finish of the Central Directory Structure.

            // Cannot always use WriteStream.Length or Position; some streams do
            // not support these. (eg, ASP.NET Response.OutputStream) In those
            // cases we have a CountingStream.

            // Also, we cannot just set Start as s.Position bfore the write, and Finish
            // as s.Position after the write.  In a split zip, the write may actually
            // flip to the next segment.  In that case, Start will be zero.  But we
            // don't know that til after we know the size of the thing to write.  So the
            // answer is to compute the directory, then ask the ZipSegmentedStream which
            // segment that directory would fall in, it it were written.  Then, include
            // that data into the directory, and finally, write the directory to the
            // output stream.

            var output = s as CountingStream;
            long Finish = (output != null) ? output.ComputedPosition : s.Position;  // BytesWritten
            long Start = Finish - a.Length;

            // need to know which segment the EOCD record starts in
            UInt32 startSegment = (zss != null)
                ? zss.CurrentSegment
                : 0;

            Int64 SizeOfCentralDirectory = Finish - Start;

            int countOfEntries = CountEntries(entries);

            bool needZip64CentralDirectory =
                zip64 == Zip64Option.Always ||
                countOfEntries >= 0xFFFF ||
                SizeOfCentralDirectory > 0xFFFFFFFF ||
                Start > 0xFFFFFFFF;

            byte[] a2 = null;

            // emit ZIP64 extensions as required
            if (needZip64CentralDirectory)
            {
                if (zip64 == Zip64Option.Never)
                {
#if NETCF
                    throw new ZipException("The archive requires a ZIP64 Central Directory. Consider enabling ZIP64 extensions.");
#else
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame(1);
                    if (sf.GetMethod().DeclaringType == typeof(ZipFile))
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipFile.UseZip64WhenSaving property.");
                    else
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipOutputStream.EnableZip64 property.");
#endif

                }

                a = GenZip64EndOfCentralDirectory(Start, Finish, countOfEntries, numSegments);
                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, encoding);
                if (startSegment != 0)
                {
                    UInt32 thisSegment = zss.ComputeSegment(a.Length + a2.Length);
                    int i = 16;
                    // number of this disk
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                    i += 4;
                    // number of the disk with the start of the central directory
                    //Array.Copy(BitConverter.GetBytes(startSegment), 0, a, i, 4);
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);

                    i = 60;
                    // offset 60
                    // number of the disk with the start of the zip64 eocd
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                    i += 4;
                    i += 8;

                    // offset 72
                    // total number of disks
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                }
                s.Write(a, 0, a.Length);
            }
            else
                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, encoding);


            // now, the regular footer
            if (startSegment != 0)
            {
                // The assumption is the central directory is never split across
                // segment boundaries.

                UInt16 thisSegment = (UInt16) zss.ComputeSegment(a2.Length);
                int i = 4;
                // number of this disk
                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
                i += 2;
                // number of the disk with the start of the central directory
                //Array.Copy(BitConverter.GetBytes((UInt16)startSegment), 0, a2, i, 2);
                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
                i += 2;
            }

            s.Write(a2, 0, a2.Length);

            // reset the contiguous write property if necessary
            if (zss != null)
                zss.ContiguousWrite = false;

            return needZip64CentralDirectory;
        }
Пример #6
0
        private static byte[] GenCentralDirectoryFooter(long StartOfCentralDirectory,
                                                        long EndOfCentralDirectory,
                                                        Zip64Option zip64,
                                                        int entryCount,
                                                        string comment,
                                                        ZipContainer container)
        {
            System.Text.Encoding encoding = GetEncoding(container, comment);
            int j            = 0;
            int bufferLength = 22;

            byte[] block         = null;
            Int16  commentLength = 0;

            if ((comment != null) && (comment.Length != 0))
            {
                block         = encoding.GetBytes(comment);
                commentLength = (Int16)block.Length;
            }
            bufferLength += commentLength;
            byte[] bytes = new byte[bufferLength];

            int i = 0;

            // signature
            byte[] sig = BitConverter.GetBytes(ZipConstants.EndOfCentralDirectorySignature);
            Array.Copy(sig, 0, bytes, i, 4);
            i += 4;

            // number of this disk
            // (this number may change later)
            bytes[i++] = 0;
            bytes[i++] = 0;

            // number of the disk with the start of the central directory
            // (this number may change later)
            bytes[i++] = 0;
            bytes[i++] = 0;

            // handle ZIP64 extensions for the end-of-central-directory
            if (entryCount >= 0xFFFF || zip64 == Zip64Option.Always)
            {
                // the ZIP64 version.
                for (j = 0; j < 4; j++)
                {
                    bytes[i++] = 0xFF;
                }
            }
            else
            {
                // the standard version.
                // total number of entries in the central dir on this disk
                bytes[i++] = (byte)(entryCount & 0x00FF);
                bytes[i++] = (byte)((entryCount & 0xFF00) >> 8);

                // total number of entries in the central directory
                bytes[i++] = (byte)(entryCount & 0x00FF);
                bytes[i++] = (byte)((entryCount & 0xFF00) >> 8);
            }

            // size of the central directory
            Int64 SizeOfCentralDirectory = EndOfCentralDirectory - StartOfCentralDirectory;

            if (SizeOfCentralDirectory >= 0xFFFFFFFF || StartOfCentralDirectory >= 0xFFFFFFFF)
            {
                // The actual data is in the ZIP64 central directory structure
                for (j = 0; j < 8; j++)
                {
                    bytes[i++] = 0xFF;
                }
            }
            else
            {
                // size of the central directory (we just get the low 4 bytes)
                bytes[i++] = (byte)(SizeOfCentralDirectory & 0x000000FF);
                bytes[i++] = (byte)((SizeOfCentralDirectory & 0x0000FF00) >> 8);
                bytes[i++] = (byte)((SizeOfCentralDirectory & 0x00FF0000) >> 16);
                bytes[i++] = (byte)((SizeOfCentralDirectory & 0xFF000000) >> 24);

                // offset of the start of the central directory (we just get the low 4 bytes)
                bytes[i++] = (byte)(StartOfCentralDirectory & 0x000000FF);
                bytes[i++] = (byte)((StartOfCentralDirectory & 0x0000FF00) >> 8);
                bytes[i++] = (byte)((StartOfCentralDirectory & 0x00FF0000) >> 16);
                bytes[i++] = (byte)((StartOfCentralDirectory & 0xFF000000) >> 24);
            }


            // zip archive comment
            if ((comment == null) || (comment.Length == 0))
            {
                // no comment!
                bytes[i++] = (byte)0;
                bytes[i++] = (byte)0;
            }
            else
            {
                // the size of our buffer defines the max length of the comment we can write
                if (commentLength + i + 2 > bytes.Length)
                {
                    commentLength = (Int16)(bytes.Length - i - 2);
                }
                bytes[i++] = (byte)(commentLength & 0x00FF);
                bytes[i++] = (byte)((commentLength & 0xFF00) >> 8);

                if (commentLength != 0)
                {
                    // now actually write the comment itself into the byte buffer
                    for (j = 0; (j < commentLength) && (i + j < bytes.Length); j++)
                    {
                        bytes[i + j] = block[j];
                    }
                    i += j;
                }
            }

            //   s.Write(bytes, 0, i);
            return(bytes);
        }
Пример #7
0
        public static bool WriteCentralDirectoryStructure(Stream s,
                                                          ICollection <ZipEntry> entries,
                                                          uint numSegments,
                                                          Zip64Option zip64,
                                                          String comment,
                                                          ZipContainer container)
        {
            var zss = s as ZipSegmentedStream;

            if (zss != null)
            {
                zss.ContiguousWrite = true;
            }

            // write to a memory stream in order to keep the
            // CDR contiguous
            Int64 aLength = 0;

            using (var ms = new MemoryStream())
            {
                foreach (ZipEntry e in entries)
                {
                    if (e.IncludedInMostRecentSave)
                    {
                        // this writes a ZipDirEntry corresponding to the ZipEntry
                        e.WriteCentralDirectoryEntry(ms);
                    }
                }
                var a = ms.ToArray();
                s.Write(a, 0, a.Length);
                aLength = a.Length;
            }


            // We need to keep track of the start and
            // Finish of the Central Directory Structure.

            // Cannot always use WriteStream.Length or Position; some streams do
            // not support these. (eg, ASP.NET Response.OutputStream) In those
            // cases we have a CountingStream.

            // Also, we cannot just set Start as s.Position bfore the write, and Finish
            // as s.Position after the write.  In a split zip, the write may actually
            // flip to the next segment.  In that case, Start will be zero.  But we
            // don't know that til after we know the size of the thing to write.  So the
            // answer is to compute the directory, then ask the ZipSegmentedStream which
            // segment that directory would fall in, it it were written.  Then, include
            // that data into the directory, and finally, write the directory to the
            // output stream.

            var  output = s as CountingStream;
            long Finish = (output != null) ? output.ComputedPosition : s.Position;  // BytesWritten
            long Start  = Finish - aLength;

            // need to know which segment the EOCD record starts in
            UInt32 startSegment = (zss != null)
                ? zss.CurrentSegment
                : 0;

            Int64 SizeOfCentralDirectory = Finish - Start;

            int countOfEntries = CountEntries(entries);

            bool needZip64CentralDirectory =
                zip64 == Zip64Option.Always ||
                countOfEntries >= 0xFFFF ||
                SizeOfCentralDirectory > 0xFFFFFFFF ||
                Start > 0xFFFFFFFF;

            byte[] a2 = null;

            // emit ZIP64 extensions as required
            if (needZip64CentralDirectory)
            {
                if (zip64 == Zip64Option.Never)
                {
#if NETCF
                    throw new ZipException("The archive requires a ZIP64 Central Directory. Consider enabling ZIP64 extensions.");
#else
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame(1);
                    if (sf.GetMethod().DeclaringType == typeof(ZipFile))
                    {
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipFile.UseZip64WhenSaving property.");
                    }
                    else
                    {
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipOutputStream.EnableZip64 property.");
                    }
#endif
                }

                var a = GenZip64EndOfCentralDirectory(Start, Finish, countOfEntries, numSegments);
                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, container);
                if (startSegment != 0)
                {
                    UInt32 thisSegment = zss.ComputeSegment(a.Length + a2.Length);
                    int    i           = 16;
                    // number of this disk
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                    i += 4;
                    // number of the disk with the start of the central directory
                    //Array.Copy(BitConverter.GetBytes(startSegment), 0, a, i, 4);
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);

                    i = 60;
                    // offset 60
                    // number of the disk with the start of the zip64 eocd
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                    i += 4;
                    i += 8;

                    // offset 72
                    // total number of disks
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                }
                s.Write(a, 0, a.Length);
            }
            else
            {
                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, container);
            }


            // now, the regular footer
            if (startSegment != 0)
            {
                // The assumption is the central directory is never split across
                // segment boundaries.

                UInt16 thisSegment = (UInt16)zss.ComputeSegment(a2.Length);
                int    i           = 4;
                // number of this disk
                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
                i += 2;
                // number of the disk with the start of the central directory
                //Array.Copy(BitConverter.GetBytes((UInt16)startSegment), 0, a2, i, 2);
                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
                i += 2;
            }

            s.Write(a2, 0, a2.Length);

            // reset the contiguous write property if necessary
            if (zss != null)
            {
                zss.ContiguousWrite = false;
            }

            return(needZip64CentralDirectory);
        }
Пример #8
0
        private void _ZOS_z64Over65534Entries
            (Zip64Option z64option,
             EncryptionAlgorithm encryption,
             Ionic.Zlib.CompressionLevel compression)
        {
            TestContext.WriteLine("_ZOS_z64Over65534Entries hello: {0}",
                                  DateTime.Now.ToString("G"));
            int fileCount = _rnd.Next(14616) + 65536;
            //int fileCount = _rnd.Next(146) + 5536;
            TestContext.WriteLine("entries: {0}", fileCount);
            var txrxLabel =
                String.Format("ZOS  #{0} 64({3}) E({1}) C({2})",
                              fileCount,
                              encryption.ToString(),
                              compression.ToString(),
                              z64option.ToString());

            TestContext.WriteLine("label: {0}", txrxLabel);
            string zipFileToCreate =
                String.Format("ZOS.Zip64.over65534.{0}.{1}.{2}.zip",
                              z64option.ToString(), encryption.ToString(),
                              compression.ToString());

            TestContext.WriteLine("zipFileToCreate: {0}", zipFileToCreate);

            _txrx = TestUtilities.StartProgressMonitor(zipFileToCreate,
                                                       txrxLabel, "starting up...");

            TestContext.WriteLine("generating {0} entries ", fileCount);
            _txrx.Send("pb 0 max 3"); // 2 stages: Write, Count, Verify
            _txrx.Send("pb 0 value 0");

            string password = Path.GetRandomFileName();

            string statusString = String.Format("status Encryption:{0} Compression:{1}",
                                                encryption.ToString(),
                                                compression.ToString());

            _txrx.Send(statusString);

            int dirCount = 0;

            using (FileStream fs = File.Create(zipFileToCreate))
            {
                using (var output = new ZipOutputStream(fs))
                {
                    _txrx.Send("test " + txrxLabel);
                    System.Threading.Thread.Sleep(400);
                    _txrx.Send("pb 1 max " + fileCount);
                    _txrx.Send("pb 1 value 0");

                    output.Password = password;
                    output.Encryption = encryption;
                    output.CompressionLevel = compression;
                    output.EnableZip64 = z64option;
                    for (int k = 0; k < fileCount; k++)
                    {
                        if (_rnd.Next(7) == 0)
                        {
                            // make it a directory
                            string entryName = String.Format("{0:D4}/", k);
                            output.PutNextEntry(entryName);
                            dirCount++;
                        }
                        else
                        {
                            string entryName = String.Format("{0:D4}.txt", k);
                            output.PutNextEntry(entryName);

                            // only a few entries are non-empty
                            if (_rnd.Next(18) == 0)
                            {
                                var block = TestUtilities.GenerateRandomAsciiString();
                                string content = String.Format("This is the content for entry #{0}.\n", k);
                                int n = _rnd.Next(4) + 1;
                                for (int j=0; j < n; j++)
                                    content+= block;

                                byte[] buffer = System.Text.Encoding.ASCII.GetBytes(content);
                                output.Write(buffer, 0, buffer.Length);
                            }
                        }
                        if (k % 1024 == 0)
                            _txrx.Send(String.Format("status saving ({0}/{1}) {2:N0}%",
                                                     k, fileCount,
                                                     ((double)k) / (0.01 * fileCount)));
                        else if (k % 256 == 0)
                            _txrx.Send("pb 1 value " + k);
                    }
                }
            }

            _txrx.Send("pb 1 max 1");
            _txrx.Send("pb 1 value 1");
            _txrx.Send("pb 0 step");

            System.Threading.Thread.Sleep(400);

            TestContext.WriteLine("Counting entries ... " + DateTime.Now.ToString("G"));
            _txrx.Send("status Counting entries...");
            Assert.AreEqual<int>
                (fileCount - dirCount,
                 TestUtilities.CountEntries(zipFileToCreate),
                 "{0}: The zip file created has the wrong number of entries.",
                 zipFileToCreate);
            _txrx.Send("pb 0 step");
            System.Threading.Thread.Sleep(140);

            // basic verify. The output is really large, so we pass emitOutput=false .
            _txrx.Send("status Verifying...");
            TestContext.WriteLine("Verifying ... " + DateTime.Now.ToString("G"));
            _numExtracted = 0;
            _numFilesToExtract = fileCount;
            _txrx.Send("pb 1 max " + fileCount);
            System.Threading.Thread.Sleep(200);
            _txrx.Send("pb 1 value 0");
            BasicVerifyZip(zipFileToCreate, password, false, Streams_ExtractProgress);
            _txrx.Send("pb 0 step");
            System.Threading.Thread.Sleep(800);
            TestContext.WriteLine("Done ... " + DateTime.Now.ToString("G"));
        }
Пример #9
0
        // Token: 0x0600051D RID: 1309 RVA: 0x00025244 File Offset: 0x00023444
        private static byte[] GenCentralDirectoryFooter(long StartOfCentralDirectory, long EndOfCentralDirectory, Zip64Option zip64, int entryCount, string comment, ZipContainer container)
        {
            Encoding encoding = ZipOutput.GetEncoding(container, comment);
            int      num      = 22;

            byte[] array = null;
            short  num2  = 0;

            if (comment != null && comment.Length != 0)
            {
                array = encoding.GetBytes(comment);
                num2  = (short)array.Length;
            }
            num += (int)num2;
            byte[] array2 = new byte[num];
            int    num3   = 0;

            byte[] bytes = BitConverter.GetBytes(101010256u);
            Array.Copy(bytes, 0, array2, num3, 4);
            num3          += 4;
            array2[num3++] = 0;
            array2[num3++] = 0;
            array2[num3++] = 0;
            array2[num3++] = 0;
            if (entryCount >= 65535 || zip64 == Zip64Option.Always)
            {
                for (int i = 0; i < 4; i++)
                {
                    array2[num3++] = byte.MaxValue;
                }
            }
            else
            {
                array2[num3++] = (byte)(entryCount & 255);
                array2[num3++] = (byte)((entryCount & 65280) >> 8);
                array2[num3++] = (byte)(entryCount & 255);
                array2[num3++] = (byte)((entryCount & 65280) >> 8);
            }
            long num4 = EndOfCentralDirectory - StartOfCentralDirectory;

            if (num4 >= (long)((ulong)-1) || StartOfCentralDirectory >= (long)((ulong)-1))
            {
                for (int i = 0; i < 8; i++)
                {
                    array2[num3++] = byte.MaxValue;
                }
            }
            else
            {
                array2[num3++] = (byte)(num4 & 255L);
                array2[num3++] = (byte)((num4 & 65280L) >> 8);
                array2[num3++] = (byte)((num4 & 16711680L) >> 16);
                array2[num3++] = (byte)((num4 & (long)((ulong)-16777216)) >> 24);
                array2[num3++] = (byte)(StartOfCentralDirectory & 255L);
                array2[num3++] = (byte)((StartOfCentralDirectory & 65280L) >> 8);
                array2[num3++] = (byte)((StartOfCentralDirectory & 16711680L) >> 16);
                array2[num3++] = (byte)((StartOfCentralDirectory & (long)((ulong)-16777216)) >> 24);
            }
            if (comment == null || comment.Length == 0)
            {
                array2[num3++] = 0;
                array2[num3++] = 0;
            }
            else
            {
                if ((int)num2 + num3 + 2 > array2.Length)
                {
                    num2 = (short)(array2.Length - num3 - 2);
                }
                array2[num3++] = (byte)(num2 & 255);
                array2[num3++] = (byte)(((int)num2 & 65280) >> 8);
                if (num2 != 0)
                {
                    int i = 0;
                    while (i < (int)num2 && num3 + i < array2.Length)
                    {
                        array2[num3 + i] = array[i];
                        i++;
                    }
                    num3 += i;
                }
            }
            return(array2);
        }
Пример #10
0
        // Token: 0x060005F6 RID: 1526 RVA: 0x00039A20 File Offset: 0x00037C20
        private static byte[] GenCentralDirectoryFooter(long StartOfCentralDirectory, long EndOfCentralDirectory, Zip64Option zip64, int entryCount, string comment, ZipContainer container)
        {
            Encoding encoding = ZipOutput.GetEncoding(container, comment);
            int      num      = 22;

            byte[] array = null;
            short  num2  = 0;

            if (comment != null && comment.Length != 0)
            {
                array = encoding.GetBytes(comment);
                num2  = (short)array.Length;
            }
            num += (int)num2;
            byte[] array2 = new byte[num];
            byte[] bytes  = BitConverter.GetBytes(101010256U);
            Array.Copy(bytes, 0, array2, 0, 4);
            array2[4] = 0;
            array2[5] = 0;
            array2[6] = 0;
            byte[] array3 = array2;
            int    num3   = 7;
            int    num4   = 8;

            array3[num3] = 0;
            if (entryCount < 65535)
            {
                if (zip64 != Zip64Option.Always)
                {
                    array2[num4++] = (byte)(entryCount & 255);
                    array2[num4++] = (byte)((entryCount & 65280) >> 8);
                    array2[num4++] = (byte)(entryCount & 255);
                    array2[num4++] = (byte)((entryCount & 65280) >> 8);
                    goto IL_F2;
                }
            }
            for (int i = 0; i < 4; i++)
            {
                array2[num4++] = byte.MaxValue;
            }
IL_F2:
            long num5 = EndOfCentralDirectory - StartOfCentralDirectory;

            if (num5 < 4294967295L && StartOfCentralDirectory < 4294967295L)
            {
                array2[num4++] = (byte)(num5 & 255L);
                array2[num4++] = (byte)((num5 & 65280L) >> 8);
                array2[num4++] = (byte)((num5 & 16711680L) >> 16);
                array2[num4++] = (byte)((num5 & 4278190080L) >> 24);
                array2[num4++] = (byte)(StartOfCentralDirectory & 255L);
                array2[num4++] = (byte)((StartOfCentralDirectory & 65280L) >> 8);
                array2[num4++] = (byte)((StartOfCentralDirectory & 16711680L) >> 16);
                array2[num4++] = (byte)((StartOfCentralDirectory & 4278190080L) >> 24);
            }
            else
            {
                for (int i = 0; i < 8; i++)
                {
                    array2[num4++] = byte.MaxValue;
                }
            }
            if (comment != null && comment.Length != 0)
            {
                if ((int)num2 + num4 + 2 > array2.Length)
                {
                    num2 = (short)(array2.Length - num4 - 2);
                }
                array2[num4++] = (byte)(num2 & 255);
                array2[num4++] = (byte)(((int)num2 & 65280) >> 8);
                if (num2 != 0)
                {
                    int i = 0;
                    while (i < (int)num2 && num4 + i < array2.Length)
                    {
                        array2[num4 + i] = array[i];
                        i++;
                    }
                    num4 += i;
                }
            }
            else
            {
                array2[num4++] = 0;
                array2[num4++] = 0;
            }
            return(array2);
        }
        public static bool WriteCentralDirectoryStructure(Stream s,
                                                          ICollection <ZipEntry> entries,
                                                          uint numSegments,
                                                          Zip64Option zip64,
                                                          String comment,
                                                          ZipContainer container)
        {
            var zss = s as ZipSegmentedStream;

            if (zss != null)
            {
                zss.ContiguousWrite = true;
            }

            // write to a memory stream in order to keep the
            // CDR contiguous
            Int64 aLength = 0;

            using (var ms = new MemoryStream())
            {
                foreach (ZipEntry e in entries)
                {
                    if (e.IncludedInMostRecentSave)
                    {
                        // this writes a ZipDirEntry corresponding to the ZipEntry
                        e.WriteCentralDirectoryEntry(ms);
                    }
                }
                var a = ms.ToArray();
                s.Write(a, 0, a.Length);
                aLength = a.Length;
            }


            var  output = s as CountingStream;
            long Finish = (output != null) ? output.ComputedPosition : s.Position;  // BytesWritten
            long Start  = Finish - aLength;

            // need to know which segment the EOCD record starts in
            UInt32 startSegment = (zss != null)
                ? zss.CurrentSegment
                : 0;

            Int64 SizeOfCentralDirectory = Finish - Start;

            int countOfEntries = CountEntries(entries);

            bool needZip64CentralDirectory =
                zip64 == Zip64Option.Always ||
                countOfEntries >= 0xFFFF ||
                SizeOfCentralDirectory > 0xFFFFFFFF ||
                Start > 0xFFFFFFFF;

            byte[] a2 = null;

            // emit ZIP64 extensions as required
            if (needZip64CentralDirectory)
            {
                if (zip64 == Zip64Option.Never)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame(1);
                    if (sf.GetMethod().DeclaringType == typeof(ZipFile))
                    {
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipFile.UseZip64WhenSaving property.");
                    }
                    else
                    {
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipOutputStream.EnableZip64 property.");
                    }
                }

                var a = GenZip64EndOfCentralDirectory(Start, Finish, countOfEntries, numSegments);
                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, container);
                if (startSegment != 0)
                {
                    UInt32 thisSegment = zss.ComputeSegment(a.Length + a2.Length);
                    int    i           = 16;
                    // number of this disk
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                    i += 4;
                    // number of the disk with the start of the central directory
                    //Array.Copy(BitConverter.GetBytes(startSegment), 0, a, i, 4);
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);

                    i = 60;
                    // offset 60
                    // number of the disk with the start of the zip64 eocd
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                    i += 4;
                    i += 8;

                    // offset 72
                    // total number of disks
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                }
                s.Write(a, 0, a.Length);
            }
            else
            {
                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, container);
            }


            // now, the regular footer
            if (startSegment != 0)
            {
                // The assumption is the central directory is never split across
                // segment boundaries.

                UInt16 thisSegment = (UInt16)zss.ComputeSegment(a2.Length);
                int    i           = 4;
                // number of this disk
                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
                i += 2;
                // number of the disk with the start of the central directory
                //Array.Copy(BitConverter.GetBytes((UInt16)startSegment), 0, a2, i, 2);
                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
                i += 2;
            }

            s.Write(a2, 0, a2.Length);

            // reset the contiguous write property if necessary
            if (zss != null)
            {
                zss.ContiguousWrite = false;
            }

            return(needZip64CentralDirectory);
        }
Пример #12
0
        /// <summary>
        /// Executes the logic for this workflow activity
        /// </summary>
        protected override void InternalExecute()
        {
            if (!string.IsNullOrEmpty(this.UseZip64WhenSaving.Get(this.ActivityContext)))
            {
                this.useZip64WhenSaving = (Zip64Option)Enum.Parse(typeof(Zip64Option), this.UseZip64WhenSaving.Get(this.ActivityContext));
            }

            switch (this.Action)
            {
                case ZipAction.Create:
                    this.Create();
                    break;
                case ZipAction.Extract:
                    this.Extract();
                    break;
                case ZipAction.AddFiles:
                    this.AddFiles();
                    break;
                default:
                    throw new ArgumentException("Action not supported");
            }
        }
Пример #13
0
 private void _Init(Stream stream, bool leaveOpen)
 {
     // workitem 9307
     _outputStream = stream.CanRead ? stream : new CountingStream(stream);
     CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
     _encryption = EncryptionAlgorithm.None;
     _entriesWritten = new Dictionary<String, ZipEntry>(StringComparer.Ordinal);
     _zip64 = Zip64Option.Never;
     _leaveUnderlyingStreamOpen = leaveOpen;
     Strategy = Ionic.Zlib.CompressionStrategy.Default;
     _name = "unknown";
     #if !NETCF
     ParallelDeflateThreshold = -1L;
     #endif
 }
Пример #14
0
        private static byte[] GenCentralDirectoryFooter(long StartOfCentralDirectory, long EndOfCentralDirectory, Zip64Option zip64, int entryCount, string comment, ZipContainer container)
        {
            Encoding encoding = GetEncoding(container, comment);
            int      num      = 0;
            int      num2     = 22;

            byte[] array = null;
            short  num3  = 0;

            if (comment != null && comment.Length != 0)
            {
                array = encoding.GetBytes(comment);
                num3  = (short)array.Length;
            }
            num2 += num3;
            byte[] array2 = new byte[num2];
            int    num4   = 0;

            byte[] bytes = BitConverter.GetBytes(101010256u);
            Array.Copy(bytes, 0, array2, num4, 4);
            num4          += 4;
            array2[num4++] = 0;
            array2[num4++] = 0;
            array2[num4++] = 0;
            array2[num4++] = 0;
            if (entryCount >= 65535 || zip64 == Zip64Option.Always)
            {
                for (num = 0; num < 4; num++)
                {
                    array2[num4++] = byte.MaxValue;
                }
            }
            else
            {
                array2[num4++] = (byte)(entryCount & 0xFF);
                array2[num4++] = (byte)((entryCount & 0xFF00) >> 8);
                array2[num4++] = (byte)(entryCount & 0xFF);
                array2[num4++] = (byte)((entryCount & 0xFF00) >> 8);
            }
            long num5 = EndOfCentralDirectory - StartOfCentralDirectory;

            if (num5 >= uint.MaxValue || StartOfCentralDirectory >= uint.MaxValue)
            {
                for (num = 0; num < 8; num++)
                {
                    array2[num4++] = byte.MaxValue;
                }
            }
            else
            {
                array2[num4++] = (byte)(num5 & 0xFF);
                array2[num4++] = (byte)((num5 & 0xFF00) >> 8);
                array2[num4++] = (byte)((num5 & 0xFF0000) >> 16);
                array2[num4++] = (byte)((num5 & 4278190080u) >> 24);
                array2[num4++] = (byte)(StartOfCentralDirectory & 0xFF);
                array2[num4++] = (byte)((StartOfCentralDirectory & 0xFF00) >> 8);
                array2[num4++] = (byte)((StartOfCentralDirectory & 0xFF0000) >> 16);
                array2[num4++] = (byte)((StartOfCentralDirectory & 4278190080u) >> 24);
            }
            if (comment == null || comment.Length == 0)
            {
                array2[num4++] = 0;
                array2[num4++] = 0;
            }
            else
            {
                if (num3 + num4 + 2 > array2.Length)
                {
                    num3 = (short)(array2.Length - num4 - 2);
                }
                array2[num4++] = (byte)(num3 & 0xFF);
                array2[num4++] = (byte)((num3 & 0xFF00) >> 8);
                if (num3 != 0)
                {
                    for (num = 0; num < num3 && num4 + num < array2.Length; num++)
                    {
                        array2[num4 + num] = array[num];
                    }
                    num4 += num;
                }
            }
            return(array2);
        }
Пример #15
0
        private static byte[] GenCentralDirectoryFooter(long StartOfCentralDirectory,
                                                        long EndOfCentralDirectory,
                                                        Zip64Option zip64,
                                                        int entryCount,
                                                        string comment,
                                                        System.Text.Encoding encoding)
        {
            int j = 0;
            int bufferLength = 22;
            byte[] block = null;
            Int16 commentLength = 0;
            if ((comment != null) && (comment.Length != 0))
            {
                block = encoding.GetBytes(comment);
                commentLength = (Int16)block.Length;
            }
            bufferLength += commentLength;
            byte[] bytes = new byte[bufferLength];

            int i = 0;
            // signature
            byte[] sig = BitConverter.GetBytes(ZipConstants.EndOfCentralDirectorySignature);
            Array.Copy(sig, 0, bytes, i, 4);
            i+=4;

            // number of this disk
            // (this number may change later)
            bytes[i++] = 0;
            bytes[i++] = 0;

            // number of the disk with the start of the central directory
            // (this number may change later)
            bytes[i++] = 0;
            bytes[i++] = 0;

            // handle ZIP64 extensions for the end-of-central-directory
            if (entryCount >= 0xFFFF || zip64 == Zip64Option.Always)
            {
                // the ZIP64 version.
                for (j = 0; j < 4; j++)
                    bytes[i++] = 0xFF;
            }
            else
            {
                // the standard version.
                // total number of entries in the central dir on this disk
                bytes[i++] = (byte)(entryCount & 0x00FF);
                bytes[i++] = (byte)((entryCount & 0xFF00) >> 8);

                // total number of entries in the central directory
                bytes[i++] = (byte)(entryCount & 0x00FF);
                bytes[i++] = (byte)((entryCount & 0xFF00) >> 8);
            }

            // size of the central directory
            Int64 SizeOfCentralDirectory = EndOfCentralDirectory - StartOfCentralDirectory;

            if (SizeOfCentralDirectory >= 0xFFFFFFFF || StartOfCentralDirectory >= 0xFFFFFFFF)
            {
                // The actual data is in the ZIP64 central directory structure
                for (j = 0; j < 8; j++)
                    bytes[i++] = 0xFF;
            }
            else
            {
                // size of the central directory (we just get the low 4 bytes)
                bytes[i++] = (byte)(SizeOfCentralDirectory & 0x000000FF);
                bytes[i++] = (byte)((SizeOfCentralDirectory & 0x0000FF00) >> 8);
                bytes[i++] = (byte)((SizeOfCentralDirectory & 0x00FF0000) >> 16);
                bytes[i++] = (byte)((SizeOfCentralDirectory & 0xFF000000) >> 24);

                // offset of the start of the central directory (we just get the low 4 bytes)
                bytes[i++] = (byte)(StartOfCentralDirectory & 0x000000FF);
                bytes[i++] = (byte)((StartOfCentralDirectory & 0x0000FF00) >> 8);
                bytes[i++] = (byte)((StartOfCentralDirectory & 0x00FF0000) >> 16);
                bytes[i++] = (byte)((StartOfCentralDirectory & 0xFF000000) >> 24);
            }


            // zip archive comment
            if ((comment == null) || (comment.Length == 0))
            {
                // no comment!
                bytes[i++] = (byte)0;
                bytes[i++] = (byte)0;
            }
            else
            {
                // the size of our buffer defines the max length of the comment we can write
                if (commentLength + i + 2 > bytes.Length) commentLength = (Int16)(bytes.Length - i - 2);
                bytes[i++] = (byte)(commentLength & 0x00FF);
                bytes[i++] = (byte)((commentLength & 0xFF00) >> 8);

                if (commentLength != 0)
                {
                    // now actually write the comment itself into the byte buffer
                    for (j = 0; (j < commentLength) && (i + j < bytes.Length); j++)
                    {
                        bytes[i + j] = block[j];
                    }
                    i += j;
                }
            }

            //   s.Write(bytes, 0, i);
            return bytes;
        }
Пример #16
0
        void _Zip64_Over65534Entries(Zip64Option z64option,
                                            EncryptionAlgorithm encryption,
                                            Ionic.Zlib.CompressionLevel compression)
        {
            // Emitting a zip file with > 65534 entries requires the use of ZIP64 in
            // the central directory.
            int numTotalEntries = _rnd.Next(4616)+65534;
            //int numTotalEntries = _rnd.Next(461)+6534;
            //int numTotalEntries = _rnd.Next(46)+653;
            string enc = encryption.ToString();
            if (enc.StartsWith("WinZip")) enc = enc.Substring(6);
            else if (enc.StartsWith("Pkzip")) enc = enc.Substring(0,5);
            string zipFileToCreate = String.Format("Zip64.ZF_Over65534.{0}.{1}.{2}.zip",
                                                   z64option.ToString(),
                                                   enc,
                                                   compression.ToString());

            _testTitle = String.Format("ZipFile #{0} 64({1}) E({2}), C({3})",
                                       numTotalEntries,
                                       z64option.ToString(),
                                       enc,
                                       compression.ToString());
            _txrx = TestUtilities.StartProgressMonitor(zipFileToCreate,
                                                       _testTitle,
                                                       "starting up...");

            _txrx.Send("pb 0 max 4"); // 3 stages: AddEntry, Save, Verify
            _txrx.Send("pb 0 value 0");

            string password = Path.GetRandomFileName();

            string statusString = String.Format("status Encrypt:{0} Compress:{1}...",
                                                enc,
                                                compression.ToString());

            int numSaved = 0;
            var saveProgress = new EventHandler<SaveProgressEventArgs>( (sender, e) => {
                    switch (e.EventType)
                    {
                        case ZipProgressEventType.Saving_Started:
                        _txrx.Send("status saving...");
                        _txrx.Send("pb 1 max " + numTotalEntries);
                        numSaved= 0;
                        break;

                        case ZipProgressEventType.Saving_AfterWriteEntry:
                        numSaved++;
                        if ((numSaved % 128) == 0)
                        {
                            _txrx.Send("pb 1 value " + numSaved);
                            _txrx.Send(String.Format("status Saving entry {0}/{1} ({2:N0}%)",
                                                     numSaved, numTotalEntries,
                                                     numSaved / (0.01 * numTotalEntries)
                                                     ));
                        }
                        break;

                        case ZipProgressEventType.Saving_Completed:
                        _txrx.Send("status Save completed");
                        _txrx.Send("pb 1 max 1");
                        _txrx.Send("pb 1 value 1");
                        break;
                    }
                });

            string contentFormatString =
                "This is the content for entry #{0}.\r\n\r\n" +
                "AAAAAAA BBBBBB AAAAA BBBBB AAAAA BBBBB AAAAA\r\n"+
                "AAAAAAA BBBBBB AAAAA BBBBB AAAAA BBBBB AAAAA\r\n";
            _txrx.Send(statusString);
            int dirCount= 0;
            using (var zip = new ZipFile())
            {
                _txrx.Send(String.Format("pb 1 max {0}", numTotalEntries));
                _txrx.Send("pb 1 value 0");

                zip.Password = password;
                zip.Encryption = encryption;
                zip.CompressionLevel = compression;
                zip.SaveProgress += saveProgress;
                zip.UseZip64WhenSaving = z64option;
                // save space when saving the file:
                zip.EmitTimesInWindowsFormatWhenSaving = false;
                zip.EmitTimesInUnixFormatWhenSaving = false;

                // add files:
                for (int m=0; m<numTotalEntries; m++)
                {
                    if (_rnd.Next(7)==0)
                    {
                        string entryName = String.Format("{0:D5}", m);
                        zip.AddDirectoryByName(entryName);
                        dirCount++;
                    }
                    else
                    {
                        string entryName = String.Format("{0:D5}.txt", m);
                        if (_rnd.Next(12)==0)
                        {
                            string contentBuffer = String.Format(contentFormatString, m);
                            byte[] buffer = System.Text.Encoding.ASCII.GetBytes(contentBuffer);
                            zip.AddEntry(entryName, contentBuffer);
                        }
                        else
                            zip.AddEntry(entryName, Stream.Null);
                    }

                    if (m % 1024 == 0)
                    {
                        _txrx.Send("pb 1 value " + m);
                        string msg = String.Format("status adding entry {0}/{1}  ({2:N0}%)",
                                            m, numTotalEntries, (m/(0.01*numTotalEntries)));
                        _txrx.Send(msg);
                    }
                }

                _txrx.Send("pb 0 step");
                _txrx.Send(statusString + " Saving...");
                zip.Save(zipFileToCreate);
            }

            _txrx.Send("pb 0 step");
            _txrx.Send("pb 1 value 0");
            _txrx.Send("status Reading...");

            // verify the zip by unpacking.
            _numFilesToExtract = numTotalEntries;
            _numExtracted= 1;
            _pb1Set = false;
            verb = "verify";
            BasicVerifyZip(zipFileToCreate, password, false, Zip64ExtractProgress);

            _txrx.Send("pb 0 step");
            _txrx.Send("status successful extract, now doing final count...");
            _txrx.Send("pb 1 value 0");
            Assert.AreEqual<int>(numTotalEntries-dirCount,
                                 TestUtilities.CountEntries(zipFileToCreate));
            _txrx.Send("pb 0 step");
        }
Пример #17
0
        // Token: 0x0600051B RID: 1307 RVA: 0x00024F38 File Offset: 0x00023138
        public static bool WriteCentralDirectoryStructure(Stream s, ICollection <ZipEntry> entries, uint numSegments, Zip64Option zip64, string comment, ZipContainer container)
        {
            ZipSegmentedStream zipSegmentedStream = s as ZipSegmentedStream;

            if (zipSegmentedStream != null)
            {
                zipSegmentedStream.ContiguousWrite = true;
            }
            long num = 0L;

            using (MemoryStream memoryStream = new MemoryStream())
            {
                foreach (ZipEntry zipEntry in entries)
                {
                    if (zipEntry.IncludedInMostRecentSave)
                    {
                        zipEntry.WriteCentralDirectoryEntry(memoryStream);
                    }
                }
                byte[] array = memoryStream.ToArray();
                s.Write(array, 0, array.Length);
                num = (long)array.Length;
            }
            CountingStream countingStream = s as CountingStream;
            long           num2           = (countingStream != null) ? countingStream.ComputedPosition : s.Position;
            long           num3           = num2 - num;
            uint           num4           = (zipSegmentedStream != null) ? zipSegmentedStream.CurrentSegment : 0u;
            long           num5           = num2 - num3;
            int            num6           = ZipOutput.CountEntries(entries);
            bool           flag           = zip64 == Zip64Option.Always || num6 >= 65535 || num5 > (long)((ulong)-1) || num3 > (long)((ulong)-1);

            byte[] array3;
            if (flag)
            {
                if (zip64 == Zip64Option.Default)
                {
                    StackFrame stackFrame = new StackFrame(1);
                    if (stackFrame.GetMethod().DeclaringType == typeof(ZipFile))
                    {
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipFile.UseZip64WhenSaving property.");
                    }
                    throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipOutputStream.EnableZip64 property.");
                }
                else
                {
                    byte[] array2 = ZipOutput.GenZip64EndOfCentralDirectory(num3, num2, num6, numSegments);
                    array3 = ZipOutput.GenCentralDirectoryFooter(num3, num2, zip64, num6, comment, container);
                    if (num4 != 0u)
                    {
                        uint value = zipSegmentedStream.ComputeSegment(array2.Length + array3.Length);
                        int  num7  = 16;
                        Array.Copy(BitConverter.GetBytes(value), 0, array2, num7, 4);
                        num7 += 4;
                        Array.Copy(BitConverter.GetBytes(value), 0, array2, num7, 4);
                        num7 = 60;
                        Array.Copy(BitConverter.GetBytes(value), 0, array2, num7, 4);
                        num7 += 4;
                        num7 += 8;
                        Array.Copy(BitConverter.GetBytes(value), 0, array2, num7, 4);
                    }
                    s.Write(array2, 0, array2.Length);
                }
            }
            else
            {
                array3 = ZipOutput.GenCentralDirectoryFooter(num3, num2, zip64, num6, comment, container);
            }
            if (num4 != 0u)
            {
                ushort value2 = (ushort)zipSegmentedStream.ComputeSegment(array3.Length);
                int    num8   = 4;
                Array.Copy(BitConverter.GetBytes(value2), 0, array3, num8, 2);
                num8 += 2;
                Array.Copy(BitConverter.GetBytes(value2), 0, array3, num8, 2);
                num8 += 2;
            }
            s.Write(array3, 0, array3.Length);
            if (zipSegmentedStream != null)
            {
                zipSegmentedStream.ContiguousWrite = false;
            }
            return(flag);
        }