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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 InstallerState* installer_state, | 374 InstallerState* installer_state, |
375 installer::InstallStatus* status) { | 375 installer::InstallStatus* status) { |
376 const Products& products = installer_state->products(); | 376 const Products& products = installer_state->products(); |
377 DCHECK(products.size()); | 377 DCHECK(products.size()); |
378 | 378 |
379 const bool system_level = installer_state->system_install(); | 379 const bool system_level = installer_state->system_install(); |
380 | 380 |
381 if (installer_state->is_multi_install()) { | 381 if (installer_state->is_multi_install()) { |
382 const Product* chrome = | 382 const Product* chrome = |
383 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); | 383 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); |
384 const Product* app_host = | |
385 installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST); | |
386 const Product* binaries = | 384 const Product* binaries = |
387 installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES); | 385 installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES); |
388 const ProductState* chrome_state = | 386 const ProductState* chrome_state = |
389 original_state.GetProductState(system_level, | 387 original_state.GetProductState(system_level, |
390 BrowserDistribution::CHROME_BROWSER); | 388 BrowserDistribution::CHROME_BROWSER); |
391 | 389 |
392 if (binaries) { | 390 if (binaries) { |
393 if (products.size() == 1) { | 391 if (products.size() == 1) { |
394 // There are no products aside from the binaries, so there is no update | 392 // 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 | 393 // to be applied. This can happen after multi-install Chrome Frame is |
396 // migrated to single-install. This is treated as an update failure | 394 // 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 | 395 // unless the binaries are not in-use, in which case they will be |
398 // uninstalled and success will be reported (see handling in wWinMain). | 396 // uninstalled and success will be reported (see handling in wWinMain). |
399 VLOG(1) << "No products to be updated."; | 397 VLOG(1) << "No products to be updated."; |
400 *status = installer::UNUSED_BINARIES; | 398 *status = installer::UNUSED_BINARIES; |
401 installer_state->WriteInstallerResult(*status, 0, NULL); | 399 installer_state->WriteInstallerResult(*status, 0, NULL); |
402 return false; | 400 return false; |
403 } | 401 } |
404 } else { | 402 } else { |
405 // This will only be hit if --multi-install is given with no products, or | 403 // 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; | 404 return true; |
439 } | 405 } |
440 | 406 |
441 if (!chrome && chrome_state) { | 407 if (!chrome && chrome_state) { |
442 // A product other than Chrome is being installed in multi-install mode, | 408 // 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 | 409 // 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. | 410 // (making it multi-install in the process) so that it is updated, too. |
445 scoped_ptr<Product> multi_chrome(new Product( | 411 scoped_ptr<Product> multi_chrome(new Product( |
446 BrowserDistribution::GetSpecificDistribution( | 412 BrowserDistribution::GetSpecificDistribution( |
447 BrowserDistribution::CHROME_BROWSER))); | 413 BrowserDistribution::CHROME_BROWSER))); |
(...skipping 17 matching lines...) Expand all Loading... | |
465 installer_state->WriteInstallerResult(*status, | 431 installer_state->WriteInstallerResult(*status, |
466 IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL); | 432 IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL); |
467 return false; | 433 return false; |
468 } | 434 } |
469 } | 435 } |
470 } | 436 } |
471 | 437 |
472 return true; | 438 return true; |
473 } | 439 } |
474 | 440 |
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 | 441 // Checks for compatibility between the current state of the system and the |
504 // desired operation. Also applies policy that mutates the desired operation; | 442 // desired operation. Also applies policy that mutates the desired operation; |
505 // specifically, the |installer_state| object. | 443 // specifically, the |installer_state| object. |
506 // Also blocks simultaneous user-level and system-level installs. In the case | 444 // 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 | 445 // of trying to install user-level Chrome when system-level exists, the |
508 // existing system-level Chrome is launched. | 446 // existing system-level Chrome is launched. |
509 // When the pre-install conditions are not satisfied, the result is written to | 447 // When the pre-install conditions are not satisfied, the result is written to |
510 // the registry (via WriteInstallerResult), |status| is set appropriately, and | 448 // the registry (via WriteInstallerResult), |status| is set appropriately, and |
511 // false is returned. | 449 // false is returned. |
512 bool CheckPreInstallConditions(const InstallationState& original_state, | 450 bool CheckPreInstallConditions(const InstallationState& original_state, |
513 InstallerState* installer_state, | 451 InstallerState* installer_state, |
514 installer::InstallStatus* status) { | 452 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 | 453 // 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. | 454 // installs, we must upgrade all installations since they share the binaries. |
522 AddExistingMultiInstalls(original_state, installer_state); | 455 AddExistingMultiInstalls(original_state, installer_state); |
523 | 456 |
524 if (!CheckMultiInstallConditions(original_state, installer_state, status)) { | 457 if (!CheckMultiInstallConditions(original_state, installer_state, status)) { |
525 DCHECK_NE(*status, installer::UNKNOWN_STATUS); | 458 DCHECK_NE(*status, installer::UNKNOWN_STATUS); |
526 return false; | 459 return false; |
527 } | 460 } |
528 | 461 |
529 const Products& products = installer_state->products(); | 462 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()); | 523 base::LaunchProcess(cmd, base::LaunchOptions()); |
591 } | 524 } |
592 } else { | 525 } else { |
593 // It's no longer possible for |product| to be anything other than | 526 // It's no longer possible for |product| to be anything other than |
594 // Chrome. | 527 // Chrome. |
595 NOTREACHED(); | 528 NOTREACHED(); |
596 } | 529 } |
597 return false; | 530 return false; |
598 } | 531 } |
599 } | 532 } |
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 } | 533 } |
613 | 534 |
614 return true; | 535 return true; |
615 } | 536 } |
616 | 537 |
617 // Initializes |temp_path| to "Temp" within the target directory, and | 538 // Initializes |temp_path| to "Temp" within the target directory, and |
618 // |unpack_path| to a random directory beginning with "source" within | 539 // |unpack_path| to a random directory beginning with "source" within |
619 // |temp_path|. Returns false on error. | 540 // |temp_path|. Returns false on error. |
620 bool CreateTemporaryAndUnpackDirectories( | 541 bool CreateTemporaryAndUnpackDirectories( |
621 const InstallerState& installer_state, | 542 const InstallerState& installer_state, |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 return; | 672 return; |
752 } | 673 } |
753 | 674 |
754 LOG(INFO) << "Uninstalling unused binaries"; | 675 LOG(INFO) << "Uninstalling unused binaries"; |
755 installer_state.UpdateStage(installer::UNINSTALLING_BINARIES); | 676 installer_state.UpdateStage(installer::UNINSTALLING_BINARIES); |
756 | 677 |
757 // Simulate the uninstall as coming from the installed version. | 678 // Simulate the uninstall as coming from the installed version. |
758 const ProductState* binaries_state = | 679 const ProductState* binaries_state = |
759 original_state.GetProductState(installer_state.system_install(), | 680 original_state.GetProductState(installer_state.system_install(), |
760 BrowserDistribution::CHROME_BINARIES); | 681 BrowserDistribution::CHROME_BINARIES); |
682 if (!binaries_state) | |
grt (UTC plus 2)
2015/01/08 21:41:49
remove this.
huangs
2015/01/18 01:18:24
Without this, if you run "setup.exe --multi-instal
grt (UTC plus 2)
2015/01/20 21:30:22
Is this a supported flag combination? I don't beli
grt (UTC plus 2)
2015/01/21 02:18:12
ping
huangs
2015/01/21 20:33:52
See next comment.
huangs
2015/01/21 20:33:52
Per discussion, no need to worry about this, but n
| |
683 return; | |
684 | |
761 const CommandLine& uninstall_cmd(binaries_state->uninstall_command()); | 685 const CommandLine& uninstall_cmd(binaries_state->uninstall_command()); |
762 MasterPreferences uninstall_prefs(uninstall_cmd); | 686 MasterPreferences uninstall_prefs(uninstall_cmd); |
763 InstallerState uninstall_state; | 687 InstallerState uninstall_state; |
764 uninstall_state.Initialize(uninstall_cmd, uninstall_prefs, original_state); | 688 uninstall_state.Initialize(uninstall_cmd, uninstall_prefs, original_state); |
765 | 689 |
766 *install_status = UninstallProducts(original_state, uninstall_state, | 690 *install_status = UninstallProducts(original_state, uninstall_state, |
767 uninstall_cmd.GetProgram(), | 691 uninstall_cmd.GetProgram(), |
768 uninstall_cmd); | 692 uninstall_cmd); |
769 | 693 |
770 // Report that the binaries were uninstalled if they were. This translates | 694 // Report that the binaries were uninstalled if they were. This translates |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1513 if (product_state != NULL && | 1437 if (product_state != NULL && |
1514 (product_state->version().CompareTo(*installer_version) > 0)) { | 1438 (product_state->version().CompareTo(*installer_version) > 0)) { |
1515 LOG(ERROR) << "Higher version of " | 1439 LOG(ERROR) << "Higher version of " |
1516 << product.distribution()->GetDisplayName() | 1440 << product.distribution()->GetDisplayName() |
1517 << " is already installed."; | 1441 << " is already installed."; |
1518 higher_products |= (1 << product.distribution()->GetType()); | 1442 higher_products |= (1 << product.distribution()->GetType()); |
1519 } | 1443 } |
1520 } | 1444 } |
1521 | 1445 |
1522 if (higher_products != 0) { | 1446 if (higher_products != 0) { |
1523 COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 4, | 1447 COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 3, |
1524 add_support_for_new_products_here_); | 1448 add_support_for_new_products_here_); |
1525 const uint32 kBrowserBit = 1 << BrowserDistribution::CHROME_BROWSER; | 1449 int message_id = IDS_INSTALL_HIGHER_VERSION_BASE; |
1526 int message_id = 0; | |
1527 | |
1528 proceed_with_installation = false; | 1450 proceed_with_installation = false; |
1529 install_status = HIGHER_VERSION_EXISTS; | 1451 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); | 1452 installer_state.WriteInstallerResult(install_status, message_id, NULL); |
1540 } | 1453 } |
1541 | 1454 |
1542 proceed_with_installation = | 1455 proceed_with_installation = |
1543 proceed_with_installation && | 1456 proceed_with_installation && |
1544 CheckGroupPolicySettings(original_state, installer_state, | 1457 CheckGroupPolicySettings(original_state, installer_state, |
1545 *installer_version, &install_status); | 1458 *installer_version, &install_status); |
1546 | 1459 |
1547 if (proceed_with_installation) { | 1460 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( | 1461 base::FilePath prefs_source_path(cmd_line.GetSwitchValueNative( |
1565 switches::kInstallerData)); | 1462 switches::kInstallerData)); |
1566 install_status = InstallOrUpdateProduct( | 1463 install_status = InstallOrUpdateProduct( |
1567 original_state, installer_state, setup_exe, uncompressed_archive, | 1464 original_state, installer_state, setup_exe, uncompressed_archive, |
1568 temp_path.path(), src_path, prefs_source_path, prefs, | 1465 temp_path.path(), src_path, prefs_source_path, prefs, |
1569 *installer_version); | 1466 *installer_version); |
1570 | 1467 |
1571 int install_msg_base = IDS_INSTALL_FAILED_BASE; | 1468 int install_msg_base = IDS_INSTALL_FAILED_BASE; |
1572 base::FilePath chrome_exe; | 1469 base::FilePath chrome_exe; |
1573 base::string16 quoted_chrome_exe; | 1470 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 | 1716 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT |
1820 // to pass through, since this is only returned on uninstall which is | 1717 // to pass through, since this is only returned on uninstall which is |
1821 // never invoked directly by Google Update. | 1718 // never invoked directly by Google Update. |
1822 return_code = InstallUtil::GetInstallReturnCode(install_status); | 1719 return_code = InstallUtil::GetInstallReturnCode(install_status); |
1823 } | 1720 } |
1824 | 1721 |
1825 VLOG(1) << "Installation complete, returning: " << return_code; | 1722 VLOG(1) << "Installation complete, returning: " << return_code; |
1826 | 1723 |
1827 return return_code; | 1724 return return_code; |
1828 } | 1725 } |
OLD | NEW |