[1096] | 1 | /*
|
---|
| 2 | Copyright (C) 2005-2014 Sergey A. Tachenov
|
---|
| 3 |
|
---|
| 4 | This file is part of QuaZIP.
|
---|
| 5 |
|
---|
| 6 | QuaZIP is free software: you can redistribute it and/or modify
|
---|
| 7 | it under the terms of the GNU Lesser General Public License as published by
|
---|
| 8 | the Free Software Foundation, either version 2.1 of the License, or
|
---|
| 9 | (at your option) any later version.
|
---|
| 10 |
|
---|
| 11 | QuaZIP is distributed in the hope that it will be useful,
|
---|
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 14 | GNU Lesser General Public License for more details.
|
---|
| 15 |
|
---|
| 16 | You should have received a copy of the GNU Lesser General Public License
|
---|
| 17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
|
---|
| 18 |
|
---|
| 19 | See COPYING file for the full LGPL text.
|
---|
| 20 |
|
---|
| 21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
|
---|
| 22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
|
---|
| 23 | */
|
---|
| 24 |
|
---|
| 25 | #include "quazipfileinfo.h"
|
---|
| 26 |
|
---|
| 27 | static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) {
|
---|
| 28 | quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
|
---|
| 29 | QFile::Permissions perm = 0;
|
---|
| 30 | if ((uPerm & 0400) != 0)
|
---|
| 31 | perm |= QFile::ReadOwner;
|
---|
| 32 | if ((uPerm & 0200) != 0)
|
---|
| 33 | perm |= QFile::WriteOwner;
|
---|
| 34 | if ((uPerm & 0100) != 0)
|
---|
| 35 | perm |= QFile::ExeOwner;
|
---|
| 36 | if ((uPerm & 0040) != 0)
|
---|
| 37 | perm |= QFile::ReadGroup;
|
---|
| 38 | if ((uPerm & 0020) != 0)
|
---|
| 39 | perm |= QFile::WriteGroup;
|
---|
| 40 | if ((uPerm & 0010) != 0)
|
---|
| 41 | perm |= QFile::ExeGroup;
|
---|
| 42 | if ((uPerm & 0004) != 0)
|
---|
| 43 | perm |= QFile::ReadOther;
|
---|
| 44 | if ((uPerm & 0002) != 0)
|
---|
| 45 | perm |= QFile::WriteOther;
|
---|
| 46 | if ((uPerm & 0001) != 0)
|
---|
| 47 | perm |= QFile::ExeOther;
|
---|
| 48 | return perm;
|
---|
| 49 |
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | QFile::Permissions QuaZipFileInfo::getPermissions() const
|
---|
| 53 | {
|
---|
| 54 | return permissionsFromExternalAttr(externalAttr);
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | QFile::Permissions QuaZipFileInfo64::getPermissions() const
|
---|
| 58 | {
|
---|
| 59 | return permissionsFromExternalAttr(externalAttr);
|
---|
| 60 | }
|
---|
| 61 |
|
---|
| 62 | bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const
|
---|
| 63 | {
|
---|
| 64 | bool noOverflow = true;
|
---|
| 65 | info.name = name;
|
---|
| 66 | info.versionCreated = versionCreated;
|
---|
| 67 | info.versionNeeded = versionNeeded;
|
---|
| 68 | info.flags = flags;
|
---|
| 69 | info.method = method;
|
---|
| 70 | info.dateTime = dateTime;
|
---|
| 71 | info.crc = crc;
|
---|
| 72 | if (compressedSize > 0xFFFFFFFFu) {
|
---|
| 73 | info.compressedSize = 0xFFFFFFFFu;
|
---|
| 74 | noOverflow = false;
|
---|
| 75 | } else {
|
---|
| 76 | info.compressedSize = compressedSize;
|
---|
| 77 | }
|
---|
| 78 | if (uncompressedSize > 0xFFFFFFFFu) {
|
---|
| 79 | info.uncompressedSize = 0xFFFFFFFFu;
|
---|
| 80 | noOverflow = false;
|
---|
| 81 | } else {
|
---|
| 82 | info.uncompressedSize = uncompressedSize;
|
---|
| 83 | }
|
---|
| 84 | info.diskNumberStart = diskNumberStart;
|
---|
| 85 | info.internalAttr = internalAttr;
|
---|
| 86 | info.externalAttr = externalAttr;
|
---|
| 87 | info.comment = comment;
|
---|
| 88 | info.extra = extra;
|
---|
| 89 | return noOverflow;
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | static QDateTime getNTFSTime(const QByteArray &extra, int position,
|
---|
| 93 | int *fineTicks)
|
---|
| 94 | {
|
---|
| 95 | QDateTime dateTime;
|
---|
| 96 | for (int i = 0; i <= extra.size() - 4; ) {
|
---|
| 97 | unsigned type = static_cast<unsigned>(static_cast<unsigned char>(
|
---|
| 98 | extra.at(i)))
|
---|
| 99 | | (static_cast<unsigned>(static_cast<unsigned char>(
|
---|
| 100 | extra.at(i + 1))) << 8);
|
---|
| 101 | i += 2;
|
---|
| 102 | unsigned length = static_cast<unsigned>(static_cast<unsigned char>(
|
---|
| 103 | extra.at(i)))
|
---|
| 104 | | (static_cast<unsigned>(static_cast<unsigned char>(
|
---|
| 105 | extra.at(i + 1))) << 8);
|
---|
| 106 | i += 2;
|
---|
| 107 | if (type == QUAZIP_EXTRA_NTFS_MAGIC && length >= 32) {
|
---|
| 108 | i += 4; // reserved
|
---|
| 109 | while (i <= extra.size() - 4) {
|
---|
| 110 | unsigned tag = static_cast<unsigned>(
|
---|
| 111 | static_cast<unsigned char>(extra.at(i)))
|
---|
| 112 | | (static_cast<unsigned>(
|
---|
| 113 | static_cast<unsigned char>(extra.at(i + 1)))
|
---|
| 114 | << 8);
|
---|
| 115 | i += 2;
|
---|
| 116 | int tagsize = static_cast<unsigned>(
|
---|
| 117 | static_cast<unsigned char>(extra.at(i)))
|
---|
| 118 | | (static_cast<unsigned>(
|
---|
| 119 | static_cast<unsigned char>(extra.at(i + 1)))
|
---|
| 120 | << 8);
|
---|
| 121 | i += 2;
|
---|
| 122 | if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC
|
---|
| 123 | && tagsize >= position + 8) {
|
---|
| 124 | i += position;
|
---|
| 125 | quint64 mtime = static_cast<quint64>(
|
---|
| 126 | static_cast<unsigned char>(extra.at(i)))
|
---|
| 127 | | (static_cast<quint64>(static_cast<unsigned char>(
|
---|
| 128 | extra.at(i + 1))) << 8)
|
---|
| 129 | | (static_cast<quint64>(static_cast<unsigned char>(
|
---|
| 130 | extra.at(i + 2))) << 16)
|
---|
| 131 | | (static_cast<quint64>(static_cast<unsigned char>(
|
---|
| 132 | extra.at(i + 3))) << 24)
|
---|
| 133 | | (static_cast<quint64>(static_cast<unsigned char>(
|
---|
| 134 | extra.at(i + 4))) << 32)
|
---|
| 135 | | (static_cast<quint64>(static_cast<unsigned char>(
|
---|
| 136 | extra.at(i + 5))) << 40)
|
---|
| 137 | | (static_cast<quint64>(static_cast<unsigned char>(
|
---|
| 138 | extra.at(i + 6))) << 48)
|
---|
| 139 | | (static_cast<quint64>(static_cast<unsigned char>(
|
---|
| 140 | extra.at(i + 7))) << 56);
|
---|
| 141 | // the NTFS time is measured from 1601 for whatever reason
|
---|
| 142 | QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
|
---|
| 143 | dateTime = base.addMSecs(mtime / 10000);
|
---|
| 144 | if (fineTicks != NULL) {
|
---|
| 145 | *fineTicks = static_cast<int>(mtime % 10000);
|
---|
| 146 | }
|
---|
| 147 | i += tagsize - position;
|
---|
| 148 | } else {
|
---|
| 149 | i += tagsize;
|
---|
| 150 | }
|
---|
| 151 |
|
---|
| 152 | }
|
---|
| 153 | } else {
|
---|
| 154 | i += length;
|
---|
| 155 | }
|
---|
| 156 | }
|
---|
| 157 | if (fineTicks != NULL && dateTime.isNull()) {
|
---|
| 158 | *fineTicks = 0;
|
---|
| 159 | }
|
---|
| 160 | return dateTime;
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const
|
---|
| 164 | {
|
---|
| 165 | return getNTFSTime(extra, 0, fineTicks);
|
---|
| 166 | }
|
---|
| 167 |
|
---|
| 168 | QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const
|
---|
| 169 | {
|
---|
| 170 | return getNTFSTime(extra, 8, fineTicks);
|
---|
| 171 | }
|
---|
| 172 |
|
---|
| 173 | QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
|
---|
| 174 | {
|
---|
| 175 | return getNTFSTime(extra, 16, fineTicks);
|
---|
| 176 | }
|
---|