Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <windows.h> | 5 #include <windows.h> |
| 6 #include <msi.h> | 6 #include <msi.h> |
| 7 #include <shellapi.h> | 7 #include <shellapi.h> |
| 8 #include <shlobj.h> | 8 #include <shlobj.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 install_list->Rollback(); | 245 install_list->Rollback(); |
| 246 ret = installer::RENAME_FAILED; | 246 ret = installer::RENAME_FAILED; |
| 247 } | 247 } |
| 248 // temp_path's dtor will take care of deleting or scheduling itself for | 248 // temp_path's dtor will take care of deleting or scheduling itself for |
| 249 // deletion at reboot when this scope closes. | 249 // deletion at reboot when this scope closes. |
| 250 VLOG(1) << "Deleting temporary directory " << temp_path.path().value(); | 250 VLOG(1) << "Deleting temporary directory " << temp_path.path().value(); |
| 251 | 251 |
| 252 return ret; | 252 return ret; |
| 253 } | 253 } |
| 254 | 254 |
| 255 // For each product that is being updated (i.e., already installed at an earlier | |
| 256 // version), see if that product has an update policy override that differs from | |
| 257 // that for the binaries. If any are found, fail with an error indicating that | |
| 258 // the Group Policy settings are in an inconsistent state. Do not do this test | |
| 259 // for same-version installs, since it would be unkind to block attempts to | |
| 260 // repair a corrupt installation. This function returns false when installation | |
| 261 // should be halted, in which case |status| contains the relevant exit code and | |
| 262 // the proper installer result has been written to the registry. | |
| 263 bool CheckGroupPolicySettings(const InstallationState& original_state, | |
| 264 const InstallerState& installer_state, | |
| 265 const Version& new_version, | |
| 266 installer::InstallStatus* status) { | |
| 267 #if !defined(GOOGLE_CHROME_BUILD) | |
| 268 // Chromium builds are not updated via Google Update, so there are no | |
| 269 // Group Policy settings to consult. | |
| 270 return true; | |
| 271 #else | |
| 272 DCHECK(status); | |
| 273 | |
| 274 // Single installs are always in good shape. | |
| 275 if (!installer_state.is_multi_install()) | |
| 276 return true; | |
| 277 | |
| 278 bool settings_are_valid = true; | |
| 279 const bool is_system_install = installer_state.system_install(); | |
| 280 BrowserDistribution* const binaries_dist = | |
| 281 installer_state.multi_package_binaries_distribution(); | |
| 282 | |
| 283 // Get the update policy for the binaries. | |
| 284 const GoogleUpdateSettings::UpdatePolicy binaries_policy = | |
| 285 GoogleUpdateSettings::GetAppUpdatePolicy(binaries_dist->GetAppGuid(), | |
| 286 NULL); | |
| 287 | |
| 288 // Check for differing update policies for all of the products being updated. | |
| 289 const Products& products = installer_state.products(); | |
| 290 Products::const_iterator scan = products.begin(); | |
| 291 for (Products::const_iterator end = products.end(); scan != end; ++scan) { | |
| 292 BrowserDistribution* dist = (*scan)->distribution(); | |
|
pastarmovj
2011/06/15 09:32:22
Can this be const as well? If all the getters belo
grt (UTC plus 2)
2011/06/15 13:38:16
I wish. :-) The BrowserDistribution interface is
| |
| 293 const ProductState* product_state = | |
| 294 original_state.GetProductState(is_system_install, dist->GetType()); | |
| 295 // Is an earlier version of this product already installed? | |
| 296 if (product_state != NULL && | |
| 297 product_state->version().CompareTo(new_version) < 0) { | |
| 298 bool is_overridden = false; | |
| 299 GoogleUpdateSettings::UpdatePolicy app_policy = | |
| 300 GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(), | |
| 301 &is_overridden); | |
| 302 if (is_overridden && app_policy != binaries_policy) { | |
| 303 // TODO(grt): add " See http://goo.gl/+++ for details." to the | |
| 304 // end of this log message and to the | |
| 305 // IDS_INSTALL_INCONSISTENT_UPDATE_POLICY string once we have a page | |
| 306 // that explains why this error is being reported and how to resolve it. | |
| 307 LOG(ERROR) << "Found legacy Group Policy setting for " | |
| 308 << dist->GetAppShortCutName() << " (value: " << app_policy | |
| 309 << ") that does not match the setting for " | |
| 310 << binaries_dist->GetAppShortCutName() | |
| 311 << " (value: " << binaries_policy << ")."; | |
| 312 settings_are_valid = false; | |
| 313 } | |
| 314 } | |
| 315 } | |
| 316 | |
| 317 if (!settings_are_valid) { | |
| 318 *status = installer::INCONSISTENT_UPDATE_POLICY; | |
| 319 installer_state.WriteInstallerResult( | |
| 320 *status, IDS_INSTALL_INCONSISTENT_UPDATE_POLICY_BASE, NULL); | |
| 321 } | |
| 322 | |
| 323 return settings_are_valid; | |
| 324 #endif // defined(GOOGLE_CHROME_BUILD) | |
| 325 } | |
| 326 | |
| 255 // The supported multi-install modes are: | 327 // The supported multi-install modes are: |
| 256 // --multi-install --chrome --chrome-frame --ready-mode | 328 // --multi-install --chrome --chrome-frame --ready-mode |
| 257 // - If a non-multi Chrome Frame installation is present, Chrome Frame is | 329 // - If a non-multi Chrome Frame installation is present, Chrome Frame is |
| 258 // removed from |installer_state|'s list of products (thereby preserving | 330 // removed from |installer_state|'s list of products (thereby preserving |
| 259 // the existing SxS install). | 331 // the existing SxS install). |
| 260 // - If a multi Chrome Frame installation is present, its options are | 332 // - If a multi Chrome Frame installation is present, its options are |
| 261 // preserved (i.e., the --ready-mode command-line option is ignored). | 333 // preserved (i.e., the --ready-mode command-line option is ignored). |
| 262 // --multi-install --chrome-frame | 334 // --multi-install --chrome-frame |
| 263 // - If a non-multi Chrome Frame installation is present, fail. | 335 // - If a non-multi Chrome Frame installation is present, fail. |
| 264 // - If --ready-mode and no Chrome installation is present, fail. | 336 // - If --ready-mode and no Chrome installation is present, fail. |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 install_status = installer::INVALID_ARCHIVE; | 591 install_status = installer::INVALID_ARCHIVE; |
| 520 installer_state.WriteInstallerResult(install_status, | 592 installer_state.WriteInstallerResult(install_status, |
| 521 IDS_INSTALL_INVALID_ARCHIVE_BASE, NULL); | 593 IDS_INSTALL_INVALID_ARCHIVE_BASE, NULL); |
| 522 } else { | 594 } else { |
| 523 // TODO(tommi): Move towards having only a single version that is common | 595 // TODO(tommi): Move towards having only a single version that is common |
| 524 // to all products. Only the package should have a version since it | 596 // to all products. Only the package should have a version since it |
| 525 // represents all the binaries. When a single product is upgraded, all | 597 // represents all the binaries. When a single product is upgraded, all |
| 526 // currently installed product for the shared binary installation, should | 598 // currently installed product for the shared binary installation, should |
| 527 // (or rather must) be upgraded. | 599 // (or rather must) be upgraded. |
| 528 VLOG(1) << "version to install: " << installer_version->GetString(); | 600 VLOG(1) << "version to install: " << installer_version->GetString(); |
| 529 bool higher_version_installed = false; | 601 bool proceed_with_installation = true; |
| 530 for (size_t i = 0; i < installer_state.products().size(); ++i) { | 602 for (size_t i = 0; i < installer_state.products().size(); ++i) { |
| 531 const Product* product = installer_state.products()[i]; | 603 const Product* product = installer_state.products()[i]; |
| 532 const ProductState* product_state = | 604 const ProductState* product_state = |
| 533 original_state.GetProductState(system_install, | 605 original_state.GetProductState(system_install, |
| 534 product->distribution()->GetType()); | 606 product->distribution()->GetType()); |
| 535 if (product_state != NULL && | 607 if (product_state != NULL && |
| 536 (product_state->version().CompareTo(*installer_version) > 0)) { | 608 (product_state->version().CompareTo(*installer_version) > 0)) { |
| 537 LOG(ERROR) << "Higher version is already installed."; | 609 LOG(ERROR) << "Higher version is already installed."; |
| 538 higher_version_installed = true; | 610 proceed_with_installation = false; |
| 539 install_status = installer::HIGHER_VERSION_EXISTS; | 611 install_status = installer::HIGHER_VERSION_EXISTS; |
| 540 | 612 |
| 541 if (product->is_chrome()) { | 613 if (product->is_chrome()) { |
| 542 // TODO(robertshield): We should take the installer result text | 614 // TODO(robertshield): We should take the installer result text |
| 543 // strings from the Product. | 615 // strings from the Product. |
| 544 installer_state.WriteInstallerResult(install_status, | 616 installer_state.WriteInstallerResult(install_status, |
| 545 IDS_INSTALL_HIGHER_VERSION_BASE, NULL); | 617 IDS_INSTALL_HIGHER_VERSION_BASE, NULL); |
| 546 } else { | 618 } else { |
| 547 installer_state.WriteInstallerResult(install_status, | 619 installer_state.WriteInstallerResult(install_status, |
| 548 IDS_INSTALL_HIGHER_VERSION_CF_BASE, NULL); | 620 IDS_INSTALL_HIGHER_VERSION_CF_BASE, NULL); |
| 549 } | 621 } |
| 550 } | 622 } |
| 551 } | 623 } |
| 552 | 624 |
| 553 if (!higher_version_installed) { | 625 proceed_with_installation = |
|
pastarmovj
2011/06/15 09:32:22
Why not &= instead?
grt (UTC plus 2)
2011/06/15 13:38:16
&= is a bitwise rather than a logical operator.
pastarmovj
2011/06/15 13:56:34
True, sorry I must have been half asleep when I wr
| |
| 626 proceed_with_installation && | |
| 627 CheckGroupPolicySettings(original_state, installer_state, | |
| 628 *installer_version, &install_status); | |
| 629 | |
| 630 if (proceed_with_installation) { | |
| 554 // We want to keep uncompressed archive (chrome.7z) that we get after | 631 // We want to keep uncompressed archive (chrome.7z) that we get after |
| 555 // uncompressing and binary patching. Get the location for this file. | 632 // uncompressing and binary patching. Get the location for this file. |
| 556 FilePath archive_to_copy( | 633 FilePath archive_to_copy( |
| 557 temp_path.path().Append(installer::kChromeArchive)); | 634 temp_path.path().Append(installer::kChromeArchive)); |
| 558 FilePath prefs_source_path(cmd_line.GetSwitchValueNative( | 635 FilePath prefs_source_path(cmd_line.GetSwitchValueNative( |
| 559 installer::switches::kInstallerData)); | 636 installer::switches::kInstallerData)); |
| 560 install_status = installer::InstallOrUpdateProduct(original_state, | 637 install_status = installer::InstallOrUpdateProduct(original_state, |
| 561 installer_state, cmd_line.GetProgram(), archive_to_copy, | 638 installer_state, cmd_line.GetProgram(), archive_to_copy, |
| 562 temp_path.path(), prefs_source_path, prefs, *installer_version); | 639 temp_path.path(), prefs_source_path, prefs, *installer_version); |
| 563 | 640 |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1222 if (!(installer_state.is_msi() && is_uninstall)) | 1299 if (!(installer_state.is_msi() && is_uninstall)) |
| 1223 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT | 1300 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT |
| 1224 // to pass through, since this is only returned on uninstall which is | 1301 // to pass through, since this is only returned on uninstall which is |
| 1225 // never invoked directly by Google Update. | 1302 // never invoked directly by Google Update. |
| 1226 return_code = InstallUtil::GetInstallReturnCode(install_status); | 1303 return_code = InstallUtil::GetInstallReturnCode(install_status); |
| 1227 | 1304 |
| 1228 VLOG(1) << "Installation complete, returning: " << return_code; | 1305 VLOG(1) << "Installation complete, returning: " << return_code; |
| 1229 | 1306 |
| 1230 return return_code; | 1307 return return_code; |
| 1231 } | 1308 } |
| OLD | NEW |