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 | }
|
---|