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 }