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 QFSFILEENGINE_P_H
6#define QFSFILEENGINE_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/private/qabstractfileengine_p.h"
21#include <QtCore/private/qfilesystementry_p.h>
22#include <QtCore/private/qfilesystemmetadata_p.h>
23#include <qhash.h>
24
25#include <optional>
26
27#ifdef Q_OS_UNIX
28#include <sys/types.h> // for mode_t
29#endif
30
31#ifndef QT_NO_FSFILEENGINE
32
33QT_BEGIN_NAMESPACE
34
35struct ProcessOpenModeResult
36{
37 bool ok;
38 QIODevice::OpenMode openMode;
39 QString error;
40};
41Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode);
42
43class QFSFileEnginePrivate;
44
45class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine
46{
47 Q_DECLARE_PRIVATE(QFSFileEngine)
48public:
49 QFSFileEngine();
50 explicit QFSFileEngine(const QString &file);
51 ~QFSFileEngine();
52
53 bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override;
54 bool open(QIODevice::OpenMode flags, FILE *fh);
55 bool close() override;
56 bool flush() override;
57 bool syncToDisk() override;
58 qint64 size() const override;
59 qint64 pos() const override;
60 bool seek(qint64) override;
61 bool isSequential() const override;
62 bool remove() override;
63 bool copy(const QString &newName) override;
64
65 bool rename(const QString &newName) override
66 { return rename_helper(newName, mode: Rename); }
67 bool renameOverwrite(const QString &newName) override
68 { return rename_helper(newName, mode: RenameOverwrite); }
69
70 bool link(const QString &newName) override;
71 bool mkdir(const QString &dirName, bool createParentDirectories,
72 std::optional<QFile::Permissions> permissions) const override;
73 bool rmdir(const QString &dirName, bool recurseParentDirectories) const override;
74 bool setSize(qint64 size) override;
75 bool caseSensitive() const override;
76 bool isRelativePath() const override;
77 FileFlags fileFlags(FileFlags type) const override;
78 bool setPermissions(uint perms) override;
79 QByteArray id() const override;
80 QString fileName(FileName file) const override;
81 uint ownerId(FileOwner) const override;
82 QString owner(FileOwner) const override;
83 bool setFileTime(const QDateTime &newDate, QFile::FileTime time) override;
84 QDateTime fileTime(QFile::FileTime time) const override;
85 void setFileName(const QString &file) override;
86 void setFileEntry(QFileSystemEntry &&entry);
87 int handle() const override;
88
89#ifndef QT_NO_FILESYSTEMITERATOR
90 IteratorUniquePtr beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
91 const QStringList &filterNames) override;
92#endif
93
94 qint64 read(char *data, qint64 maxlen) override;
95 qint64 readLine(char *data, qint64 maxlen) override;
96 qint64 write(const char *data, qint64 len) override;
97 TriStateResult cloneTo(QAbstractFileEngine *target) override;
98
99 virtual bool isUnnamedFile() const
100 { return false; }
101
102 bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr) override;
103 bool supportsExtension(Extension extension) const override;
104
105 //FS only!!
106 bool open(QIODevice::OpenMode flags, int fd);
107 bool open(QIODevice::OpenMode flags, int fd, QFile::FileHandleFlags handleFlags);
108 bool open(QIODevice::OpenMode flags, FILE *fh, QFile::FileHandleFlags handleFlags);
109 static bool setCurrentPath(const QString &path);
110 static QString currentPath(const QString &path = QString());
111 static QFileInfoList drives();
112
113protected:
114 QFSFileEngine(QFSFileEnginePrivate &dd);
115
116private:
117 enum RenameMode : int { Rename, RenameOverwrite };
118 bool rename_helper(const QString &newName, RenameMode mode);
119};
120
121class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate
122{
123 Q_DECLARE_PUBLIC(QFSFileEngine)
124
125public:
126#ifdef Q_OS_WIN
127 static QString longFileName(const QString &path);
128#endif
129
130 QFileSystemEntry fileEntry;
131 QIODevice::OpenMode openMode;
132
133 bool nativeOpen(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions);
134 bool openFh(QIODevice::OpenMode flags, FILE *fh);
135 bool openFd(QIODevice::OpenMode flags, int fd);
136 bool nativeClose();
137 bool closeFdFh();
138 bool nativeFlush();
139 bool nativeSyncToDisk();
140 bool flushFh();
141 qint64 nativeSize() const;
142#ifndef Q_OS_WIN
143 qint64 sizeFdFh() const;
144#endif
145 qint64 nativePos() const;
146 qint64 posFdFh() const;
147 bool nativeSeek(qint64);
148 bool seekFdFh(qint64);
149 qint64 nativeRead(char *data, qint64 maxlen);
150 qint64 readFdFh(char *data, qint64 maxlen);
151 qint64 nativeReadLine(char *data, qint64 maxlen);
152 qint64 readLineFdFh(char *data, qint64 maxlen);
153 qint64 nativeWrite(const char *data, qint64 len);
154 qint64 writeFdFh(const char *data, qint64 len);
155 int nativeHandle() const;
156 bool nativeIsSequential() const;
157#ifndef Q_OS_WIN
158 bool isSequentialFdFh() const;
159#endif
160#ifdef Q_OS_WIN
161 bool nativeRenameOverwrite(const QFileSystemEntry &newEntry);
162#endif
163
164 uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);
165 bool unmap(uchar *ptr);
166 void unmapAll();
167
168 mutable QFileSystemMetaData metaData;
169
170 FILE *fh;
171
172#ifdef Q_OS_WIN
173 HANDLE fileHandle;
174 HANDLE mapHandle;
175 QHash<uchar *, DWORD /* offset % AllocationGranularity */> maps;
176
177 mutable int cachedFd;
178 mutable DWORD fileAttrib;
179#else
180 struct StartAndLength {
181 int start; // offset % PageSize
182 size_t length; // length + offset % PageSize
183 };
184 QHash<uchar *, StartAndLength> maps;
185#endif
186 int fd;
187
188 enum LastIOCommand
189 {
190 IOFlushCommand,
191 IOReadCommand,
192 IOWriteCommand
193 };
194 LastIOCommand lastIOCommand;
195 bool lastFlushFailed;
196 bool closeFileHandle;
197
198 mutable uint is_sequential : 2;
199 mutable uint tried_stat : 1;
200 mutable uint need_lstat : 1;
201 mutable uint is_link : 1;
202
203#if defined(Q_OS_WIN)
204 bool doStat(QFileSystemMetaData::MetaDataFlags flags) const;
205#else
206 bool doStat(QFileSystemMetaData::MetaDataFlags flags = QFileSystemMetaData::PosixStatFlags) const;
207#endif
208 bool isSymlink() const;
209
210#if defined(Q_OS_WIN32)
211 int sysOpen(const QString &, int flags);
212#endif
213
214 static bool openModeCanCreate(QIODevice::OpenMode openMode)
215 {
216 // WriteOnly can create, but only when ExistingOnly isn't specified.
217 // ReadOnly by itself never creates.
218 return (openMode & QFile::WriteOnly) && !(openMode & QFile::ExistingOnly);
219 }
220protected:
221 QFSFileEnginePrivate(QAbstractFileEngine *q);
222
223 void init();
224
225 QAbstractFileEngine::FileFlags getPermissions(QAbstractFileEngine::FileFlags type) const;
226
227#ifdef Q_OS_UNIX
228 bool nativeOpenImpl(QIODevice::OpenMode openMode, mode_t mode);
229#endif
230};
231
232QT_END_NAMESPACE
233
234#endif // QT_NO_FSFILEENGINE
235
236#endif // QFSFILEENGINE_P_H
237

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