예제 #1
0
        public void ZipFileCloseFake(ulong fileOffset, out byte[] centralDir)
        {
            centralDir = null;
            if (ZipOpen != ZipOpenType.OpenFakeWrite)
            {
                return;
            }

            _zip64 = false;
            bool lTrrntzip = true;

            _zipFs = new MemoryStream();

            _centralDirStart = fileOffset;

            CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true);

            foreach (LocalFile t in _localFiles)
            {
                t.CenteralDirectoryWrite(crcCs);
                lTrrntzip &= t.TrrntZip;
            }

            crcCs.Flush();
            crcCs.Close();

            _centralDirSize = (ulong)_zipFs.Position;

            _fileComment = lTrrntzip ? ZipUtils.GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0];
            ZipStatus    = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None;

            crcCs.Dispose();

            _zip64 = (_centralDirStart >= 0xffffffff) || (_centralDirSize >= 0xffffffff) || (_localFiles.Count >= 0xffff);

            if (_zip64)
            {
                _endOfCenterDir64 = fileOffset + (ulong)_zipFs.Position;
                Zip64EndOfCentralDirWrite();
                Zip64EndOfCentralDirectoryLocatorWrite();
            }
            EndOfCentralDirWrite();

            centralDir = ((MemoryStream)_zipFs).ToArray();
            _zipFs.Close();
            _zipFs.Dispose();
            ZipOpen = ZipOpenType.Closed;
        }
예제 #2
0
        private void zipFileCloseWrite()
        {
            _zip64 = false;
            bool lTrrntzip = true;

            _centerDirStart = (ulong)_zipFs.Position;

            using (CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true))
            {
                foreach (LocalFile t in _localFiles)
                {
                    t.CenteralDirectoryWrite(crcCs);
                    _zip64    |= t.Zip64;
                    lTrrntzip &= t.TrrntZip;
                }

                crcCs.Flush();
                crcCs.Close();

                _centerDirSize = (ulong)_zipFs.Position - _centerDirStart;

                _fileComment = lTrrntzip ? ZipUtils.GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0];
                ZipStatus    = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None;
            }
            _zip64 |= _centerDirStart >= 0xffffffff;
            _zip64 |= _centerDirSize >= 0xffffffff;
            _zip64 |= _localFiles.Count >= 0xffff;

            if (_zip64)
            {
                _endOfCenterDir64 = (ulong)_zipFs.Position;
                Zip64EndOfCentralDirWrite();
                Zip64EndOfCentralDirectoryLocatorWrite();
            }
            EndOfCentralDirWrite();

            _zipFs.SetLength(_zipFs.Position);
            _zipFs.Flush();
            _zipFs.Close();
            _zipFs.Dispose();
            _zipFileInfo = new FileInfo(_zipFileInfo.FullName);
            ZipOpen      = ZipOpenType.Closed;
        }
예제 #3
0
 public Zip()
 {
     ZipUtils.EncodeSetup();
 }
예제 #4
0
            public static ZipReturn ReadLocalExtraField(byte[] extraField, byte[] bFileName, LocalFile lf, bool centralDir)
            {
                int extraFieldLength = extraField.Length;

                lf.Zip64 = false;
                int blockPos = 0;

                while (extraFieldLength > blockPos)
                {
                    ushort type = BitConverter.ToUInt16(extraField, blockPos);
                    blockPos += 2;
                    ushort blockLength = BitConverter.ToUInt16(extraField, blockPos);
                    blockPos += 2;

                    int pos = blockPos;
                    switch (type)
                    {
                    /*
                     *      -Zip64 Extended Information Extra Field (0x0001):
                     *      ===============================================
                     *
                     *      The following is the layout of the zip64 extended
                     *      information "extra" block. If one of the size or
                     *      offset fields in the Local or Central directory
                     *      record is too small to hold the required data,
                     *      a zip64 extended information record is created.
                     *      The order of the fields in the zip64 extended
                     *      information record is fixed, but the fields will
                     *      only appear if the corresponding Local or Central
                     *      directory record field is set to 0xFFFF or 0xFFFFFFFF.
                     *
                     *      Note: all fields stored in Intel low-byte/high-byte order.
                     *
                     *      Value      Size       Description
                     *      -----      ----       -----------
                     * (ZIP64) 0x0001     2 bytes    Tag for this "extra" block type
                     *      Size       2 bytes    Size of this "extra" block
                     *      Original
                     *      Size       8 bytes    Original uncompressed file size
                     *      Compressed
                     *      Size       8 bytes    Size of compressed data
                     *      Relative Header
                     *      Offset     8 bytes    Offset of local header record
                     *      Disk Start
                     *      Number     4 bytes    Number of the disk on which
                     *                          this file starts
                     *
                     *      This entry in the Local header must include BOTH original
                     *      and compressed file size fields.  If encrypting the
                     *      central directory and bit 13 of the general purpose bit
                     *      flag is set indicating masking, the value stored in the
                     *      Local Header for the original file size will be zero.
                     */
                    case 0x0001:
                        lf.Zip64 = true;
                        if (centralDir)
                        {
                            if (lf.UncompressedSize == 0xffffffff)
                            {
                                lf.UncompressedSize = BitConverter.ToUInt64(extraField, pos);
                                pos += 8;
                            }
                            if (lf._compressedSize == 0xffffffff)
                            {
                                lf._compressedSize = BitConverter.ToUInt64(extraField, pos);
                                pos += 8;
                            }
                            if (lf.RelativeOffsetOfLocalHeader == 0xffffffff)
                            {
                                lf.RelativeOffsetOfLocalHeader = BitConverter.ToUInt64(extraField, pos);
                                pos += 8;
                            }
                        }
                        else
                        {
                            if (lf._localHeaderUncompressedSize == 0xffffffff)
                            {
                                lf._localHeaderUncompressedSize = BitConverter.ToUInt64(extraField, pos);
                                pos += 8;
                            }
                            if (lf._localHeaderCompressedSize == 0xffffffff)
                            {
                                lf._localHeaderCompressedSize = BitConverter.ToUInt64(extraField, pos);
                                pos += 8;
                            }
                        }

                        break;


                    /* PKWARE's authenticity verification */
                    case 0x0007:     // Not Needed
                        break;


                    /*
                     *       -PKWARE Win95/WinNT Extra Field (0x000a):
                     *        =======================================
                     *
                     *        The following description covers PKWARE's "NTFS" attributes
                     *        "extra" block, introduced with the release of PKZIP 2.50 for
                     *        Windows. (Last Revision 20001118)
                     *
                     *        (Note: At this time the Mtime, Atime and Ctime values may
                     *        be used on any WIN32 system.)
                     *       [Info-ZIP note: In the current implementations, this field has
                     *        a fixed total data size of 32 bytes and is only stored as local
                     *        extra field.]
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (NTFS)  0x000a        Short       Tag for this "extra" block type
                     *        TSize         Short       Total Data Size for this block
                     *        Reserved      Long        for future use
                     *        Tag1          Short       NTFS attribute tag value #1
                     *        Size1         Short       Size of attribute #1, in bytes
                     *        (var.)        SubSize1    Attribute #1 data
                     *        .
                     *        .
                     *        .
                     *        TagN          Short       NTFS attribute tag value #N
                     *        SizeN         Short       Size of attribute #N, in bytes
                     *        (var.)        SubSizeN    Attribute #N data
                     *
                     *        For NTFS, values for Tag1 through TagN are as follows:
                     *        (currently only one set of attributes is defined for NTFS)
                     *
                     *        Tag        Size       Description
                     *        -----      ----       -----------
                     *        0x0001     2 bytes    Tag for attribute #1
                     *        Size1      2 bytes    Size of attribute #1, in bytes (24)
                     *        Mtime      8 bytes    64-bit NTFS file last modification time
                     *        Atime      8 bytes    64-bit NTFS file last access time
                     *        Ctime      8 bytes    64-bit NTFS file creation time
                     *
                     *        The total length for this block is 28 bytes, resulting in a
                     *        fixed size value of 32 for the TSize field of the NTFS block.
                     *
                     *        The NTFS filetimes are 64-bit unsigned integers, stored in Intel
                     *        (least significant byte first) byte order. They determine the
                     *        number of 1.0E-07 seconds (1/10th microseconds!) past WinNT "epoch",
                     *        which is "01-Jan-1601 00:00:00 UTC".
                     */
                    case 0x000a:
                        pos += 4;                                          // Reserved      Long        for future use
                        int tag1 = BitConverter.ToInt16(extraField, pos);  // Tag1          Short       NTFS attribute tag value #1
                        pos += 2;
                        int size1 = BitConverter.ToInt16(extraField, pos); // Size1         Short       Size of attribute #1, in bytes
                        pos += 2;
                        if (tag1 == 0x0001 && size1 == 24
                            )                                                                             // (currently only one set of attributes is defined for NTFS)
                        {
                            lf.mTime = ZipUtils.FileTimeToUTCTime(BitConverter.ToInt64(extraField, pos)); // Mtime      8 bytes    64-bit NTFS file last modification time
                            pos     += 8;
                            lf.aTime = ZipUtils.FileTimeToUTCTime(BitConverter.ToInt64(extraField, pos)); // Atime      8 bytes    64-bit NTFS file last access time
                            pos     += 8;
                            lf.cTime = ZipUtils.FileTimeToUTCTime(BitConverter.ToInt64(extraField, pos)); // Ctime      8 bytes    64-bit NTFS file creation time
                            pos     += 8;

                            Debug.WriteLine("modtime = " + new DateTime((long)lf.mTime));
                            Debug.WriteLine("Acctime = " + new DateTime((long)lf.aTime));
                            Debug.WriteLine("Cretime = " + new DateTime((long)lf.cTime));
                        }

                        break;


                    /*
                     *        -Windows NT Security Descriptor Extra Field (0x4453):
                     *        ===================================================
                     *
                     *        The following is the layout of the NT Security Descriptor (another
                     *        type of ACL) extra block.  (Last Revision 19960922)
                     *
                     *        Local-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (SD)    0x4453        Short       tag for this extra block type ("SD")
                     *        TSize         Short       total data size for this block
                     *        BSize         Long        uncompressed SD data size
                     *        Version       Byte        version of uncompressed SD data format
                     *        CType         Short       compression type
                     *        EACRC         Long        CRC value for uncompressed SD data
                     *        (var.)        variable    compressed SD data
                     *
                     *        Central-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (SD)    0x4453        Short       tag for this extra block type ("SD")
                     *        TSize         Short       total data size for this block (4)
                     *        BSize         Long        size of uncompressed local SD data
                     *
                     *        The value of CType is interpreted according to the "compression
                     *        method" section above; i.e., 0 for stored, 8 for deflated, etc.
                     *        Version specifies how the compressed data are to be interpreted
                     *        and allows for future expansion of this extra field type.  Currently
                     *        only version 0 is defined.
                     *
                     *        For version 0, the compressed data are to be interpreted as a single
                     *        valid Windows NT SECURITY_DESCRIPTOR data structure, in self-relative
                     *        format.
                     *
                     */
                    case 0x4453:     // Not Needed
                        break;


                    /*
                     *       -FWKCS MD5 Extra Field (0x4b46):
                     *        ==============================
                     *
                     *        The FWKCS Contents_Signature System, used in automatically
                     *        identifying files independent of filename, optionally adds
                     *        and uses an extra field to support the rapid creation of
                     *        an enhanced contents_signature.
                     *        There is no local-header version; the following applies
                     *        only to the central header.  (Last Revision 19961207)
                     *
                     *        Central-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (MD5)   0x4b46        Short       tag for this extra block type ("FK")
                     *        TSize         Short       total data size for this block (19)
                     *        "MD5"         3 bytes     extra-field signature
                     *        MD5hash       16 bytes    128-bit MD5 hash of uncompressed data
                     *                                  (low byte first)
                     *
                     *        When FWKCS revises a .ZIP file central directory to add
                     *        this extra field for a file, it also replaces the
                     *        central directory entry for that file's uncompressed
                     *        file length with a measured value.
                     *
                     *        FWKCS provides an option to strip this extra field, if
                     *        present, from a .ZIP file central directory. In adding
                     *        this extra field, FWKCS preserves .ZIP file Authenticity
                     *        Verification; if stripping this extra field, FWKCS
                     *        preserves all versions of AV through PKZIP version 2.04g.
                     *
                     *        FWKCS, and FWKCS Contents_Signature System, are
                     *        trademarks of Frederick W. Kantor.
                     *
                     *        (1) R. Rivest, RFC1321.TXT, MIT Laboratory for Computer
                     *            Science and RSA Data Security, Inc., April 1992.
                     *            ll.76-77: "The MD5 algorithm is being placed in the
                     *            public domain for review and possible adoption as a
                     *            standard."
                     */
                    case 0x4B46:     // Not Needed
                        break;


                    /*
                     *       -Extended Timestamp Extra Field:
                     *        ==============================
                     *
                     *        The following is the layout of the extended-timestamp extra block.
                     *        (Last Revision 19970118)
                     *
                     *        Local-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (time)  0x5455        Short       tag for this extra block type ("UT")
                     *        TSize         Short       total data size for this block
                     *        Flags         Byte        info bits
                     *        (ModTime)     Long        time of last modification (UTC/GMT)
                     *        (AcTime)      Long        time of last access (UTC/GMT)
                     *        (CrTime)      Long        time of original creation (UTC/GMT)
                     *
                     *        Central-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (time)  0x5455        Short       tag for this extra block type ("UT")
                     *        TSize         Short       total data size for this block
                     *        Flags         Byte        info bits (refers to local header!)
                     *        (ModTime)     Long        time of last modification (UTC/GMT)
                     *
                     *        The central-header extra field contains the modification time only,
                     *        or no timestamp at all.  TSize is used to flag its presence or
                     *        absence.  But note:
                     *
                     *            If "Flags" indicates that Modtime is present in the local header
                     *            field, it MUST be present in the central header field, too!
                     *            This correspondence is required because the modification time
                     *            value may be used to support trans-timezone freshening and
                     *            updating operations with zip archives.
                     *
                     *        The time values are in standard Unix signed-long format, indicating
                     *        the number of seconds since 1 January 1970 00:00:00.  The times
                     *        are relative to Coordinated Universal Time (UTC), also sometimes
                     *        referred to as Greenwich Mean Time (GMT).  To convert to local time,
                     *        the software must know the local timezone offset from UTC/GMT.
                     *
                     *        The lower three bits of Flags in both headers indicate which time-
                     *        stamps are present in the LOCAL extra field:
                     *
                     *              bit 0           if set, modification time is present
                     *              bit 1           if set, access time is present
                     *              bit 2           if set, creation time is present
                     *              bits 3-7        reserved for additional timestamps; not set
                     *
                     *        Those times that are present will appear in the order indicated, but
                     *        any combination of times may be omitted.  (Creation time may be
                     *        present without access time, for example.)  TSize should equal
                     *        (1 + 4*(number of set bits in Flags)), as the block is currently
                     *        defined.  Other timestamps may be added in the future.
                     */
                    case 0x5455:
                        byte flags = extraField[pos];
                        pos += 1;
                        if ((flags & 1) == 1)
                        {
                            lf.mTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos));     // (ModTime)     Long        time of last modification (UTC/GMT)
                            Debug.WriteLine("Umodtime = " + new DateTime((long)lf.mTime));
                            pos += 4;
                        }

                        if (!centralDir)
                        {
                            if ((flags & 2) == 2)
                            {
                                lf.aTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos));     // (AcTime)      Long        time of last access (UTC/GMT)
                                Debug.WriteLine("UAcctime = " + new DateTime((long)lf.aTime));
                                pos += 4;
                            }

                            if ((flags & 4) == 4)
                            {
                                lf.cTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos));     // (CrTime)      Long        time of original creation (UTC/GMT)
                                Debug.WriteLine("UCretime = " + new DateTime((long)lf.cTime));
                                pos += 4;
                            }
                        }

                        break;


                    /*
                     *       -Info-ZIP Unix Extra Field (type 1):
                     *        ==================================
                     *
                     *        The following is the layout of the old Info-ZIP extra block for
                     *        Unix.  It has been replaced by the extended-timestamp extra block
                     *        (0x5455) and the Unix type 2 extra block (0x7855).
                     *        (Last Revision 19970118)
                     *
                     *        Local-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (Unix1) 0x5855        Short       tag for this extra block type ("UX")
                     *        TSize         Short       total data size for this block
                     *        AcTime        Long        time of last access (UTC/GMT)
                     *        ModTime       Long        time of last modification (UTC/GMT)
                     *        UID           Short       Unix user ID (optional)
                     *        GID           Short       Unix group ID (optional)
                     *
                     *        Central-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (Unix1) 0x5855        Short       tag for this extra block type ("UX")
                     *        TSize         Short       total data size for this block
                     *        AcTime        Long        time of last access (GMT/UTC)
                     *        ModTime       Long        time of last modification (GMT/UTC)
                     *
                     *        The file access and modification times are in standard Unix signed-
                     *        long format, indicating the number of seconds since 1 January 1970
                     *        00:00:00.  The times are relative to Coordinated Universal Time
                     *        (UTC), also sometimes referred to as Greenwich Mean Time (GMT).  To
                     *        convert to local time, the software must know the local timezone
                     *        offset from UTC/GMT.  The modification time may be used by non-Unix
                     *        systems to support inter-timezone freshening and updating of zip
                     *        archives.
                     *
                     *        The local-header extra block may optionally contain UID and GID
                     *        info for the file.  The local-header TSize value is the only
                     *        indication of this.  Note that Unix UIDs and GIDs are usually
                     *        specific to a particular machine, and they generally require root
                     *        access to restore.
                     *
                     *        This extra field type is obsolete, but it has been in use since
                     *        mid-1994.  Therefore future archiving software should continue to
                     *        support it.  Some guidelines:
                     *
                     *            An archive member should either contain the old "Unix1"
                     *            extra field block or the new extra field types "time" and/or
                     *            "Unix2".
                     *
                     *            If both the old "Unix1" block type and one or both of the new
                     *            block types "time" and "Unix2" are found, the "Unix1" block
                     *            should be considered invalid and ignored.
                     *
                     *            Unarchiving software should recognize both old and new extra
                     *            field block types, but the info from new types overrides the
                     *            old "Unix1" field.
                     *
                     *            Archiving software should recognize "Unix1" extra fields for
                     *            timestamp comparison but never create it for updated, freshened
                     *            or new archive members.  When copying existing members to a new
                     *            archive, any "Unix1" extra field blocks should be converted to
                     *            the new "time" and/or "Unix2" types.
                     */
                    case 0x5855:
                        lf.aTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos));     // AcTime        Long        time of last access (UTC/GMT)
                        Debug.WriteLine("UAcctime = " + new DateTime((long)lf.aTime));
                        pos     += 4;
                        lf.mTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos));     // ModTime       Long        time of last modification (UTC/GMT)
                        Debug.WriteLine("Umodtime = " + new DateTime((long)lf.mTime));
                        pos += 4;
                        break;


                    /*
                     *       -Info-ZIP Unicode Path Extra Field:
                     *        =================================
                     *
                     *        Stores the UTF-8 version of the entry path as stored in the
                     *        local header and central directory header.
                     *        (Last Revision 20070912)
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (UPath) 0x7075        Short       tag for this extra block type ("up")
                     *        TSize         Short       total data size for this block
                     *        Version       Byte        version of this extra field, currently 1
                     *        NameCRC32     Long        CRC-32 checksum of standard name field
                     *        UnicodeName   variable    UTF-8 version of the entry file name
                     *
                     *        Currently Version is set to the number 1.  If there is a need
                     *        to change this field, the version will be incremented.  Changes
                     *        may not be backward compatible so this extra field should not be
                     *        used if the version is not recognized.
                     *
                     *        The NameCRC32 is the standard zip CRC32 checksum of the File Name
                     *        field in the header.  This is used to verify that the header
                     *        File Name field has not changed since the Unicode Path extra field
                     *        was created.  This can happen if a utility renames the entry but
                     *        does not update the UTF-8 path extra field.  If the CRC check fails,
                     *        this UTF-8 Path Extra Field should be ignored and the File Name field
                     *        in the header should be used instead.
                     *
                     *        The UnicodeName is the UTF-8 version of the contents of the File
                     *        Name field in the header, without any trailing NUL.  The standard
                     *        name field in the Zip entry header remains filled with the entry
                     *        name coded in the local machine's extended ASCII system charset.
                     *        As UnicodeName is defined to be UTF-8, no UTF-8 byte order mark
                     *        (BOM) is used.  The length of this field is determined by
                     *        subtracting the size of the previous fields from TSize.
                     *        If both the File Name and Comment fields are UTF-8, the new General
                     *        Purpose Bit Flag, bit 11 (Language encoding flag (EFS)), should be
                     *        used to indicate that both the header File Name and Comment fields
                     *        are UTF-8 and, in this case, the Unicode Path and Unicode Comment
                     *        extra fields are not needed and should not be created.  Note that,
                     *        for backward compatibility, bit 11 should only be used if the native
                     *        character set of the paths and comments being zipped up are already
                     *        in UTF-8.  The same method, either general purpose bit 11 or extra
                     *        fields, should be used in both the Local and Central Directory Header
                     *        for a file.
                     *
                     *        Utilisation rules:
                     *        1. This field shall never be created for names consisting solely of
                     *           7-bit ASCII characters.
                     *        2. On a system that already uses UTF-8 as system charset, this field
                     *           shall not repeat the string pattern already stored in the Zip
                     *           entry's standard name field. Instead, a field of exactly 9 bytes
                     *           (70 75 05 00 01 and 4 bytes CRC) should be created.
                     *           In this form with 5 data bytes, the field serves as indicator
                     *           for the UTF-8 encoding of the standard Zip header's name field.
                     *        3. This field shall not be used whenever the calculated CRC-32 of
                     *           the entry's standard name field does not match the provided
                     *           CRC checksum value.  A mismatch of the CRC check indicates that
                     *           the standard name field was changed by some non-"up"-aware
                     *           utility without synchronizing this UTF-8 name e.f. block.
                     */
                    case 0x7075:
                        pos += 1;
                        uint nameCRC32 = BitConverter.ToUInt32(extraField, pos);
                        pos += 4;

                        CRC crcTest = new CRC();
                        crcTest.SlurpBlock(bFileName, 0, bFileName.Length);
                        uint fCRC = crcTest.Crc32ResultU;

                        if (nameCRC32 == fCRC)
                        {
                            int charLen = blockLength - 5;
                            lf.FileName = Encoding.UTF8.GetString(extraField, pos, charLen);
                        }

                        break;


                    /*
                     *       -Info-ZIP UNIX Extra Field (type 2):
                     *        ==================================
                     *
                     *        The following is the layout of the new Info-ZIP extra block for
                     *        Unix.  (Last Revision 19960922)
                     *
                     *        Local-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (Unix2) 0x7855        Short       tag for this extra block type ("Ux")
                     *        TSize         Short       total data size for this block (4)
                     *        UID           Short       Unix user ID
                     *        GID           Short       Unix group ID
                     *
                     *        Central-header version:
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (Unix2) 0x7855        Short       tag for this extra block type ("Ux")
                     *        TSize         Short       total data size for this block (0)
                     *
                     *        The data size of the central-header version is zero; it is used
                     *        solely as a flag that UID/GID info is present in the local-header
                     *        extra field.  If additional fields are ever added to the local
                     *        version, the central version may be extended to indicate this.
                     *
                     *        Note that Unix UIDs and GIDs are usually specific to a particular
                     *        machine, and they generally require root access to restore.
                     *
                     */
                    case 0x7855:     // Not Needed
                        break;


                    /*
                     *       -Info-ZIP New Unix Extra Field:
                     *        ====================================
                     *
                     *        Currently stores Unix UIDs/GIDs up to 32 bits.
                     *        (Last Revision 20080509)
                     *
                     *        Value         Size        Description
                     *        -----         ----        -----------
                     * (UnixN) 0x7875        Short       tag for this extra block type ("ux")
                     *        TSize         Short       total data size for this block
                     *        Version       1 byte      version of this extra field, currently 1
                     *        UIDSize       1 byte      Size of UID field
                     *        UID           Variable    UID for this entry
                     *        GIDSize       1 byte      Size of GID field
                     *        GID           Variable    GID for this entry
                     *
                     *        Currently Version is set to the number 1.  If there is a need
                     *        to change this field, the version will be incremented.  Changes
                     *        may not be backward compatible so this extra field should not be
                     *        used if the version is not recognized.
                     *
                     *        UIDSize is the size of the UID field in bytes.  This size should
                     *        match the size of the UID field on the target OS.
                     *
                     *        UID is the UID for this entry in standard little endian format.
                     *
                     *        GIDSize is the size of the GID field in bytes.  This size should
                     *        match the size of the GID field on the target OS.
                     *
                     *        GID is the GID for this entry in standard little endian format.
                     *
                     *        If both the old 16-bit Unix extra field (tag 0x7855, Info-ZIP Unix2)
                     *        and this extra field are present, the values in this extra field
                     *        supercede the values in that extra field.
                     */
                    case 0x7875:     // Not Needed
                        break;



                    /*      UNKNOWN    */
                    case 0xe57a:
                        break;


                    default:
                        break;
                    }

                    blockPos += blockLength;
                }

                return(ZipReturn.ZipGood);
            }
예제 #5
0
        private ZipReturn ZipFileReadHeaders()
        {
            try
            {
                ZipReturn zRet = FindEndOfCentralDirSignature();
                if (zRet != ZipReturn.ZipGood)
                {
                    ZipFileClose();
                    return(zRet);
                }

                long endOfCentralDir = _zipFs.Position;
                zRet = EndOfCentralDirRead();
                if (zRet != ZipReturn.ZipGood)
                {
                    ZipFileClose();
                    return(zRet);
                }

                // check if this is a ZIP64 zip and if it is read the Zip64 End Of Central Dir Info
                if (_centerDirStart == 0xffffffff || _centerDirSize == 0xffffffff || _localFilesCount == 0xffff)
                {
                    _zip64          = true;
                    _zipFs.Position = endOfCentralDir - 20;
                    zRet            = Zip64EndOfCentralDirectoryLocatorRead();
                    if (zRet != ZipReturn.ZipGood)
                    {
                        ZipFileClose();
                        return(zRet);
                    }
                    _zipFs.Position = (long)_endOfCenterDir64;
                    zRet            = Zip64EndOfCentralDirRead();
                    if (zRet != ZipReturn.ZipGood)
                    {
                        ZipFileClose();
                        return(zRet);
                    }
                }

                bool trrntzip = false;

                // check if the ZIP has a valid TorrentZip file comment
                if (_fileComment.Length == 22)
                {
                    if (ZipUtils.GetString(_fileComment).Substring(0, 14) == "TORRENTZIPPED-")
                    {
                        CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true);
                        byte[] buffer             = new byte[_centerDirSize];
                        _zipFs.Position = (long)_centerDirStart;
                        crcCs.Read(buffer, 0, (int)_centerDirSize);
                        crcCs.Flush();
                        crcCs.Close();

                        uint r = (uint)crcCs.Crc;
                        crcCs.Dispose();

                        string tcrc = ZipUtils.GetString(_fileComment).Substring(14, 8);
                        string zcrc = r.ToString("X8");
                        if (string.Compare(tcrc, zcrc, StringComparison.Ordinal) == 0)
                        {
                            trrntzip = true;
                        }
                    }
                }
                // now read the central directory
                _zipFs.Position = (long)_centerDirStart;

                _localFiles.Clear();
                _localFiles.Capacity = (int)_localFilesCount;
                for (int i = 0; i < _localFilesCount; i++)
                {
                    LocalFile lc = new LocalFile();
                    zRet = lc.CenteralDirectoryRead(_zipFs);
                    if (zRet != ZipReturn.ZipGood)
                    {
                        ZipFileClose();
                        return(zRet);
                    }
                    _zip64 |= lc.Zip64;
                    _localFiles.Add(lc);
                }

                for (int i = 0; i < _localFilesCount; i++)
                {
                    zRet = _localFiles[i].LocalFileHeaderRead(_zipFs);
                    if (zRet != ZipReturn.ZipGood)
                    {
                        ZipFileClose();
                        return(zRet);
                    }
                    trrntzip &= _localFiles[i].TrrntZip;
                }

                // check trrntzip file order
                if (trrntzip)
                {
                    for (int i = 0; i < _localFilesCount - 1; i++)
                    {
                        if (ZipUtils.TrrntZipStringCompare(_localFiles[i].FileName, _localFiles[i + 1].FileName) < 0)
                        {
                            continue;
                        }
                        trrntzip = false;
                        break;
                    }
                }

                // check trrntzip directories
                if (trrntzip)
                {
                    for (int i = 0; i < _localFilesCount - 1; i++)
                    {
                        // see if we found a directory
                        string filename0 = _localFiles[i].FileName;
                        if (filename0.Substring(filename0.Length - 1, 1) != "/")
                        {
                            continue;
                        }

                        // see if the next file is in that directory
                        string filename1 = _localFiles[i + 1].FileName;
                        if (filename1.Length <= filename0.Length)
                        {
                            continue;
                        }
                        if (ZipUtils.TrrntZipStringCompare(filename0, filename1.Substring(0, filename0.Length)) != 0)
                        {
                            continue;
                        }

                        // if we found a file in the directory then we do not need the directory entry
                        trrntzip = false;
                        break;
                    }
                }

                if (trrntzip)
                {
                    ZipStatus |= ZipStatus.TrrntZip;
                }

                return(ZipReturn.ZipGood);
            }
            catch
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorReadingFile);
            }
        }