OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/installer/util/installation_state.h" | 5 #include "chrome/installer/util/installation_state.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "base/version.h" | 10 #include "base/version.h" |
11 #include "base/win/registry.h" | 11 #include "base/win/registry.h" |
12 #include "chrome/installer/util/browser_distribution.h" | |
12 #include "chrome/installer/util/google_update_constants.h" | 13 #include "chrome/installer/util/google_update_constants.h" |
13 #include "chrome/installer/util/install_util.h" | 14 #include "chrome/installer/util/install_util.h" |
14 | 15 |
15 namespace installer { | 16 namespace installer { |
16 | 17 |
17 ProductState::ProductState() | 18 ProductState::ProductState() |
18 : uninstall_command_(base::CommandLine::NO_PROGRAM), | 19 : uninstall_command_(base::CommandLine::NO_PROGRAM), |
19 eula_accepted_(0), | 20 eula_accepted_(0), |
20 usagestats_(0), | 21 usagestats_(0), |
21 msi_(false), | 22 msi_(false), |
22 multi_install_(false), | 23 multi_install_(false), |
23 has_eula_accepted_(false), | 24 has_eula_accepted_(false), |
24 has_oem_install_(false), | 25 has_oem_install_(false), |
25 has_usagestats_(false) { | 26 has_usagestats_(false) { |
26 } | 27 } |
27 | 28 |
28 ProductState::~ProductState() { | 29 ProductState::~ProductState() { |
29 } | 30 } |
30 | 31 |
31 bool ProductState::Initialize(bool system_install, | 32 bool ProductState::Initialize(bool system_install) { |
32 BrowserDistribution::Type type) { | |
33 return Initialize(system_install, | |
34 BrowserDistribution::GetSpecificDistribution(type)); | |
35 } | |
36 | |
37 // Initializes |commands| from the "Commands" subkey of |version_key|. | |
38 // Returns false if there is no "Commands" subkey or on error. | |
39 // static | |
40 bool ProductState::InitializeCommands(const base::win::RegKey& version_key, | |
41 AppCommands* commands) { | |
42 static const DWORD kAccess = | |
43 KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_32KEY; | |
44 base::win::RegKey commands_key; | |
45 | |
46 if (commands_key.Open(version_key.Handle(), google_update::kRegCommandsKey, | |
47 kAccess) == ERROR_SUCCESS) | |
48 return commands->Initialize(commands_key, KEY_WOW64_32KEY); | |
49 return false; | |
50 } | |
51 | |
52 bool ProductState::Initialize(bool system_install, | |
53 BrowserDistribution* distribution) { | |
54 static const DWORD kAccess = KEY_QUERY_VALUE | KEY_WOW64_32KEY; | 33 static const DWORD kAccess = KEY_QUERY_VALUE | KEY_WOW64_32KEY; |
34 const BrowserDistribution* distribution = | |
35 BrowserDistribution::GetDistribution(); | |
55 const std::wstring version_key(distribution->GetVersionKey()); | 36 const std::wstring version_key(distribution->GetVersionKey()); |
56 const std::wstring state_key(distribution->GetStateKey()); | 37 const std::wstring state_key(distribution->GetStateKey()); |
57 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 38 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
58 base::win::RegKey key; | 39 base::win::RegKey key; |
59 | 40 |
60 // Clear the runway. | 41 // Clear the runway. |
61 Clear(); | 42 Clear(); |
62 | 43 |
63 // Read from the Clients key. | 44 // Read from the Clients key. |
64 if (key.Open(root_key, version_key.c_str(), kAccess) == ERROR_SUCCESS) { | 45 if (key.Open(root_key, version_key.c_str(), kAccess) == ERROR_SUCCESS) { |
(...skipping 23 matching lines...) Expand all Loading... | |
88 // Read from the ClientState key. | 69 // Read from the ClientState key. |
89 if (key.Open(root_key, state_key.c_str(), kAccess) == ERROR_SUCCESS) { | 70 if (key.Open(root_key, state_key.c_str(), kAccess) == ERROR_SUCCESS) { |
90 std::wstring setup_path; | 71 std::wstring setup_path; |
91 std::wstring uninstall_arguments; | 72 std::wstring uninstall_arguments; |
92 // "ap" will be absent if not managed by Google Update. | 73 // "ap" will be absent if not managed by Google Update. |
93 channel_.Initialize(key); | 74 channel_.Initialize(key); |
94 | 75 |
95 // Read in the brand code, it may be absent | 76 // Read in the brand code, it may be absent |
96 key.ReadValue(google_update::kRegBrandField, &brand_); | 77 key.ReadValue(google_update::kRegBrandField, &brand_); |
97 | 78 |
98 // "UninstallString" will be absent for the multi-installer package. | |
99 key.ReadValue(kUninstallStringField, &setup_path); | 79 key.ReadValue(kUninstallStringField, &setup_path); |
100 // "UninstallArguments" will be absent for the multi-installer package. | |
101 key.ReadValue(kUninstallArgumentsField, &uninstall_arguments); | 80 key.ReadValue(kUninstallArgumentsField, &uninstall_arguments); |
102 InstallUtil::ComposeCommandLine(setup_path, uninstall_arguments, | 81 InstallUtil::ComposeCommandLine(setup_path, uninstall_arguments, |
103 &uninstall_command_); | 82 &uninstall_command_); |
104 | 83 |
105 // "usagestats" may be absent, 0 (false), or 1 (true). On the chance that | 84 // "usagestats" may be absent, 0 (false), or 1 (true). On the chance that |
106 // different values are permitted in the future, we'll simply hold whatever | 85 // different values are permitted in the future, we'll simply hold whatever |
107 // we find. | 86 // we find. |
108 has_usagestats_ = (key.ReadValueDW(google_update::kRegUsageStatsField, | 87 has_usagestats_ = (key.ReadValueDW(google_update::kRegUsageStatsField, |
109 &usagestats_) == ERROR_SUCCESS); | 88 &usagestats_) == ERROR_SUCCESS); |
110 // "oeminstall" may be present with any value or absent. | 89 // "oeminstall" may be present with any value or absent. |
111 has_oem_install_ = (key.ReadValue(google_update::kRegOemInstallField, | 90 has_oem_install_ = (key.ReadValue(google_update::kRegOemInstallField, |
112 &oem_install_) == ERROR_SUCCESS); | 91 &oem_install_) == ERROR_SUCCESS); |
113 // "eulaaccepted" may be absent, 0 or 1. | 92 // "eulaaccepted" may be absent, 0 or 1. |
114 has_eula_accepted_ = (key.ReadValueDW(google_update::kRegEULAAceptedField, | 93 has_eula_accepted_ = (key.ReadValueDW(google_update::kRegEULAAceptedField, |
115 &eula_accepted_) == ERROR_SUCCESS); | 94 &eula_accepted_) == ERROR_SUCCESS); |
116 // "msi" may be absent, 0 or 1 | 95 // "msi" may be absent, 0 or 1 |
117 DWORD dw_value = 0; | 96 DWORD dw_value = 0; |
118 msi_ = (key.ReadValueDW(google_update::kRegMSIField, | 97 msi_ = (key.ReadValueDW(google_update::kRegMSIField, |
119 &dw_value) == ERROR_SUCCESS) && (dw_value != 0); | 98 &dw_value) == ERROR_SUCCESS) && (dw_value != 0); |
120 // Multi-install is implied or is derived from the command-line. | 99 // Multi-install is a legacy option that is read for the sole purpose of |
121 if (distribution->GetType() == BrowserDistribution::CHROME_BINARIES) | 100 // migrating clients away from it. |
122 multi_install_ = true; | 101 multi_install_ = uninstall_command_.HasSwitch(switches::kMultiInstall); |
123 else | |
124 multi_install_ = uninstall_command_.HasSwitch(switches::kMultiInstall); | |
125 } | 102 } |
126 | 103 |
127 // Read from the ClientStateMedium key. Values here override those in | 104 // Read from the ClientStateMedium key. Values here override those in |
128 // ClientState. | 105 // ClientState. |
129 if (system_install && | 106 if (system_install && |
130 key.Open(root_key, distribution->GetStateMediumKey().c_str(), kAccess) == | 107 key.Open(root_key, distribution->GetStateMediumKey().c_str(), kAccess) == |
131 ERROR_SUCCESS) { | 108 ERROR_SUCCESS) { |
132 DWORD dword_value = 0; | 109 DWORD dword_value = 0; |
133 | 110 |
134 if (key.ReadValueDW(google_update::kRegUsageStatsField, | 111 if (key.ReadValueDW(google_update::kRegUsageStatsField, |
135 &dword_value) == ERROR_SUCCESS) { | 112 &dword_value) == ERROR_SUCCESS) { |
136 has_usagestats_ = true; | 113 has_usagestats_ = true; |
137 usagestats_ = dword_value; | 114 usagestats_ = dword_value; |
138 } | 115 } |
139 | 116 |
140 if (key.ReadValueDW(google_update::kRegEULAAceptedField, | 117 if (key.ReadValueDW(google_update::kRegEULAAceptedField, |
141 &dword_value) == ERROR_SUCCESS) { | 118 &dword_value) == ERROR_SUCCESS) { |
142 has_eula_accepted_ = true; | 119 has_eula_accepted_ = true; |
143 eula_accepted_ = dword_value; | 120 eula_accepted_ = dword_value; |
144 } | 121 } |
145 } | 122 } |
146 | 123 |
147 return version_.get() != NULL; | 124 return version_.get() != nullptr; |
148 } | 125 } |
149 | 126 |
150 base::FilePath ProductState::GetSetupPath() const { | 127 base::FilePath ProductState::GetSetupPath() const { |
151 return uninstall_command_.GetProgram(); | 128 return uninstall_command_.GetProgram(); |
152 } | 129 } |
153 | 130 |
154 const base::Version& ProductState::version() const { | 131 const base::Version& ProductState::version() const { |
155 DCHECK(version_.get() != NULL); | 132 DCHECK(version_); |
156 return *version_; | 133 return *version_; |
157 } | 134 } |
158 | 135 |
159 ProductState& ProductState::CopyFrom(const ProductState& other) { | 136 ProductState& ProductState::CopyFrom(const ProductState& other) { |
160 channel_.set_value(other.channel_.value()); | 137 channel_.set_value(other.channel_.value()); |
161 version_.reset( | 138 version_.reset(other.version_.get() ? new base::Version(*other.version_) |
162 other.version_.get() ? new base::Version(*other.version_) : NULL); | 139 : nullptr); |
163 old_version_.reset( | 140 old_version_.reset(other.old_version_.get() |
164 other.old_version_.get() ? new base::Version(*other.old_version_) : NULL); | 141 ? new base::Version(*other.old_version_) |
142 : nullptr); | |
165 brand_ = other.brand_; | 143 brand_ = other.brand_; |
166 rename_cmd_ = other.rename_cmd_; | 144 rename_cmd_ = other.rename_cmd_; |
167 uninstall_command_ = other.uninstall_command_; | 145 uninstall_command_ = other.uninstall_command_; |
168 oem_install_ = other.oem_install_; | 146 oem_install_ = other.oem_install_; |
169 commands_.CopyFrom(other.commands_); | 147 commands_.CopyFrom(other.commands_); |
170 eula_accepted_ = other.eula_accepted_; | 148 eula_accepted_ = other.eula_accepted_; |
171 usagestats_ = other.usagestats_; | 149 usagestats_ = other.usagestats_; |
172 msi_ = other.msi_; | 150 msi_ = other.msi_; |
173 multi_install_ = other.multi_install_; | 151 multi_install_ = other.multi_install_; |
174 has_eula_accepted_ = other.has_eula_accepted_; | 152 has_eula_accepted_ = other.has_eula_accepted_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 } | 191 } |
214 | 192 |
215 bool ProductState::GetUsageStats(DWORD* usagestats) const { | 193 bool ProductState::GetUsageStats(DWORD* usagestats) const { |
216 DCHECK(usagestats); | 194 DCHECK(usagestats); |
217 if (!has_usagestats_) | 195 if (!has_usagestats_) |
218 return false; | 196 return false; |
219 *usagestats = usagestats_; | 197 *usagestats = usagestats_; |
220 return true; | 198 return true; |
221 } | 199 } |
222 | 200 |
223 InstallationState::InstallationState() { | 201 // Initializes |commands| from the "Commands" subkey of |version_key|. |
huangs
2017/01/09 09:09:10
Seems this is only called from within the file? M
grt (UTC plus 2)
2017/01/09 10:11:45
Done.
| |
202 // Returns false if there is no "Commands" subkey or on error. | |
203 // static | |
204 bool ProductState::InitializeCommands(const base::win::RegKey& version_key, | |
205 AppCommands* commands) { | |
206 static const DWORD kAccess = | |
207 KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_32KEY; | |
208 base::win::RegKey commands_key; | |
209 | |
210 if (commands_key.Open(version_key.Handle(), google_update::kRegCommandsKey, | |
211 kAccess) == ERROR_SUCCESS) | |
huangs
2017/01/09 09:09:10
NIT: Not sure if we should use {}? I'll leave to y
grt (UTC plus 2)
2017/01/09 10:11:45
I like them there. Thanks.
| |
212 return commands->Initialize(commands_key, KEY_WOW64_32KEY); | |
213 return false; | |
224 } | 214 } |
225 | 215 |
226 // static | 216 InstallationState::InstallationState() {} |
227 int InstallationState::IndexFromDistType(BrowserDistribution::Type type) { | 217 |
228 static_assert(BrowserDistribution::CHROME_BROWSER == CHROME_BROWSER_INDEX, | 218 void InstallationState::Initialize() { |
229 "unexpected_chrome_browser_distribution_value_"); | 219 user_chrome_.Initialize(false); |
huangs
2017/01/09 09:09:10
// TODO(grt): Do something with return value, or r
grt (UTC plus 2)
2017/01/09 10:11:45
Return value of ProductState::Initialize isn't use
| |
230 static_assert(BrowserDistribution::CHROME_FRAME == CHROME_FRAME_INDEX, | 220 system_chrome_.Initialize(true); |
231 "unexpected_chrome_frame_distribution_value_"); | |
232 static_assert(BrowserDistribution::CHROME_BINARIES == CHROME_BINARIES_INDEX, | |
233 "unexpected_chrome_frame_distribution_value_"); | |
234 DCHECK(type == BrowserDistribution::CHROME_BROWSER || | |
235 type == BrowserDistribution::CHROME_FRAME || | |
236 type == BrowserDistribution::CHROME_BINARIES); | |
237 return type; | |
238 } | 221 } |
239 | 222 |
240 void InstallationState::Initialize() { | 223 const ProductState* InstallationState::GetProductState( |
241 BrowserDistribution* distribution; | 224 bool system_install) const { |
242 | 225 const ProductState* product_state = |
243 distribution = BrowserDistribution::GetSpecificDistribution( | 226 GetNonVersionedProductState(system_install); |
244 BrowserDistribution::CHROME_BROWSER); | 227 return product_state->version_.get() ? product_state : nullptr; |
245 user_products_[CHROME_BROWSER_INDEX].Initialize(false, distribution); | |
246 system_products_[CHROME_BROWSER_INDEX].Initialize(true, distribution); | |
247 | |
248 distribution = BrowserDistribution::GetSpecificDistribution( | |
249 BrowserDistribution::CHROME_FRAME); | |
250 user_products_[CHROME_FRAME_INDEX].Initialize(false, distribution); | |
251 system_products_[CHROME_FRAME_INDEX].Initialize(true, distribution); | |
252 | |
253 distribution = BrowserDistribution::GetSpecificDistribution( | |
254 BrowserDistribution::CHROME_BINARIES); | |
255 user_products_[CHROME_BINARIES_INDEX].Initialize(false, distribution); | |
256 system_products_[CHROME_BINARIES_INDEX].Initialize(true, distribution); | |
257 } | 228 } |
258 | 229 |
259 const ProductState* InstallationState::GetNonVersionedProductState( | 230 const ProductState* InstallationState::GetNonVersionedProductState( |
260 bool system_install, | 231 bool system_install) const { |
261 BrowserDistribution::Type type) const { | 232 return system_install ? &system_chrome_ : &user_chrome_; |
262 const ProductState& product_state = (system_install ? system_products_ : | |
263 user_products_)[IndexFromDistType(type)]; | |
264 return &product_state; | |
265 } | 233 } |
266 | 234 |
267 const ProductState* InstallationState::GetProductState( | |
268 bool system_install, | |
269 BrowserDistribution::Type type) const { | |
270 const ProductState* product_state = | |
271 GetNonVersionedProductState(system_install, type); | |
272 return product_state->version_.get() == NULL ? NULL : product_state; | |
273 } | |
274 } // namespace installer | 235 } // namespace installer |
OLD | NEW |