File indexing completed on 2025-01-26 04:24:54

0001 /*
0002 Copyright (C) 2005-2014 Sergey A. Tachenov
0003 
0004 This file is part of QuaZIP.
0005 
0006 QuaZIP is free software: you can redistribute it and/or modify
0007 it under the terms of the GNU Lesser General Public License as published by
0008 the Free Software Foundation, either version 2.1 of the License, or
0009 (at your option) any later version.
0010 
0011 QuaZIP is distributed in the hope that it will be useful,
0012 but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 GNU Lesser General Public License for more details.
0015 
0016 You should have received a copy of the GNU Lesser General Public License
0017 along with QuaZIP.  If not, see <http://www.gnu.org/licenses/>.
0018 
0019 See COPYING file for the full LGPL text.
0020 
0021 Original ZIP package is copyrighted by Gilles Vollant and contributors,
0022 see quazip/(un)zip.h files for details. Basically it's the zlib license.
0023 */
0024 
0025 #include "quazipfileinfo.h"
0026 
0027 static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) {
0028     quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
0029     QFile::Permissions perm = 0;
0030     if ((uPerm & 0400) != 0)
0031         perm |= QFile::ReadOwner;
0032     if ((uPerm & 0200) != 0)
0033         perm |= QFile::WriteOwner;
0034     if ((uPerm & 0100) != 0)
0035         perm |= QFile::ExeOwner;
0036     if ((uPerm & 0040) != 0)
0037         perm |= QFile::ReadGroup;
0038     if ((uPerm & 0020) != 0)
0039         perm |= QFile::WriteGroup;
0040     if ((uPerm & 0010) != 0)
0041         perm |= QFile::ExeGroup;
0042     if ((uPerm & 0004) != 0)
0043         perm |= QFile::ReadOther;
0044     if ((uPerm & 0002) != 0)
0045         perm |= QFile::WriteOther;
0046     if ((uPerm & 0001) != 0)
0047         perm |= QFile::ExeOther;
0048     return perm;
0049 
0050 }
0051 
0052 QFile::Permissions QuaZipFileInfo::getPermissions() const
0053 {
0054     return permissionsFromExternalAttr(externalAttr);
0055 }
0056 
0057 QFile::Permissions QuaZipFileInfo64::getPermissions() const
0058 {
0059     return permissionsFromExternalAttr(externalAttr);
0060 }
0061 
0062 bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const
0063 {
0064     bool noOverflow = true;
0065     info.name = name;
0066     info.versionCreated = versionCreated;
0067     info.versionNeeded = versionNeeded;
0068     info.flags = flags;
0069     info.method = method;
0070     info.dateTime = dateTime;
0071     info.crc = crc;
0072     if (compressedSize > 0xFFFFFFFFu) {
0073         info.compressedSize = 0xFFFFFFFFu;
0074         noOverflow = false;
0075     } else {
0076         info.compressedSize = compressedSize;
0077     }
0078     if (uncompressedSize > 0xFFFFFFFFu) {
0079         info.uncompressedSize = 0xFFFFFFFFu;
0080         noOverflow = false;
0081     } else {
0082         info.uncompressedSize = uncompressedSize;
0083     }
0084     info.diskNumberStart = diskNumberStart;
0085     info.internalAttr = internalAttr;
0086     info.externalAttr = externalAttr;
0087     info.comment = comment;
0088     info.extra = extra;
0089     return noOverflow;
0090 }
0091 
0092 static QDateTime getNTFSTime(const QByteArray &extra, int position,
0093                              int *fineTicks)
0094 {
0095     QDateTime dateTime;
0096     for (int i = 0; i <= extra.size() - 4; ) {
0097         unsigned type = static_cast<unsigned>(static_cast<unsigned char>(
0098                                                   extra.at(i)))
0099                 | (static_cast<unsigned>(static_cast<unsigned char>(
0100                                                   extra.at(i + 1))) << 8);
0101         i += 2;
0102         unsigned length = static_cast<unsigned>(static_cast<unsigned char>(
0103                                                   extra.at(i)))
0104                 | (static_cast<unsigned>(static_cast<unsigned char>(
0105                                                   extra.at(i + 1))) << 8);
0106         i += 2;
0107         if (type == QUAZIP_EXTRA_NTFS_MAGIC && length >= 32) {
0108             i += 4; // reserved
0109             while (i <= extra.size() - 4) {
0110                 unsigned tag = static_cast<unsigned>(
0111                             static_cast<unsigned char>(extra.at(i)))
0112                         | (static_cast<unsigned>(
0113                                static_cast<unsigned char>(extra.at(i + 1)))
0114                            << 8);
0115                 i += 2;
0116                 int tagsize = static_cast<unsigned>(
0117                             static_cast<unsigned char>(extra.at(i)))
0118                         | (static_cast<unsigned>(
0119                                static_cast<unsigned char>(extra.at(i + 1)))
0120                            << 8);
0121                 i += 2;
0122                 if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC
0123                         && tagsize >= position + 8) {
0124                     i += position;
0125                     quint64 mtime = static_cast<quint64>(
0126                                 static_cast<unsigned char>(extra.at(i)))
0127                         | (static_cast<quint64>(static_cast<unsigned char>(
0128                                                  extra.at(i + 1))) << 8)
0129                         | (static_cast<quint64>(static_cast<unsigned char>(
0130                                                  extra.at(i + 2))) << 16)
0131                         | (static_cast<quint64>(static_cast<unsigned char>(
0132                                                  extra.at(i + 3))) << 24)
0133                         | (static_cast<quint64>(static_cast<unsigned char>(
0134                                                  extra.at(i + 4))) << 32)
0135                         | (static_cast<quint64>(static_cast<unsigned char>(
0136                                                  extra.at(i + 5))) << 40)
0137                         | (static_cast<quint64>(static_cast<unsigned char>(
0138                                                  extra.at(i + 6))) << 48)
0139                         | (static_cast<quint64>(static_cast<unsigned char>(
0140                                                  extra.at(i + 7))) << 56);
0141                     // the NTFS time is measured from 1601 for whatever reason
0142                     QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
0143                     dateTime = base.addMSecs(mtime / 10000);
0144                     if (fineTicks != NULL) {
0145                         *fineTicks = static_cast<int>(mtime % 10000);
0146                     }
0147                     i += tagsize - position;
0148                 } else {
0149                     i += tagsize;
0150                 }
0151 
0152             }
0153         } else {
0154             i += length;
0155         }
0156     }
0157     if (fineTicks != NULL && dateTime.isNull()) {
0158         *fineTicks = 0;
0159     }
0160     return dateTime;
0161 }
0162 
0163 QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const
0164 {
0165     return getNTFSTime(extra, 0, fineTicks);
0166 }
0167 
0168 QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const
0169 {
0170     return getNTFSTime(extra, 8, fineTicks);
0171 }
0172 
0173 QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
0174 {
0175     return getNTFSTime(extra, 16, fineTicks);
0176 }