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
qfilesystemiterator_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// Qt-Security score:significant reason:default
4
8#include "qplatformdefs.h"
9
10#include <QtCore/qt_windows.h>
11#include <QtCore/private/wcharhelpers_win_p.h>
12
14
15using namespace Qt::StringLiterals;
16
17bool done = true;
18
19QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry)
20 : dirPath(entry.filePath())
21 , nativePath(entry.nativeFilePath())
22 , findFileHandle(INVALID_HANDLE_VALUE)
23 , uncFallback(false)
24 , uncShareIndex(0)
25 , onlyDirs(false)
26{
27 if (nativePath.endsWith(u".lnk"_s) && !QFileSystemEngine::isDirPath(dirPath, nullptr)) {
28 QFileSystemMetaData metaData;
29 QFileSystemEntry link = QFileSystemEngine::getLinkTarget(entry, metaData);
30 nativePath = link.nativeFilePath();
31 }
32 if (!nativePath.endsWith(u'\\'))
33 nativePath.append(u'\\');
34 nativePath.append(u'*');
35 // In MSVC2015+ case we prepend //?/ for longer file-name support
36 if (!dirPath.endsWith(u'/'))
37 dirPath.append(u'/');
38}
39
40QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters)
41 : QFileSystemIterator(entry)
42{
43 if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files))))
44 onlyDirs = true;
45}
46
47QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry,
48 QDirListing::IteratorFlags flags)
49 : QFileSystemIterator(entry)
50{
51 onlyDirs = flags.testAnyFlags(QDirListing::IteratorFlag::DirsOnly);
52}
53
54QFileSystemIterator::~QFileSystemIterator()
55{
56 if (findFileHandle != INVALID_HANDLE_VALUE)
57 FindClose(findFileHandle);
58}
59
60QFileSystemNativeId QFileSystemIterator::nativeId() const
61{
62 // nativePath is the resolved directory path with a trailing "\*" search
63 // glob appended (see the constructor). Drop the '*' to recover the
64 // directory itself (the trailing backslash is accepted by CreateFile).
65 QFileSystemEntry entry(nativePath.chopped(1), QFileSystemEntry::FromNativePath());
66 return QFileSystemEngine::nativeId(entry);
67}
68
69std::optional<QDirEntryInfo> QFileSystemIterator::advance()
70{
71 bool haveData = false;
72 WIN32_FIND_DATA findData;
73
74 if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback) {
75 haveData = true;
76 int infoLevel = 0 ; // FindExInfoStandard;
77 DWORD dwAdditionalFlags = 0;
78 dwAdditionalFlags = 2; // FIND_FIRST_EX_LARGE_FETCH
79 infoLevel = 1 ; // FindExInfoBasic;
80 int searchOps = 0; // FindExSearchNameMatch
81 if (onlyDirs)
82 searchOps = 1 ; // FindExSearchLimitToDirectories
83 findFileHandle = FindFirstFileEx(qt_castToWchar(nativePath),
84 FINDEX_INFO_LEVELS(infoLevel), &findData,
85 FINDEX_SEARCH_OPS(searchOps), 0, dwAdditionalFlags);
86 if (findFileHandle == INVALID_HANDLE_VALUE) {
87 if (nativePath.startsWith("\\\\?\\UNC\\"_L1)) {
88 const auto parts = QStringView{nativePath}.split(u'\\', Qt::SkipEmptyParts);
89 if (parts.count() == 4 && QFileSystemEngine::uncListSharesOnServer(
90 "\\\\"_L1 + parts.at(2), &uncShares)) {
91 if (uncShares.isEmpty())
92 return std::nullopt; // No shares found in the server
93 uncFallback = true;
94 }
95 }
96 }
97 }
98 if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback)
99 return std::nullopt;
100 // Retrieve the new file information.
101 if (!haveData) {
102 if (uncFallback) {
103 if (++uncShareIndex >= uncShares.count())
104 return std::nullopt;
105 } else {
106 if (!FindNextFile(findFileHandle, &findData))
107 return std::nullopt;
108 }
109 }
110 // Create the new file system entry & meta data.
111 QFileSystemEntry fileEntry;
112 QFileSystemMetaData metaData;
113 if (uncFallback) {
114 fileEntry = QFileSystemEntry(dirPath + uncShares.at(uncShareIndex));
115 metaData.fillFromFileAttribute(FILE_ATTRIBUTE_DIRECTORY);
116 } else {
117 QString fileName = QString::fromWCharArray(findData.cFileName);
118 fileEntry = QFileSystemEntry(dirPath + fileName);
119 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY || !fileName.endsWith(".lnk"_L1)) {
120 metaData.fillFromFindData(findData, true);
121 }
122 }
123 return QDirEntryInfo{std::move(fileEntry), std::move(metaData)};
124}
125
126QT_END_NAMESPACE
Combined button and popup list for selecting options.