diff options
Diffstat (limited to 'src/corelib/io/qstandardpaths_win.cpp')
-rw-r--r-- | src/corelib/io/qstandardpaths_win.cpp | 118 |
1 files changed, 45 insertions, 73 deletions
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index eb0ed58bcb..805ce65a5a 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -1,53 +1,15 @@ -/**************************************************************************** -** -** 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 "qstandardpaths.h" #include <qdir.h> -#include <private/qsystemlibrary_p.h> #include <qstringlist.h> #ifndef QT_BOOTSTRAPPED #include <qcoreapplication.h> #endif -#include <qoperatingsystemversion.h> #include <qt_windows.h> #include <shlobj.h> #include <intshcut.h> @@ -57,6 +19,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + static QString convertCharArray(const wchar_t *path) { return QDir::fromNativeSeparators(QString::fromWCharArray(path)); @@ -79,10 +43,10 @@ static void appendOrganizationAndApp(QString &path) // Courtesy qstandardpaths_u #ifndef QT_BOOTSTRAPPED const QString &org = QCoreApplication::organizationName(); if (!org.isEmpty()) - path += QLatin1Char('/') + org; + path += u'/' + org; const QString &appName = QCoreApplication::applicationName(); if (!appName.isEmpty()) - path += QLatin1Char('/') + appName; + path += u'/' + appName; #else // !QT_BOOTSTRAPPED Q_UNUSED(path); #endif @@ -91,26 +55,19 @@ static void appendOrganizationAndApp(QString &path) // Courtesy qstandardpaths_u static inline void appendTestMode(QString &path) { if (QStandardPaths::isTestModeEnabled()) - path += QLatin1String("/qttest"); + path += "/qttest"_L1; } -static bool isProcessLowIntegrity() { -#ifdef Q_CC_MINGW - // GetCurrentProcessToken was introduced in MinGW w64 in v7 - // Disable function until Qt CI is updated - return false; -#else - if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8) - return false; - // non-leaking pseudo-handle. Expanded inline function GetCurrentProcessToken() - // (was made an inline function in Windows 8). +static bool isProcessLowIntegrity() +{ + // same as GetCurrentProcessToken() const auto process_token = HANDLE(quintptr(-4)); QVarLengthArray<char,256> token_info_buf(256); auto* token_info = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_info_buf.data()); DWORD token_info_length = token_info_buf.size(); if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_info, token_info_length, &token_info_length)) { - // grow bufer and retry GetTokenInformation + // grow buffer and retry GetTokenInformation token_info_buf.resize(token_info_length); token_info = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_info_buf.data()); if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_info, token_info_length, &token_info_length)) @@ -121,7 +78,6 @@ static bool isProcessLowIntegrity() { // there's no point in checking before dereferencing DWORD integrity_level = *GetSidSubAuthority(token_info->Label.Sid, *GetSidSubAuthorityCount(token_info->Label.Sid) - 1); return (integrity_level < SECURITY_MANDATORY_MEDIUM_RID); -#endif } // Map QStandardPaths::StandardLocation to KNOWNFOLDERID of SHGetKnownFolderPath() @@ -142,12 +98,17 @@ static GUID writableSpecialFolderId(QStandardPaths::StandardLocation type) FOLDERID_LocalAppData, // GenericDataLocation ("Local" path) GUID(), // RuntimeLocation FOLDERID_LocalAppData, // ConfigLocation ("Local" path) - GUID(), GUID(), // DownloadLocation/GenericCacheLocation + FOLDERID_Downloads, // DownloadLocation + GUID(), // GenericCacheLocation FOLDERID_LocalAppData, // GenericConfigLocation ("Local" path) FOLDERID_RoamingAppData,// AppDataLocation ("Roaming" path) FOLDERID_LocalAppData, // AppConfigLocation ("Local" path) + FOLDERID_Public, // PublicShareLocation + FOLDERID_Templates, // TemplatesLocation + GUID(), // StateLocation + GUID(), // GenericStateLocation }; - static_assert(sizeof(folderIds) / sizeof(folderIds[0]) == size_t(QStandardPaths::AppConfigLocation + 1)); + static_assert(sizeof(folderIds) / sizeof(folderIds[0]) == size_t(QStandardPaths::GenericStateLocation + 1)); // folders for low integrity processes static const GUID folderIds_li[] = { @@ -164,10 +125,15 @@ static GUID writableSpecialFolderId(QStandardPaths::StandardLocation type) FOLDERID_LocalAppDataLow,// GenericDataLocation ("Local" path) GUID(), // RuntimeLocation FOLDERID_LocalAppDataLow,// ConfigLocation ("Local" path) - GUID(), GUID(), // DownloadLocation/GenericCacheLocation + FOLDERID_Downloads, // DownloadLocation + GUID(), // GenericCacheLocation FOLDERID_LocalAppDataLow,// GenericConfigLocation ("Local" path) FOLDERID_RoamingAppData, // AppDataLocation ("Roaming" path) FOLDERID_LocalAppDataLow,// AppConfigLocation ("Local" path) + FOLDERID_Public, // PublicShareLocation + FOLDERID_Templates, // TemplatesLocation + GUID(), // StateLocation + GUID(), // GenericStateLocation }; static_assert(sizeof(folderIds_li) == sizeof(folderIds)); @@ -181,13 +147,8 @@ static GUID writableSpecialFolderId(QStandardPaths::StandardLocation type) static QString sHGetKnownFolderPath(const GUID &clsid) { QString result; - typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*); - - static const GetKnownFolderPath sHGetKnownFolderPath = // Vista onwards. - reinterpret_cast<GetKnownFolderPath>(QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath")); - LPWSTR path; - if (Q_LIKELY(sHGetKnownFolderPath && SUCCEEDED(sHGetKnownFolderPath(clsid, KF_FLAG_DONT_VERIFY, 0, &path)))) { + if (Q_LIKELY(SUCCEEDED(SHGetKnownFolderPath(clsid, KF_FLAG_DONT_VERIFY, 0, &path)))) { result = convertCharArray(path); CoTaskMemFree(path); } @@ -198,12 +159,6 @@ QString QStandardPaths::writableLocation(StandardLocation type) { QString result; switch (type) { - case DownloadLocation: - result = sHGetKnownFolderPath(FOLDERID_Downloads); - if (result.isEmpty()) - result = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); - break; - case CacheLocation: // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache // location for everyone. Most applications seem to be using a @@ -212,7 +167,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) if (!result.isEmpty()) { appendTestMode(result); appendOrganizationAndApp(result); - result += QLatin1String("/cache"); + result += "/cache"_L1; } break; @@ -220,7 +175,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) result = sHGetKnownFolderPath(writableSpecialFolderId(GenericDataLocation)); if (!result.isEmpty()) { appendTestMode(result); - result += QLatin1String("/cache"); + result += "/cache"_L1; } break; @@ -233,6 +188,23 @@ QString QStandardPaths::writableLocation(StandardLocation type) result = QDir::tempPath(); break; + case StateLocation: + result = sHGetKnownFolderPath(writableSpecialFolderId(AppLocalDataLocation)); + if (!result.isEmpty()) { + appendTestMode(result); + appendOrganizationAndApp(result); + result += "/State"_L1; + } + break; + + case GenericStateLocation: + result = sHGetKnownFolderPath(writableSpecialFolderId(GenericDataLocation)); + if (!result.isEmpty()) { + appendTestMode(result); + result += "/State"_L1; + } + break; + default: result = sHGetKnownFolderPath(writableSpecialFolderId(type)); if (!result.isEmpty() && isConfigLocation(type)) { @@ -271,7 +243,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type) QString applicationDirPath = qApp ? QCoreApplication::applicationDirPath() : QFileInfo(qAppFileName()).path(); dirs.append(applicationDirPath); - const QString dataDir = applicationDirPath + QLatin1String("/data"); + const QString dataDir = applicationDirPath + "/data"_L1; dirs.append(dataDir); if (!isGenericConfigLocation(type)) { |