Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qfsfileengine_win.cpp
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
4#include "qplatformdefs.h"
5#include "private/qabstractfileengine_p.h"
6#include "private/qfiledevice_p.h"
7#include "private/qfsfileengine_p.h"
9#include <qdebug.h>
10
11#include "qfile.h"
12#include "qdir.h"
13#include "qvarlengtharray.h"
14#include "qdatetime.h"
15#include "qt_windows.h"
16
17#include <sys/types.h>
18#include <direct.h>
19#include <winioctl.h>
20#include <objbase.h>
21#include <shlobj.h>
22#include <accctrl.h>
23#include <initguid.h>
24#include <ctype.h>
25#include <limits.h>
26#include <stdio.h>
27#define SECURITY_WIN32
28#include <security.h>
29
30#ifndef PATH_MAX
31#define PATH_MAX FILENAME_MAX
32#endif
33
35
36using namespace Qt::StringLiterals;
37
38static inline bool isUncPath(const QString &path)
39{
40 // Starts with \\, but not \\.
41 return (path.startsWith("\\\\"_L1)
42 && path.size() > 2 && path.at(2) != u'.');
43}
44
48QString QFSFileEnginePrivate::longFileName(const QString &path)
49{
50 if (path.startsWith("\\\\.\\"_L1))
51 return path;
52
53 QString absPath = QFileSystemEngine::nativeAbsoluteFilePath(path);
54 QString prefix = "\\\\?\\"_L1;
55 if (isUncPath(absPath)) {
56 prefix.append("UNC\\"_L1); // "\\\\?\\UNC\\"
57 absPath.remove(0, 2);
58 }
59 return prefix + absPath;
60}
61
62/*
63 \internal
64*/
65bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode,
66 std::optional<QFile::Permissions> permissions)
67{
68 Q_Q(QFSFileEngine);
69
70 // All files are opened in share mode (both read and write).
71 DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
72
73 int accessRights = 0;
75 accessRights |= GENERIC_READ;
77 accessRights |= GENERIC_WRITE;
78
79 // WriteOnly can create files, ReadOnly cannot.
80 DWORD creationDisp = (openMode & QIODevice::NewOnly)
81 ? CREATE_NEW
83 ? OPEN_ALWAYS
84 : OPEN_EXISTING;
85 // Create the file handle.
86 QNativeFilePermissions nativePermissions(permissions, false);
87 if (!nativePermissions.isOk())
88 return false;
89
90 fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
91 accessRights,
92 shareMode,
93 nativePermissions.securityAttributes(),
94 creationDisp,
95 FILE_ATTRIBUTE_NORMAL,
96 NULL);
97
98 // Bail out on error.
99 if (fileHandle == INVALID_HANDLE_VALUE) {
100 q->setError(QFile::OpenError, qt_error_string());
101 return false;
102 }
103
104 // Truncate the file after successfully opening it if Truncate is passed.
106 q->setSize(0);
107
108 return true;
109}
110
111/*
112 \internal
113*/
115{
116 Q_Q(QFSFileEngine);
117 if (fh || fd != -1) {
118 // stdlib / stdio mode.
119 return closeFdFh();
120 }
121
122 // Windows native mode.
123 bool ok = true;
124
125 if (cachedFd != -1) {
126 if (::_close(cachedFd) && !::CloseHandle(fileHandle)) {
128 ok = false;
129 }
130
131 // System handle is closed with associated file descriptor.
132 fileHandle = INVALID_HANDLE_VALUE;
133 cachedFd = -1;
134
135 return ok;
136 }
137
138 if ((fileHandle == INVALID_HANDLE_VALUE || !::CloseHandle(fileHandle))) {
140 ok = false;
141 }
142 fileHandle = INVALID_HANDLE_VALUE;
143 return ok;
144}
145
146/*
147 \internal
148*/
150{
151 if (fh) {
152 // Buffered stdlib mode.
153 return flushFh();
154 }
155 if (fd != -1) {
156 // Unbuffered stdio mode; always succeeds (no buffer).
157 return true;
158 }
159
160 // Windows native mode; flushing is unnecessary.
161 return true;
162}
163
164/*
165 \internal
166 \since 5.1
167*/
169{
170 if (fh || fd != -1) {
171 // stdlib / stdio mode. No API available.
172 return false;
173 }
174 return FlushFileBuffers(fileHandle);
175}
176
177/*
178 \internal
179*/
181{
182 Q_Q(const QFSFileEngine);
183 QFSFileEngine *thatQ = const_cast<QFSFileEngine *>(q);
184
185 // ### Don't flush; for buffered files, we should get away with ftell.
186 thatQ->flush();
187
188 // Always retrieve the current information
190 bool filled = false;
191 if (fileHandle != INVALID_HANDLE_VALUE && openMode != QIODevice::NotOpen )
192 filled = QFileSystemEngine::fillMetaData(fileHandle, metaData,
194 else
196
197 if (!filled) {
199 return 0;
200 }
201 return metaData.size();
202}
203
204/*
205 \internal
206*/
208{
209 Q_Q(const QFSFileEngine);
210 QFSFileEngine *thatQ = const_cast<QFSFileEngine *>(q);
211
212 if (fh || fd != -1) {
213 // stdlib / stido mode.
214 return posFdFh();
215 }
216
217 // Windows native mode.
218 if (fileHandle == INVALID_HANDLE_VALUE)
219 return 0;
220
221 LARGE_INTEGER currentFilePos;
222 LARGE_INTEGER offset;
223 offset.QuadPart = 0;
224 if (!::SetFilePointerEx(fileHandle, offset, &currentFilePos, FILE_CURRENT)) {
226 return 0;
227 }
228
229 return qint64(currentFilePos.QuadPart);
230}
231
232/*
233 \internal
234*/
236{
237 Q_Q(QFSFileEngine);
238
239 if (fh || fd != -1) {
240 // stdlib / stdio mode.
241 return seekFdFh(pos);
242 }
243
244 LARGE_INTEGER currentFilePos;
245 LARGE_INTEGER offset;
246 offset.QuadPart = pos;
247 if (!::SetFilePointerEx(fileHandle, offset, &currentFilePos, FILE_BEGIN)) {
249 return false;
250 }
251
252 return true;
253}
254
255/*
256 \internal
257*/
259{
260 Q_Q(QFSFileEngine);
261
262 if (fh || fd != -1) {
263 // stdio / stdlib mode.
264 if (fh && nativeIsSequential() && feof(fh)) {
266 return -1;
267 }
268
269 return readFdFh(data, maxlen);
270 }
271
272 // Windows native mode.
273 if (fileHandle == INVALID_HANDLE_VALUE)
274 return -1;
275
276 qint64 bytesToRead = maxlen;
277
278 // Reading on Windows fails with ERROR_NO_SYSTEM_RESOURCES when
279 // the chunks are too large, so we limit the block size to 32MB.
280 static const qint64 maxBlockSize = 32 * 1024 * 1024;
281
282 qint64 totalRead = 0;
283 do {
284 DWORD blockSize = DWORD(qMin(bytesToRead, maxBlockSize));
285 DWORD bytesRead;
286 if (!ReadFile(fileHandle, data + totalRead, blockSize, &bytesRead, NULL)) {
287 if (totalRead == 0) {
288 // Note: only return failure if the first ReadFile fails.
289 q->setError(QFile::ReadError, qt_error_string());
290 return -1;
291 }
292 break;
293 }
294 if (bytesRead == 0)
295 break;
296 totalRead += bytesRead;
297 bytesToRead -= bytesRead;
298 } while (totalRead < maxlen);
299 return totalRead;
300}
301
302/*
303 \internal
304*/
306{
307 Q_Q(QFSFileEngine);
308
309 if (fh || fd != -1) {
310 // stdio / stdlib mode.
311 return readLineFdFh(data, maxlen);
312 }
313
314 // Windows native mode.
315 if (fileHandle == INVALID_HANDLE_VALUE)
316 return -1;
317
318 // ### No equivalent in Win32?
319 return q->QAbstractFileEngine::readLine(data, maxlen);
320}
321
322/*
323 \internal
324*/
326{
327 Q_Q(QFSFileEngine);
328
329 if (fh || fd != -1) {
330 // stdio / stdlib mode.
331 return writeFdFh(data, len);
332 }
333
334 // Windows native mode.
335 if (fileHandle == INVALID_HANDLE_VALUE)
336 return -1;
337
338 qint64 bytesToWrite = len;
339
340 // Writing on Windows fails with ERROR_NO_SYSTEM_RESOURCES when
341 // the chunks are too large, so we limit the block size to 32MB.
342 qint64 totalWritten = 0;
343 do {
344 const DWORD currentBlockSize = DWORD(qMin(bytesToWrite, qint64(32 * 1024 * 1024)));
345 DWORD bytesWritten;
346 if (!WriteFile(fileHandle, data + totalWritten, currentBlockSize, &bytesWritten, NULL)) {
347 if (totalWritten == 0) {
348 // Note: Only return error if the first WriteFile failed.
349 q->setError(QFile::WriteError, qt_error_string());
350 return -1;
351 }
352 break;
353 }
354 if (bytesWritten == 0)
355 break;
356 totalWritten += bytesWritten;
357 bytesToWrite -= bytesWritten;
358 } while (totalWritten < len);
359 return qint64(totalWritten);
360}
361
362/*
363 \internal
364*/
366{
367 if (fh || fd != -1)
368 return fh ? QT_FILENO(fh) : fd;
369 if (cachedFd != -1)
370 return cachedFd;
371
372 int flags = 0;
374 flags |= _O_APPEND;
376 flags |= _O_RDONLY;
377 cachedFd = _open_osfhandle((intptr_t) fileHandle, flags);
378 return cachedFd;
379}
380
381/*
382 \internal
383*/
385{
386 HANDLE handle = fileHandle;
387 if (fh || fd != -1)
388 handle = (HANDLE)_get_osfhandle(fh ? QT_FILENO(fh) : fd);
389 if (handle == INVALID_HANDLE_VALUE)
390 return false;
391
392 DWORD fileType = GetFileType(handle);
393 return (fileType == FILE_TYPE_CHAR)
394 || (fileType == FILE_TYPE_PIPE);
395}
396
398{
399 return false;
400}
401
403{
404 QString ret;
405 //if filename is a drive: then get the pwd of that drive
406 if (fileName.length() >= 2 &&
407 fileName.at(0).isLetter() && fileName.at(1) == u':') {
408 int drv = fileName.toUpper().at(0).toLatin1() - 'A' + 1;
409 if (_getdrive() != drv) {
410 wchar_t buf[PATH_MAX];
411 ::_wgetdcwd(drv, buf, PATH_MAX);
413 }
414 }
415 if (ret.isEmpty()) {
416 //just the pwd
418 }
419 if (ret.length() >= 2 && ret[1] == u':')
420 ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
421 return ret;
422}
423
424// cf QStorageInfo::isReady
425static inline bool isDriveReady(const wchar_t *path)
426{
427 DWORD fileSystemFlags;
428 const UINT driveType = GetDriveType(path);
429 return (driveType != DRIVE_REMOVABLE && driveType != DRIVE_CDROM)
430 || GetVolumeInformation(path, nullptr, 0, nullptr, nullptr,
431 &fileSystemFlags, nullptr, 0) == TRUE;
432}
433
435{
437 const UINT oldErrorMode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
438 quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff;
439 wchar_t driveName[] = L"A:\\";
440
441 while (driveBits) {
442 if ((driveBits & 1) && isDriveReady(driveName))
443 ret.append(QFileInfo(QString::fromWCharArray(driveName)));
444 driveName[0]++;
445 driveBits = driveBits >> 1;
446 }
447 ::SetErrorMode(oldErrorMode);
448 return ret;
449}
450
451bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const
452{
453 if (!tried_stat || !metaData.hasFlags(flags)) {
454 tried_stat = true;
455
456 int localFd = fd;
457 if (fh && fileEntry.isEmpty())
458 localFd = QT_FILENO(fh);
459 if (localFd != -1)
463 }
464
465 return metaData.exists();
466}
467
468// ### assume that they add .lnk to newName
469bool QFSFileEngine::link(const QString &newName)
470{
473 QFileSystemEntry(newName), error);
474 if (!ret)
475 setError(QFile::RenameError, error.toString());
476 return ret;
477}
478
482QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::FileFlags type) const
483{
484 Q_D(const QFSFileEngine);
485
486 if (type & Refresh)
487 d->metaData.clear();
488
489 QAbstractFileEngine::FileFlags ret;
490
491 if (type & FlagsMask)
493
494 bool exists;
495 {
496 QFileSystemMetaData::MetaDataFlags queryFlags;
497
498 queryFlags |= QFileSystemMetaData::MetaDataFlags::fromInt(type.toInt())
500
501 // AliasType and BundleType are 0x0
502 if (type & TypesMask)
508
509 if (type & FlagsMask)
512
513 queryFlags |= QFileSystemMetaData::LinkType;
514
515 exists = d->doStat(queryFlags);
516 }
517
518 if (exists && (type & PermsMask))
519 ret |= FileFlags::fromInt(d->metaData.permissions().toInt());
520
521 if (type & TypesMask) {
522 if ((type & LinkType) && d->metaData.isLegacyLink())
523 ret |= LinkType;
524 if (d->metaData.isDirectory()) {
526 } else {
527 ret |= FileType;
528 }
529 }
530 if (type & FlagsMask) {
531 if (d->metaData.exists()) {
532 // if we succeeded in querying, then the file exists: a file on
533 // Windows cannot be deleted if we have an open handle to it
534 ret |= ExistsFlag;
535 if (d->fileEntry.isRoot())
536 ret |= RootFlag;
537 else if (d->metaData.isHidden())
538 ret |= HiddenFlag;
539 }
540 }
541 return ret;
542}
543
545{
546 Q_D(const QFSFileEngine);
547 HANDLE h = d->fileHandle;
548 if (h == INVALID_HANDLE_VALUE) {
549 int localFd = d->fd;
550 if (d->fh && d->fileEntry.isEmpty())
551 localFd = QT_FILENO(d->fh);
552 if (localFd != -1)
553 h = HANDLE(_get_osfhandle(localFd));
554 }
555 if (h != INVALID_HANDLE_VALUE)
556 return QFileSystemEngine::id(h);
557
558 // file is not open, try by path
559 return QFileSystemEngine::id(d->fileEntry);
560}
561
563{
564 Q_D(const QFSFileEngine);
565 switch (file) {
566 case BaseName:
567 return d->fileEntry.fileName();
568 case PathName:
569 return d->fileEntry.path();
570 case AbsoluteName:
571 case AbsolutePathName: {
572 QString ret = d->fileEntry.filePath();
573 if (isRelativePath()) {
575 } else if (ret.startsWith(u'/') // absolute path to the current drive, so \a.txt -> Z:\a.txt
576 || ret.size() == 2 // or a drive letter that needs to get a working dir appended
577 // or a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt
578 || (ret.size() > 2 && ret.at(2) != u'/')
579 || ret.contains(QStringView(u"/../"))
580 || ret.contains(QStringView(u"/./"))
581 || ret.endsWith(QStringView(u"/.."))
582 || ret.endsWith(QStringView(u"/."))) {
583 ret = QDir::fromNativeSeparators(QFileSystemEngine::nativeAbsoluteFilePath(ret));
584 }
585
586 // The path should be absolute at this point.
587 // From the docs :
588 // Absolute paths begin with the directory separator "/"
589 // (optionally preceded by a drive specification under Windows).
590 if (ret.at(0) != u'/') {
591 Q_ASSERT(ret.length() >= 2);
592 Q_ASSERT(ret.at(0).isLetter());
593 Q_ASSERT(ret.at(1) == u':');
594
595 // Force uppercase drive letters.
596 ret[0] = ret.at(0).toUpper();
597 }
598
599 if (file == AbsolutePathName) {
600 int slash = ret.lastIndexOf(u'/');
601 if (slash < 0)
602 return ret;
603 if (ret.at(0) != u'/' && slash == 2)
604 return ret.left(3); // include the slash
605 return ret.left(slash > 0 ? slash : 1);
606 }
607 return ret;
608 }
609 case CanonicalName:
610 case CanonicalPathName: {
612 return QString();
613 const QFileSystemEntry entry =
615
616 if (file == CanonicalPathName)
617 return entry.path();
618 return entry.filePath();
619 }
621 return QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData).filePath();
622 case RawLinkPath:
623 return QFileSystemEngine::getRawLinkPath(d->fileEntry, d->metaData).filePath();
624 case BundleName:
625 return QString();
626 case JunctionName:
627 return QFileSystemEngine::getJunctionTarget(d->fileEntry, d->metaData).filePath();
628 case DefaultName:
629 break;
630 case NFileNames:
631 Q_ASSERT(false);
632 break;
633 }
634 return d->fileEntry.filePath();
635}
636
638{
639 Q_D(const QFSFileEngine);
640 // drive, e.g. "a:", or UNC root, e.q. "//"
641 return d->fileEntry.isRelative();
642}
643
644uint QFSFileEngine::ownerId(FileOwner /*own*/) const
645{
646 static const uint nobodyID = (uint) -2;
647 return nobodyID;
648}
649
650QString QFSFileEngine::owner(FileOwner own) const
651{
652 Q_D(const QFSFileEngine);
653 return QFileSystemEngine::owner(d->fileEntry, own);
654}
655
657{
658 Q_D(QFSFileEngine);
660
661 // clear cached state (if any)
662 d->metaData.clearFlags(QFileSystemMetaData::Permissions);
663
664 bool ret = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error);
665 if (!ret)
667 return ret;
668}
669
671{
672 Q_D(QFSFileEngine);
673
674 if (d->fileHandle != INVALID_HANDLE_VALUE || d->fd != -1 || d->fh) {
675 // resize open file
676 HANDLE fh = d->fileHandle;
677 if (fh == INVALID_HANDLE_VALUE) {
678 if (d->fh)
679 fh = (HANDLE)_get_osfhandle(QT_FILENO(d->fh));
680 else
681 fh = (HANDLE)_get_osfhandle(d->fd);
682 }
683 if (fh == INVALID_HANDLE_VALUE)
684 return false;
685 qint64 currentPos = pos();
686
687 if (seek(size) && SetEndOfFile(fh)) {
688 seek(qMin(currentPos, size));
689 return true;
690 }
691
692 seek(currentPos);
693 return false;
694 }
695
696 if (!d->fileEntry.isEmpty()) {
697 // resize file on disk
698 QFile file(d->fileEntry.filePath());
700 bool ret = file.resize(size);
701 if (!ret)
703 return ret;
704 }
705 }
706 return false;
707}
708
709bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time)
710{
711 Q_D(QFSFileEngine);
712
713 if (d->openMode == QFile::NotOpen) {
714 setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
715 return false;
716 }
717
719 setError(QFile::UnspecifiedError, qt_error_string(ERROR_INVALID_PARAMETER));
720 return false;
721 }
722
723 HANDLE handle = d->fileHandle;
724 if (handle == INVALID_HANDLE_VALUE) {
725 if (d->fh)
726 handle = reinterpret_cast<HANDLE>(::_get_osfhandle(QT_FILENO(d->fh)));
727 else if (d->fd != -1)
728 handle = reinterpret_cast<HANDLE>(::_get_osfhandle(d->fd));
729 }
730
731 if (handle == INVALID_HANDLE_VALUE) {
732 setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
733 return false;
734 }
735
739 return false;
740 }
741
742 d->metaData.clearFlags(QFileSystemMetaData::Times);
743 return true;
744}
745
747 QFile::MemoryMapFlags flags)
748{
749 Q_Q(QFSFileEngine);
751 if (openMode == QFile::NotOpen) {
752 q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
753 return 0;
754 }
755 if (offset == 0 && size == 0) {
756 q->setError(QFile::UnspecifiedError, qt_error_string(ERROR_INVALID_PARAMETER));
757 return 0;
758 }
759
760 // check/setup args to map
761 DWORD access = 0;
763#ifdef FILE_MAP_COPY
764 access = FILE_MAP_COPY;
765#else
766 q->setError(QFile::UnspecifiedError, "MapPrivateOption unsupported");
767 return 0;
768#endif
769 } else if (openMode & QIODevice::WriteOnly) {
770 access = FILE_MAP_WRITE;
771 } else if (openMode & QIODevice::ReadOnly) {
772 access = FILE_MAP_READ;
773 }
774
775 if (mapHandle == NULL) {
776 // get handle to the file
777 HANDLE handle = fileHandle;
778
779 if (handle == INVALID_HANDLE_VALUE && fh)
780 handle = (HANDLE)::_get_osfhandle(QT_FILENO(fh));
781
782#ifdef Q_USE_DEPRECATED_MAP_API
783 nativeClose();
784 // handle automatically closed by kernel with mapHandle (below).
785 handle = ::CreateFileForMapping((const wchar_t*)fileEntry.nativeFilePath().utf16(),
786 GENERIC_READ | (openMode & QIODevice::WriteOnly ? GENERIC_WRITE : 0),
787 0,
788 NULL,
789 OPEN_EXISTING,
790 FILE_ATTRIBUTE_NORMAL,
791 NULL);
792 // Since this is a special case, we check if the return value was NULL and if so
793 // we change it to INVALID_HANDLE_VALUE to follow the logic inside this function.
794 if (!handle)
795 handle = INVALID_HANDLE_VALUE;
796#endif
797
798 if (handle == INVALID_HANDLE_VALUE) {
799 q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
800 return 0;
801 }
802
803 // first create the file mapping handle
804 DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY;
805 mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0);
806 if (mapHandle == NULL) {
808#ifdef Q_USE_DEPRECATED_MAP_API
809 ::CloseHandle(handle);
810#endif
811 return 0;
812 }
813 }
814
815 DWORD offsetHi = offset >> 32;
816 DWORD offsetLo = offset & Q_UINT64_C(0xffffffff);
817 SYSTEM_INFO sysinfo;
818 ::GetSystemInfo(&sysinfo);
819 DWORD mask = sysinfo.dwAllocationGranularity - 1;
820 DWORD extra = offset & mask;
821 if (extra)
822 offsetLo &= ~mask;
823
824 // attempt to create the map
825 LPVOID mapAddress = ::MapViewOfFile(mapHandle, access,
826 offsetHi, offsetLo, size + extra);
827 if (mapAddress) {
828 uchar *address = extra + static_cast<uchar*>(mapAddress);
829 maps[address] = extra;
830 return address;
831 }
832
833 switch(GetLastError()) {
834 case ERROR_ACCESS_DENIED:
836 break;
837 case ERROR_INVALID_PARAMETER:
838 // size are out of bounds
839 default:
841 }
842
843 ::CloseHandle(mapHandle);
844 mapHandle = NULL;
845 return 0;
846}
847
849{
850 Q_Q(QFSFileEngine);
851 const auto it = std::as_const(maps).find(ptr);
852 if (it == maps.cend()) {
853 q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
854 return false;
855 }
856 uchar *start = ptr - *it;
857 if (!UnmapViewOfFile(start)) {
859 return false;
860 }
861
862 maps.erase(it);
863 if (maps.isEmpty()) {
864 ::CloseHandle(mapHandle);
865 mapHandle = NULL;
866 }
867
868 return true;
869}
870
875{
876 // There's some Windows Server 2016 API, but we won't
877 // bother with it.
879 return false;
880}
881
\inmodule QtCore \reentrant
void setError(QFile::FileError error, const QString &str)
Sets the error type to error, and the error string to errorString.
QFile::FileError error() const
Returns the QFile::FileError that resulted from the last failed operation.
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore\reentrant
Definition qdatetime.h:257
bool isValid() const
Returns true if this datetime represents a definite moment, otherwise false.
static QString fromNativeSeparators(const QString &pathName)
Definition qdir.cpp:962
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2395
static QString currentPath()
Returns the absolute path of the application's current directory.
Definition qdir.cpp:2051
qint64 nativeRead(char *data, qint64 maxlen)
qint64 readFdFh(char *data, qint64 maxlen)
QHash< uchar *, StartAndLength > maps
qint64 writeFdFh(const char *data, qint64 len)
QIODevice::OpenMode openMode
QFileSystemEntry fileEntry
bool doStat(QFileSystemMetaData::MetaDataFlags flags=QFileSystemMetaData::PosixStatFlags) const
bool nativeOpen(QIODevice::OpenMode openMode, std::optional< QFile::Permissions > permissions)
QFileSystemMetaData metaData
static bool openModeCanCreate(QIODevice::OpenMode openMode)
qint64 readLineFdFh(char *data, qint64 maxlen)
qint64 nativeWrite(const char *data, qint64 len)
uchar * map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags)
qint64 nativeReadLine(char *data, qint64 maxlen)
\inmodule QtCore
static QFileInfoList drives()
For Windows, returns the list of drives in the file system as a list of QFileInfo objects.
QString fileName(FileName file) const override
\reimp
uint ownerId(FileOwner) const override
In Unix, if stat() is successful, the uid is returned if own is the owner.
static QString currentPath(const QString &path=QString())
For Unix, returns the current working directory for the file engine.
bool cloneTo(QAbstractFileEngine *target) override
\reimp
bool setSize(qint64 size) override
\reimp
bool setPermissions(uint perms) override
\reimp
qint64 pos() const override
\reimp
bool caseSensitive() const override
Returns false for Windows, true for Unix.
QByteArray id() const override
bool seek(qint64) override
\reimp
bool link(const QString &newName) override
Creates a link from the file currently specified by fileName() to newName.
bool isRelativePath() const override
\reimp
bool setFileTime(const QDateTime &newDate, FileTime time) override
\reimp
FileFlags fileFlags(FileFlags type) const override
\reimp
QString owner(FileOwner) const override
\reimp
bool flush() override
\reimp
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
static bool setFileTime(const QFileSystemEntry &entry, const QDateTime &newDate, QAbstractFileEngine::FileTime whatTime, QSystemError &error)
static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data)
static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data)
static QByteArray id(const QFileSystemEntry &entry)
static QFileSystemEntry getRawLinkPath(const QFileSystemEntry &link, QFileSystemMetaData &data)
static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what)
static bool createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
static QFileSystemEntry getJunctionTarget(const QFileSystemEntry &link, QFileSystemMetaData &data)
static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data=nullptr)
static QFileSystemEntry currentPath()
Q_AUTOTEST_EXPORT NativePath nativeFilePath() const
Q_AUTOTEST_EXPORT bool isEmpty() const
Q_AUTOTEST_EXPORT QString filePath() const
bool hasFlags(MetaDataFlags flags) const
void clearFlags(MetaDataFlags flags=AllMetaDataFlags)
MetaDataFlags missingFlags(MetaDataFlags flags)
\inmodule QtCore
Definition qfile.h:93
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition qfile.cpp:881
bool resize(qint64 sz) override
\reimp
Definition qfile.cpp:1080
QString errorString() const
Returns a human-readable description of the last device error that occurred.
iterator find(const T &value)
Definition qset.h:159
\inmodule QtCore
Definition qstringview.h:76
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
Definition qstring.h:1164
QString & append(QChar c)
Definition qstring.cpp:3227
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition qstring.cpp:3435
static Q_CORE_EXPORT QString stdString(int errorCode=-1)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
void * HANDLE
const int blockSize
INT_PTR intptr_t
#define PATH_MAX
static bool isDriveReady(const wchar_t *path)
static bool isUncPath(const QString &path)
Q_DECL_COLD_FUNCTION Q_CORE_EXPORT QString qt_error_string(int errorCode=-1)
return ret
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLenum GLsizei GLuint GLint * bytesWritten
GLuint64 GLenum void * handle
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum type
GLenum access
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum target
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLenum GLuint GLintptr offset
GLuint64 GLenum GLint fd
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLfloat GLfloat GLfloat GLfloat h
GLuint entry
GLenum GLsizei len
GLuint GLuint64EXT address
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static FileType fileType(const QFileInfo &fi)
#define Q_UNUSED(x)
#define Q_UINT64_C(c)
Definition qtypes.h:53
unsigned int quint32
Definition qtypes.h:45
unsigned char uchar
Definition qtypes.h:27
unsigned int uint
Definition qtypes.h:29
long long qint64
Definition qtypes.h:55
QFile file
[0]