forked from Pissandshittium/pissandshittium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser_data_dir.cc
156 lines (131 loc) · 5.29 KB
/
user_data_dir.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/install_static/user_data_dir.h"
#include <assert.h>
#include <windows.h>
#include "chrome/chrome_elf/nt_registry/nt_registry.h"
#include "chrome/install_static/install_details.h"
#include "chrome/install_static/install_util.h"
#include "chrome/install_static/policy_path_parser.h"
namespace install_static {
namespace {
std::wstring* g_user_data_dir;
std::wstring* g_invalid_user_data_dir;
// Retrieves a registry policy for the user data directory from the registry, if
// one is set. If there's none set in either HKLM or HKCU, |user_data_dir| will
// be unmodified.
void GetUserDataDirFromRegistryPolicyIfSet(const InstallConstants& mode,
std::wstring* user_data_dir) {
assert(user_data_dir);
std::wstring policies_path = L"SOFTWARE\\Policies\\";
AppendChromeInstallSubDirectory(mode, false /* !include_suffix */,
&policies_path);
std::wstring value;
constexpr wchar_t kUserDataDirRegistryKeyName[] = L"UserDataDir";
// First, try HKLM.
if (nt::QueryRegValueSZ(nt::HKLM, nt::NONE, policies_path.c_str(),
kUserDataDirRegistryKeyName, &value)) {
*user_data_dir = ExpandPathVariables(value);
return;
}
// Second, try HKCU.
if (nt::QueryRegValueSZ(nt::HKCU, nt::NONE, policies_path.c_str(),
kUserDataDirRegistryKeyName, &value)) {
*user_data_dir = ExpandPathVariables(value);
return;
}
}
std::wstring MakeAbsoluteFilePath(const std::wstring& input) {
wchar_t file_path[MAX_PATH];
if (!_wfullpath(file_path, input.c_str(), _countof(file_path)))
return std::wstring();
return file_path;
}
// The same as GetUserDataDirectory(), but directly queries the global command
// line object for the --user-data-dir flag. This is the more commonly used
// function, where GetUserDataDirectory() is used primiarily for testing.
bool GetUserDataDirectoryUsingProcessCommandLine(
const InstallConstants& mode,
std::wstring* result,
std::wstring* invalid_supplied_directory) {
return GetUserDataDirectoryImpl(
GetSwitchValueFromCommandLine(::GetCommandLine(), kUserDataDirSwitch),
mode, result, invalid_supplied_directory);
}
// Populates |result| with the default User Data directory for the current
// user. Returns false if all attempts at locating a User Data directory fail.
// TODO(ananta)
// http://crbug.com/604923
// Unify this with the Browser Distribution code.
bool GetDefaultUserDataDirectory(const InstallConstants& mode,
std::wstring* result) {
// This environment variable should be set on Windows Vista and later
// (https://msdn.microsoft.com/library/windows/desktop/dd378457.aspx).
std::wstring user_data_dir = GetEnvironmentString(L"LOCALAPPDATA");
if (user_data_dir.empty()) {
// LOCALAPPDATA was not set; fallback to the temporary files path.
DWORD size = ::GetTempPath(0, nullptr);
if (!size)
return false;
user_data_dir.resize(size + 1);
size = ::GetTempPath(size + 1, &user_data_dir[0]);
if (!size || size >= user_data_dir.size())
return false;
user_data_dir.resize(size);
}
result->swap(user_data_dir);
if ((*result)[result->length() - 1] != L'\\')
result->push_back(L'\\');
AppendChromeInstallSubDirectory(mode, true /* include_suffix */, result);
result->push_back(L'\\');
result->append(L"User Data");
return true;
}
} // namespace
bool GetUserDataDirectoryImpl(
const std::wstring& user_data_dir_from_command_line,
const InstallConstants& mode,
std::wstring* result,
std::wstring* invalid_supplied_directory) {
std::wstring user_data_dir = user_data_dir_from_command_line;
GetUserDataDirFromRegistryPolicyIfSet(mode, &user_data_dir);
// On Windows, trailing separators leave Chrome in a bad state. See
// crbug.com/464616.
while (!user_data_dir.empty() &&
(user_data_dir.back() == '\\' || user_data_dir.back() == '/')) {
user_data_dir.pop_back();
}
bool got_valid_directory =
!user_data_dir.empty() && RecursiveDirectoryCreate(user_data_dir);
if (!got_valid_directory) {
*invalid_supplied_directory = user_data_dir;
got_valid_directory = GetDefaultUserDataDirectory(mode, &user_data_dir);
}
// The Chrome implementation CHECKs() here in the browser process. We
// don't as this function is used to initialize crash reporting, so
// we would get no report of this failure.
assert(got_valid_directory);
if (!got_valid_directory)
return false;
*result = MakeAbsoluteFilePath(user_data_dir);
return true;
}
bool GetUserDataDirectory(std::wstring* user_data_dir,
std::wstring* invalid_user_data_dir) {
if (!g_user_data_dir) {
g_user_data_dir = new std::wstring();
g_invalid_user_data_dir = new std::wstring();
if (!GetUserDataDirectoryUsingProcessCommandLine(
InstallDetails::Get().mode(), g_user_data_dir,
g_invalid_user_data_dir)) {
return false;
}
assert(!g_user_data_dir->empty());
}
*user_data_dir = *g_user_data_dir;
if (invalid_user_data_dir)
*invalid_user_data_dir = *g_invalid_user_data_dir;
return true;
}
} // namespace install_static