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/setup/setup_main.h" | 5 #include "chrome/installer/setup/setup_main.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <msi.h> | 8 #include <msi.h> |
9 #include <shellapi.h> | 9 #include <shellapi.h> |
10 #include <shlobj.h> | 10 #include <shlobj.h> |
(...skipping 29 matching lines...) Expand all Loading... |
40 #include "chrome/installer/setup/archive_patch_helper.h" | 40 #include "chrome/installer/setup/archive_patch_helper.h" |
41 #include "chrome/installer/setup/install.h" | 41 #include "chrome/installer/setup/install.h" |
42 #include "chrome/installer/setup/install_worker.h" | 42 #include "chrome/installer/setup/install_worker.h" |
43 #include "chrome/installer/setup/setup_constants.h" | 43 #include "chrome/installer/setup/setup_constants.h" |
44 #include "chrome/installer/setup/setup_util.h" | 44 #include "chrome/installer/setup/setup_util.h" |
45 #include "chrome/installer/setup/uninstall.h" | 45 #include "chrome/installer/setup/uninstall.h" |
46 #include "chrome/installer/util/browser_distribution.h" | 46 #include "chrome/installer/util/browser_distribution.h" |
47 #include "chrome/installer/util/channel_info.h" | 47 #include "chrome/installer/util/channel_info.h" |
48 #include "chrome/installer/util/delete_after_reboot_helper.h" | 48 #include "chrome/installer/util/delete_after_reboot_helper.h" |
49 #include "chrome/installer/util/delete_tree_work_item.h" | 49 #include "chrome/installer/util/delete_tree_work_item.h" |
50 #include "chrome/installer/util/eula_util.h" | |
51 #include "chrome/installer/util/google_update_constants.h" | 50 #include "chrome/installer/util/google_update_constants.h" |
52 #include "chrome/installer/util/google_update_settings.h" | 51 #include "chrome/installer/util/google_update_settings.h" |
53 #include "chrome/installer/util/google_update_util.h" | 52 #include "chrome/installer/util/google_update_util.h" |
54 #include "chrome/installer/util/helper.h" | 53 #include "chrome/installer/util/helper.h" |
55 #include "chrome/installer/util/html_dialog.h" | 54 #include "chrome/installer/util/html_dialog.h" |
56 #include "chrome/installer/util/install_util.h" | 55 #include "chrome/installer/util/install_util.h" |
57 #include "chrome/installer/util/installation_state.h" | 56 #include "chrome/installer/util/installation_state.h" |
58 #include "chrome/installer/util/installation_validator.h" | 57 #include "chrome/installer/util/installation_validator.h" |
59 #include "chrome/installer/util/installer_state.h" | 58 #include "chrome/installer/util/installer_state.h" |
60 #include "chrome/installer/util/l10n_string_util.h" | 59 #include "chrome/installer/util/l10n_string_util.h" |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 InstallerState* installer_state, | 373 InstallerState* installer_state, |
375 installer::InstallStatus* status) { | 374 installer::InstallStatus* status) { |
376 const Products& products = installer_state->products(); | 375 const Products& products = installer_state->products(); |
377 DCHECK(products.size()); | 376 DCHECK(products.size()); |
378 | 377 |
379 const bool system_level = installer_state->system_install(); | 378 const bool system_level = installer_state->system_install(); |
380 | 379 |
381 if (installer_state->is_multi_install()) { | 380 if (installer_state->is_multi_install()) { |
382 const Product* chrome = | 381 const Product* chrome = |
383 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); | 382 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); |
384 const Product* app_host = | |
385 installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST); | |
386 const Product* binaries = | 383 const Product* binaries = |
387 installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES); | 384 installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES); |
388 const ProductState* chrome_state = | 385 const ProductState* chrome_state = |
389 original_state.GetProductState(system_level, | 386 original_state.GetProductState(system_level, |
390 BrowserDistribution::CHROME_BROWSER); | 387 BrowserDistribution::CHROME_BROWSER); |
391 | 388 |
392 if (binaries) { | 389 if (binaries) { |
393 if (products.size() == 1) { | 390 if (products.size() == 1) { |
394 // There are no products aside from the binaries, so there is no update | 391 // There are no products aside from the binaries, so there is no update |
395 // to be applied. This can happen after multi-install Chrome Frame is | 392 // to be applied. This can happen after multi-install Chrome Frame is |
396 // migrated to single-install. This is treated as an update failure | 393 // migrated to single-install. This is treated as an update failure |
397 // unless the binaries are not in-use, in which case they will be | 394 // unless the binaries are not in-use, in which case they will be |
398 // uninstalled and success will be reported (see handling in wWinMain). | 395 // uninstalled and success will be reported (see handling in wWinMain). |
399 VLOG(1) << "No products to be updated."; | 396 VLOG(1) << "No products to be updated."; |
400 *status = installer::UNUSED_BINARIES; | 397 *status = installer::UNUSED_BINARIES; |
401 installer_state->WriteInstallerResult(*status, 0, NULL); | 398 installer_state->WriteInstallerResult(*status, 0, NULL); |
402 return false; | 399 return false; |
403 } | 400 } |
404 } else { | 401 } else { |
405 // This will only be hit if --multi-install is given with no products, or | 402 // This will only be hit if --multi-install is given with no products. |
406 // if the app host is being installed and doesn't need the binaries at | |
407 // user-level. | |
408 // The former case might be due to a request by an orphaned Application | |
409 // Host to re-install the binaries. Thus we add them to the installation. | |
410 // The latter case is fine and we let it be. | |
411 // If this is not an app host install and the binaries are not already | |
412 // present, the installation will fail later due to a lack of products to | |
413 // install. | |
414 if (app_host && !chrome && !chrome_state) { | |
415 DCHECK(!system_level); | |
416 // App Host may use Chrome/Chrome binaries at system-level. | |
417 if (original_state.GetProductState( | |
418 true, // system | |
419 BrowserDistribution::CHROME_BROWSER) || | |
420 original_state.GetProductState( | |
421 true, // system | |
422 BrowserDistribution::CHROME_BINARIES)) { | |
423 VLOG(1) << "Installing/updating App Launcher without binaries."; | |
424 } else { | |
425 // Somehow the binaries were present when the quick-enable app host | |
426 // command was run, but now they appear to be missing. | |
427 // Force binaries to be installed/updated. | |
428 scoped_ptr<Product> binaries_to_add(new Product( | |
429 BrowserDistribution::GetSpecificDistribution( | |
430 BrowserDistribution::CHROME_BINARIES))); | |
431 binaries_to_add->SetOption(installer::kOptionMultiInstall, true); | |
432 binaries = installer_state->AddProduct(&binaries_to_add); | |
433 VLOG(1) << | |
434 "Adding binaries for pre-existing App Launcher installation."; | |
435 } | |
436 } | |
437 | |
438 return true; | 403 return true; |
439 } | 404 } |
440 | 405 |
441 if (!chrome && chrome_state) { | 406 if (!chrome && chrome_state) { |
442 // A product other than Chrome is being installed in multi-install mode, | 407 // A product other than Chrome is being installed in multi-install mode, |
443 // and Chrome is already present. Add Chrome to the set of products | 408 // and Chrome is already present. Add Chrome to the set of products |
444 // (making it multi-install in the process) so that it is updated, too. | 409 // (making it multi-install in the process) so that it is updated, too. |
445 scoped_ptr<Product> multi_chrome(new Product( | 410 scoped_ptr<Product> multi_chrome(new Product( |
446 BrowserDistribution::GetSpecificDistribution( | 411 BrowserDistribution::GetSpecificDistribution( |
447 BrowserDistribution::CHROME_BROWSER))); | 412 BrowserDistribution::CHROME_BROWSER))); |
(...skipping 17 matching lines...) Expand all Loading... |
465 installer_state->WriteInstallerResult(*status, | 430 installer_state->WriteInstallerResult(*status, |
466 IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL); | 431 IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL); |
467 return false; | 432 return false; |
468 } | 433 } |
469 } | 434 } |
470 } | 435 } |
471 | 436 |
472 return true; | 437 return true; |
473 } | 438 } |
474 | 439 |
475 // Checks app host pre-install conditions, specifically that this is a | |
476 // user-level multi-install. When the pre-install conditions are not | |
477 // satisfied, the result is written to the registry (via WriteInstallerResult), | |
478 // |status| is set appropriately, and false is returned. | |
479 bool CheckAppHostPreconditions(const InstallationState& original_state, | |
480 InstallerState* installer_state, | |
481 installer::InstallStatus* status) { | |
482 if (installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST)) { | |
483 if (!installer_state->is_multi_install()) { | |
484 LOG(DFATAL) << "App Launcher requires multi install"; | |
485 *status = installer::APP_HOST_REQUIRES_MULTI_INSTALL; | |
486 // No message string since there is nothing a user can do. | |
487 installer_state->WriteInstallerResult(*status, 0, NULL); | |
488 return false; | |
489 } | |
490 | |
491 if (installer_state->system_install()) { | |
492 LOG(DFATAL) << "App Launcher may only be installed at user-level."; | |
493 *status = installer::APP_HOST_REQUIRES_USER_LEVEL; | |
494 // No message string since there is nothing a user can do. | |
495 installer_state->WriteInstallerResult(*status, 0, NULL); | |
496 return false; | |
497 } | |
498 } | |
499 | |
500 return true; | |
501 } | |
502 | |
503 // Checks for compatibility between the current state of the system and the | 440 // Checks for compatibility between the current state of the system and the |
504 // desired operation. Also applies policy that mutates the desired operation; | 441 // desired operation. Also applies policy that mutates the desired operation; |
505 // specifically, the |installer_state| object. | 442 // specifically, the |installer_state| object. |
506 // Also blocks simultaneous user-level and system-level installs. In the case | 443 // Also blocks simultaneous user-level and system-level installs. In the case |
507 // of trying to install user-level Chrome when system-level exists, the | 444 // of trying to install user-level Chrome when system-level exists, the |
508 // existing system-level Chrome is launched. | 445 // existing system-level Chrome is launched. |
509 // When the pre-install conditions are not satisfied, the result is written to | 446 // When the pre-install conditions are not satisfied, the result is written to |
510 // the registry (via WriteInstallerResult), |status| is set appropriately, and | 447 // the registry (via WriteInstallerResult), |status| is set appropriately, and |
511 // false is returned. | 448 // false is returned. |
512 bool CheckPreInstallConditions(const InstallationState& original_state, | 449 bool CheckPreInstallConditions(const InstallationState& original_state, |
513 InstallerState* installer_state, | 450 InstallerState* installer_state, |
514 installer::InstallStatus* status) { | 451 installer::InstallStatus* status) { |
515 if (!CheckAppHostPreconditions(original_state, installer_state, status)) { | |
516 DCHECK_NE(*status, installer::UNKNOWN_STATUS); | |
517 return false; | |
518 } | |
519 | |
520 // See what products are already installed in multi mode. When we do multi | 452 // See what products are already installed in multi mode. When we do multi |
521 // installs, we must upgrade all installations since they share the binaries. | 453 // installs, we must upgrade all installations since they share the binaries. |
522 AddExistingMultiInstalls(original_state, installer_state); | 454 AddExistingMultiInstalls(original_state, installer_state); |
523 | 455 |
524 if (!CheckMultiInstallConditions(original_state, installer_state, status)) { | 456 if (!CheckMultiInstallConditions(original_state, installer_state, status)) { |
525 DCHECK_NE(*status, installer::UNKNOWN_STATUS); | 457 DCHECK_NE(*status, installer::UNKNOWN_STATUS); |
526 return false; | 458 return false; |
527 } | 459 } |
528 | 460 |
529 const Products& products = installer_state->products(); | 461 const Products& products = installer_state->products(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 base::LaunchProcess(cmd, base::LaunchOptions()); | 522 base::LaunchProcess(cmd, base::LaunchOptions()); |
591 } | 523 } |
592 } else { | 524 } else { |
593 // It's no longer possible for |product| to be anything other than | 525 // It's no longer possible for |product| to be anything other than |
594 // Chrome. | 526 // Chrome. |
595 NOTREACHED(); | 527 NOTREACHED(); |
596 } | 528 } |
597 return false; | 529 return false; |
598 } | 530 } |
599 } | 531 } |
600 | |
601 } else { // System-level install. | |
602 // --ensure-google-update-present is supported for user-level only. | |
603 // The flag is generic, but its primary use case involves App Host. | |
604 if (installer_state->ensure_google_update_present()) { | |
605 LOG(DFATAL) << "--" << installer::switches::kEnsureGoogleUpdatePresent | |
606 << " is supported for user-level only."; | |
607 *status = installer::APP_HOST_REQUIRES_USER_LEVEL; | |
608 // No message string since there is nothing a user can do. | |
609 installer_state->WriteInstallerResult(*status, 0, NULL); | |
610 return false; | |
611 } | |
612 } | 532 } |
613 | 533 |
614 return true; | 534 return true; |
615 } | 535 } |
616 | 536 |
617 // Initializes |temp_path| to "Temp" within the target directory, and | 537 // Initializes |temp_path| to "Temp" within the target directory, and |
618 // |unpack_path| to a random directory beginning with "source" within | 538 // |unpack_path| to a random directory beginning with "source" within |
619 // |temp_path|. Returns false on error. | 539 // |temp_path|. Returns false on error. |
620 bool CreateTemporaryAndUnpackDirectories( | 540 bool CreateTemporaryAndUnpackDirectories( |
621 const InstallerState& installer_state, | 541 const InstallerState& installer_state, |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); | 1054 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); |
1135 installer::InstallStatus status = installer::INVALID_STATE_FOR_OPTION; | 1055 installer::InstallStatus status = installer::INVALID_STATE_FOR_OPTION; |
1136 if (chrome_install) { | 1056 if (chrome_install) { |
1137 installer::HandleOsUpgradeForBrowser(*installer_state, | 1057 installer::HandleOsUpgradeForBrowser(*installer_state, |
1138 *chrome_install); | 1058 *chrome_install); |
1139 status = installer::INSTALL_REPAIRED; | 1059 status = installer::INSTALL_REPAIRED; |
1140 } else { | 1060 } else { |
1141 LOG(DFATAL) << "Chrome product not found."; | 1061 LOG(DFATAL) << "Chrome product not found."; |
1142 } | 1062 } |
1143 *exit_code = InstallUtil::GetInstallReturnCode(status); | 1063 *exit_code = InstallUtil::GetInstallReturnCode(status); |
1144 } else if (cmd_line.HasSwitch(installer::switches::kQueryEULAAcceptance)) { | |
1145 *exit_code = installer::IsEULAAccepted(installer_state->system_install()); | |
1146 } else if (cmd_line.HasSwitch(installer::switches::kInactiveUserToast)) { | 1064 } else if (cmd_line.HasSwitch(installer::switches::kInactiveUserToast)) { |
1147 // Launch the inactive user toast experiment. | 1065 // Launch the inactive user toast experiment. |
1148 int flavor = -1; | 1066 int flavor = -1; |
1149 base::StringToInt(cmd_line.GetSwitchValueNative( | 1067 base::StringToInt(cmd_line.GetSwitchValueNative( |
1150 installer::switches::kInactiveUserToast), &flavor); | 1068 installer::switches::kInactiveUserToast), &flavor); |
1151 std::string experiment_group = | 1069 std::string experiment_group = |
1152 cmd_line.GetSwitchValueASCII(installer::switches::kExperimentGroup); | 1070 cmd_line.GetSwitchValueASCII(installer::switches::kExperimentGroup); |
1153 DCHECK_NE(-1, flavor); | 1071 DCHECK_NE(-1, flavor); |
1154 if (flavor == -1) { | 1072 if (flavor == -1) { |
1155 *exit_code = installer::UNKNOWN_STATUS; | 1073 *exit_code = installer::UNKNOWN_STATUS; |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 if (product_state != NULL && | 1431 if (product_state != NULL && |
1514 (product_state->version().CompareTo(*installer_version) > 0)) { | 1432 (product_state->version().CompareTo(*installer_version) > 0)) { |
1515 LOG(ERROR) << "Higher version of " | 1433 LOG(ERROR) << "Higher version of " |
1516 << product.distribution()->GetDisplayName() | 1434 << product.distribution()->GetDisplayName() |
1517 << " is already installed."; | 1435 << " is already installed."; |
1518 higher_products |= (1 << product.distribution()->GetType()); | 1436 higher_products |= (1 << product.distribution()->GetType()); |
1519 } | 1437 } |
1520 } | 1438 } |
1521 | 1439 |
1522 if (higher_products != 0) { | 1440 if (higher_products != 0) { |
1523 COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 4, | 1441 COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 3, |
1524 add_support_for_new_products_here_); | 1442 add_support_for_new_products_here_); |
1525 const uint32 kBrowserBit = 1 << BrowserDistribution::CHROME_BROWSER; | 1443 int message_id = IDS_INSTALL_HIGHER_VERSION_BASE; |
1526 int message_id = 0; | |
1527 | |
1528 proceed_with_installation = false; | 1444 proceed_with_installation = false; |
1529 install_status = HIGHER_VERSION_EXISTS; | 1445 install_status = HIGHER_VERSION_EXISTS; |
1530 switch (higher_products) { | |
1531 case kBrowserBit: | |
1532 message_id = IDS_INSTALL_HIGHER_VERSION_BASE; | |
1533 break; | |
1534 default: | |
1535 message_id = IDS_INSTALL_HIGHER_VERSION_APP_LAUNCHER_BASE; | |
1536 break; | |
1537 } | |
1538 | |
1539 installer_state.WriteInstallerResult(install_status, message_id, NULL); | 1446 installer_state.WriteInstallerResult(install_status, message_id, NULL); |
1540 } | 1447 } |
1541 | 1448 |
1542 proceed_with_installation = | 1449 proceed_with_installation = |
1543 proceed_with_installation && | 1450 proceed_with_installation && |
1544 CheckGroupPolicySettings(original_state, installer_state, | 1451 CheckGroupPolicySettings(original_state, installer_state, |
1545 *installer_version, &install_status); | 1452 *installer_version, &install_status); |
1546 | 1453 |
1547 if (proceed_with_installation) { | 1454 if (proceed_with_installation) { |
1548 // If Google Update is absent at user-level, install it using the | |
1549 // Google Update installer from an existing system-level installation. | |
1550 // This is for quick-enable App Host install from a system-level | |
1551 // Chrome Binaries installation. | |
1552 if (!system_install && installer_state.ensure_google_update_present()) { | |
1553 if (!google_update::EnsureUserLevelGoogleUpdatePresent()) { | |
1554 LOG(ERROR) << "Failed to install Google Update"; | |
1555 proceed_with_installation = false; | |
1556 install_status = INSTALL_OF_GOOGLE_UPDATE_FAILED; | |
1557 installer_state.WriteInstallerResult(install_status, 0, NULL); | |
1558 } | |
1559 } | |
1560 | |
1561 } | |
1562 | |
1563 if (proceed_with_installation) { | |
1564 base::FilePath prefs_source_path(cmd_line.GetSwitchValueNative( | 1455 base::FilePath prefs_source_path(cmd_line.GetSwitchValueNative( |
1565 switches::kInstallerData)); | 1456 switches::kInstallerData)); |
1566 install_status = InstallOrUpdateProduct( | 1457 install_status = InstallOrUpdateProduct( |
1567 original_state, installer_state, setup_exe, uncompressed_archive, | 1458 original_state, installer_state, setup_exe, uncompressed_archive, |
1568 temp_path.path(), src_path, prefs_source_path, prefs, | 1459 temp_path.path(), src_path, prefs_source_path, prefs, |
1569 *installer_version); | 1460 *installer_version); |
1570 | 1461 |
1571 int install_msg_base = IDS_INSTALL_FAILED_BASE; | 1462 int install_msg_base = IDS_INSTALL_FAILED_BASE; |
1572 base::FilePath chrome_exe; | 1463 base::FilePath chrome_exe; |
1573 base::string16 quoted_chrome_exe; | 1464 base::string16 quoted_chrome_exe; |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1819 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT | 1710 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT |
1820 // to pass through, since this is only returned on uninstall which is | 1711 // to pass through, since this is only returned on uninstall which is |
1821 // never invoked directly by Google Update. | 1712 // never invoked directly by Google Update. |
1822 return_code = InstallUtil::GetInstallReturnCode(install_status); | 1713 return_code = InstallUtil::GetInstallReturnCode(install_status); |
1823 } | 1714 } |
1824 | 1715 |
1825 VLOG(1) << "Installation complete, returning: " << return_code; | 1716 VLOG(1) << "Installation complete, returning: " << return_code; |
1826 | 1717 |
1827 return return_code; | 1718 return return_code; |
1828 } | 1719 } |
OLD | NEW |