Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qstandardpaths_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
4#include "qstandardpaths.h"
5
6#include <qdir.h>
7#include <qstringlist.h>
8
9#ifndef QT_BOOTSTRAPPED
10#include <qcoreapplication.h>
11#endif
12
13#include <qt_windows.h>
14#include <shlobj.h>
15#include <intshcut.h>
16#include <qvarlengtharray.h>
17
18#ifndef QT_NO_STANDARDPATHS
19
21
22using namespace Qt::StringLiterals;
23
24static QString convertCharArray(const wchar_t *path)
25{
27}
28
30{
32}
33
35{
39}
40
41static void appendOrganizationAndApp(QString &path) // Courtesy qstandardpaths_unix.cpp
42{
43#ifndef QT_BOOTSTRAPPED
45 if (!org.isEmpty())
46 path += u'/' + org;
48 if (!appName.isEmpty())
49 path += u'/' + appName;
50#else // !QT_BOOTSTRAPPED
52#endif
53}
54
55static inline void appendTestMode(QString &path)
56{
58 path += "/qttest"_L1;
59}
60
62{
63 // same as GetCurrentProcessToken()
64 const auto process_token = HANDLE(quintptr(-4));
65
66 QVarLengthArray<char,256> token_info_buf(256);
67 auto* token_info = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_info_buf.data());
68 DWORD token_info_length = token_info_buf.size();
69 if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_info, token_info_length, &token_info_length)) {
70 // grow buffer and retry GetTokenInformation
71 token_info_buf.resize(token_info_length);
72 token_info = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_info_buf.data());
73 if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_info, token_info_length, &token_info_length))
74 return false; // assume "normal" process
75 }
76
77 // The GetSidSubAuthorityCount return-code is undefined on failure, so
78 // there's no point in checking before dereferencing
79 DWORD integrity_level = *GetSidSubAuthority(token_info->Label.Sid, *GetSidSubAuthorityCount(token_info->Label.Sid) - 1);
80 return (integrity_level < SECURITY_MANDATORY_MEDIUM_RID);
81}
82
83// Map QStandardPaths::StandardLocation to KNOWNFOLDERID of SHGetKnownFolderPath()
85{
86 // folders for medium & high integrity processes
87 static const GUID folderIds[] = {
88 FOLDERID_Desktop, // DesktopLocation
89 FOLDERID_Documents, // DocumentsLocation
90 FOLDERID_Fonts, // FontsLocation
91 FOLDERID_Programs, // ApplicationsLocation
92 FOLDERID_Music, // MusicLocation
93 FOLDERID_Videos, // MoviesLocation
94 FOLDERID_Pictures, // PicturesLocation
95 GUID(), GUID(), // TempLocation/HomeLocation
96 FOLDERID_LocalAppData, // AppLocalDataLocation ("Local" path)
97 GUID(), // CacheLocation
98 FOLDERID_LocalAppData, // GenericDataLocation ("Local" path)
99 GUID(), // RuntimeLocation
100 FOLDERID_LocalAppData, // ConfigLocation ("Local" path)
101 FOLDERID_Downloads, // DownloadLocation
102 GUID(), // GenericCacheLocation
103 FOLDERID_LocalAppData, // GenericConfigLocation ("Local" path)
104 FOLDERID_RoamingAppData,// AppDataLocation ("Roaming" path)
105 FOLDERID_LocalAppData, // AppConfigLocation ("Local" path)
106 FOLDERID_Public, // PublicShareLocation
107 FOLDERID_Templates, // TemplatesLocation
108 };
109 static_assert(sizeof(folderIds) / sizeof(folderIds[0]) == size_t(QStandardPaths::TemplatesLocation + 1));
110
111 // folders for low integrity processes
112 static const GUID folderIds_li[] = {
113 FOLDERID_Desktop, // DesktopLocation
114 FOLDERID_Documents, // DocumentsLocation
115 FOLDERID_Fonts, // FontsLocation
116 FOLDERID_Programs, // ApplicationsLocation
117 FOLDERID_Music, // MusicLocation
118 FOLDERID_Videos, // MoviesLocation
119 FOLDERID_Pictures, // PicturesLocation
120 GUID(), GUID(), // TempLocation/HomeLocation
121 FOLDERID_LocalAppDataLow,// AppLocalDataLocation ("Local" path)
122 GUID(), // CacheLocation
123 FOLDERID_LocalAppDataLow,// GenericDataLocation ("Local" path)
124 GUID(), // RuntimeLocation
125 FOLDERID_LocalAppDataLow,// ConfigLocation ("Local" path)
126 FOLDERID_Downloads, // DownloadLocation
127 GUID(), // GenericCacheLocation
128 FOLDERID_LocalAppDataLow,// GenericConfigLocation ("Local" path)
129 FOLDERID_RoamingAppData, // AppDataLocation ("Roaming" path)
130 FOLDERID_LocalAppDataLow,// AppConfigLocation ("Local" path)
131 FOLDERID_Public, // PublicShareLocation
132 FOLDERID_Templates, // TemplatesLocation
133 };
134 static_assert(sizeof(folderIds_li) == sizeof(folderIds));
135
136 static bool low_integrity_process = isProcessLowIntegrity();
137 if (size_t(type) < sizeof(folderIds) / sizeof(folderIds[0]))
138 return low_integrity_process ? folderIds_li[type] : folderIds[type];
139 return GUID();
140}
141
142// Convenience for SHGetKnownFolderPath().
143static QString sHGetKnownFolderPath(const GUID &clsid)
144{
146 LPWSTR path;
147 if (Q_LIKELY(SUCCEEDED(SHGetKnownFolderPath(clsid, KF_FLAG_DONT_VERIFY, 0, &path)))) {
149 CoTaskMemFree(path);
150 }
151 return result;
152}
153
155{
157 switch (type) {
158 case CacheLocation:
159 // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
160 // location for everyone. Most applications seem to be using a
161 // cache directory located in their AppData directory
163 if (!result.isEmpty()) {
166 result += "/cache"_L1;
167 }
168 break;
169
172 if (!result.isEmpty()) {
174 result += "/cache"_L1;
175 }
176 break;
177
178 case RuntimeLocation:
179 case HomeLocation:
181 break;
182
183 case TempLocation:
185 break;
186
187 default:
189 if (!result.isEmpty() && isConfigLocation(type)) {
193 }
194 break;
195 }
196 return result;
197}
198
199#ifndef QT_BOOTSTRAPPED
200extern QString qAppFileName();
201#endif
202
204{
205 QStringList dirs;
206 const QString localDir = writableLocation(type);
207 if (!localDir.isEmpty())
208 dirs.append(localDir);
209
210 // type-specific handling goes here
211 if (isConfigLocation(type)) {
212 QString programData = sHGetKnownFolderPath(FOLDERID_ProgramData);
213 if (!programData.isEmpty()) {
215 appendOrganizationAndApp(programData);
216 dirs.append(programData);
217 }
218#ifndef QT_BOOTSTRAPPED
219 // Note: QCoreApplication::applicationDirPath(), while static, requires
220 // an application instance. But we might need to resolve the standard
221 // locations earlier than that, so we fall back to qAppFileName().
222 QString applicationDirPath = qApp ? QCoreApplication::applicationDirPath()
224 dirs.append(applicationDirPath);
225 const QString dataDir = applicationDirPath + "/data"_L1;
226 dirs.append(dataDir);
227
229 QString appDataDir = dataDir;
230 appendOrganizationAndApp(appDataDir);
231 if (appDataDir != dataDir)
232 dirs.append(appDataDir);
233 }
234#endif // !QT_BOOTSTRAPPED
235 } // isConfigLocation()
236
237 return dirs;
238}
239
241
242#endif // QT_NO_STANDARDPATHS
QString organizationName
the name of the organization that wrote this application
static QString applicationDirPath()
Returns the directory that contains the application executable.
QString applicationName
the name of this application
static QString fromNativeSeparators(const QString &pathName)
Definition qdir.cpp:962
static QString tempPath()
Returns the absolute canonical path of the system's temporary directory.
Definition qdir.cpp:2130
static QString homePath()
Returns the absolute path of the user's home directory.
Definition qdir.cpp:2100
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
static bool isTestModeEnabled()
static QStringList standardLocations(StandardLocation type)
static QString writableLocation(StandardLocation type)
StandardLocation
This enum describes the different locations that can be queried using methods such as QStandardPaths:...
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
Definition qstring.h:1164
constexpr size_type size() const noexcept
void resize(qsizetype sz)
T * data() noexcept
Combined button and popup list for selecting options.
void * HANDLE
#define Q_LIKELY(x)
#define qApp
GLenum type
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
static void appendOrganizationAndApp(QString &path)
static GUID writableSpecialFolderId(QStandardPaths::StandardLocation type)
static bool isGenericConfigLocation(QStandardPaths::StandardLocation type)
QString qAppFileName()
static bool isProcessLowIntegrity()
static void appendTestMode(QString &path)
static void appendOrganizationAndApp(QString &path)
static bool isConfigLocation(QStandardPaths::StandardLocation type)
static QString sHGetKnownFolderPath(const GUID &clsid)
static QString convertCharArray(const wchar_t *path)
#define Q_UNUSED(x)
size_t quintptr
Definition qtypes.h:72