1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QFILESYSTEMMETADATA_P_H
41#define QFILESYSTEMMETADATA_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include "qplatformdefs.h"
55#include <QtCore/qglobal.h>
56#include <QtCore/qdatetime.h>
57#include <QtCore/private/qabstractfileengine_p.h>
58
59// Platform-specific includes
60#ifdef Q_OS_WIN
61# include <QtCore/qt_windows.h>
62# ifndef IO_REPARSE_TAG_SYMLINK
63# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
64# endif
65#endif
66
67#ifdef Q_OS_UNIX
68struct statx;
69#endif
70
71QT_BEGIN_NAMESPACE
72
73class QFileSystemEngine;
74
75class Q_AUTOTEST_EXPORT QFileSystemMetaData
76{
77public:
78 QFileSystemMetaData()
79 : size_(-1)
80 {
81 }
82
83 enum MetaDataFlag {
84 // Permissions, overlaps with QFile::Permissions
85 OtherReadPermission = 0x00000004, OtherWritePermission = 0x00000002, OtherExecutePermission = 0x00000001,
86 GroupReadPermission = 0x00000040, GroupWritePermission = 0x00000020, GroupExecutePermission = 0x00000010,
87 UserReadPermission = 0x00000400, UserWritePermission = 0x00000200, UserExecutePermission = 0x00000100,
88 OwnerReadPermission = 0x00004000, OwnerWritePermission = 0x00002000, OwnerExecutePermission = 0x00001000,
89
90 OtherPermissions = OtherReadPermission | OtherWritePermission | OtherExecutePermission,
91 GroupPermissions = GroupReadPermission | GroupWritePermission | GroupExecutePermission,
92 UserPermissions = UserReadPermission | UserWritePermission | UserExecutePermission,
93 OwnerPermissions = OwnerReadPermission | OwnerWritePermission | OwnerExecutePermission,
94
95 ReadPermissions = OtherReadPermission | GroupReadPermission | UserReadPermission | OwnerReadPermission,
96 WritePermissions = OtherWritePermission | GroupWritePermission | UserWritePermission | OwnerWritePermission,
97 ExecutePermissions = OtherExecutePermission | GroupExecutePermission | UserExecutePermission | OwnerExecutePermission,
98
99 Permissions = OtherPermissions | GroupPermissions | UserPermissions | OwnerPermissions,
100
101 // Type
102 LinkType = 0x00010000,
103 FileType = 0x00020000,
104 DirectoryType = 0x00040000,
105#if defined(Q_OS_DARWIN)
106 BundleType = 0x00080000,
107 AliasType = 0x08000000,
108#else
109 BundleType = 0x0,
110 AliasType = 0x0,
111#endif
112#if defined(Q_OS_WIN)
113 JunctionType = 0x04000000,
114 WinLnkType = 0x08000000, // Note: Uses the same position for AliasType on Mac
115#else
116 JunctionType = 0x0,
117 WinLnkType = 0x0,
118#endif
119 SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag
120
121 LegacyLinkType = LinkType | AliasType | WinLnkType,
122
123 Type = LinkType | FileType | DirectoryType | BundleType | SequentialType | AliasType,
124
125 // Attributes
126 HiddenAttribute = 0x00100000,
127 SizeAttribute = 0x00200000, // Note: overlaps with QAbstractFileEngine::LocalDiskFlag
128 ExistsAttribute = 0x00400000, // For historical reasons, indicates existence of data, not the file
129#if defined(Q_OS_WIN)
130 WasDeletedAttribute = 0x0,
131#else
132 WasDeletedAttribute = 0x40000000, // Indicates the file was deleted
133#endif
134
135 Attributes = HiddenAttribute | SizeAttribute | ExistsAttribute | WasDeletedAttribute,
136
137 // Times - if we know one of them, we know them all
138 AccessTime = 0x02000000,
139 BirthTime = 0x02000000,
140 MetadataChangeTime = 0x02000000,
141 ModificationTime = 0x02000000,
142
143 Times = AccessTime | BirthTime | MetadataChangeTime | ModificationTime,
144
145 // Owner IDs
146 UserId = 0x10000000,
147 GroupId = 0x20000000,
148
149 OwnerIds = UserId | GroupId,
150
151 PosixStatFlags = QFileSystemMetaData::OtherPermissions
152 | QFileSystemMetaData::GroupPermissions
153 | QFileSystemMetaData::OwnerPermissions
154 | QFileSystemMetaData::FileType
155 | QFileSystemMetaData::DirectoryType
156 | QFileSystemMetaData::SequentialType
157 | QFileSystemMetaData::SizeAttribute
158 | QFileSystemMetaData::WasDeletedAttribute
159 | QFileSystemMetaData::Times
160 | QFileSystemMetaData::OwnerIds,
161
162#if defined(Q_OS_WIN)
163 WinStatFlags = QFileSystemMetaData::FileType
164 | QFileSystemMetaData::DirectoryType
165 | QFileSystemMetaData::HiddenAttribute
166 | QFileSystemMetaData::ExistsAttribute
167 | QFileSystemMetaData::SizeAttribute
168 | QFileSystemMetaData::Times,
169#endif
170
171 AllMetaDataFlags = 0xFFFFFFFF
172
173 };
174 Q_DECLARE_FLAGS(MetaDataFlags, MetaDataFlag)
175
176 bool hasFlags(MetaDataFlags flags) const
177 {
178 return ((knownFlagsMask & flags) == flags);
179 }
180
181 MetaDataFlags missingFlags(MetaDataFlags flags)
182 {
183 return flags & ~knownFlagsMask;
184 }
185
186 void clear()
187 {
188 knownFlagsMask = {};
189 }
190
191 void clearFlags(MetaDataFlags flags = AllMetaDataFlags)
192 {
193 knownFlagsMask &= ~flags;
194 }
195
196 bool exists() const { return (entryFlags & ExistsAttribute); }
197
198 bool isLink() const { return (entryFlags & LinkType); }
199 bool isFile() const { return (entryFlags & FileType); }
200 bool isDirectory() const { return (entryFlags & DirectoryType); }
201 bool isBundle() const;
202 bool isAlias() const;
203 bool isLegacyLink() const { return (entryFlags & LegacyLinkType); }
204 bool isSequential() const { return (entryFlags & SequentialType); }
205 bool isHidden() const { return (entryFlags & HiddenAttribute); }
206 bool wasDeleted() const { return (entryFlags & WasDeletedAttribute); }
207#if defined(Q_OS_WIN)
208 bool isLnkFile() const { return (entryFlags & WinLnkType); }
209 bool isJunction() const { return (entryFlags & JunctionType); }
210#else
211 bool isLnkFile() const { return false; }
212 bool isJunction() const { return false; }
213#endif
214
215 qint64 size() const { return size_; }
216
217 QFile::Permissions permissions() const { return QFile::Permissions(Permissions & entryFlags); }
218
219 QDateTime accessTime() const;
220 QDateTime birthTime() const;
221 QDateTime metadataChangeTime() const;
222 QDateTime modificationTime() const;
223
224 QDateTime fileTime(QAbstractFileEngine::FileTime time) const;
225 uint userId() const;
226 uint groupId() const;
227 uint ownerId(QAbstractFileEngine::FileOwner owner) const;
228
229#ifdef Q_OS_UNIX
230 void fillFromStatxBuf(const struct statx &statBuffer);
231 void fillFromStatBuf(const QT_STATBUF &statBuffer);
232 void fillFromDirEnt(const QT_DIRENT &statBuffer);
233#endif
234
235#if defined(Q_OS_WIN)
236 inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false);
237 inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false);
238# ifndef Q_OS_WINRT
239 inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo);
240# endif
241#endif
242private:
243 friend class QFileSystemEngine;
244
245 MetaDataFlags knownFlagsMask;
246 MetaDataFlags entryFlags;
247
248 qint64 size_;
249
250 // Platform-specific data goes here:
251#if defined(Q_OS_WIN)
252 DWORD fileAttribute_;
253 FILETIME birthTime_;
254 FILETIME changeTime_;
255 FILETIME lastAccessTime_;
256 FILETIME lastWriteTime_;
257#else
258 // msec precision
259 qint64 accessTime_;
260 qint64 birthTime_;
261 qint64 metadataChangeTime_;
262 qint64 modificationTime_;
263
264 uint userId_;
265 uint groupId_;
266#endif
267
268};
269
270Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags)
271
272#if defined(Q_OS_DARWIN)
273inline bool QFileSystemMetaData::isBundle() const { return (entryFlags & BundleType); }
274inline bool QFileSystemMetaData::isAlias() const { return (entryFlags & AliasType); }
275#else
276inline bool QFileSystemMetaData::isBundle() const { return false; }
277inline bool QFileSystemMetaData::isAlias() const { return false; }
278#endif
279
280#if defined(Q_OS_UNIX) || defined (Q_OS_WIN)
281inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime time) const
282{
283 switch (time) {
284 case QAbstractFileEngine::ModificationTime:
285 return modificationTime();
286
287 case QAbstractFileEngine::AccessTime:
288 return accessTime();
289
290 case QAbstractFileEngine::BirthTime:
291 return birthTime();
292
293 case QAbstractFileEngine::MetadataChangeTime:
294 return metadataChangeTime();
295 }
296
297 return QDateTime();
298}
299#endif
300
301#if defined(Q_OS_UNIX)
302inline QDateTime QFileSystemMetaData::birthTime() const
303{ return birthTime_ ? QDateTime::fromMSecsSinceEpoch(msecs: birthTime_) : QDateTime(); }
304inline QDateTime QFileSystemMetaData::metadataChangeTime() const
305{ return metadataChangeTime_ ? QDateTime::fromMSecsSinceEpoch(msecs: metadataChangeTime_) : QDateTime(); }
306inline QDateTime QFileSystemMetaData::modificationTime() const
307{ return modificationTime_ ? QDateTime::fromMSecsSinceEpoch(msecs: modificationTime_) : QDateTime(); }
308inline QDateTime QFileSystemMetaData::accessTime() const
309{ return accessTime_ ? QDateTime::fromMSecsSinceEpoch(msecs: accessTime_) : QDateTime(); }
310
311inline uint QFileSystemMetaData::userId() const { return userId_; }
312inline uint QFileSystemMetaData::groupId() const { return groupId_; }
313
314inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const
315{
316 if (owner == QAbstractFileEngine::OwnerUser)
317 return userId();
318 else
319 return groupId();
320}
321#endif
322
323#if defined(Q_OS_WIN)
324inline uint QFileSystemMetaData::userId() const { return (uint) -2; }
325inline uint QFileSystemMetaData::groupId() const { return (uint) -2; }
326inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const
327{
328 if (owner == QAbstractFileEngine::OwnerUser)
329 return userId();
330 else
331 return groupId();
332}
333
334inline void QFileSystemMetaData::fillFromFileAttribute(DWORD fileAttribute,bool isDriveRoot)
335{
336 fileAttribute_ = fileAttribute;
337 // Ignore the hidden attribute for drives.
338 if (!isDriveRoot && (fileAttribute_ & FILE_ATTRIBUTE_HIDDEN))
339 entryFlags |= HiddenAttribute;
340 entryFlags |= ((fileAttribute & FILE_ATTRIBUTE_DIRECTORY) ? DirectoryType: FileType);
341 entryFlags |= ExistsAttribute;
342 knownFlagsMask |= FileType | DirectoryType | HiddenAttribute | ExistsAttribute;
343}
344
345inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType, bool isDriveRoot)
346{
347 fillFromFileAttribute(findData.dwFileAttributes, isDriveRoot);
348 birthTime_ = findData.ftCreationTime;
349 lastAccessTime_ = findData.ftLastAccessTime;
350 changeTime_ = lastWriteTime_ = findData.ftLastWriteTime;
351 if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) {
352 size_ = 0;
353 } else {
354 size_ = findData.nFileSizeHigh;
355 size_ <<= 32;
356 size_ += findData.nFileSizeLow;
357 }
358 knownFlagsMask |= Times | SizeAttribute;
359 if (setLinkType) {
360 knownFlagsMask |= LinkType;
361 entryFlags &= ~LinkType;
362 if (fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) {
363 if (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
364 entryFlags |= LinkType;
365#if defined(IO_REPARSE_TAG_MOUNT_POINT)
366 } else if ((fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY)
367 && (findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) {
368 entryFlags |= JunctionType;
369#endif
370 }
371 }
372 }
373}
374
375#ifndef Q_OS_WINRT
376inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo)
377{
378 fillFromFileAttribute(fileInfo.dwFileAttributes);
379 birthTime_ = fileInfo.ftCreationTime;
380 lastAccessTime_ = fileInfo.ftLastAccessTime;
381 changeTime_ = lastWriteTime_ = fileInfo.ftLastWriteTime;
382 if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) {
383 size_ = 0;
384 } else {
385 size_ = fileInfo.nFileSizeHigh;
386 size_ <<= 32;
387 size_ += fileInfo.nFileSizeLow;
388 }
389 knownFlagsMask |= Times | SizeAttribute;
390}
391#endif // !Q_OS_WINRT
392#endif // Q_OS_WIN
393
394QT_END_NAMESPACE
395
396#endif // include guard
397

source code of qtbase/src/corelib/io/qfilesystemmetadata_p.h