diff options
Diffstat (limited to 'src/corelib/io/qfilesystemengine_win.cpp')
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 134 |
1 files changed, 78 insertions, 56 deletions
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index efcc2c2c31..3ec32e31a1 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -37,6 +37,8 @@ #define SECURITY_WIN32 #include <security.h> +#include <QtCore/private/qfunctions_win_p.h> + #ifndef SPI_GETPLATFORMTYPE #define SPI_GETPLATFORMTYPE 257 #endif @@ -379,8 +381,36 @@ constexpr QFileDevice::Permissions toSpecificPermissions(PermissionTag tag, } // anonymous namespace #endif // QT_CONFIG(fslibs) +#if QT_DEPRECATED_SINCE(6,6) +int qt_ntfs_permission_lookup = 0; +#endif + +static QBasicAtomicInt qt_ntfs_permission_lookup_v2 = Q_BASIC_ATOMIC_INITIALIZER(0); + +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + +bool qEnableNtfsPermissionChecks() noexcept +{ + return qt_ntfs_permission_lookup_v2.fetchAndAddRelaxed(1) +QT_IF_DEPRECATED_SINCE(6, 6, /*nothing*/, + qt_ntfs_permission_lookup) + != 0; +} + +bool qDisableNtfsPermissionChecks() noexcept +{ + return qt_ntfs_permission_lookup_v2.fetchAndSubRelaxed(1) +QT_IF_DEPRECATED_SINCE(6, 6, /*nothing*/, + qt_ntfs_permission_lookup) + == 1; +} -Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0; +bool qAreNtfsPermissionChecksEnabled() noexcept +{ + return qt_ntfs_permission_lookup_v2.loadRelaxed() +QT_IF_DEPRECATED_SINCE(6, 6, /*nothing*/, + qt_ntfs_permission_lookup) + ; +} +QT_WARNING_POP /*! \class QNativeFilePermissions @@ -565,7 +595,7 @@ QNativeFilePermissions::QNativeFilePermissions(std::optional<QFileDevice::Permis Return pointer to a \c SECURITY_ATTRIBUTES object describing the permissions. The returned pointer many be null if default permissions were requested or - during bootstrap. The calles must call \c isOk() to check if the object + during bootstrap. The callers must call \c isOk() to check if the object was successfully constructed before using this method. */ SECURITY_ATTRIBUTES *QNativeFilePermissions::securityAttributes() @@ -668,21 +698,16 @@ static QString readLink(const QFileSystemEntry &link) #if QT_CONFIG(fslibs) QString ret; - bool neededCoInit = false; IShellLink *psl; // pointer to IShellLink i/f WIN32_FIND_DATA wfd; wchar_t szGotPath[MAX_PATH]; + QComHelper comHelper; + // Get pointer to the IShellLink interface. HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl); - if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized - neededCoInit = true; - CoInitialize(nullptr); - hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, - (LPVOID *)&psl); - } if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface. IPersistFile *ppf; hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); @@ -698,8 +723,6 @@ static QString readLink(const QFileSystemEntry &link) } psl->Release(); } - if (neededCoInit) - CoUninitialize(); return ret; #else @@ -799,9 +822,10 @@ public: return (dwFlags & TSF_DELETE_RECYCLE_IF_POSSIBLE) ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE PostDeleteItem(DWORD /* dwFlags */, IShellItem * /* psiItem */, - HRESULT /* hrDelete */, + HRESULT hrDelete, IShellItem *psiNewlyCreated) override { + deleteResult = hrDelete; if (psiNewlyCreated) { wchar_t *pszName = nullptr; psiNewlyCreated->GetDisplayName(SIGDN_FILESYSPATH, &pszName); @@ -822,6 +846,7 @@ public: HRESULT STDMETHODCALLTYPE ResumeTimer() override { return S_OK; } QString targetPath; + HRESULT deleteResult = S_OK; private: ULONG ref; }; @@ -861,6 +886,18 @@ void QFileSystemEngine::clearWinStatData(QFileSystemMetaData &data) QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { + QFileSystemEntry ret = getRawLinkPath(link, data); + if (!ret.isEmpty() && ret.isRelative()) { + QString target = absoluteName(link).path() + u'/' + ret.filePath(); + ret = QFileSystemEntry(QDir::cleanPath(target)); + } + return ret; +} + +//static +QFileSystemEntry QFileSystemEngine::getRawLinkPath(const QFileSystemEntry &link, + QFileSystemMetaData &data) +{ Q_CHECK_FILE_NAME(link, link); if (data.missingFlags(QFileSystemMetaData::LinkType)) @@ -871,12 +908,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, target = readLink(link); else if (data.isLink()) target = readSymLink(link); - QFileSystemEntry ret(target); - if (!target.isEmpty() && ret.isRelative()) { - target.prepend(absoluteName(link).path() + u'/'); - ret = QFileSystemEntry(QDir::cleanPath(target)); - } - return ret; + return QFileSystemEntry(target); } //static @@ -1037,7 +1069,7 @@ QByteArray QFileSystemEngine::id(HANDLE fHandle) //static bool QFileSystemEngine::setFileTime(HANDLE fHandle, const QDateTime &newDate, - QAbstractFileEngine::FileTime time, QSystemError &error) + QFile::FileTime time, QSystemError &error) { FILETIME fTime; FILETIME *pLastWrite = nullptr; @@ -1045,15 +1077,15 @@ bool QFileSystemEngine::setFileTime(HANDLE fHandle, const QDateTime &newDate, FILETIME *pCreationTime = nullptr; switch (time) { - case QAbstractFileEngine::ModificationTime: + case QFile::FileModificationTime: pLastWrite = &fTime; break; - case QAbstractFileEngine::AccessTime: + case QFile::FileAccessTime: pLastAccess = &fTime; break; - case QAbstractFileEngine::BirthTime: + case QFile::FileBirthTime: pCreationTime = &fTime; break; @@ -1076,8 +1108,7 @@ QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEng { QString name; #if QT_CONFIG(fslibs) - extern int qt_ntfs_permission_lookup; - if (qt_ntfs_permission_lookup > 0) { + if (qAreNtfsPermissionChecksEnabled()) { initGlobalSid(); { PSID pOwner = 0; @@ -1131,7 +1162,7 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst QFileSystemMetaData::MetaDataFlags what) { #if QT_CONFIG(fslibs) - if (qt_ntfs_permission_lookup > 0) { + if (qAreNtfsPermissionChecksEnabled()) { initGlobalSid(); QString fname = entry.nativeFilePath(); @@ -1157,7 +1188,7 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst // Check for generic permissions and file-specific bits that most closely // represent POSIX permissions. - // Contants like FILE_GENERIC_{READ,WRITE,EXECUTE} cannot be used + // Constants like FILE_GENERIC_{READ,WRITE,EXECUTE} cannot be used // here because they contain permission bits shared between all of them. if (accessMask & (GENERIC_READ | FILE_READ_DATA)) data.entryFlags |= readFlags; @@ -1640,23 +1671,20 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry) QFileSystemEntry QFileSystemEngine::currentPath() { - QString ret; - DWORD size = 0; - wchar_t currentName[PATH_MAX]; - size = ::GetCurrentDirectory(PATH_MAX, currentName); - if (size != 0) { - if (size > PATH_MAX) { - wchar_t *newCurrentName = new wchar_t[size]; - if (::GetCurrentDirectory(PATH_MAX, newCurrentName) != 0) - ret = QString::fromWCharArray(newCurrentName, size); - delete [] newCurrentName; - } else { - ret = QString::fromWCharArray(currentName, size); - } + QString ret(PATH_MAX, Qt::Uninitialized); + DWORD size = GetCurrentDirectoryW(PATH_MAX, reinterpret_cast<wchar_t *>(ret.data())); + if (size > PATH_MAX) { + // try again after enlarging the buffer + ret.resize(size); + size = GetCurrentDirectoryW(size, reinterpret_cast<wchar_t *>(ret.data())); + + // note: the current directory may have changed underneath us; if the + // new one is even bigger, we may return a truncated string! } - if (ret.length() >= 2 && ret[1] == u':') + if (size >= 2 && ret.at(1) == u':') ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. - return QFileSystemEntry(ret, QFileSystemEntry::FromNativePath()); + ret.resize(size); + return QFileSystemEntry(std::move(ret), QFileSystemEntry::FromNativePath()); } //static @@ -1664,18 +1692,11 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy QSystemError &error) { bool ret = false; + QComHelper comHelper; IShellLink *psl = nullptr; HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, reinterpret_cast<void **>(&psl)); - bool neededCoInit = false; - if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized - neededCoInit = true; - CoInitialize(nullptr); - hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, - reinterpret_cast<void **>(&psl)); - } - if (SUCCEEDED(hres)) { const auto name = QDir::toNativeSeparators(source.filePath()); const auto pathName = QDir::toNativeSeparators(source.path()); @@ -1695,9 +1716,6 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy if (!ret) error = QSystemError(::GetLastError(), QSystemError::NativeError); - if (neededCoInit) - CoUninitialize(); - return ret; } @@ -1765,7 +1783,8 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, // we need the "display name" of the file, so can't use nativeAbsoluteFilePath const QString sourcePath = QDir::toNativeSeparators(absoluteName(source).filePath()); - CoInitialize(nullptr); + QComHelper comHelper; + IFileOperation *pfo = nullptr; IShellItem *deleteItem = nullptr; FileOperationProgressSink *sink = nullptr; @@ -1778,7 +1797,6 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, deleteItem->Release(); if (pfo) pfo->Release(); - CoUninitialize(); if (!SUCCEEDED(hres)) error = QSystemError(hres, QSystemError::NativeError); }); @@ -1799,8 +1817,12 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, hres = pfo->PerformOperations(); if (!SUCCEEDED(hres)) return false; - newLocation = QFileSystemEntry(sink->targetPath); + if (!SUCCEEDED(sink->deleteResult)) { + error = QSystemError(sink->deleteResult, QSystemError::NativeError); + return false; + } + newLocation = QFileSystemEntry(sink->targetPath); return true; } @@ -1840,7 +1862,7 @@ static inline QDateTime fileTimeToQDateTime(const FILETIME *time) FileTimeToSystemTime(time, &sTime); return QDateTime(QDate(sTime.wYear, sTime.wMonth, sTime.wDay), QTime(sTime.wHour, sTime.wMinute, sTime.wSecond, sTime.wMilliseconds), - Qt::UTC); + QTimeZone::UTC); } QDateTime QFileSystemMetaData::birthTime() const |