Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: client/install_self.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « client/install_self.h ('k') | client/install_self_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2007-2010 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16 #include "omaha/client/install_self.h"
17 #include "omaha/client/install_self_internal.h"
18 #include "omaha/base/debug.h"
19 #include "omaha/base/error.h"
20 #include "omaha/base/logging.h"
21 #include "omaha/base/omaha_version.h"
22 #include "omaha/base/reg_key.h"
23 #include "omaha/base/string.h"
24 #include "omaha/base/utils.h"
25 #include "omaha/base/vistautil.h"
26 #include "omaha/base/xml_utils.h"
27 #include "omaha/client/client_utils.h"
28 #include "omaha/common/app_registry_utils.h"
29 #include "omaha/common/command_line.h"
30 #include "omaha/common/const_cmd_line.h"
31 #include "omaha/common/config_manager.h"
32 #include "omaha/common/const_goopdate.h"
33 #include "omaha/common/ping.h"
34 #include "omaha/setup/setup.h"
35 #include "omaha/setup/setup_metrics.h"
36
37 namespace omaha {
38
39 namespace install_self {
40
41 namespace {
42
43 // Returns whether elevation is required.
44 bool IsElevationRequired(bool is_machine) {
45 return is_machine && !vista_util::IsUserAdmin();
46 }
47
48 } // namespace
49
50 namespace internal {
51
52 HRESULT DoSelfUpdate(bool is_machine, int* extra_code1) {
53 ASSERT1(extra_code1);
54
55 *extra_code1 = 0;
56
57 HRESULT hr = DoInstallSelf(is_machine, true, false, false, extra_code1);
58 if (FAILED(hr)) {
59 PersistUpdateErrorInfo(is_machine, hr, *extra_code1, GetVersionString());
60 return hr;
61 }
62
63 return S_OK;
64 }
65
66 // Does not need to update the UI during Omaha install. This should be quick
67 // with a simple throbbing UI. UI will transition when product install begins.
68 HRESULT DoInstallSelf(bool is_machine,
69 bool is_self_update,
70 bool is_eula_required,
71 bool set_keepalive,
72 int* extra_code1) {
73 ASSERT1(extra_code1);
74 ASSERT1(!is_self_update || !is_eula_required);
75 ASSERT1(!IsElevationRequired(is_machine));
76
77 *extra_code1 = 0;
78
79 // TODO(omaha3): This needs to be in some type of lock(s) when
80 // !is_eula_required. See comments for SetEulaNotAccepted.
81 // TODO(omaha3): Integrate CL 11232530 - fix for bug 1866730 - from mainline.
82 // The Omaha 2 implementation of EULA [not] accepted was completely changed in
83 // this CL, which has not been integrated yet.
84 // TODO(omaha3): Code running in install-related processes before this point
85 // need to check for /eularequired before sending pings OR we need to move
86 // this before any pings can be sent. Even the latter is insufficient for
87 // the non-elevated machine install instance on Vista.
88 HRESULT hr = SetEulaRequiredState(is_machine, is_eula_required);
89 if (FAILED(hr)) {
90 return hr;
91 }
92
93 // Checking system requirements here keeps requirements checks for other
94 // modules out of Setup.
95 // It is possible that an older metainstaller would fail the install for
96 // system requirements that are not required for the installed version when
97 // doing a handoff install.
98 hr = CheckSystemRequirements();
99 if (FAILED(hr)) {
100 return hr;
101 }
102
103 Setup setup(is_machine);
104 setup.set_is_self_update(is_self_update);
105 hr = setup.Install(set_keepalive);
106 *extra_code1 = setup.extra_code1();
107
108 if (FAILED(hr)) {
109 CORE_LOG(LE, (_T("[Setup::Install failed][0x%08x]"), hr));
110 return hr;
111 }
112
113 // All Omaha installs are "offline" because there is no update check.
114 const CString omaha_client_state_key_path =
115 ConfigManager::Instance()->registry_client_state_goopdate(is_machine);
116 app_registry_utils::PersistSuccessfulInstall(omaha_client_state_key_path,
117 is_self_update,
118 !is_self_update); // is_offline
119
120 CORE_LOG(L1, (_T("[Setup successfully completed]")));
121
122 return S_OK;
123 }
124
125 HRESULT CheckSystemRequirements() {
126 // Validate that key OS components are installed.
127 if (!HasXmlParser()) {
128 return GOOPDATE_E_RUNNING_INFERIOR_MSXML;
129 }
130
131 return S_OK;
132 }
133
134 bool HasXmlParser() {
135 CComPtr<IXMLDOMDocument> my_xmldoc;
136 HRESULT hr = CoCreateSafeDOMDocument(&my_xmldoc);
137 const bool ret = SUCCEEDED(hr);
138 CORE_LOG(L3, (_T("[HasXmlParser returned %d][0x%08x]"), ret, hr));
139 return ret;
140 }
141
142 // Failing to set the state fails installation because this would prevent
143 // updates or allow updates that should not be allowed.
144 HRESULT SetEulaRequiredState(bool is_machine, bool is_eula_required) {
145 ASSERT1(!IsElevationRequired(is_machine));
146
147 const bool eula_accepted = !is_eula_required;
148 HRESULT hr = eula_accepted ? SetEulaAccepted(is_machine) :
149 SetEulaNotAccepted(is_machine);
150 if (FAILED(hr)) {
151 CORE_LOG(LE, (_T("[set EULA accepted state failed][accepted=%d][0x%08x]"),
152 eula_accepted, hr));
153 return hr;
154 }
155
156 return S_OK;
157 }
158
159 // Does not write the registry if Google Update is already installed as
160 // determined by the presence of 2 or more registered apps. In those cases, we
161 // assume the existing EULA state is correct and do not want to disable updates
162 // for an existing installation.
163 // Assumes it is called with appropriate synchronization protection such that it
164 // can reliably check the number of registered clients.
165 // TODO(omaha3): How do we assure the above assumption?
166 HRESULT SetEulaNotAccepted(bool is_machine) {
167 CORE_LOG(L4, (_T("[SetEulaNotAccepted][%d]"), is_machine));
168
169 size_t num_clients(0);
170 if (SUCCEEDED(app_registry_utils::GetNumClients(is_machine, &num_clients)) &&
171 num_clients >= 2) {
172 CORE_LOG(L4, (_T(" [Apps registered. Not setting eulaaccepted=0.]")));
173 return S_OK;
174 }
175
176 const ConfigManager* cm = ConfigManager::Instance();
177 return RegKey::SetValue(cm->registry_update(is_machine),
178 kRegValueOmahaEulaAccepted,
179 static_cast<DWORD>(0));
180 }
181
182 HRESULT SetInstallationId(const CString& omaha_client_state_key_path,
183 const GUID& iid) {
184 if (GUID_NULL != iid) {
185 return RegKey::SetValue(omaha_client_state_key_path,
186 kRegValueInstallationId,
187 GuidToString(iid));
188 }
189
190 return S_OK;
191 }
192
193 // Persist experiment labels that are specific to Google Update itself during
194 // an initial install. These are specified in a tag using "omahaexperiments";
195 // once it's on the machine, Google Update's experiment labels will be read
196 // and modified like any other app on the system.
197 HRESULT SetExperimentLabels(const CString& omaha_client_state_key_path,
198 const CString& experiment_labels) {
199 if (!experiment_labels.IsEmpty()) {
200 return RegKey::SetValue(omaha_client_state_key_path,
201 kRegValueExperimentLabels,
202 experiment_labels);
203 }
204
205 return S_OK;
206 }
207
208 void PersistUpdateErrorInfo(bool is_machine,
209 HRESULT error,
210 int extra_code1,
211 const CString& version) {
212 const TCHAR* update_key_name =
213 ConfigManager::Instance()->registry_update(is_machine);
214 VERIFY1(SUCCEEDED(RegKey::SetValue(update_key_name,
215 kRegValueSelfUpdateErrorCode,
216 static_cast<DWORD>(error))));
217 VERIFY1(SUCCEEDED(RegKey::SetValue(update_key_name,
218 kRegValueSelfUpdateExtraCode1,
219 static_cast<DWORD>(extra_code1))));
220 VERIFY1(SUCCEEDED(RegKey::SetValue(update_key_name,
221 kRegValueSelfUpdateVersion,
222 version)));
223 }
224
225 } // namespace internal
226
227 // Returns false if the values cannot be deleted to avoid skewing the log data
228 // with a single user pinging repeatedly with the same data.
229 bool ReadAndClearUpdateErrorInfo(bool is_machine,
230 DWORD* error_code,
231 DWORD* extra_code1,
232 CString* version) {
233 ASSERT1(error_code);
234 ASSERT1(extra_code1);
235 ASSERT1(version);
236
237 const TCHAR* update_key_name =
238 ConfigManager::Instance()->registry_update(is_machine);
239 RegKey update_key;
240 HRESULT hr = update_key.Open(update_key_name);
241 if (FAILED(hr)) {
242 ASSERT1(false);
243 return false;
244 }
245
246 if (!update_key.HasValue(kRegValueSelfUpdateErrorCode)) {
247 ASSERT1(!update_key.HasValue(kRegValueSelfUpdateExtraCode1));
248 return false;
249 }
250
251 VERIFY1(SUCCEEDED(update_key.GetValue(kRegValueSelfUpdateErrorCode,
252 error_code)));
253 ASSERT1(FAILED(*error_code));
254
255 VERIFY1(SUCCEEDED(update_key.GetValue(kRegValueSelfUpdateExtraCode1,
256 extra_code1)));
257
258 VERIFY1(SUCCEEDED(update_key.GetValue(kRegValueSelfUpdateVersion, version)));
259
260 if (FAILED(update_key.DeleteValue(kRegValueSelfUpdateErrorCode)) ||
261 FAILED(update_key.DeleteValue(kRegValueSelfUpdateExtraCode1)) ||
262 FAILED(update_key.DeleteValue(kRegValueSelfUpdateVersion))) {
263 ASSERT1(false);
264 return false;
265 }
266
267 return true;
268 }
269
270 HRESULT SetEulaAccepted(bool is_machine) {
271 CORE_LOG(L4, (_T("[SetEulaAccepted][%d]"), is_machine));
272 const TCHAR* update_key_name =
273 ConfigManager::Instance()->registry_update(is_machine);
274 return RegKey::HasKey(update_key_name) ?
275 RegKey::DeleteValue(update_key_name, kRegValueOmahaEulaAccepted) :
276 S_OK;
277 }
278
279 HRESULT InstallSelf(bool is_machine,
280 bool is_eula_required,
281 bool is_oem_install,
282 const CString& current_version,
283 const CString& install_source,
284 const CommandLineExtraArgs& extra_args,
285 const CString& session_id,
286 int* extra_code1) {
287 CORE_LOG(L2, (_T("[InstallSelf]")));
288
289 HRESULT hr = internal::DoInstallSelf(is_machine,
290 false,
291 is_eula_required,
292 extra_args.runtime_only,
293 extra_code1);
294 if (FAILED(hr)) {
295 CORE_LOG(LE, (_T("[DoInstallSelf failed][0x%08x]"), hr));
296 return hr;
297 }
298
299 // Set Omaha's optional IID, experiment labels, and branding.
300 // IID and experiment labels are always written on install; branding will
301 // only be written if no branding exists, which should only be true on the
302 // first install.
303 const CString omaha_client_state_key_path =
304 ConfigManager::Instance()->registry_client_state_goopdate(is_machine);
305
306 // TODO(omaha): move SetInstallationId to app_registry_utils
307 VERIFY1(SUCCEEDED(internal::SetInstallationId(omaha_client_state_key_path,
308 extra_args.installation_id)));
309 VERIFY1(SUCCEEDED(internal::SetExperimentLabels(
310 omaha_client_state_key_path,
311 extra_args.experiment_labels)));
312 VERIFY1(SUCCEEDED(app_registry_utils::SetGoogleUpdateBranding(
313 omaha_client_state_key_path,
314 extra_args.brand_code,
315 extra_args.client_id)));
316
317 if (is_eula_required || is_oem_install) {
318 return S_OK;
319 }
320
321 // Send a successful EVENT_INSTALL_COMPLETE ping and do not wait for the
322 // completion of the ping. This reduces the overall latency of Omaha
323 // installs. The 'curent_version' parameter represent the version of
324 // Omaha before the setup has run.
325 Ping install_ping(is_machine, session_id, install_source);
326 PingEventPtr setup_install_complete_ping_event(
327 new PingEvent(PingEvent::EVENT_INSTALL_COMPLETE,
328 PingEvent::EVENT_RESULT_SUCCESS,
329 hr,
330 *extra_code1));
331 const CString next_version(GetVersionString());
332 install_ping.LoadAppDataFromExtraArgs(extra_args);
333 install_ping.BuildOmahaPing(current_version,
334 next_version,
335 setup_install_complete_ping_event);
336 HRESULT send_result = install_ping.Send(true);
337 if (FAILED(send_result)) {
338 CORE_LOG(LW, (_T("[InstallPing::Send failed][0x%x]"), send_result));
339 }
340
341 return S_OK;
342 }
343
344 HRESULT UpdateSelf(bool is_machine, const CString& session_id) {
345 CORE_LOG(L2, (_T("[UpdateSelf]")));
346
347 ++metric_setup_update_self_total;
348
349 // 'current_version' corresponds to the value of 'pv' read from the registry.
350 CString current_version;
351 app_registry_utils::GetAppVersion(is_machine,
352 kGoogleUpdateAppId,
353 &current_version);
354
355 int extra_code1 = 0;
356 const HRESULT hr = internal::DoSelfUpdate(is_machine, &extra_code1);
357 if (SUCCEEDED(hr)) {
358 ++metric_setup_update_self_succeeded;
359 } else {
360 CORE_LOG(LE, (_T("[DoSelfUpdate failed][0x%08x]"), hr));
361 }
362
363 // If a self-update failed because an uninstall of that Omaha is in progress,
364 // don't bother with an update failure ping; the uninstall ping will suffice.
365 if (hr == GOOPDATE_E_FAILED_TO_GET_LOCK_UNINSTALL_PROCESS_RUNNING) {
366 return hr;
367 }
368
369 if (!ConfigManager::Instance()->CanUseNetwork(is_machine)) {
370 return hr;
371 }
372
373 // Send an update complete ping and wait for send to complete.
374 PingEvent::Results result = SUCCEEDED(hr) ?
375 PingEvent::EVENT_RESULT_SUCCESS :
376 PingEvent::EVENT_RESULT_ERROR;
377
378 const CString next_version(GetVersionString());
379
380 PingEventPtr update_complete_ping_event(
381 new PingEvent(PingEvent::EVENT_UPDATE_COMPLETE, result, hr, extra_code1));
382
383 Ping ping(is_machine, session_id, kCmdLineInstallSource_SelfUpdate);
384 ping.LoadOmahaDataFromRegistry();
385 ping.BuildOmahaPing(current_version,
386 next_version,
387 update_complete_ping_event);
388 ping.Send(false);
389
390 return hr;
391 }
392
393 HRESULT Repair(bool is_machine) {
394 CORE_LOG(L2, (_T("[Repair]")));
395 int extra_code1 = 0;
396 return internal::DoSelfUpdate(is_machine, &extra_code1);
397 }
398
399 void CheckInstallStateConsistency(bool is_machine) {
400 Setup::CheckInstallStateConsistency(is_machine);
401 }
402
403 HRESULT UninstallSelf(bool is_machine, bool send_uninstall_ping) {
404 CORE_LOG(L2, (_T("[UninstallSelf]")));
405 Setup setup(is_machine);
406 return setup.Uninstall(send_uninstall_ping);
407 }
408
409 } // namespace install_self
410
411 } // namespace omaha
OLDNEW
« no previous file with comments | « client/install_self.h ('k') | client/install_self_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698