File indexing completed on 2024-12-22 04:35:00
0001 /* 0002 SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies). 0003 Contact: Qt Software Information (qt-info@nokia.com) 0004 0005 This file is part of the QtCore module of the Qt Toolkit. 0006 0007 $QT_BEGIN_LICENSE:LGPL$ 0008 Commercial Usage 0009 Licensees holding valid Qt Commercial licenses may use this file in 0010 accordance with the Qt Commercial License Agreement provided with the 0011 Software or, alternatively, in accordance with the terms contained in 0012 a written agreement between you and Nokia. 0013 0014 GNU Lesser General Public License Usage 0015 Alternatively, this file may be used under the terms of the GNU Lesser 0016 General Public License version 2.1 as published by the Free Software 0017 Foundation and appearing in the file LICENSE.LGPL included in the 0018 packaging of this file. Please review the following information to 0019 ensure the GNU Lesser General Public License version 2.1 requirements 0020 will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 0021 0022 In addition, as a special exception, Nokia gives you certain 0023 additional rights. These rights are described in the Nokia Qt LGPL 0024 Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 0025 package. 0026 0027 GNU General Public License Usage 0028 Alternatively, this file may be used under the terms of the GNU 0029 General Public License version 3.0 as published by the Free Software 0030 Foundation and appearing in the file LICENSE.GPL included in the 0031 packaging of this file. Please review the following information to 0032 ensure the GNU General Public License version 3.0 requirements will be 0033 met: https://www.gnu.org/licenses/gpl-3.0.html. 0034 0035 If you are unsure which license is appropriate for your use, please 0036 contact the sales department at qt-sales@nokia.com. 0037 $QT_END_LICENSE$ 0038 0039 */ 0040 0041 #include "qdebug.h" 0042 #include "qfsfileengine_iterator_p.h" 0043 #include "qfsfileengine_p.h" 0044 #include "qplatformdefs.h" 0045 0046 #include <qvariant.h> 0047 #include <QMutex> 0048 #include <private/qmutexpool_p.h> 0049 0050 QT_BEGIN_NAMESPACE 0051 0052 class QFSFileEngineIteratorPlatformSpecificData 0053 { 0054 public: 0055 inline QFSFileEngineIteratorPlatformSpecificData() 0056 : uncShareIndex(-1), findFileHandle(INVALID_HANDLE_VALUE), 0057 done(false), uncFallback(false) 0058 { } 0059 0060 QFSFileEngineIterator *it; 0061 0062 QStringList uncShares; 0063 int uncShareIndex; 0064 0065 HANDLE findFileHandle; 0066 WIN32_FIND_DATA findData; 0067 bool done; 0068 bool uncFallback; 0069 0070 void advance(); 0071 void saveCurrentFileName(); 0072 }; 0073 0074 void QFSFileEngineIteratorPlatformSpecificData::saveCurrentFileName() 0075 { 0076 if (uncFallback) { 0077 // Windows share / UNC path 0078 it->currentEntry = uncShares.at(uncShareIndex - 1); 0079 } else { 0080 // Local directory 0081 QT_WA({ 0082 it->currentEntry = QString::fromUtf16((unsigned short *)findData.cFileName); 0083 } , { 0084 it->currentEntry = QString::fromLocal8Bit((const char *)findData.cFileName); 0085 }); 0086 } 0087 } 0088 0089 void QFSFileEngineIterator::advance() 0090 { 0091 platform->saveCurrentFileName(); 0092 0093 if (platform->done) 0094 return; 0095 0096 if (platform->uncFallback) { 0097 ++platform->uncShareIndex; 0098 } else if (platform->findFileHandle != INVALID_HANDLE_VALUE) { 0099 QT_WA({ 0100 if (!FindNextFile(platform->findFileHandle, &platform->findData)) { 0101 platform->done = true; 0102 FindClose(platform->findFileHandle); 0103 } 0104 } , { 0105 if (!FindNextFileA(platform->findFileHandle, (WIN32_FIND_DATAA *)&platform->findData)) { 0106 platform->done = true; 0107 FindClose(platform->findFileHandle); 0108 } 0109 }); 0110 } 0111 } 0112 0113 void QFSFileEngineIterator::newPlatformSpecifics() 0114 { 0115 platform = new QFSFileEngineIteratorPlatformSpecificData; 0116 platform->it = this; 0117 } 0118 0119 void QFSFileEngineIterator::deletePlatformSpecifics() 0120 { 0121 delete platform; 0122 platform = 0; 0123 } 0124 0125 bool QFSFileEngineIterator::hasNext() const 0126 { 0127 if (platform->done) 0128 return false; 0129 0130 if (platform->uncFallback) 0131 return platform->uncShareIndex > 0 && platform->uncShareIndex <= platform->uncShares.size(); 0132 0133 if (platform->findFileHandle == INVALID_HANDLE_VALUE) { 0134 QString path = this->path(); 0135 // Local directory 0136 if (path.endsWith(QLatin1String(".lnk"))) 0137 path = QFileInfo(path).readLink(); 0138 0139 if (!path.endsWith(QLatin1Char('/'))) 0140 path.append(QLatin1Char('/')); 0141 path.append(QLatin1String("*.*")); 0142 0143 QT_WA({ 0144 QString fileName = QFSFileEnginePrivate::longFileName(path); 0145 platform->findFileHandle = FindFirstFileW((TCHAR *)fileName.utf16(), 0146 &platform->findData); 0147 }, { 0148 // Cast is safe, since char is at end of WIN32_FIND_DATA 0149 platform->findFileHandle = FindFirstFileA(QFSFileEnginePrivate::win95Name(path), 0150 (WIN32_FIND_DATAA*)&platform->findData); 0151 }); 0152 0153 if (platform->findFileHandle == INVALID_HANDLE_VALUE) { 0154 if (path.startsWith(QLatin1String("//"))) { 0155 path = this->path(); 0156 // UNC 0157 QStringList parts = QDir::toNativeSeparators(path).split(QLatin1Char('\\'), QString::SkipEmptyParts); 0158 0159 if (parts.count() == 1 && QFSFileEnginePrivate::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(0), 0160 &platform->uncShares)) { 0161 if (platform->uncShares.isEmpty()) { 0162 platform->done = true; 0163 } else { 0164 platform->uncShareIndex = 1; 0165 } 0166 platform->uncFallback = true; 0167 } else { 0168 platform->done = true; 0169 } 0170 } else { 0171 platform->done = true; 0172 } 0173 } 0174 0175 if (!platform->done && (!platform->uncFallback || !platform->uncShares.isEmpty())) 0176 platform->saveCurrentFileName(); 0177 } 0178 0179 return !platform->done; 0180 } 0181 0182 QT_END_NAMESPACE