Chromium Code Reviews| 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 <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 "base/at_exit.h" | 10 #include "base/at_exit.h" |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 InstallerState* installer_state, | 349 InstallerState* installer_state, |
| 350 installer::InstallStatus* status) { | 350 installer::InstallStatus* status) { |
| 351 const Products& products = installer_state->products(); | 351 const Products& products = installer_state->products(); |
| 352 DCHECK(products.size()); | 352 DCHECK(products.size()); |
| 353 | 353 |
| 354 const bool system_level = installer_state->system_install(); | 354 const bool system_level = installer_state->system_install(); |
| 355 | 355 |
| 356 if (installer_state->is_multi_install()) { | 356 if (installer_state->is_multi_install()) { |
| 357 const Product* chrome = | 357 const Product* chrome = |
| 358 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); | 358 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); |
| 359 const Product* binaries = | |
| 360 installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES); | |
| 359 const Product* chrome_frame = | 361 const Product* chrome_frame = |
| 360 installer_state->FindProduct(BrowserDistribution::CHROME_FRAME); | 362 installer_state->FindProduct(BrowserDistribution::CHROME_FRAME); |
| 361 const ProductState* cf_state = | 363 const ProductState* cf_state = |
| 362 original_state.GetProductState(system_level, | 364 original_state.GetProductState(system_level, |
| 363 BrowserDistribution::CHROME_FRAME); | 365 BrowserDistribution::CHROME_FRAME); |
| 364 if (chrome != NULL) { | 366 if (chrome != NULL) { |
| 365 if (chrome_frame != NULL && | 367 if (chrome_frame != NULL && |
| 366 chrome_frame->HasOption(installer::kOptionReadyMode)) { | 368 chrome_frame->HasOption(installer::kOptionReadyMode)) { |
| 367 // We're being asked to install Chrome with Chrome Frame in ready-mode. | 369 // We're being asked to install Chrome with Chrome Frame in ready-mode. |
| 368 // This is an optimistic operation: if a SxS install of Chrome Frame | 370 // This is an optimistic operation: if a SxS install of Chrome Frame |
| 369 // is already present, don't touch it; if a multi-install of Chrome | 371 // is already present, don't touch it; if a multi-install of Chrome |
| 370 // Frame is present, preserve its settings (ready-mode). | 372 // Frame is present, preserve its settings (ready-mode). |
| 371 if (cf_state != NULL) { | 373 if (cf_state != NULL) { |
| 372 installer_state->RemoveProduct(chrome_frame); | 374 installer_state->RemoveProduct(chrome_frame); |
| 373 chrome_frame = NULL; | 375 chrome_frame = NULL; |
| 374 if (cf_state->is_multi_install()) { | 376 if (cf_state->is_multi_install()) { |
| 375 chrome_frame = installer_state->AddProductFromState( | 377 chrome_frame = installer_state->AddProductFromState( |
| 376 BrowserDistribution::CHROME_FRAME, *cf_state); | 378 BrowserDistribution::CHROME_FRAME, *cf_state); |
| 377 VLOG(1) << "Upgrading existing multi-install Chrome Frame rather " | 379 VLOG(1) << "Upgrading existing multi-install Chrome Frame rather " |
| 378 "than installing in ready-mode."; | 380 "than installing in ready-mode."; |
| 379 } else { | 381 } else { |
| 380 VLOG(1) << "Skipping upgrade of single-install Chrome Frame rather " | 382 VLOG(1) << "Skipping upgrade of single-install Chrome Frame rather " |
| 381 "than installing in ready-mode."; | 383 "than installing in ready-mode."; |
| 382 } | 384 } |
| 383 } else { | 385 } else { |
| 384 VLOG(1) << "Performing initial install of Chrome Frame ready-mode."; | 386 VLOG(1) << "Performing initial install of Chrome Frame ready-mode."; |
| 385 } | 387 } |
| 386 } | 388 } |
| 387 } else if (chrome_frame != NULL) { | 389 } else if (binaries != NULL) { |
| 388 // We're being asked to install or update Chrome Frame alone. | 390 // We're being asked to install or update the binaries without Chrome. |
| 389 const ProductState* chrome_state = | 391 const ProductState* chrome_state = |
| 390 original_state.GetProductState(system_level, | 392 original_state.GetProductState(system_level, |
| 391 BrowserDistribution::CHROME_BROWSER); | 393 BrowserDistribution::CHROME_BROWSER); |
| 392 if (chrome_state != NULL) { | 394 if (chrome_state != NULL) { |
| 393 // Add Chrome to the set of products (making it multi-install in the | 395 // Add Chrome to the set of products (making it multi-install in the |
| 394 // process) so that it is updated, too. | 396 // process) so that it is updated, too. |
| 395 scoped_ptr<Product> multi_chrome(new Product( | 397 scoped_ptr<Product> multi_chrome(new Product( |
| 396 BrowserDistribution::GetSpecificDistribution( | 398 BrowserDistribution::GetSpecificDistribution( |
| 397 BrowserDistribution::CHROME_BROWSER))); | 399 BrowserDistribution::CHROME_BROWSER))); |
| 398 multi_chrome->SetOption(installer::kOptionMultiInstall, true); | 400 multi_chrome->SetOption(installer::kOptionMultiInstall, true); |
| 399 chrome = installer_state->AddProduct(&multi_chrome); | 401 chrome = installer_state->AddProduct(&multi_chrome); |
| 400 VLOG(1) << "Upgrading existing multi-install Chrome browser along with " | 402 VLOG(1) << "Upgrading existing Chrome browser in multi-install mode."; |
| 401 << chrome_frame->distribution()->GetAppShortCutName(); | 403 } else if (chrome_frame && chrome_frame->HasOption(installer::kOptionReady Mode)) { |
|
grt (UTC plus 2)
2012/07/12 18:37:10
80 cols
erikwright (departed)
2012/07/16 20:13:11
Done.
| |
| 402 } else if (chrome_frame->HasOption(installer::kOptionReadyMode)) { | |
| 403 // Chrome Frame with ready-mode is to be installed, yet Chrome is | 404 // Chrome Frame with ready-mode is to be installed, yet Chrome is |
| 404 // neither installed nor being installed. Fail. | 405 // neither installed nor being installed. Fail. |
| 405 LOG(ERROR) << "Cannot install Chrome Frame in ready mode without " | 406 LOG(ERROR) << "Cannot install Chrome Frame in ready mode without " |
| 406 "Chrome."; | 407 "Chrome."; |
| 407 *status = installer::READY_MODE_REQUIRES_CHROME; | 408 *status = installer::READY_MODE_REQUIRES_CHROME; |
| 408 installer_state->WriteInstallerResult(*status, | 409 installer_state->WriteInstallerResult(*status, |
| 409 IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL); | 410 IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL); |
| 410 return false; | 411 return false; |
| 411 } | 412 } |
| 412 } | 413 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 427 } else if (DCHECK_IS_ON()) { | 428 } else if (DCHECK_IS_ON()) { |
| 428 // It isn't possible to stuff two products into a single-install | 429 // It isn't possible to stuff two products into a single-install |
| 429 // InstallerState. Abort the process here in debug builds just in case | 430 // InstallerState. Abort the process here in debug builds just in case |
| 430 // someone finds a way. | 431 // someone finds a way. |
| 431 DCHECK_EQ(1U, products.size()); | 432 DCHECK_EQ(1U, products.size()); |
| 432 } | 433 } |
| 433 | 434 |
| 434 return true; | 435 return true; |
| 435 } | 436 } |
| 436 | 437 |
| 438 bool CheckAppHostPreconditions(const InstallationState& original_state, | |
|
grt (UTC plus 2)
2012/07/12 18:37:10
please document the failure modes and side effects
erikwright (departed)
2012/07/16 20:13:11
The logic you refer to moved to InstallerState.
| |
| 439 InstallerState* installer_state) { | |
| 440 if (!installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST)) | |
| 441 return true; | |
| 442 | |
| 443 if (installer_state->level() == InstallerState::SYSTEM_LEVEL) | |
| 444 return false; | |
|
grt (UTC plus 2)
2012/07/12 18:37:10
VLOG(1) the reason for failure
erikwright (departed)
2012/07/16 20:13:11
Done.
| |
| 445 | |
|
grt (UTC plus 2)
2012/07/12 18:37:10
if (instaler_state->package_type() != InstallerSta
erikwright (departed)
2012/07/16 20:13:11
Done.
| |
| 446 const ProductState* chrome_state = original_state.GetProductState( | |
| 447 true /* system level */, BrowserDistribution::CHROME_BROWSER); | |
|
tommi (sloooow) - chröme
2012/07/12 08:11:31
nit: I think we avoid /**/ comments in general. in
grt (UTC plus 2)
2012/07/12 18:37:10
InstallerState::Level could be moved up into the "
erikwright (departed)
2012/07/16 20:13:11
Done.
erikwright (departed)
2012/07/16 20:13:11
Not done for this CL.
| |
| 448 if (chrome_state) { | |
| 449 // Chrome is at system-level, multi- or otherwise. We'll use it. | |
| 450 return true; | |
| 451 } | |
| 452 | |
| 453 const ProductState* binaries_state = original_state.GetProductState( | |
| 454 false /* system level */, BrowserDistribution::CHROME_BINARIES); | |
|
grt (UTC plus 2)
2012/07/12 18:37:10
should the comment be "!system level"? i find it
erikwright (departed)
2012/07/16 20:13:11
This particular instance is gone.
| |
| 455 if (!binaries_state) { | |
| 456 binaries_state = original_state.GetProductState( | |
| 457 true /* system level */, BrowserDistribution::CHROME_BINARIES); | |
| 458 } | |
| 459 | |
| 460 if (binaries_state) { | |
| 461 // Binaries are installed somewhere. We'll use 'em. | |
| 462 return true; | |
| 463 } | |
| 464 | |
| 465 if (!binaries_state && ! installer_state->is_multi_install()) { | |
|
grt (UTC plus 2)
2012/07/12 18:37:10
remove this block as discussed
erikwright (departed)
2012/07/16 20:13:11
Done.
| |
| 466 // Can't install binaries because this isn't a multi install. | |
| 467 return false; | |
| 468 } | |
| 469 | |
| 470 if (!installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES)) { | |
| 471 // Force binaries to be installed. | |
| 472 scoped_ptr<Product> binaries_product(new Product( | |
| 473 BrowserDistribution::GetSpecificDistribution( | |
| 474 BrowserDistribution::CHROME_BINARIES))); | |
| 475 binaries_product->SetOption(installer::kOptionMultiInstall, true); | |
| 476 if (!installer_state->AddProduct(&binaries_product)) { | |
| 477 // Can't install binaries for some reason. | |
| 478 return false; | |
| 479 } | |
| 480 } | |
| 481 | |
| 482 return true; | |
| 483 } | |
| 484 | |
| 437 // Checks for compatibility between the current state of the system and the | 485 // Checks for compatibility between the current state of the system and the |
| 438 // desired operation. Also applies policy that mutates the desired operation; | 486 // desired operation. Also applies policy that mutates the desired operation; |
| 439 // specifically, the |installer_state| object. | 487 // specifically, the |installer_state| object. |
| 440 // Also blocks simultaneous user-level and system-level installs. In the case | 488 // Also blocks simultaneous user-level and system-level installs. In the case |
| 441 // of trying to install user-level Chrome when system-level exists, the | 489 // of trying to install user-level Chrome when system-level exists, the |
| 442 // existing system-level Chrome is launched. | 490 // existing system-level Chrome is launched. |
| 443 // When the pre-install conditions are not satisfied, the result is written to | 491 // When the pre-install conditions are not satisfied, the result is written to |
| 444 // the registry (via WriteInstallerResult), |status| is set appropriately, and | 492 // the registry (via WriteInstallerResult), |status| is set appropriately, and |
| 445 // false is returned. | 493 // false is returned. |
| 446 bool CheckPreInstallConditions(const InstallationState& original_state, | 494 bool CheckPreInstallConditions(const InstallationState& original_state, |
| 447 InstallerState* installer_state, | 495 InstallerState* installer_state, |
| 448 installer::InstallStatus* status) { | 496 installer::InstallStatus* status) { |
| 497 if (!CheckAppHostPreconditions(original_state, installer_state)) | |
| 498 return false; | |
| 499 | |
| 449 // See what products are already installed in multi mode. When we do multi | 500 // See what products are already installed in multi mode. When we do multi |
| 450 // installs, we must upgrade all installations since they share the binaries. | 501 // installs, we must upgrade all installations since they share the binaries. |
| 451 AddExistingMultiInstalls(original_state, installer_state); | 502 AddExistingMultiInstalls(original_state, installer_state); |
| 452 | 503 |
| 453 const Products& products = installer_state->products(); | 504 const Products& products = installer_state->products(); |
| 454 if (products.empty()) { | 505 if (products.empty()) { |
| 455 // We haven't been given any products on which to operate. | 506 // We haven't been given any products on which to operate. |
| 456 LOG(ERROR) | 507 LOG(ERROR) |
| 457 << "Not given any products to install and no products found to update."; | 508 << "Not given any products to install and no products found to update."; |
| 458 *status = installer::CHROME_NOT_INSTALLED; | 509 *status = installer::CHROME_NOT_INSTALLED; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 617 if (product_state != NULL && | 668 if (product_state != NULL && |
| 618 (product_state->version().CompareTo(*installer_version) > 0)) { | 669 (product_state->version().CompareTo(*installer_version) > 0)) { |
| 619 LOG(ERROR) << "Higher version of " | 670 LOG(ERROR) << "Higher version of " |
| 620 << product->distribution()->GetAppShortCutName() | 671 << product->distribution()->GetAppShortCutName() |
| 621 << " is already installed."; | 672 << " is already installed."; |
| 622 higher_products |= (1 << product->distribution()->GetType()); | 673 higher_products |= (1 << product->distribution()->GetType()); |
| 623 } | 674 } |
| 624 } | 675 } |
| 625 | 676 |
| 626 if (higher_products != 0) { | 677 if (higher_products != 0) { |
| 627 COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 3, | 678 COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 4, |
| 628 add_support_for_new_products_here_); | 679 add_support_for_new_products_here_); |
| 629 const uint32 kBrowserBit = 1 << BrowserDistribution::CHROME_BROWSER; | 680 const uint32 kBrowserBit = 1 << BrowserDistribution::CHROME_BROWSER; |
| 630 const uint32 kGCFBit = 1 << BrowserDistribution::CHROME_FRAME; | 681 const uint32 kGCFBit = 1 << BrowserDistribution::CHROME_FRAME; |
| 682 const uint32 kAppHostBit = 1 << BrowserDistribution::CHROME_APP_HOST; | |
| 631 int message_id = 0; | 683 int message_id = 0; |
| 632 | 684 |
| 633 proceed_with_installation = false; | 685 proceed_with_installation = false; |
| 634 install_status = installer::HIGHER_VERSION_EXISTS; | 686 install_status = installer::HIGHER_VERSION_EXISTS; |
| 635 if ((higher_products & kBrowserBit) != 0) { | 687 switch (higher_products) { |
| 636 if ((higher_products & kGCFBit) != 0) | 688 case kBrowserBit: |
| 689 message_id = IDS_INSTALL_HIGHER_VERSION_BASE; | |
| 690 break; | |
| 691 case kGCFBit: | |
| 692 message_id = IDS_INSTALL_HIGHER_VERSION_CF_BASE; | |
| 693 break; | |
| 694 case kGCFBit & kBrowserBit: | |
|
grt (UTC plus 2)
2012/07/12 18:37:10
i think you mean "kGCFBit | kBrowserBit" here.
erikwright (departed)
2012/07/16 20:13:11
Done.
| |
| 637 message_id = IDS_INSTALL_HIGHER_VERSION_CB_CF_BASE; | 695 message_id = IDS_INSTALL_HIGHER_VERSION_CB_CF_BASE; |
| 638 else | 696 break; |
| 639 message_id = IDS_INSTALL_HIGHER_VERSION_BASE; | 697 default: |
| 640 } else { | 698 message_id = IDS_INSTALL_HIGHER_VERSION_APP_HOST_BASE; |
| 641 DCHECK(higher_products == kGCFBit); | 699 break; |
| 642 message_id = IDS_INSTALL_HIGHER_VERSION_CF_BASE; | |
| 643 } | 700 } |
| 644 | 701 |
| 645 installer_state.WriteInstallerResult(install_status, message_id, NULL); | 702 installer_state.WriteInstallerResult(install_status, message_id, NULL); |
| 646 } | 703 } |
| 647 | 704 |
| 648 proceed_with_installation = | 705 proceed_with_installation = |
| 649 proceed_with_installation && | 706 proceed_with_installation && |
| 650 CheckGroupPolicySettings(original_state, installer_state, | 707 CheckGroupPolicySettings(original_state, installer_state, |
| 651 *installer_version, &install_status); | 708 *installer_version, &install_status); |
| 652 | 709 |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 876 | 933 |
| 877 installer::InstallStatus UninstallProducts( | 934 installer::InstallStatus UninstallProducts( |
| 878 const InstallationState& original_state, | 935 const InstallationState& original_state, |
| 879 const InstallerState& installer_state, | 936 const InstallerState& installer_state, |
| 880 const CommandLine& cmd_line) { | 937 const CommandLine& cmd_line) { |
| 881 const Products& products = installer_state.products(); | 938 const Products& products = installer_state.products(); |
| 882 // InstallerState::Initialize always puts Chrome first, and we rely on that | 939 // InstallerState::Initialize always puts Chrome first, and we rely on that |
| 883 // here for this reason: if Chrome is in-use, the user will be prompted to | 940 // here for this reason: if Chrome is in-use, the user will be prompted to |
| 884 // confirm uninstallation. Upon cancel, we should not continue with the | 941 // confirm uninstallation. Upon cancel, we should not continue with the |
| 885 // other products. | 942 // other products. |
| 886 DCHECK(products.size() < 2 || products[0]->is_chrome()); | 943 // TODO(erikwright): if product 0 is not chrome, assert chrome not in products |
|
tommi (sloooow) - chröme
2012/07/12 08:11:31
do you intend to do that before checkin?
erikwright (departed)
2012/07/16 20:13:11
Done.
| |
| 887 installer::InstallStatus install_status = installer::UNINSTALL_SUCCESSFUL; | 944 installer::InstallStatus install_status = installer::UNINSTALL_SUCCESSFUL; |
| 888 installer::InstallStatus prod_status = installer::UNKNOWN_STATUS; | 945 installer::InstallStatus prod_status = installer::UNKNOWN_STATUS; |
| 889 const bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall); | 946 const bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall); |
| 890 const bool remove_all = !cmd_line.HasSwitch( | 947 const bool remove_all = !cmd_line.HasSwitch( |
| 891 installer::switches::kDoNotRemoveSharedItems); | 948 installer::switches::kDoNotRemoveSharedItems); |
| 892 | 949 |
| 893 for (size_t i = 0; | 950 for (size_t i = 0; |
| 894 install_status != installer::UNINSTALL_CANCELLED && | 951 install_status != installer::UNINSTALL_CANCELLED && |
| 895 i < products.size(); | 952 i < products.size(); |
| 896 ++i) { | 953 ++i) { |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1388 if (!(installer_state.is_msi() && is_uninstall)) | 1445 if (!(installer_state.is_msi() && is_uninstall)) |
| 1389 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT | 1446 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT |
| 1390 // to pass through, since this is only returned on uninstall which is | 1447 // to pass through, since this is only returned on uninstall which is |
| 1391 // never invoked directly by Google Update. | 1448 // never invoked directly by Google Update. |
| 1392 return_code = InstallUtil::GetInstallReturnCode(install_status); | 1449 return_code = InstallUtil::GetInstallReturnCode(install_status); |
| 1393 | 1450 |
| 1394 VLOG(1) << "Installation complete, returning: " << return_code; | 1451 VLOG(1) << "Installation complete, returning: " << return_code; |
| 1395 | 1452 |
| 1396 return return_code; | 1453 return return_code; |
| 1397 } | 1454 } |
| OLD | NEW |