diff options
Diffstat (limited to 'src/corelib/io/qfsfileengine_win.cpp')
-rw-r--r-- | src/corelib/io/qfsfileengine_win.cpp | 97 |
1 files changed, 50 insertions, 47 deletions
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 60e25d34f1..4ac305f49b 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qplatformdefs.h" #include "private/qabstractfileengine_p.h" @@ -63,17 +27,21 @@ #define SECURITY_WIN32 #include <security.h> +#include <memory> + #ifndef PATH_MAX #define PATH_MAX FILENAME_MAX #endif QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + static inline bool isUncPath(const QString &path) { // Starts with \\, but not \\. - return (path.startsWith(QLatin1String("\\\\")) - && path.size() > 2 && path.at(2) != QLatin1Char('.')); + return (path.startsWith("\\\\"_L1) + && path.size() > 2 && path.at(2) != u'.'); } /*! @@ -81,13 +49,13 @@ static inline bool isUncPath(const QString &path) */ QString QFSFileEnginePrivate::longFileName(const QString &path) { - if (path.startsWith(QLatin1String("\\\\.\\"))) + if (path.startsWith("\\\\.\\"_L1)) return path; QString absPath = QFileSystemEngine::nativeAbsoluteFilePath(path); - QString prefix = QLatin1String("\\\\?\\"); + QString prefix = "\\\\?\\"_L1; if (isUncPath(absPath)) { - prefix.append(QLatin1String("UNC\\")); // "\\\\?\\UNC\\" + prefix.append("UNC\\"_L1); // "\\\\?\\UNC\\" absPath.remove(0, 2); } return prefix + absPath; @@ -428,6 +396,35 @@ bool QFSFileEnginePrivate::nativeIsSequential() const || (fileType == FILE_TYPE_PIPE); } +bool QFSFileEnginePrivate::nativeRenameOverwrite(const QFileSystemEntry &newEntry) +{ + if (fileHandle == INVALID_HANDLE_VALUE) + return false; + const QString newFilePath = newEntry.nativeFilePath(); + const size_t nameByteLength = newFilePath.length() * sizeof(wchar_t); + if (nameByteLength + sizeof(wchar_t) > std::numeric_limits<DWORD>::max()) + return false; + + constexpr size_t RenameInfoSize = sizeof(FILE_RENAME_INFO); + const size_t renameDataSize = RenameInfoSize + nameByteLength + sizeof(wchar_t); + QVarLengthArray<char> v(qsizetype(renameDataSize), 0); + + auto *renameInfo = q20::construct_at(reinterpret_cast<FILE_RENAME_INFO *>(v.data())); + auto renameInfoRAII = qScopeGuard([&] { std::destroy_at(renameInfo); }); + renameInfo->ReplaceIfExists = TRUE; + renameInfo->RootDirectory = nullptr; + renameInfo->FileNameLength = DWORD(nameByteLength); + memcpy(renameInfo->FileName, newFilePath.data(), nameByteLength); + + bool res = SetFileInformationByHandle(fileHandle, FileRenameInfo, renameInfo, + DWORD(renameDataSize)); + if (!res) { + DWORD error = GetLastError(); + q_func()->setError(QFile::RenameError, qt_error_string(int(error))); + } + return res; +} + bool QFSFileEngine::caseSensitive() const { return false; @@ -438,7 +435,7 @@ QString QFSFileEngine::currentPath(const QString &fileName) QString ret; //if filename is a drive: then get the pwd of that drive if (fileName.length() >= 2 && - fileName.at(0).isLetter() && fileName.at(1) == QLatin1Char(':')) { + fileName.at(0).isLetter() && fileName.at(1) == u':') { int drv = fileName.toUpper().at(0).toLatin1() - 'A' + 1; if (_getdrive() != drv) { wchar_t buf[PATH_MAX]; @@ -450,7 +447,7 @@ QString QFSFileEngine::currentPath(const QString &fileName) //just the pwd ret = QFileSystemEngine::currentPath().filePath(); } - if (ret.length() >= 2 && ret[1] == QLatin1Char(':')) + if (ret.length() >= 2 && ret[1] == u':') ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. return ret; } @@ -653,6 +650,8 @@ QString QFSFileEngine::fileName(FileName file) const } case AbsoluteLinkTarget: return QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData).filePath(); + case RawLinkPath: + return QFileSystemEngine::getRawLinkPath(d->fileEntry, d->metaData).filePath(); case BundleName: return QString(); case JunctionName: @@ -689,6 +688,10 @@ bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); QSystemError error; + + // clear cached state (if any) + d->metaData.clearFlags(QFileSystemMetaData::Permissions); + bool ret = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error); if (!ret) setError(QFile::PermissionsError, error.toString()); @@ -734,7 +737,7 @@ bool QFSFileEngine::setSize(qint64 size) return false; } -bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time) +bool QFSFileEngine::setFileTime(const QDateTime &newDate, QFile::FileTime time) { Q_D(QFSFileEngine); @@ -743,7 +746,7 @@ bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time) return false; } - if (!newDate.isValid() || time == QAbstractFileEngine::MetadataChangeTime) { + if (!newDate.isValid() || time == QFile::FileMetadataChangeTime) { setError(QFile::UnspecifiedError, qt_error_string(ERROR_INVALID_PARAMETER)); return false; } |