Thanks to visit codestin.com
Credit goes to chromium.googlesource.com

blob: 741638e9b8bd34002376a142b4e1d4afbb2af994 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2012 The Chromium Authors
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]ac510e12008-08-05 19:46:314
Takuto Ikutac8d6b16f2024-04-15 16:59:195#include "base/base_paths.h"
6
[email protected]5d99d63b2008-08-19 09:26:577#include <windows.h>
Bruce Dawsona1e1cfcb2022-11-22 20:04:358
Bruce Dawson8dcf6bc62017-12-07 17:46:049#include <KnownFolders.h>
[email protected]ac510e12008-08-05 19:46:3110#include <shlobj.h>
11
wfh16d2f122015-03-13 14:34:4712#include "base/environment.h"
[email protected]57999812013-02-24 05:40:5213#include "base/files/file_path.h"
Greg Thompson0a8c33ed2024-08-20 17:46:4114#include "base/files/file_util.h"
[email protected]ac510e12008-08-05 19:46:3115#include "base/path_service.h"
jdoerrie5c4dc4e2019-02-01 18:02:3316#include "base/strings/string_util.h"
wfh16d2f122015-03-13 14:34:4717#include "base/strings/utf_string_conversions.h"
thakisd62f54472016-04-04 02:21:1018#include "base/win/current_module.h"
[email protected]b2721b02012-08-30 09:16:5519#include "base/win/scoped_co_mem.h"
[email protected]935aa542010-10-15 01:59:1520#include "base/win/windows_version.h"
[email protected]ac510e12008-08-05 19:46:3121
[email protected]631a5472013-02-18 06:14:5922using base::FilePath;
23
[email protected]ac510e12008-08-05 19:46:3124namespace base {
25
[email protected]4792a262008-11-19 16:50:0326bool PathProviderWin(int key, FilePath* result) {
[email protected]ac510e12008-08-05 19:46:3127 // We need to go compute the value. It would be nice to support paths with
28 // names longer than MAX_PATH, but the system functions don't seem to be
29 // designed for it either, with the exception of GetTempPath (but other
30 // things will surely break if the temp path is too long, so we don't bother
31 // handling it.
Jan Wilken Dörrieb630aca2019-12-04 10:59:1132 wchar_t system_buffer[MAX_PATH];
[email protected]ac510e12008-08-05 19:46:3133 system_buffer[0] = 0;
34
[email protected]4792a262008-11-19 16:50:0335 FilePath cur;
[email protected]ac510e12008-08-05 19:46:3136 switch (key) {
37 case base::FILE_EXE:
Peter Kasting134ef9af2024-12-28 02:30:0938 if (GetModuleFileName(NULL, system_buffer, MAX_PATH) == 0) {
aranovskii8dcedce2015-06-24 09:03:5139 return false;
Peter Kasting134ef9af2024-12-28 02:30:0940 }
[email protected]4792a262008-11-19 16:50:0341 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:3142 break;
43 case base::FILE_MODULE: {
44 // the resource containing module is assumed to be the one that
45 // this code lives in, whether that's a dll or exe
Peter Kasting134ef9af2024-12-28 02:30:0946 if (GetModuleFileName(CURRENT_MODULE(), system_buffer, MAX_PATH) == 0) {
aranovskii8dcedce2015-06-24 09:03:5147 return false;
Peter Kasting134ef9af2024-12-28 02:30:0948 }
[email protected]4792a262008-11-19 16:50:0349 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:3150 break;
51 }
52 case base::DIR_WINDOWS:
Jan Wilken Dörrieb630aca2019-12-04 10:59:1153 GetWindowsDirectory(system_buffer, MAX_PATH);
[email protected]4792a262008-11-19 16:50:0354 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:3155 break;
56 case base::DIR_SYSTEM:
Jan Wilken Dörrieb630aca2019-12-04 10:59:1157 GetSystemDirectory(system_buffer, MAX_PATH);
[email protected]4792a262008-11-19 16:50:0358 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:3159 break;
[email protected]9759ffc2011-04-25 18:03:1260 case base::DIR_PROGRAM_FILESX86:
Lei Zhang10d9e1562019-03-14 18:46:0261 if (win::OSInfo::GetArchitecture() != win::OSInfo::X86_ARCHITECTURE) {
[email protected]9759ffc2011-04-25 18:03:1262 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILESX86, NULL,
Peter Kasting134ef9af2024-12-28 02:30:0963 SHGFP_TYPE_CURRENT, system_buffer))) {
[email protected]9759ffc2011-04-25 18:03:1264 return false;
Peter Kasting134ef9af2024-12-28 02:30:0965 }
[email protected]9759ffc2011-04-25 18:03:1266 cur = FilePath(system_buffer);
67 break;
68 }
69 // Fall through to base::DIR_PROGRAM_FILES if we're on an X86 machine.
Roland Bockf534f6b02022-01-04 16:09:1870 [[fallthrough]];
[email protected]ac510e12008-08-05 19:46:3171 case base::DIR_PROGRAM_FILES:
72 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
Peter Kasting134ef9af2024-12-28 02:30:0973 SHGFP_TYPE_CURRENT, system_buffer))) {
[email protected]ac510e12008-08-05 19:46:3174 return false;
Peter Kasting134ef9af2024-12-28 02:30:0975 }
[email protected]4792a262008-11-19 16:50:0376 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:3177 break;
wfh16d2f122015-03-13 14:34:4778 case base::DIR_PROGRAM_FILES6432:
79#if !defined(_WIN64)
S. Ganesha4c49ce2023-11-15 02:04:2580 if (base::win::OSInfo::GetInstance()->IsWowX86OnAMD64() ||
81 base::win::OSInfo::GetInstance()->IsWowX86OnARM64()) {
dcheng093de9b2016-04-04 21:25:5182 std::unique_ptr<base::Environment> env(base::Environment::Create());
wfh16d2f122015-03-13 14:34:4783 // 32-bit process running in WOW64 sets ProgramW6432 environment
84 // variable. See
85 // https://msdn.microsoft.com/library/windows/desktop/aa384274.aspx.
Helmut Januschka726658b2025-03-21 22:44:5786 std::optional<std::string> programfiles_w6432 =
87 env->GetVar("ProgramW6432");
88 if (!programfiles_w6432.has_value()) {
wfh16d2f122015-03-13 14:34:4789 return false;
Peter Kasting134ef9af2024-12-28 02:30:0990 }
wfh16d2f122015-03-13 14:34:4791 // GetVar returns UTF8 - convert back to Wide.
Helmut Januschka726658b2025-03-21 22:44:5792 cur = FilePath(UTF8ToWide(programfiles_w6432.value()));
wfh16d2f122015-03-13 14:34:4793 break;
94 }
95#endif
96 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
Peter Kasting134ef9af2024-12-28 02:30:0997 SHGFP_TYPE_CURRENT, system_buffer))) {
wfh16d2f122015-03-13 14:34:4798 return false;
Peter Kasting134ef9af2024-12-28 02:30:0999 }
wfh16d2f122015-03-13 14:34:47100 cur = FilePath(system_buffer);
101 break;
[email protected]ac510e12008-08-05 19:46:31102 case base::DIR_IE_INTERNET_CACHE:
103 if (FAILED(SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL,
Peter Kasting134ef9af2024-12-28 02:30:09104 SHGFP_TYPE_CURRENT, system_buffer))) {
[email protected]ac510e12008-08-05 19:46:31105 return false;
Peter Kasting134ef9af2024-12-28 02:30:09106 }
[email protected]4792a262008-11-19 16:50:03107 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:31108 break;
109 case base::DIR_COMMON_START_MENU:
110 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL,
Peter Kasting134ef9af2024-12-28 02:30:09111 SHGFP_TYPE_CURRENT, system_buffer))) {
[email protected]ac510e12008-08-05 19:46:31112 return false;
Peter Kasting134ef9af2024-12-28 02:30:09113 }
[email protected]4792a262008-11-19 16:50:03114 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:31115 break;
116 case base::DIR_START_MENU:
jdoerrie5c4dc4e2019-02-01 18:02:33117 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL, SHGFP_TYPE_CURRENT,
Peter Kasting134ef9af2024-12-28 02:30:09118 system_buffer))) {
[email protected]ac510e12008-08-05 19:46:31119 return false;
Peter Kasting134ef9af2024-12-28 02:30:09120 }
[email protected]4792a262008-11-19 16:50:03121 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:31122 break;
Carlos Frias5ddded62020-05-27 23:38:18123 case base::DIR_COMMON_STARTUP:
124 if (FAILED(SHGetFolderPath(nullptr, CSIDL_COMMON_STARTUP, nullptr,
Peter Kasting134ef9af2024-12-28 02:30:09125 SHGFP_TYPE_CURRENT, system_buffer))) {
Carlos Frias5ddded62020-05-27 23:38:18126 return false;
Peter Kasting134ef9af2024-12-28 02:30:09127 }
Carlos Frias5ddded62020-05-27 23:38:18128 cur = FilePath(system_buffer);
129 break;
130 case base::DIR_USER_STARTUP:
131 if (FAILED(SHGetFolderPath(nullptr, CSIDL_STARTUP, nullptr,
Peter Kasting134ef9af2024-12-28 02:30:09132 SHGFP_TYPE_CURRENT, system_buffer))) {
Carlos Frias5ddded62020-05-27 23:38:18133 return false;
Peter Kasting134ef9af2024-12-28 02:30:09134 }
Carlos Frias5ddded62020-05-27 23:38:18135 cur = FilePath(system_buffer);
136 break;
David Dorwin048cb9da2021-11-09 00:22:44137 case base::DIR_ROAMING_APP_DATA:
[email protected]ac510e12008-08-05 19:46:31138 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
Peter Kasting134ef9af2024-12-28 02:30:09139 system_buffer))) {
[email protected]ac510e12008-08-05 19:46:31140 return false;
Peter Kasting134ef9af2024-12-28 02:30:09141 }
[email protected]4792a262008-11-19 16:50:03142 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:31143 break;
[email protected]bf3e52c32012-04-04 05:18:47144 case base::DIR_COMMON_APP_DATA:
145 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
Peter Kasting134ef9af2024-12-28 02:30:09146 SHGFP_TYPE_CURRENT, system_buffer))) {
[email protected]bf3e52c32012-04-04 05:18:47147 return false;
Peter Kasting134ef9af2024-12-28 02:30:09148 }
[email protected]bf3e52c32012-04-04 05:18:47149 cur = FilePath(system_buffer);
150 break;
[email protected]ac510e12008-08-05 19:46:31151 case base::DIR_LOCAL_APP_DATA:
152 if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL,
Peter Kasting134ef9af2024-12-28 02:30:09153 SHGFP_TYPE_CURRENT, system_buffer))) {
[email protected]ac510e12008-08-05 19:46:31154 return false;
Peter Kasting134ef9af2024-12-28 02:30:09155 }
[email protected]4792a262008-11-19 16:50:03156 cur = FilePath(system_buffer);
[email protected]ac510e12008-08-05 19:46:31157 break;
David Dorwinc694f722021-10-29 22:46:59158 case base::DIR_SRC_TEST_DATA_ROOT: {
[email protected]14a25e502010-06-15 06:53:52159 FilePath executableDir;
[email protected]37088fef2008-08-15 17:32:10160 // On Windows, unit tests execute two levels deep from the source root.
161 // For example: chrome/{Debug|Release}/ui_tests.exe
[email protected]14a25e502010-06-15 06:53:52162 PathService::Get(base::DIR_EXE, &executableDir);
163 cur = executableDir.DirName().DirName();
[email protected]37088fef2008-08-15 17:32:10164 break;
[email protected]14a25e502010-06-15 06:53:52165 }
[email protected]b2721b02012-08-30 09:16:55166 case base::DIR_APP_SHORTCUTS: {
[email protected]b2721b02012-08-30 09:16:55167 base::win::ScopedCoMem<wchar_t> path_buf;
168 if (FAILED(SHGetKnownFolderPath(FOLDERID_ApplicationShortcuts, 0, NULL,
Peter Kasting134ef9af2024-12-28 02:30:09169 &path_buf))) {
[email protected]b2721b02012-08-30 09:16:55170 return false;
Peter Kasting134ef9af2024-12-28 02:30:09171 }
[email protected]b2721b02012-08-30 09:16:55172
Jan Wilken Dörrieb630aca2019-12-04 10:59:11173 cur = FilePath(path_buf.get());
[email protected]b2721b02012-08-30 09:16:55174 break;
175 }
[email protected]dea1d7d2012-09-20 16:24:52176 case base::DIR_USER_DESKTOP:
177 if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL,
Jan Wilken Dörrieb630aca2019-12-04 10:59:11178 SHGFP_TYPE_CURRENT, system_buffer))) {
[email protected]dea1d7d2012-09-20 16:24:52179 return false;
180 }
181 cur = FilePath(system_buffer);
182 break;
183 case base::DIR_COMMON_DESKTOP:
184 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL,
Jan Wilken Dörrieb630aca2019-12-04 10:59:11185 SHGFP_TYPE_CURRENT, system_buffer))) {
[email protected]dea1d7d2012-09-20 16:24:52186 return false;
187 }
188 cur = FilePath(system_buffer);
189 break;
190 case base::DIR_USER_QUICK_LAUNCH:
Peter Kasting134ef9af2024-12-28 02:30:09191 if (!PathService::Get(base::DIR_ROAMING_APP_DATA, &cur)) {
[email protected]dea1d7d2012-09-20 16:24:52192 return false;
Peter Kasting134ef9af2024-12-28 02:30:09193 }
[email protected]da4d4fb2014-08-08 18:17:53194 // According to various sources, appending
195 // "Microsoft\Internet Explorer\Quick Launch" to %appdata% is the only
196 // reliable way to get the quick launch folder across all versions of
197 // Windows.
198 // http://stackoverflow.com/questions/76080/how-do-you-reliably-get-the-quick-
199 // http://www.microsoft.com/technet/scriptcenter/resources/qanda/sept05/hey0901.mspx
pmonette565a8802016-06-21 00:03:43200 cur = cur.Append(FILE_PATH_LITERAL("Microsoft"))
201 .Append(FILE_PATH_LITERAL("Internet Explorer"))
202 .Append(FILE_PATH_LITERAL("Quick Launch"));
[email protected]dea1d7d2012-09-20 16:24:52203 break;
Greg Thompson62b01f82020-03-11 15:39:00204 case base::DIR_TASKBAR_PINS: {
Peter Kasting134ef9af2024-12-28 02:30:09205 if (!PathService::Get(base::DIR_USER_QUICK_LAUNCH, &cur)) {
[email protected]e5f9d822012-11-06 22:27:01206 return false;
Peter Kasting134ef9af2024-12-28 02:30:09207 }
pmonette5057ca3b2016-07-04 16:48:40208 cur = cur.Append(FILE_PATH_LITERAL("User Pinned"))
209 .Append(FILE_PATH_LITERAL("TaskBar"));
210 break;
Greg Thompson62b01f82020-03-11 15:39:00211 }
pmonette5057ca3b2016-07-04 16:48:40212 case base::DIR_IMPLICIT_APP_SHORTCUTS:
Peter Kasting134ef9af2024-12-28 02:30:09213 if (!PathService::Get(base::DIR_USER_QUICK_LAUNCH, &cur)) {
pmonette5057ca3b2016-07-04 16:48:40214 return false;
Peter Kasting134ef9af2024-12-28 02:30:09215 }
pmonette5057ca3b2016-07-04 16:48:40216 cur = cur.Append(FILE_PATH_LITERAL("User Pinned"))
217 .Append(FILE_PATH_LITERAL("ImplicitAppShortcuts"));
[email protected]e5f9d822012-11-06 22:27:01218 break;
[email protected]3f18e8d2014-03-26 01:41:04219 case base::DIR_WINDOWS_FONTS:
jdoerrie5c4dc4e2019-02-01 18:02:33220 if (FAILED(SHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT,
Jan Wilken Dörrieb630aca2019-12-04 10:59:11221 system_buffer))) {
[email protected]3f18e8d2014-03-26 01:41:04222 return false;
223 }
224 cur = FilePath(system_buffer);
225 break;
Greg Thompson0a8c33ed2024-08-20 17:46:41226 case base::DIR_SYSTEM_TEMP:
227 // Try C:\Windows\SystemTemp, which was introduced sometime before Windows
228 // 10 build 19042. Do not use GetTempPath2, as it only appeared later and
229 // will only return the path for processes running as SYSTEM.
230 if (PathService::Get(DIR_WINDOWS, &cur)) {
231 cur = cur.Append(FILE_PATH_LITERAL("SystemTemp"));
232 if (PathIsWritable(cur)) {
233 break;
234 }
235 }
236 // Failing that, use C:\Program Files or C:\Program Files (x86) for older
237 // versions of Windows 10.
238 if (!PathService::Get(DIR_PROGRAM_FILES, &cur) || !PathIsWritable(cur)) {
239 return false;
240 }
241 break;
Foromo Daniel Soromoua1e334d2025-03-06 23:35:36242 case base::DIR_ONE_DRIVE: {
243 base::win::ScopedCoMem<wchar_t> path_buf;
244 // FOLDERID_OneDrive points on the user OneDrive folder. The default path
245 // is %USERPROFILE%\OneDrive. It is formerly known as FOLDERID_SkyDrive.
246 if (FAILED(SHGetKnownFolderPath(FOLDERID_OneDrive, 0, NULL, &path_buf))) {
247 return false;
248 }
249
250 cur = FilePath(path_buf.get());
251 break;
252 }
[email protected]ac510e12008-08-05 19:46:31253 default:
254 return false;
255 }
256
[email protected]4792a262008-11-19 16:50:03257 *result = cur;
[email protected]ac510e12008-08-05 19:46:31258 return true;
259}
260
261} // namespace base