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
60bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData)
61{
62 bool haveData = false;
63 WIN32_FIND_DATA findData;
64
65 if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback) {
66 haveData = true;
67 int infoLevel = 0 ; // FindExInfoStandard;
68 DWORD dwAdditionalFlags = 0;
69 dwAdditionalFlags = 2; // FIND_FIRST_EX_LARGE_FETCH
70 infoLevel = 1 ; // FindExInfoBasic;
71 int searchOps = 0; // FindExSearchNameMatch
72 if (onlyDirs)
73 searchOps = 1 ; // FindExSearchLimitToDirectories
74 findFileHandle = FindFirstFileEx(qt_castToWchar(nativePath),
75 FINDEX_INFO_LEVELS(infoLevel), &findData,
76 FINDEX_SEARCH_OPS(searchOps), 0, dwAdditionalFlags);
77 if (findFileHandle == INVALID_HANDLE_VALUE) {
78 if (nativePath.startsWith("\\\\?\\UNC\\"_L1)) {
79 const auto parts = QStringView{nativePath}.split(u'\\', Qt::SkipEmptyParts);
80 if (parts.count() == 4 && QFileSystemEngine::uncListSharesOnServer(
81 "\\\\"_L1 + parts.at(2), &uncShares)) {
82 if (uncShares.isEmpty())
83 return false; // No shares found in the server
84 uncFallback = true;
85 }
86 }
87 }
88 }
89 if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback)
90 return false;
91 // Retrieve the new file information.
92 if (!haveData) {
93 if (uncFallback) {
94 if (++uncShareIndex >= uncShares.count())
95 return false;
96 } else {
97 if (!FindNextFile(findFileHandle, &findData))
98 return false;
99 }
100 }
101 // Create the new file system entry & meta data.
102 if (uncFallback) {
103 fileEntry = QFileSystemEntry(dirPath + uncShares.at(uncShareIndex));
104 metaData.fillFromFileAttribute(FILE_ATTRIBUTE_DIRECTORY);
105 return true;
106 } else {
107 QString fileName = QString::fromWCharArray(findData.cFileName);
108 fileEntry = QFileSystemEntry(dirPath + fileName);
109 metaData = QFileSystemMetaData();
110 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY || !fileName.endsWith(".lnk"_L1)) {
111 metaData.fillFromFindData(findData, true);
112 }
113 return true;
114 }
115 return false;
116}
117
118QT_END_NAMESPACE