private ZipIOZip64EndOfCentralDirectoryLocatorBlock(ZipIOBlockManager blockManager)
 {
     Debug.Assert(blockManager != null);
     _blockManager = blockManager;
 }
Ejemplo n.º 2
0
 //------------------------------------------------------
 //
 //  Private Methods
 //
 //------------------------------------------------------
 private ZipIOCentralDirectoryBlock(ZipIOBlockManager blockManager)
 {
     _blockManager = blockManager;
 }
Ejemplo n.º 3
0
 //------------------------------------------------------
 //
 //  Private Methods
 //
 //------------------------------------------------------
 private ZipIORawDataFileBlock(ZipIOBlockManager blockManager)
 {
     _blockManager = blockManager;
 }
Ejemplo n.º 4
0
        // !!! ATTENTION !!!! This function is only supposed to be called by
        // Block Manager.Save which has proper protection to ensure no stack overflow will happen
        // as a result of Stream.Flush calls which in turn result in BlockManager.Save calls
        public void UpdateReferences(bool closingFlag)
        {
            Invariant.Assert(!_blockManager.Streaming);

            long uncompressedSize;
            long compressedSize;

            CheckDisposed();

            if (closingFlag)
            {
                CloseExposedStreams();
            }
            else
            {
                FlushExposedStreams();
            }

            // At this point we can update Local Headers with the proper CRC Value
            // We can also update other Local File Header Values (compressed/uncompressed size)
            // we rely on our DirtyFlag property to properly account for all possbile modifications within streams
            if (GetDirtyFlag(closingFlag))
            {
                // Remember the size of the header before update
                long headerSizeBeforeUpdate = _localFileHeader.Size;

                // now prior to possibly closing streams we need to preserve uncompressed Size
                // otherwise Length function will fail to give it to us later after closing
                uncompressedSize = _crcCalculatingStream.Length;

                // calculate CRC prior to closing
                _localFileHeader.Crc32 = _crcCalculatingStream.CalculateCrc();

                // If we are closing we can do extra things , calculate CRC , close deflate stream
                // it is particularly important to close the deflate stream as it might hold some extra bytes
                // even after Flush()
                if (closingFlag)
                {
                    // we have got the CRC so we can close the stream
                    _crcCalculatingStream.Close();

                    // in order to get proper compressed size we have to close the deflate stream
                    if (_deflateStream != null)
                    {
                        _deflateStream.Close();
                    }
                }

                if (_fileItemStream.DataChanged)
                {
                    _localFileHeader.LastModFileDateTime = ZipIOBlockManager.ToMsDosDateTime(DateTime.Now);
                }

                // get compressed size after possible closing Deflated stream
                // as a result of some ineffeciencies in CRC calculation it might result in Seek in compressed stream
                // and there fore switching mode and flushing extra compressed bytes
                compressedSize = _fileItemStream.Length;

                // this will properly (taking into account ZIP64 scenario) update local file header
                // Offset is passed in to determine whether ZIP 64 is required for small files that
                // happened to be located required 32 bit offset in the archive
                _localFileHeader.UpdateZip64Structures(compressedSize, uncompressedSize, Offset);

                // Add/remove padding to compensate the header size change
                // NOTE: Padding needs to be updated only after updating all the header fields
                //  that can affect the header size
                _localFileHeader.UpdatePadding(_localFileHeader.Size - headerSizeBeforeUpdate);

                // We always save File Items in Non-streaming mode unless it wasn't touched
                //in which case we leave them alone
                _localFileHeader.StreamingCreationFlag = false;
                _localFileDataDescriptor = null;

                // in some cases UpdateZip64Structures call might result in creation/removal
                // of extra field if such thing happened we need to move FileItemStream appropriatel
                _fileItemStream.Move(checked (Offset + _localFileHeader.Size - _fileItemStream.Offset));

                _dirtyFlag = true;
            }
#if FALSE
            // we would like to take this oppportunity and validate basic asumption
            // that our GetDirtyFlag method is a reliable way to finding changes
            // there is no scenario in which change will happened, affecting sizes
            // and will not be registered by the GetDirtyFlag
            // ???????????????????????
            else
            {
                // we even willing to recalculate CRC just in case for verification purposes

                UInt32 calculatedCRC32 = CalculateCrc32();
                if (!_localFileHeader.StreamingCreationFlag)
                {
                    Debug.Assert(_localFileHeader.Crc32 == calculatedCRC32);
                    Debug.Assert(_localFileHeader.CompressedSize == CompressedSize);
                    Debug.Assert(_localFileHeader.UncompressedSize == UncompressedSize);
                }
                else
                {
                    Debug.Assert(_localFileDataDescriptor.Crc32 == calculatedCRC32);
                    Debug.Assert(_localFileDataDescriptor.CompressedSize == CompressedSize);
                    Debug.Assert(_localFileDataDescriptor.UncompressedSize == UncompressedSize);
                }

///////////////////////////////////////////////////////////////////////

                // we do not have an initialized value for the compressed size in this case
                compressedSize = _fileItemStream.Length;

                Debug.Assert(CompressedSize == compressedSize);
                Debug.Assert(UncompressedSize == uncompressedSize);
            }
#endif
        }
Ejemplo n.º 5
0
 /////////////////////////////
 // Internal Constructor
 /////////////////////////////
 internal ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream) :
     this(blockManager, underlyingStream, 0)
 {
     _validateCrcWithExpectedCrc = false;
 }
Ejemplo n.º 6
0
        internal static ZipIOLocalFileDataDescriptor ParseRecord(BinaryReader reader,
                                                                 long compressedSizeFromCentralDir,
                                                                 long uncompressedSizeFromCentralDir,
                                                                 UInt32 crc32FromCentralDir,
                                                                 UInt16 versionNeededToExtract)
        {
            ZipIOLocalFileDataDescriptor descriptor = new ZipIOLocalFileDataDescriptor();

            // There are 4 distinct scenario we would like to support
            //   1.based on the appnote it seems that the structure of this record is following:
            //                  crc-32                          4 bytes
            //                  compressed size                 4 bytes (scenario 1.a has 8 bytes)
            //                  uncompressed size               4 bytes (scenario 1.a has 8 bytes)
            //
            //   2.based on files that we have been able to examine
            //                  data descriptor signature        4 bytes  (0x08074b50)
            //                  crc-32                                  4 bytes
            //                  compressed size                   4 bytes (scenario 2.a has 8 bytes)
            //                  uncompressed size               4 bytes (scenario 2.a has 8 bytes)
            //
            // we can safely assume that this record is not the last one in the file, so let's just
            // read the max Bytes required to store the largest structure , and compare results

            // at most we are looking at 6 * 4  = 24 bytes
            UInt32[] buffer = new UInt32[6];

            // let's try to match the smallest possible structure (3 x 4) 32 bit without signature
            buffer[0] = reader.ReadUInt32();
            buffer[1] = reader.ReadUInt32();
            buffer[2] = reader.ReadUInt32();

            if (descriptor.TestMatch(_signatureConstant,
                                     crc32FromCentralDir,
                                     compressedSizeFromCentralDir,
                                     uncompressedSizeFromCentralDir,
                                     _signatureConstant,
                                     buffer[0],
                                     buffer[1],
                                     buffer[2]))
            {
                descriptor._size = _fixedMinimalRecordSizeWithoutSignature;
                return(descriptor);
            }

            // let's try to match the next record size (4 x 4) 32 bit with signature
            buffer[3] = reader.ReadUInt32();
            if (descriptor.TestMatch(_signatureConstant,
                                     crc32FromCentralDir,
                                     compressedSizeFromCentralDir,
                                     uncompressedSizeFromCentralDir,
                                     buffer[0],
                                     buffer[1],
                                     buffer[2],
                                     buffer[3]))
            {
                descriptor._size = _fixedMinimalRecordSizeWithSignature;
                return(descriptor);
            }

            // At this point prior to trying to match 64 bit structures we need to make sure that version is high enough
            if (versionNeededToExtract < (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat)
            {
                throw new FileFormatException(SR.Get(SRID.CorruptedData));
            }

            //let's try to match the 64 bit structures 64 bit without signature
            buffer[4] = reader.ReadUInt32();
            if (descriptor.TestMatch(_signatureConstant,
                                     crc32FromCentralDir,
                                     compressedSizeFromCentralDir,
                                     uncompressedSizeFromCentralDir,
                                     _signatureConstant,
                                     buffer[0],
                                     ZipIOBlockManager.ConvertToUInt64(buffer[1], buffer[2]),
                                     ZipIOBlockManager.ConvertToUInt64(buffer[3], buffer[4])))
            {
                descriptor._size = _fixedMinimalRecordSizeWithoutSignatureZip64;
                return(descriptor);
            }

            //let's try to match the 64 bit structures 64 bit with signature
            buffer[5] = reader.ReadUInt32();
            if (descriptor.TestMatch(_signatureConstant,
                                     crc32FromCentralDir,
                                     compressedSizeFromCentralDir,
                                     uncompressedSizeFromCentralDir,
                                     buffer[0],
                                     buffer[1],
                                     ZipIOBlockManager.ConvertToUInt64(buffer[2], buffer[3]),
                                     ZipIOBlockManager.ConvertToUInt64(buffer[4], buffer[5])))
            {
                descriptor._size = _fixedMinimalRecordSizeWithSignatureZip64;
                return(descriptor);
            }

            // we couldn't match anything at this point we need to fail
            throw new FileFormatException(SR.Get(SRID.CorruptedData));
        }