Пример #1
0
        public override void Close()
        {
            internalReader = new ReadDataHandler(ReadingNotAvailable);
            crc = null;
            entry = null;

            base.Close();
        }
Пример #2
0
 public ZipUpdate(IStaticDataSource dataSource, ZipEntry entry)
 {
     command_ = UpdateCommand.Add;
     entry_ = entry;
     dataSource_ = dataSource;
 }
Пример #3
0
        /// <summary>
        /// Write a data descriptor.
        /// </summary>
        /// <param name="entry">The entry to write a descriptor for.</param>
        /// <returns>Returns the number of descriptor bytes written.</returns>
        public int WriteDataDescriptor(ZipEntry entry)
        {
            if (entry == null) {
                throw new ArgumentNullException("entry");
            }

            int result=0;

            // Add data descriptor if flagged as required
            if ((entry.Flags & (int)GeneralBitFlags.Descriptor) != 0)
            {
                // The signature is not PKZIP originally but is now described as optional
                // in the PKZIP Appnote documenting trhe format.
                WriteLEInt(ZipConstants.DataDescriptorSignature);
                WriteLEInt(unchecked((int)(entry.Crc)));

                result+=8;

                if (entry.LocalHeaderRequiresZip64)
                {
                    WriteLELong(entry.CompressedSize);
                    WriteLELong(entry.Size);
                    result+=16;
                }
                else
                {
                    WriteLEInt((int)entry.CompressedSize);
                    WriteLEInt((int)entry.Size);
                    result+=8;
                }
            }

            return result;
        }
Пример #4
0
        public ZipEntry GetNextEntry()
        {
            if (crc == null) {
                throw new InvalidOperationException("Closed.");
            }

            if (entry != null) {
                CloseEntry();
            }

            int header = inputBuffer.ReadLeInt();

            if (header == ZipConstants.CentralHeaderSignature ||
                header == ZipConstants.EndOfCentralDirectorySignature ||
                header == ZipConstants.CentralHeaderDigitalSignature ||
                header == ZipConstants.ArchiveExtraDataSignature ||
                header == ZipConstants.Zip64CentralFileHeaderSignature) {
                Close();
                return null;
            }

            if ( (header == ZipConstants.SpanningTempSignature) || (header == ZipConstants.SpanningSignature) ) {
                header = inputBuffer.ReadLeInt();
            }

            short versionRequiredToExtract = (short)inputBuffer.ReadLeShort();

            flags          = inputBuffer.ReadLeShort();
            method         = inputBuffer.ReadLeShort();
            uint dostime   = (uint)inputBuffer.ReadLeInt();
            int crc2       = inputBuffer.ReadLeInt();
            csize          = inputBuffer.ReadLeInt();
            size           = inputBuffer.ReadLeInt();
            int nameLen    = inputBuffer.ReadLeShort();
            int extraLen   = inputBuffer.ReadLeShort();

            bool isCrypted = (flags & 1) == 1;

            byte[] buffer = new byte[nameLen];
            inputBuffer.ReadRawBuffer(buffer);

            string name = ZipConstants.ConvertToStringExt(flags, buffer);

            entry = new ZipEntry(name, versionRequiredToExtract);
            entry.Flags = flags;

            entry.CompressionMethod = (CompressionMethod)method;

            if ((flags & 8) == 0) {
                entry.Crc  = crc2 & 0xFFFFFFFFL;
                entry.Size = size & 0xFFFFFFFFL;
                entry.CompressedSize = csize & 0xFFFFFFFFL;

                entry.CryptoCheckValue = (byte)((crc2 >> 24) & 0xff);

            } else {

                if (crc2 != 0) {
                    entry.Crc = crc2 & 0xFFFFFFFFL;
                }

                if (size != 0) {
                    entry.Size = size & 0xFFFFFFFFL;
                }

                if (csize != 0) {
                    entry.CompressedSize = csize & 0xFFFFFFFFL;
                }

                entry.CryptoCheckValue = (byte)((dostime >> 8) & 0xff);
            }

            entry.DosTime = dostime;

            if (extraLen > 0) {
                byte[] extra = new byte[extraLen];
                inputBuffer.ReadRawBuffer(extra);
                entry.ExtraData = extra;
            }

            entry.ProcessExtraData(true);
            if ( entry.CompressedSize >= 0 ) {
                csize = entry.CompressedSize;
            }

            if ( entry.Size >= 0 ) {
                size = entry.Size;
            }

            if (entry.IsCompressionMethodSupported()) {
                internalReader = new ReadDataHandler(InitialRead);
            } else {
                internalReader = new ReadDataHandler(ReadingNotSupported);
            }

            return entry;
        }
Пример #5
0
        Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry)
        {
            CryptoStream result = null;

            if ( (entry.Version < ZipConstants.VersionStrongEncryption)
                || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0) {
                PkzipClassicManaged classicManaged = new PkzipClassicManaged();

                OnKeysRequired(entry.Name);

                result = new CryptoStream(baseStream, classicManaged.CreateDecryptor(key, null), CryptoStreamMode.Read);
                CheckClassicPassword(result, entry);
            }
            else {
            #if !NET_1_1 && !NETCF_2_0
                if (entry.Version == ZipConstants.VERSION_AES) {
                    //
                    OnKeysRequired(entry.Name);
                    int saltLen = entry.AESSaltLen;
                    byte[] saltBytes = new byte[saltLen];
                    int saltIn = baseStream.Read(saltBytes, 0, saltLen);
                    byte[] pwdVerifyRead = new byte[2];
                    baseStream.Read(pwdVerifyRead, 0, 2);
                    int blockSize = entry.AESKeySize / 8;	// bits to bytes

                    ZipAESTransform decryptor = new ZipAESTransform(rawPassword_, saltBytes, blockSize, false);
                    byte[] pwdVerifyCalc = decryptor.PwdVerifier;
                    if (pwdVerifyCalc[0] != pwdVerifyRead[0] || pwdVerifyCalc[1] != pwdVerifyRead[1])
                        throw new Exception("Invalid password for AES");
                    result = new ZipAESStream(baseStream, decryptor, CryptoStreamMode.Read);
                }
                else
            #endif
                {
                }
            }

            return result;
        }
Пример #6
0
        /// <summary>
        /// Get a <see cref="Stream"/> providing data for an entry.
        /// </summary>
        /// <param name="entry">The entry to provide data for.</param>
        /// <param name="name">The file name for data if known.</param>
        /// <returns>Returns a stream providing data; or null if not available</returns>
        public Stream GetSource(ZipEntry entry, string name)
        {
            Stream result = null;

            if ( name != null ) {
                result = File.Open(name, FileMode.Open, FileAccess.Read, FileShare.Read);
            }

            return result;
        }
Пример #7
0
        /// <summary>
        /// Search for and read the central directory of a zip file filling the entries array.
        /// </summary>
        /// <exception cref="System.IO.IOException">
        /// An i/o error occurs.
        /// </exception>
        /// <exception cref="Mikolaytis.Unzip.Zip.ZipException">
        /// The central directory is malformed or cannot be found
        /// </exception>
        void ReadEntries()
        {
            // Search for the End Of Central Directory.  When a zip comment is
            // present the directory will start earlier
            //
            // The search is limited to 64K which is the maximum size of a trailing comment field to aid speed.
            // This should be compatible with both SFX and ZIP files but has only been tested for Zip files
            // If a SFX file has the Zip data attached as a resource and there are other resources occuring later then
            // this could be invalid.
            // Could also speed this up by reading memory in larger blocks.

            long locatedEndOfCentralDir = LocateBlockWithSignature(ZipConstants.EndOfCentralDirectorySignature,
                baseStream_.Length, ZipConstants.EndOfCentralRecordBaseSize, 0xffff);

            // Read end of central directory record
            ushort thisDiskNumber           = ReadLEUshort();
            ushort startCentralDirDisk      = ReadLEUshort();
            ulong entriesForThisDisk        = ReadLEUshort();
            ulong entriesForWholeCentralDir = ReadLEUshort();
            ulong centralDirSize            = ReadLEUint();
            long offsetOfCentralDir         = ReadLEUint();
            uint commentSize                = ReadLEUshort();

            if ( commentSize > 0 ) {
                byte[] comment = new byte[commentSize];

                StreamUtils.ReadFully(baseStream_, comment);
                comment_ = ZipConstants.ConvertToString(comment);
            }
            else {
                comment_ = string.Empty;
            }

            bool isZip64 = false;

            // Check if zip64 header information is required.
            if ( (thisDiskNumber == 0xffff) ||
                (startCentralDirDisk == 0xffff) ||
                (entriesForThisDisk == 0xffff) ||
                (entriesForWholeCentralDir == 0xffff) ||
                (centralDirSize == 0xffffffff) ||
                (offsetOfCentralDir == 0xffffffff) ) {
                isZip64 = true;

                long offset = LocateBlockWithSignature(ZipConstants.Zip64CentralDirLocatorSignature, locatedEndOfCentralDir, 0, 0x1000);

                // number of the disk with the start of the zip64 end of central directory 4 bytes
                // relative offset of the zip64 end of central directory record 8 bytes
                // total number of disks 4 bytes
                ReadLEUint(); // startDisk64 is not currently used
                ulong offset64 = ReadLEUlong();
                uint totalDisks = ReadLEUint();

                baseStream_.Position = (long)offset64;
                long sig64 = ReadLEUint();

                // NOTE: Record size = SizeOfFixedFields + SizeOfVariableData - 12.
                ulong recordSize = ReadLEUlong();
                int versionMadeBy = ReadLEUshort();
                int versionToExtract = ReadLEUshort();
                uint thisDisk = ReadLEUint();
                uint centralDirDisk = ReadLEUint();
                entriesForThisDisk = ReadLEUlong();
                entriesForWholeCentralDir = ReadLEUlong();
                centralDirSize = ReadLEUlong();
                offsetOfCentralDir = (long)ReadLEUlong();

                // NOTE: zip64 extensible data sector (variable size) is ignored.
            }

            entries_ = new ZipEntry[entriesForThisDisk];

            // SFX/embedded support, find the offset of the first entry vis the start of the stream
            // This applies to Zip files that are appended to the end of an SFX stub.
            // Or are appended as a resource to an executable.
            // Zip files created by some archivers have the offsets altered to reflect the true offsets
            // and so dont require any adjustment here...
            // TODO: Difficulty with Zip64 and SFX offset handling needs resolution - maths?
            if ( !isZip64 && (offsetOfCentralDir < locatedEndOfCentralDir - (4 + (long)centralDirSize)) ) {
                offsetOfFirstEntry = locatedEndOfCentralDir - (4 + (long)centralDirSize + offsetOfCentralDir);
            }

            baseStream_.Seek(offsetOfFirstEntry + offsetOfCentralDir, SeekOrigin.Begin);

            for (ulong i = 0; i < entriesForThisDisk; i++) {

                int versionMadeBy      = ReadLEUshort();
                int versionToExtract   = ReadLEUshort();
                int bitFlags           = ReadLEUshort();
                int method             = ReadLEUshort();
                uint dostime           = ReadLEUint();
                uint crc               = ReadLEUint();
                long csize             = (long)ReadLEUint();
                long size              = (long)ReadLEUint();
                int nameLen            = ReadLEUshort();
                int extraLen           = ReadLEUshort();
                int commentLen         = ReadLEUshort();

                int diskStartNo        = ReadLEUshort();  // Not currently used
                int internalAttributes = ReadLEUshort();  // Not currently used

                uint externalAttributes = ReadLEUint();
                long offset             = ReadLEUint();

                byte[] buffer = new byte[Math.Max(nameLen, commentLen)];

                StreamUtils.ReadFully(baseStream_, buffer, 0, nameLen);
                string name = ZipConstants.ConvertToStringExt(bitFlags, buffer, nameLen);

                ZipEntry entry = new ZipEntry(name, versionToExtract, versionMadeBy, (CompressionMethod)method);
                entry.Crc = crc & 0xffffffffL;
                entry.Size = size & 0xffffffffL;
                entry.CompressedSize = csize & 0xffffffffL;
                entry.Flags = bitFlags;
                entry.DosTime = (uint)dostime;
                entry.ZipFileIndex = (long)i;
                entry.Offset = offset;
                entry.ExternalFileAttributes = (int)externalAttributes;

                if ((bitFlags & 8) == 0) {
                    entry.CryptoCheckValue = (byte)(crc >> 24);
                }
                else {
                    entry.CryptoCheckValue = (byte)((dostime >> 8) & 0xff);
                }

                if (extraLen > 0) {
                    byte[] extra = new byte[extraLen];
                    StreamUtils.ReadFully(baseStream_, extra);
                    entry.ExtraData = extra;
                }

                entry.ProcessExtraData(false);

                if (commentLen > 0) {
                    StreamUtils.ReadFully(baseStream_, buffer, 0, commentLen);
                    entry.Comment = ZipConstants.ConvertToStringExt(bitFlags, buffer, commentLen);
                }

                entries_[i] = entry;
            }
        }
Пример #8
0
 /// <summary>
 /// Copy an existing entry.
 /// </summary>
 /// <param name="entry">The existing entry to copy.</param>
 public ZipUpdate(ZipEntry entry)
     : this(UpdateCommand.Copy, entry)
 {
     // Do nothing.
 }
Пример #9
0
        /// <summary>
        /// Get an output stream for the specified <see cref="ZipEntry"/>
        /// </summary>
        /// <param name="entry">The entry to get an output stream for.</param>
        /// <returns>The output stream obtained for the entry.</returns>
        Stream GetOutputStream(ZipEntry entry)
        {
            Stream result = baseStream_;

            if ( entry.IsCrypted == true ) {
            #if NETCF_1_0
                throw new ZipException("Encryption not supported for Compact Framework 1.0");
            #else
                result = CreateAndInitEncryptionStream(result, entry);
            #endif
            }

            switch ( entry.CompressionMethod ) {
                case CompressionMethod.Stored:
                    result = new UncompressedStream(result);
                    break;

                case CompressionMethod.Deflated:
                    DeflaterOutputStream dos = new DeflaterOutputStream(result, new Deflater(9, true));
                    dos.IsStreamOwner = false;
                    result = dos;
                    break;

            }
            return result;
        }
Пример #10
0
 /// <summary>
 /// Locate the data for a given entry.
 /// </summary>
 /// <returns>
 /// The start offset of the data.
 /// </returns>
 /// <exception cref="System.IO.EndOfStreamException">
 /// The stream ends prematurely
 /// </exception>
 /// <exception cref="Mikolaytis.Unzip.Zip.ZipException">
 /// The local header signature is invalid, the entry and central header file name lengths are different
 /// or the local and entry compression methods dont match
 /// </exception>
 long LocateEntry(ZipEntry entry)
 {
     return TestLocalHeader(entry, HeaderTest.Extract);
 }
Пример #11
0
        int FindExistingUpdate(ZipEntry entry)
        {
            int result = -1;
            string convertedName = GetTransformedFileName(entry.Name);

            if (updateIndex_.ContainsKey(convertedName)) {
                result = (int)updateIndex_[convertedName];
            }
            /*
            // This is slow like the coming of the next ice age but takes less storage and may be useful
            // for CF?
            for (int index = 0; index < updates_.Count; ++index)
            {
                ZipUpdate zu = ( ZipUpdate )updates_[index];
                if ( (zu.Entry.ZipFileIndex == entry.ZipFileIndex) &&
                    (string.Compare(convertedName, zu.Entry.Name, true, CultureInfo.InvariantCulture) == 0) ) {
                    result = index;
                    break;
                }
            }
             */
            return result;
        }
Пример #12
0
        /// <summary>
        /// Gets an input stream for reading the given zip entry data in an uncompressed form.
        /// Normally the <see cref="ZipEntry"/> should be an entry returned by GetEntry().
        /// </summary>
        /// <param name="entry">The <see cref="ZipEntry"/> to obtain a data <see cref="Stream"/> for</param>
        /// <returns>An input <see cref="Stream"/> containing data for this <see cref="ZipEntry"/></returns>
        /// <exception cref="ObjectDisposedException">
        /// The ZipFile has already been closed
        /// </exception>
        /// <exception cref="Mikolaytis.Unzip.Zip.ZipException">
        /// The compression method for the entry is unknown
        /// </exception>
        /// <exception cref="IndexOutOfRangeException">
        /// The entry is not found in the ZipFile
        /// </exception>
        public Stream GetInputStream(ZipEntry entry)
        {
            if ( entry == null ) {
                throw new ArgumentNullException("entry");
            }

            if ( isDisposed_ ) {
                throw new ObjectDisposedException("ZipFile");
            }

            long index = entry.ZipFileIndex;
            if ( (index < 0) || (index >= entries_.Length) || (entries_[index].Name != entry.Name) ) {
                index = FindEntry(entry.Name, true);
                if (index < 0) {
                }
            }
            return GetInputStream(index);
        }
Пример #13
0
        /// <summary>
        /// Delete a <see cref="ZipEntry"/> from the archive.
        /// </summary>
        /// <param name="entry">The entry to delete.</param>
        public void Delete(ZipEntry entry)
        {
            if ( entry == null ) {
                throw new ArgumentNullException("entry");
            }

            CheckUpdating();

            int index = FindExistingUpdate(entry);
            if ( index >= 0 ) {
                contentsEdited_ = true;
                updates_[index] = null;
                updateCount_ -= 1;
            }
            else {
            }
        }
Пример #14
0
        /// <summary>
        /// Add a <see cref="ZipEntry"/> that contains no data.
        /// </summary>
        /// <param name="entry">The entry to add.</param>
        /// <remarks>This can be used to add directories, volume labels, or empty file entries.</remarks>
        public void Add(ZipEntry entry)
        {
            if ( entry == null ) {
                throw new ArgumentNullException("entry");
            }

            CheckUpdating();

            AddUpdate(new ZipUpdate(UpdateCommand.Add, entry));
        }
Пример #15
0
        /// <summary>
        /// Test a local header against that provided from the central directory
        /// </summary>
        /// <param name="entry">
        /// The entry to test against
        /// </param>
        /// <param name="tests">The type of <see cref="HeaderTest">tests</see> to carry out.</param>
        /// <returns>The offset of the entries data in the file</returns>
        long TestLocalHeader(ZipEntry entry, HeaderTest tests)
        {
            lock(baseStream_)
            {
                bool testHeader = (tests & HeaderTest.Header) != 0;
                bool testData = (tests & HeaderTest.Extract) != 0;

                baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin);
                if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature) {
                }

                short extractVersion = ( short )ReadLEUshort();
                short localFlags = ( short )ReadLEUshort();
                short compressionMethod = ( short )ReadLEUshort();
                short fileTime = ( short )ReadLEUshort();
                short fileDate = ( short )ReadLEUshort();
                uint crcValue = ReadLEUint();
                long compressedSize = ReadLEUint();
                long size = ReadLEUint();
                int storedNameLength = ReadLEUshort();
                int extraDataLength = ReadLEUshort();

                byte[] nameData = new byte[storedNameLength];
                StreamUtils.ReadFully(baseStream_, nameData);

                byte[] extraData = new byte[extraDataLength];
                StreamUtils.ReadFully(baseStream_, extraData);

                ZipExtraData localExtraData = new ZipExtraData(extraData);

                // Extra data / zip64 checks
                if (localExtraData.Find(1))
                {
                    // 2010-03-04 Forum 10512: removed checks for version >= ZipConstants.VersionZip64
                    // and size or compressedSize = MaxValue, due to rogue creators.

                    size = localExtraData.ReadLong();
                    compressedSize = localExtraData.ReadLong();

                    if ((localFlags & (int)GeneralBitFlags.Descriptor) != 0)
                    {
                        // These may be valid if patched later
                        if ( (size != -1) && (size != entry.Size)) {
                        }

                        if ((compressedSize != -1) && (compressedSize != entry.CompressedSize)) {
                        }
                    }
                }
                else
                {
                    // No zip64 extra data but entry requires it.
                    if ((extractVersion >= ZipConstants.VersionZip64) &&
                        (((uint)size == uint.MaxValue) || ((uint)compressedSize == uint.MaxValue)))
                    {
                    }
                }

                if ( testData ) {
                    if ( entry.IsFile ) {
                        if ( !entry.IsCompressionMethodSupported() ) {
                        }

                        if ( (extractVersion > ZipConstants.VersionMadeBy)
                            || ((extractVersion > 20) && (extractVersion < ZipConstants.VersionZip64)) ) {
                        }

                        if ( (localFlags & ( int )(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0 ) {

                        }
                    }
                }

                if (testHeader)
                {

                    // Name data has already been read convert it and compare.
                    string localName = ZipConstants.ConvertToStringExt(localFlags, nameData);

                    // Directories have zero actual size but can have compressed size
                    if (entry.IsDirectory)
                    {
                        // There may be other cases where the compressed size can be greater than this?
                        // If so until details are known we will be strict.
                        if (entry.IsCrypted)
                        {

                        }
                        else if (compressedSize > 2)
                        {
                        }
                    }
                }

                // Tests that apply to both data and header.

                // Size can be verified only if it is known in the local header.
                // it will always be known in the central header.

                int extraLength = storedNameLength + extraDataLength;
                return offsetOfFirstEntry + entry.Offset + ZipConstants.LocalHeaderBaseSize + extraLength;
            }
        }
Пример #16
0
 public ZipUpdate(UpdateCommand command, ZipEntry entry)
 {
     command_ = command;
     entry_ = ( ZipEntry )entry.Clone();
 }
Пример #17
0
        int WriteCentralDirectoryHeader(ZipEntry entry)
        {
            // Write the central file header
            WriteLEInt(ZipConstants.CentralHeaderSignature);

            // Version made by
            WriteLEShort(ZipConstants.VersionMadeBy);

            // Version required to extract
            WriteLEShort(entry.Version);

            WriteLEShort(entry.Flags);

            unchecked {
                WriteLEShort((byte)entry.CompressionMethod);
                WriteLEInt((int)entry.DosTime);
                WriteLEInt((int)entry.Crc);
            }

            if ( (entry.IsZip64Forced()) || (entry.CompressedSize >= 0xffffffff) ) {
                WriteLEInt(-1);
            }
            else {
                WriteLEInt((int)(entry.CompressedSize & 0xffffffff));
            }

            if ( (entry.IsZip64Forced()) || (entry.Size >= 0xffffffff) ) {
                WriteLEInt(-1);
            }
            else {
                WriteLEInt((int)entry.Size);
            }

            byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name);

            WriteLEShort(name.Length);

            // Central header extra data is different to local header version so regenerate.
            ZipExtraData ed = new ZipExtraData(entry.ExtraData);

            if ( entry.CentralHeaderRequiresZip64 ) {
                ed.StartNewEntry();

                if ( (entry.Size >= 0xffffffff) || (useZip64_ == UseZip64.On) )
                {
                    ed.AddLeLong(entry.Size);
                }

                if ( (entry.CompressedSize >= 0xffffffff) || (useZip64_ == UseZip64.On) )
                {
                    ed.AddLeLong(entry.CompressedSize);
                }

                if ( entry.Offset >= 0xffffffff ) {
                    ed.AddLeLong(entry.Offset);
                }

                // Number of disk on which this file starts isnt supported and is never written here.
                ed.AddNewEntry(1);
            }
            else {
                // Should have already be done when local header was added.
                ed.Delete(1);
            }

            byte[] centralExtraData = ed.GetEntryData();

            WriteLEShort(centralExtraData.Length);
            WriteLEShort(entry.Comment != null ? entry.Comment.Length : 0);

            WriteLEShort(0);	// disk number
            WriteLEShort(0);	// internal file attributes

            // External file attributes...
            if ( entry.ExternalFileAttributes != -1 ) {
                WriteLEInt(entry.ExternalFileAttributes);
            }
            else {
                if ( entry.IsDirectory ) {
                    WriteLEUint(16);
                }
                else {
                    WriteLEUint(0);
                }
            }

            if ( entry.Offset >= 0xffffffff ) {
                WriteLEUint(0xffffffff);
            }
            else {
                WriteLEUint((uint)(int)entry.Offset);
            }

            if ( name.Length > 0 ) {
                baseStream_.Write(name, 0, name.Length);
            }

            if ( centralExtraData.Length > 0 ) {
                baseStream_.Write(centralExtraData, 0, centralExtraData.Length);
            }

            byte[] rawComment = (entry.Comment != null) ? Encoding.ASCII.GetBytes(entry.Comment) : new byte[0];

            if ( rawComment.Length > 0 ) {
                baseStream_.Write(rawComment, 0, rawComment.Length);
            }

            return ZipConstants.CentralHeaderBaseSize + name.Length + centralExtraData.Length + rawComment.Length;
        }
Пример #18
0
        //        TBD: Direct form of updating
        //
        //        public void Update(IEntryMatcher deleteMatcher)
        //        {
        //        }
        //
        //        public void Update(IScanner addScanner)
        //        {
        //        }
        /* Modify not yet ready for public consumption.
           Direct modification of an entry should not overwrite original data before its read.
           Safe mode is trivial in this sense.
        public void Modify(ZipEntry original, ZipEntry updated)
        {
            if ( original == null ) {
                throw new ArgumentNullException("original");
            }

            if ( updated == null ) {
                throw new ArgumentNullException("updated");
            }

            CheckUpdating();
            contentsEdited_ = true;
            updates_.Add(new ZipUpdate(original, updated));
        }
        */

        #endregion Other

        #if !NETCF_1_0

        static void CheckClassicPassword(CryptoStream classicCryptoStream, ZipEntry entry)
        {
            byte[] cryptbuffer = new byte[ZipConstants.CryptoHeaderSize];
            StreamUtils.ReadFully(classicCryptoStream, cryptbuffer);
        }
Пример #19
0
 public ZipEntryEnumerator(ZipEntry[] entries)
 {
     array = entries;
 }
Пример #20
0
        Stream CreateAndInitEncryptionStream(Stream baseStream, ZipEntry entry)
        {
            CryptoStream result = null;
            if ( (entry.Version < ZipConstants.VersionStrongEncryption)
                || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0) {
                PkzipClassicManaged classicManaged = new PkzipClassicManaged();

                OnKeysRequired(entry.Name);

                // Closing a CryptoStream will close the base stream as well so wrap it in an UncompressedStream
                // which doesnt do this.
                result = new CryptoStream(new UncompressedStream(baseStream),
                    classicManaged.CreateEncryptor(key, null), CryptoStreamMode.Write);

                if ( (entry.Crc < 0) || (entry.Flags & 8) != 0) {
                    WriteEncryptionHeader(result, entry.DosTime << 16);
                }
                else {
                    WriteEncryptionHeader(result, entry.Crc);
                }
            }
            return result;
        }
Пример #21
0
 public ZipUpdate(string fileName, ZipEntry entry)
 {
     command_ = UpdateCommand.Add;
     entry_ = entry;
     filename_ = fileName;
 }
Пример #22
0
 internal void SetEntry(ZipEntry entry)
 {
     entry_ = entry;
     entryValid_ = true;
     bytesTested_ = 0;
 }
Пример #23
0
 public ZipUpdate(string fileName, string entryName, CompressionMethod compressionMethod)
 {
     command_ = UpdateCommand.Add;
     entry_ = new ZipEntry(entryName);
     entry_.CompressionMethod = compressionMethod;
     filename_ = fileName;
 }
Пример #24
0
        // Write the local file header
        // TODO: ZipHelperStream.WriteLocalHeader is not yet used and needs checking for ZipFile and ZipOuptutStream usage
        void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData)
        {
            CompressionMethod method = entry.CompressionMethod;
            bool headerInfoAvailable = true; // How to get this?
            bool patchEntryHeader = false;

            WriteLEInt(ZipConstants.LocalHeaderSignature);

            WriteLEShort(entry.Version);
            WriteLEShort(entry.Flags);
            WriteLEShort((byte)method);
            WriteLEInt((int)entry.DosTime);

            if (headerInfoAvailable == true) {
                WriteLEInt((int)entry.Crc);
                if ( entry.LocalHeaderRequiresZip64 ) {
                    WriteLEInt(-1);
                    WriteLEInt(-1);
                }
                else {
                    WriteLEInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize);
                    WriteLEInt((int)entry.Size);
                }
            } else {
                if (patchData != null) {
                    patchData.CrcPatchOffset = stream_.Position;
                }
                WriteLEInt(0);	// Crc

                if ( patchData != null ) {
                    patchData.SizePatchOffset = stream_.Position;
                }

                // For local header both sizes appear in Zip64 Extended Information
                if ( entry.LocalHeaderRequiresZip64 && patchEntryHeader ) {
                    WriteLEInt(-1);
                    WriteLEInt(-1);
                }
                else {
                    WriteLEInt(0);	// Compressed size
                    WriteLEInt(0);	// Uncompressed size
                }
            }

            byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name);

            ZipExtraData ed = new ZipExtraData(entry.ExtraData);

            if (entry.LocalHeaderRequiresZip64 && (headerInfoAvailable || patchEntryHeader)) {
                ed.StartNewEntry();
                if (headerInfoAvailable) {
                    ed.AddLeLong(entry.Size);
                    ed.AddLeLong(entry.CompressedSize);
                }
                else {
                    ed.AddLeLong(-1);
                    ed.AddLeLong(-1);
                }
                ed.AddNewEntry(1);

                if ( patchData != null ) {
                    patchData.SizePatchOffset = ed.CurrentReadIndex;
                }
            }
            else {
                ed.Delete(1);
            }

            byte[] extra = ed.GetEntryData();

            WriteLEShort(name.Length);
            WriteLEShort(extra.Length);

            if ( name.Length > 0 ) {
                stream_.Write(name, 0, name.Length);
            }

            if ( entry.LocalHeaderRequiresZip64 && patchEntryHeader ) {
                patchData.SizePatchOffset += stream_.Position;
            }

            if ( extra.Length > 0 ) {
                stream_.Write(extra, 0, extra.Length);
            }
        }
Пример #25
0
 public ZipUpdate(IStaticDataSource dataSource, string entryName, CompressionMethod compressionMethod)
 {
     command_ = UpdateCommand.Add;
     entry_ = new ZipEntry(entryName);
     entry_.CompressionMethod = compressionMethod;
     dataSource_ = dataSource;
 }
Пример #26
0
        void CompleteCloseEntry(bool testCrc)
        {
            StopDecrypting();

            if ((flags & 8) != 0) {
                ReadDataDescriptor();
            }

            size = 0;

            crc.Reset();

            if (method == (int)CompressionMethod.Deflated) {
                inf.Reset();
            }
            entry = null;
        }
Пример #27
0
 public ZipUpdate(ZipEntry original, ZipEntry updated)
 {
     /*
     command_ = UpdateCommand.Modify;
     entry_ = ( ZipEntry )original.Clone();
     outEntry_ = ( ZipEntry )updated.Clone();
     */
 }
Пример #28
0
        public ZipEntry MakeFileEntry(string fileName, bool useFileSystem)
        {
            ZipEntry result = new ZipEntry(nameTransform_.TransformFile(fileName));
            result.IsUnicodeText = isUnicodeText_;

            int externalAttributes = 0;
            bool useAttributes = (setAttributes_ != 0);

            FileInfo fi = null;
            if (useFileSystem)
            {
                fi = new FileInfo(fileName);
            }

            if ((fi != null) && fi.Exists)
            {
                switch (timeSetting_)
                {
                    case TimeSetting.CreateTime:
                        result.DateTime = fi.CreationTime;
                        break;

                    case TimeSetting.CreateTimeUtc:
            #if NETCF_1_0 || NETCF_2_0
                        result.DateTime = fi.CreationTime.ToUniversalTime();
            #else
                        result.DateTime = fi.CreationTimeUtc;
            #endif
                        break;

                    case TimeSetting.LastAccessTime:
                        result.DateTime = fi.LastAccessTime;
                        break;

                    case TimeSetting.LastAccessTimeUtc:
            #if NETCF_1_0 || NETCF_2_0
                        result.DateTime = fi.LastAccessTime.ToUniversalTime();
            #else
                        result.DateTime = fi.LastAccessTimeUtc;
            #endif
                        break;

                    case TimeSetting.LastWriteTime:
                        result.DateTime = fi.LastWriteTime;
                        break;

                    case TimeSetting.LastWriteTimeUtc:
            #if NETCF_1_0 || NETCF_2_0
                        result.DateTime = fi.LastWriteTime.ToUniversalTime();
            #else
                        result.DateTime = fi.LastWriteTimeUtc;
            #endif
                        break;

                    case TimeSetting.Fixed:
                        result.DateTime = fixedDateTime_;
                        break;

                }

                result.Size = fi.Length;

                useAttributes = true;
                externalAttributes = ((int)fi.Attributes & getAttributes_);
            }
            else
            {
                if (timeSetting_ == TimeSetting.Fixed)
                {
                    result.DateTime = fixedDateTime_;
                }
            }

            if (useAttributes)
            {
                externalAttributes |= setAttributes_;
                result.ExternalFileAttributes = externalAttributes;
            }

            return result;
        }
Пример #29
0
        public ZipEntry(ZipEntry entry)
        {
            if ( entry == null ) {
                throw new ArgumentNullException("entry");
            }

            known                  = entry.known;
            name                   = entry.name;
            size                   = entry.size;
            compressedSize         = entry.compressedSize;
            crc                    = entry.crc;
            dosTime                = entry.dosTime;
            method                 = entry.method;
            comment                = entry.comment;
            versionToExtract       = entry.versionToExtract;
            versionMadeBy          = entry.versionMadeBy;
            externalFileAttributes = entry.externalFileAttributes;
            flags                  = entry.flags;

            zipFileIndex           = entry.zipFileIndex;
            offset                 = entry.offset;

            forceZip64_			   = entry.forceZip64_;

            if ( entry.extra != null ) {
                extra = new byte[entry.extra.Length];
                Array.Copy(entry.extra, 0, extra, 0, entry.extra.Length);
            }
        }
Пример #30
-1
        public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem)
        {
            ZipEntry result = new ZipEntry(nameTransform_.TransformDirectory(directoryName));
            result.IsUnicodeText = isUnicodeText_;
            result.Size = 0;

            int externalAttributes = 0;

            DirectoryInfo di = null;

            if (useFileSystem)
            {
                di = new DirectoryInfo(directoryName);
            }

            if ((di != null) && di.Exists)
            {
                switch (timeSetting_)
                {
                    case TimeSetting.CreateTime:
                        result.DateTime = di.CreationTime;
                        break;

                    case TimeSetting.CreateTimeUtc:
            #if NETCF_1_0 || NETCF_2_0
                        result.DateTime = di.CreationTime.ToUniversalTime();
            #else
                        result.DateTime = di.CreationTimeUtc;
            #endif
                        break;

                    case TimeSetting.LastAccessTime:
                        result.DateTime = di.LastAccessTime;
                        break;

                    case TimeSetting.LastAccessTimeUtc:
            #if NETCF_1_0 || NETCF_2_0
                        result.DateTime = di.LastAccessTime.ToUniversalTime();
            #else
                        result.DateTime = di.LastAccessTimeUtc;
            #endif
                        break;

                    case TimeSetting.LastWriteTime:
                        result.DateTime = di.LastWriteTime;
                        break;

                    case TimeSetting.LastWriteTimeUtc:
            #if NETCF_1_0 || NETCF_2_0
                        result.DateTime = di.LastWriteTime.ToUniversalTime();
            #else
                        result.DateTime = di.LastWriteTimeUtc;
            #endif
                        break;

                    case TimeSetting.Fixed:
                        result.DateTime = fixedDateTime_;
                        break;

                }

                externalAttributes = ((int)di.Attributes & getAttributes_);
            }
            else
            {
                if (timeSetting_ == TimeSetting.Fixed)
                {
                    result.DateTime = fixedDateTime_;
                }
            }

            externalAttributes |= (setAttributes_ | 16);
            result.ExternalFileAttributes = externalAttributes;

            return result;
        }