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
permissionsFromExternalAttr(quint32 externalAttr)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
getPermissions() const52 QFile::Permissions QuaZipFileInfo::getPermissions() const
53 {
54 return permissionsFromExternalAttr(externalAttr);
55 }
56
getPermissions() const57 QFile::Permissions QuaZipFileInfo64::getPermissions() const
58 {
59 return permissionsFromExternalAttr(externalAttr);
60 }
61
toQuaZipFileInfo(QuaZipFileInfo & info) const62 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
getNTFSTime(const QByteArray & extra,int position,int * fineTicks)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
getNTFSmTime(int * fineTicks) const163 QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const
164 {
165 return getNTFSTime(extra, 0, fineTicks);
166 }
167
getNTFSaTime(int * fineTicks) const168 QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const
169 {
170 return getNTFSTime(extra, 8, fineTicks);
171 }
172
getNTFScTime(int * fineTicks) const173 QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
174 {
175 return getNTFSTime(extra, 16, fineTicks);
176 }
177