Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qfilesystemmetadata_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QFILESYSTEMMETADATA_P_H
6#define QFILESYSTEMMETADATA_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "qplatformdefs.h"
20#include <QtCore/qglobal.h>
21#include <QtCore/qdatetime.h>
22#include <QtCore/qtimezone.h>
23#include <QtCore/private/qabstractfileengine_p.h>
24
25// Platform-specific includes
26#ifdef Q_OS_WIN
27# include <QtCore/qt_windows.h>
28# ifndef IO_REPARSE_TAG_SYMLINK
29# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
30# endif
31#endif
32
33#ifdef Q_OS_UNIX
34struct statx;
35#endif
36
38
39class QFileSystemEngine;
40
41class Q_AUTOTEST_EXPORT QFileSystemMetaData
42{
43public:
44 QFileSystemMetaData()
45 : size_(-1)
46 {
47 }
48
49 enum MetaDataFlag {
50 // Permissions, overlaps with QFile::Permissions
51 OtherReadPermission = 0x00000004, OtherWritePermission = 0x00000002, OtherExecutePermission = 0x00000001,
52 GroupReadPermission = 0x00000040, GroupWritePermission = 0x00000020, GroupExecutePermission = 0x00000010,
53 UserReadPermission = 0x00000400, UserWritePermission = 0x00000200, UserExecutePermission = 0x00000100,
54 OwnerReadPermission = 0x00004000, OwnerWritePermission = 0x00002000, OwnerExecutePermission = 0x00001000,
55
56 OtherPermissions = OtherReadPermission | OtherWritePermission | OtherExecutePermission,
57 GroupPermissions = GroupReadPermission | GroupWritePermission | GroupExecutePermission,
58 UserPermissions = UserReadPermission | UserWritePermission | UserExecutePermission,
59 OwnerPermissions = OwnerReadPermission | OwnerWritePermission | OwnerExecutePermission,
60
61 ReadPermissions = OtherReadPermission | GroupReadPermission | UserReadPermission | OwnerReadPermission,
62 WritePermissions = OtherWritePermission | GroupWritePermission | UserWritePermission | OwnerWritePermission,
63 ExecutePermissions = OtherExecutePermission | GroupExecutePermission | UserExecutePermission | OwnerExecutePermission,
64
65 Permissions = OtherPermissions | GroupPermissions | UserPermissions | OwnerPermissions,
66
67 // Type
68 LinkType = 0x00010000,
69 FileType = 0x00020000,
70 DirectoryType = 0x00040000,
71#if defined(Q_OS_DARWIN)
72 BundleType = 0x00080000,
73 AliasType = 0x08000000,
74#else
75 BundleType = 0x0,
76 AliasType = 0x0,
77#endif
78#if defined(Q_OS_WIN)
79 JunctionType = 0x04000000,
80 WinLnkType = 0x08000000, // Note: Uses the same position for AliasType on Mac
81#else
82 JunctionType = 0x0,
83 WinLnkType = 0x0,
84#endif
85 SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag
86
87 LegacyLinkType = LinkType | AliasType | WinLnkType,
88
89 Type = LinkType | FileType | DirectoryType | BundleType | SequentialType | AliasType,
90
91 // Attributes
92 HiddenAttribute = 0x00100000,
93 SizeAttribute = 0x00200000, // Note: overlaps with QAbstractFileEngine::LocalDiskFlag
94 ExistsAttribute = 0x00400000, // For historical reasons, indicates existence of data, not the file
95#if defined(Q_OS_WIN)
96 WasDeletedAttribute = 0x0,
97#else
98 WasDeletedAttribute = 0x40000000, // Indicates the file was deleted
99#endif
100
101 Attributes = HiddenAttribute | SizeAttribute | ExistsAttribute | WasDeletedAttribute,
102
103 // Times - if we know one of them, we know them all
104 AccessTime = 0x02000000,
105 BirthTime = 0x02000000,
106 MetadataChangeTime = 0x02000000,
107 ModificationTime = 0x02000000,
108
109 Times = AccessTime | BirthTime | MetadataChangeTime | ModificationTime,
110
111 // Owner IDs
112 UserId = 0x10000000,
113 GroupId = 0x20000000,
114
115 CaseSensitive = 0x80000000,
116
117 OwnerIds = UserId | GroupId,
118
119 PosixStatFlags = OtherPermissions
120 | GroupPermissions
121 | OwnerPermissions
122 | FileType
123 | DirectoryType
124 | SequentialType
125 | SizeAttribute
126 | WasDeletedAttribute
127 | Times
128 | OwnerIds,
129
130#if defined(Q_OS_WIN)
131 WinStatFlags = FileType
132 | DirectoryType
133 | HiddenAttribute
134 | ExistsAttribute
135 | SizeAttribute
136 | Times,
137#endif
138
139 AllMetaDataFlags = 0xFFFFFFFF
140
141 };
142 Q_DECLARE_FLAGS(MetaDataFlags, MetaDataFlag)
143
144 bool hasFlags(MetaDataFlags flags) const
145 {
146 return ((knownFlagsMask & flags) == flags);
147 }
148
149 MetaDataFlags missingFlags(MetaDataFlags flags)
150 {
151 return flags & ~knownFlagsMask;
152 }
153
154 void clear()
155 {
156 knownFlagsMask = {};
157 }
158
159 void clearFlags(MetaDataFlags flags = AllMetaDataFlags)
160 {
161 knownFlagsMask &= ~flags;
162 }
163
164 bool exists() const { return entryFlags.testAnyFlag(ExistsAttribute); }
165
166 bool isLink() const { return entryFlags.testAnyFlag(LinkType); }
167 bool isFile() const { return entryFlags.testAnyFlag(FileType); }
168 bool isDirectory() const { return entryFlags.testAnyFlag(DirectoryType); }
169 bool isBundle() const;
170 bool isAlias() const;
171 bool isLegacyLink() const { return entryFlags.testAnyFlag(LegacyLinkType); }
172 bool isSequential() const { return entryFlags.testAnyFlag(SequentialType); }
173 bool isHidden() const { return entryFlags.testAnyFlag(HiddenAttribute); }
174 bool wasDeleted() const { return entryFlags.testAnyFlag(WasDeletedAttribute); }
175#if defined(Q_OS_WIN)
176 bool isLnkFile() const { return entryFlags.testAnyFlag(WinLnkType); }
177 bool isJunction() const { return entryFlags.testAnyFlag(JunctionType); }
178#else
179 bool isLnkFile() const { return false; }
180 bool isJunction() const { return false; }
181#endif
182
183 qint64 size() const { return size_; }
184
185 inline QFile::Permissions permissions() const;
186 // Has to be defined after the
187 // Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags) call below.
188 inline void setPermissions(QFile::Permissions permissions);
189
190 QDateTime accessTime() const;
191 QDateTime birthTime() const;
192 QDateTime metadataChangeTime() const;
193 QDateTime modificationTime() const;
194
195 QDateTime fileTime(QFile::FileTime time) const;
196 uint userId() const;
197 uint groupId() const;
198 uint ownerId(QAbstractFileEngine::FileOwner owner) const;
199
200 bool isReadable() const { return permissions().testAnyFlags(QFile::ReadUser); }
201 bool isWritable() const { return permissions().testAnyFlags(QFile::WriteUser); }
202 bool isExecutable() const { return permissions().testAnyFlags(QFile::ExeUser); }
203
204#ifdef Q_OS_UNIX
205 void fillFromStatxBuf(const struct statx &statBuffer);
206 void fillFromStatBuf(const QT_STATBUF &statBuffer);
207 void fillFromDirEnt(const QT_DIRENT &statBuffer);
208#endif
209
210#if defined(Q_OS_WIN)
211 inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false);
212 inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false);
213 inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo);
214#endif
215private:
216 friend class QFileSystemEngine;
217
218 MetaDataFlags knownFlagsMask;
219 MetaDataFlags entryFlags;
220
221 qint64 size_ = 0;
222
223 // Platform-specific data goes here:
224#if defined(Q_OS_WIN)
225 DWORD fileAttribute_;
226 FILETIME birthTime_;
227 FILETIME changeTime_;
228 FILETIME lastAccessTime_;
229 FILETIME lastWriteTime_;
230#else
231 // msec precision
232 qint64 accessTime_ = 0;
233 qint64 birthTime_ = 0;
234 qint64 metadataChangeTime_ = 0;
235 qint64 modificationTime_ = 0;
236
237 uint userId_ = (uint) -2;
238 uint groupId_ = (uint) -2;
239#endif
240
241};
242
243Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags)
244
245inline QFile::Permissions QFileSystemMetaData::permissions() const { return QFile::Permissions::fromInt((Permissions & entryFlags).toInt()); }
246
247void QFileSystemMetaData::setPermissions(QFile::Permissions permissions)
248{
249 entryFlags &= ~Permissions;
250 entryFlags |= MetaDataFlag(uint(permissions.toInt()));
251 knownFlagsMask |= Permissions;
252}
253
254#if defined(Q_OS_DARWIN)
255inline bool QFileSystemMetaData::isBundle() const { return entryFlags.testAnyFlag(BundleType); }
256inline bool QFileSystemMetaData::isAlias() const { return entryFlags.testAnyFlag(AliasType); }
257#else
258inline bool QFileSystemMetaData::isBundle() const { return false; }
259inline bool QFileSystemMetaData::isAlias() const { return false; }
260#endif
261
262#if defined(Q_OS_UNIX) || defined (Q_OS_WIN)
263inline QDateTime QFileSystemMetaData::fileTime(QFile::FileTime time) const
264{
265 switch (time) {
266 case QFile::FileModificationTime:
267 return modificationTime();
268
269 case QFile::FileAccessTime:
270 return accessTime();
271
272 case QFile::FileBirthTime:
273 return birthTime();
274
275 case QFile::FileMetadataChangeTime:
276 return metadataChangeTime();
277 }
278
279 return QDateTime();
280}
281#endif
282
283#if defined(Q_OS_UNIX)
284inline QDateTime QFileSystemMetaData::birthTime() const
285{
286 return birthTime_
287 ? QDateTime::fromMSecsSinceEpoch(birthTime_, QTimeZone::UTC)
288 : QDateTime();
289}
290inline QDateTime QFileSystemMetaData::metadataChangeTime() const
291{
292 return metadataChangeTime_
293 ? QDateTime::fromMSecsSinceEpoch(metadataChangeTime_, QTimeZone::UTC)
294 : QDateTime();
295}
296inline QDateTime QFileSystemMetaData::modificationTime() const
297{
298 return modificationTime_
299 ? QDateTime::fromMSecsSinceEpoch(modificationTime_, QTimeZone::UTC)
300 : QDateTime();
301}
302inline QDateTime QFileSystemMetaData::accessTime() const
303{
304 return accessTime_
305 ? QDateTime::fromMSecsSinceEpoch(accessTime_, QTimeZone::UTC)
306 : QDateTime();
307}
308
309inline uint QFileSystemMetaData::userId() const { return userId_; }
310inline uint QFileSystemMetaData::groupId() const { return groupId_; }
311
312inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const
313{
314 if (owner == QAbstractFileEngine::OwnerUser)
315 return userId();
316 else
317 return groupId();
318}
319#endif
320
321#if defined(Q_OS_WIN)
322inline uint QFileSystemMetaData::userId() const { return (uint) -2; }
323inline uint QFileSystemMetaData::groupId() const { return (uint) -2; }
324inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const
325{
326 if (owner == QAbstractFileEngine::OwnerUser)
327 return userId();
328 else
329 return groupId();
330}
331
332inline void QFileSystemMetaData::fillFromFileAttribute(DWORD fileAttribute,bool isDriveRoot)
333{
334 fileAttribute_ = fileAttribute;
335 // Ignore the hidden attribute for drives.
336 if (!isDriveRoot && (fileAttribute_ & FILE_ATTRIBUTE_HIDDEN))
337 entryFlags |= HiddenAttribute;
338 entryFlags |= ((fileAttribute & FILE_ATTRIBUTE_DIRECTORY) ? DirectoryType: FileType);
339 entryFlags |= ExistsAttribute;
340 knownFlagsMask |= FileType | DirectoryType | HiddenAttribute | ExistsAttribute;
341
342 // this function is never called for a .lnk file
343 knownFlagsMask |= WinLnkType;
344}
345
346inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType, bool isDriveRoot)
347{
348 fillFromFileAttribute(findData.dwFileAttributes, isDriveRoot);
349 birthTime_ = findData.ftCreationTime;
350 lastAccessTime_ = findData.ftLastAccessTime;
351 changeTime_ = lastWriteTime_ = findData.ftLastWriteTime;
352 if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) {
353 size_ = 0;
354 } else {
355 size_ = findData.nFileSizeHigh;
356 size_ <<= 32;
357 size_ += findData.nFileSizeLow;
358 }
359 knownFlagsMask |= Times | SizeAttribute;
360 if (setLinkType) {
361 knownFlagsMask |= LinkType;
362 entryFlags &= ~LinkType;
363 if (fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) {
364 if (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
365 entryFlags |= LinkType;
366#if defined(IO_REPARSE_TAG_MOUNT_POINT)
367 } else if ((fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY)
368 && (findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) {
369 entryFlags |= JunctionType;
370#endif
371 }
372 }
373 }
374}
375
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_WIN
392
393QT_END_NAMESPACE
394
395#endif // include guard
\inmodule QtCore
Definition qdirlisting.h:68
QDirPrivate(const QDirPrivate &copy)
Definition qdir.cpp:105
@ UrlNormalizationMode
Definition qdir_p.h:34
@ RemotePath
Definition qdir_p.h:35
MetaDataClearing
Definition qdir_p.h:65
@ IncludingMetaData
Definition qdir_p.h:65
void clearCache(MetaDataClearing mode)
Definition qdir.cpp:470
void initFileLists(const QDir &dir) const
Definition qdir.cpp:455
bool exists() const
Definition qdir.cpp:122
QString resolveAbsoluteEntry() const
Definition qdir.cpp:178
bool operator()(const QDirSortItem &, const QDirSortItem &) const
Definition qdir.cpp:258
QDirSortItemComparator(QDir::SortFlags flags, QCollator *coll=nullptr)
Definition qdir.cpp:232
int compareStrings(const QString &a, const QString &b, Qt::CaseSensitivity cs) const
Definition qdir.cpp:248
\inmodule QtCore
Definition qmutex.h:346
static void appendIfMatchesNonDirListingFlags(const QDirListing::DirEntry &dirEntry, QDir::Filters filters, QFileInfoList &l)
Definition qdir.cpp:402
static qsizetype rootLength(QStringView name, QDirPrivate::PathNormalizations flags)
Definition qdir.cpp:56
static bool qt_cleanPath(QString *path)
Definition qdir.cpp:2485
bool comparesEqual(const QDir &lhs, const QDir &rhs)
Definition qdir.cpp:1936
static bool treatAsAbsolute(const QString &path)
Definition qdir.cpp:866
static bool checkPermissions(const QDirListing::DirEntry &dirEntry, QDir::Filters filters)
Definition qdir.cpp:364
bool qt_normalizePathSegments(QString *path, QDirPrivate::PathNormalizations flags)
Definition qdir.cpp:2346
static bool checkDotOrDotDot(const QDirListing::DirEntry &dirEntry, QDir::Filters filters)
Definition qdir.cpp:380
Q_AUTOTEST_EXPORT bool qt_normalizePathSegments(QString *path, QDirPrivate::PathNormalizations flags)
Definition qdir.cpp:2346
QFileInfo item
Definition qdir.cpp:220
QString suffix_cache
Definition qdir.cpp:219
QDirSortItem(const QFileInfo &fi, QDir::SortFlags sort)
Definition qdir.cpp:208
QDirSortItem()=default
QString filename_cache
Definition qdir.cpp:218