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 |