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/util/installer_state.h" | 5 #include "chrome/installer/util/installer_state.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 operand = BrowserDistribution::GetSpecificDistribution( | 286 operand = BrowserDistribution::GetSpecificDistribution( |
287 operand_distribution_type); | 287 operand_distribution_type); |
288 } | 288 } |
289 | 289 |
290 state_key_ = operand->GetStateKey(); | 290 state_key_ = operand->GetStateKey(); |
291 state_type_ = operand->GetType(); | 291 state_type_ = operand->GetType(); |
292 | 292 |
293 // Parse --critical-update-version=W.X.Y.Z | 293 // Parse --critical-update-version=W.X.Y.Z |
294 std::string critical_version_value( | 294 std::string critical_version_value( |
295 command_line.GetSwitchValueASCII(switches::kCriticalUpdateVersion)); | 295 command_line.GetSwitchValueASCII(switches::kCriticalUpdateVersion)); |
296 critical_update_version_ = base::Version(critical_version_value); | 296 critical_update_version_ = Version(critical_version_value); |
297 } | 297 } |
298 | 298 |
299 void InstallerState::set_level(Level level) { | 299 void InstallerState::set_level(Level level) { |
300 level_ = level; | 300 level_ = level; |
301 switch (level) { | 301 switch (level) { |
302 case USER_LEVEL: | 302 case USER_LEVEL: |
303 root_key_ = HKEY_CURRENT_USER; | 303 root_key_ = HKEY_CURRENT_USER; |
304 break; | 304 break; |
305 case SYSTEM_LEVEL: | 305 case SYSTEM_LEVEL: |
306 root_key_ = HKEY_LOCAL_MACHINE; | 306 root_key_ = HKEY_LOCAL_MACHINE; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 const Product* InstallerState::FindProduct( | 494 const Product* InstallerState::FindProduct( |
495 BrowserDistribution::Type distribution_type) const { | 495 BrowserDistribution::Type distribution_type) const { |
496 for (Products::const_iterator scan = products_.begin(), end = products_.end(); | 496 for (Products::const_iterator scan = products_.begin(), end = products_.end(); |
497 scan != end; ++scan) { | 497 scan != end; ++scan) { |
498 if ((*scan)->is_type(distribution_type)) | 498 if ((*scan)->is_type(distribution_type)) |
499 return *scan; | 499 return *scan; |
500 } | 500 } |
501 return NULL; | 501 return NULL; |
502 } | 502 } |
503 | 503 |
504 base::Version* InstallerState::GetCurrentVersion( | 504 Version* InstallerState::GetCurrentVersion( |
505 const InstallationState& machine_state) const { | 505 const InstallationState& machine_state) const { |
506 DCHECK(!products_.empty()); | 506 DCHECK(!products_.empty()); |
507 scoped_ptr<base::Version> current_version; | 507 scoped_ptr<Version> current_version; |
508 // If we're doing a multi-install, the current version may be either an | 508 // If we're doing a multi-install, the current version may be either an |
509 // existing multi or an existing single product that is being migrated | 509 // existing multi or an existing single product that is being migrated |
510 // in place (i.e., Chrome). In the latter case, there is no existing | 510 // in place (i.e., Chrome). In the latter case, there is no existing |
511 // CHROME_BINARIES installation so we need to search for the product. | 511 // CHROME_BINARIES installation so we need to search for the product. |
512 BrowserDistribution::Type prod_type; | 512 BrowserDistribution::Type prod_type; |
513 if (package_type_ == MULTI_PACKAGE) { | 513 if (package_type_ == MULTI_PACKAGE) { |
514 prod_type = BrowserDistribution::CHROME_BINARIES; | 514 prod_type = BrowserDistribution::CHROME_BINARIES; |
515 if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, | 515 if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, |
516 prod_type) == NULL) { | 516 prod_type) == NULL) { |
517 // Search for a product on which we're operating that is installed in our | 517 // Search for a product on which we're operating that is installed in our |
(...skipping 11 matching lines...) Expand all Loading... |
529 } | 529 } |
530 } | 530 } |
531 } | 531 } |
532 } else { | 532 } else { |
533 prod_type = products_[0]->distribution()->GetType(); | 533 prod_type = products_[0]->distribution()->GetType(); |
534 } | 534 } |
535 const ProductState* product_state = | 535 const ProductState* product_state = |
536 machine_state.GetProductState(level_ == SYSTEM_LEVEL, prod_type); | 536 machine_state.GetProductState(level_ == SYSTEM_LEVEL, prod_type); |
537 | 537 |
538 if (product_state != NULL) { | 538 if (product_state != NULL) { |
539 const base::Version* version = NULL; | 539 const Version* version = NULL; |
540 | 540 |
541 // Be aware that there might be a pending "new_chrome.exe" already in the | 541 // Be aware that there might be a pending "new_chrome.exe" already in the |
542 // installation path. If so, we use old_version, which holds the version of | 542 // installation path. If so, we use old_version, which holds the version of |
543 // "chrome.exe" itself. | 543 // "chrome.exe" itself. |
544 if (base::PathExists(target_path().Append(kChromeNewExe))) | 544 if (base::PathExists(target_path().Append(kChromeNewExe))) |
545 version = product_state->old_version(); | 545 version = product_state->old_version(); |
546 | 546 |
547 if (version == NULL) | 547 if (version == NULL) |
548 version = &product_state->version(); | 548 version = &product_state->version(); |
549 | 549 |
550 current_version.reset(new base::Version(*version)); | 550 current_version.reset(new Version(*version)); |
551 } | 551 } |
552 | 552 |
553 return current_version.release(); | 553 return current_version.release(); |
554 } | 554 } |
555 | 555 |
556 base::Version InstallerState::DetermineCriticalVersion( | 556 Version InstallerState::DetermineCriticalVersion( |
557 const base::Version* current_version, | 557 const Version* current_version, |
558 const base::Version& new_version) const { | 558 const Version& new_version) const { |
559 DCHECK(current_version == NULL || current_version->IsValid()); | 559 DCHECK(current_version == NULL || current_version->IsValid()); |
560 DCHECK(new_version.IsValid()); | 560 DCHECK(new_version.IsValid()); |
561 if (critical_update_version_.IsValid() && | 561 if (critical_update_version_.IsValid() && |
562 (current_version == NULL || | 562 (current_version == NULL || |
563 (current_version->CompareTo(critical_update_version_) < 0)) && | 563 (current_version->CompareTo(critical_update_version_) < 0)) && |
564 new_version.CompareTo(critical_update_version_) >= 0) { | 564 new_version.CompareTo(critical_update_version_) >= 0) { |
565 return critical_update_version_; | 565 return critical_update_version_; |
566 } | 566 } |
567 return base::Version(); | 567 return Version(); |
568 } | 568 } |
569 | 569 |
570 bool InstallerState::IsChromeFrameRunning( | 570 bool InstallerState::IsChromeFrameRunning( |
571 const InstallationState& machine_state) const { | 571 const InstallationState& machine_state) const { |
572 return AnyExistsAndIsInUse(machine_state, CHROME_FRAME_DLL); | 572 return AnyExistsAndIsInUse(machine_state, CHROME_FRAME_DLL); |
573 } | 573 } |
574 | 574 |
575 bool InstallerState::AreBinariesInUse( | 575 bool InstallerState::AreBinariesInUse( |
576 const InstallationState& machine_state) const { | 576 const InstallationState& machine_state) const { |
577 return AnyExistsAndIsInUse( | 577 return AnyExistsAndIsInUse( |
578 machine_state, | 578 machine_state, |
579 (CHROME_FRAME_HELPER_EXE | CHROME_FRAME_HELPER_DLL | | 579 (CHROME_FRAME_HELPER_EXE | CHROME_FRAME_HELPER_DLL | |
580 CHROME_FRAME_DLL | CHROME_DLL)); | 580 CHROME_FRAME_DLL | CHROME_DLL)); |
581 } | 581 } |
582 | 582 |
583 base::FilePath InstallerState::GetInstallerDirectory( | 583 base::FilePath InstallerState::GetInstallerDirectory( |
584 const base::Version& version) const { | 584 const Version& version) const { |
585 return target_path().Append(base::ASCIIToWide(version.GetString())) | 585 return target_path().Append(base::ASCIIToWide(version.GetString())) |
586 .Append(kInstallerDir); | 586 .Append(kInstallerDir); |
587 } | 587 } |
588 | 588 |
589 // static | 589 // static |
590 bool InstallerState::IsFileInUse(const base::FilePath& file) { | 590 bool InstallerState::IsFileInUse(const base::FilePath& file) { |
591 // Call CreateFile with a share mode of 0 which should cause this to fail | 591 // Call CreateFile with a share mode of 0 which should cause this to fail |
592 // with ERROR_SHARING_VIOLATION if the file exists and is in-use. | 592 // with ERROR_SHARING_VIOLATION if the file exists and is in-use. |
593 return !base::win::ScopedHandle(CreateFile(file.value().c_str(), | 593 return !base::win::ScopedHandle(CreateFile(file.value().c_str(), |
594 GENERIC_WRITE, 0, NULL, | 594 GENERIC_WRITE, 0, NULL, |
(...skipping 29 matching lines...) Expand all Loading... |
624 DCHECK_LT(file_bits, 1U << NUM_BINARIES); | 624 DCHECK_LT(file_bits, 1U << NUM_BINARIES); |
625 COMPILE_ASSERT(CHROME_DLL == 1, no_youre_out_of_order); | 625 COMPILE_ASSERT(CHROME_DLL == 1, no_youre_out_of_order); |
626 COMPILE_ASSERT(CHROME_FRAME_DLL == 2, no_youre_out_of_order); | 626 COMPILE_ASSERT(CHROME_FRAME_DLL == 2, no_youre_out_of_order); |
627 COMPILE_ASSERT(CHROME_FRAME_HELPER_DLL == 4, no_youre_out_of_order); | 627 COMPILE_ASSERT(CHROME_FRAME_HELPER_DLL == 4, no_youre_out_of_order); |
628 COMPILE_ASSERT(CHROME_FRAME_HELPER_EXE == 8, no_youre_out_of_order); | 628 COMPILE_ASSERT(CHROME_FRAME_HELPER_EXE == 8, no_youre_out_of_order); |
629 | 629 |
630 // Check only for the current version (i.e., the version we are upgrading | 630 // Check only for the current version (i.e., the version we are upgrading |
631 // _from_). Later versions from pending in-use updates need not be checked | 631 // _from_). Later versions from pending in-use updates need not be checked |
632 // since the current version is guaranteed to be in use if any such are. | 632 // since the current version is guaranteed to be in use if any such are. |
633 bool in_use = false; | 633 bool in_use = false; |
634 scoped_ptr<base::Version> current_version(GetCurrentVersion(machine_state)); | 634 scoped_ptr<Version> current_version(GetCurrentVersion(machine_state)); |
635 if (!current_version) | 635 if (!current_version) |
636 return false; | 636 return false; |
637 base::FilePath directory( | 637 base::FilePath directory( |
638 target_path().AppendASCII(current_version->GetString())); | 638 target_path().AppendASCII(current_version->GetString())); |
639 for (int i = 0; i < NUM_BINARIES; ++i) { | 639 for (int i = 0; i < NUM_BINARIES; ++i) { |
640 if (!(file_bits & (1U << i))) | 640 if (!(file_bits & (1U << i))) |
641 continue; | 641 continue; |
642 base::FilePath file(directory.Append(kBinaryFileNames[i])); | 642 base::FilePath file(directory.Append(kBinaryFileNames[i])); |
643 if (base::PathExists(file) && IsFileInUse(file)) | 643 if (base::PathExists(file) && IsFileInUse(file)) |
644 return true; | 644 return true; |
(...skipping 16 matching lines...) Expand all Loading... |
661 FileVersionInfo::CreateFileVersionInfo(chrome_exe)); | 661 FileVersionInfo::CreateFileVersionInfo(chrome_exe)); |
662 if (file_version_info) { | 662 if (file_version_info) { |
663 base::string16 version_string = file_version_info->file_version(); | 663 base::string16 version_string = file_version_info->file_version(); |
664 if (!version_string.empty() && IsStringASCII(version_string)) | 664 if (!version_string.empty() && IsStringASCII(version_string)) |
665 existing_versions->insert(WideToASCII(version_string)); | 665 existing_versions->insert(WideToASCII(version_string)); |
666 } | 666 } |
667 } | 667 } |
668 } | 668 } |
669 | 669 |
670 void InstallerState::RemoveOldVersionDirectories( | 670 void InstallerState::RemoveOldVersionDirectories( |
671 const base::Version& new_version, | 671 const Version& new_version, |
672 base::Version* existing_version, | 672 Version* existing_version, |
673 const base::FilePath& temp_path) const { | 673 const base::FilePath& temp_path) const { |
674 base::Version version; | 674 Version version; |
675 scoped_ptr<WorkItem> item; | 675 scoped_ptr<WorkItem> item; |
676 | 676 |
677 std::set<std::string> existing_version_strings; | 677 std::set<std::string> existing_version_strings; |
678 existing_version_strings.insert(new_version.GetString()); | 678 existing_version_strings.insert(new_version.GetString()); |
679 if (existing_version) | 679 if (existing_version) |
680 existing_version_strings.insert(existing_version->GetString()); | 680 existing_version_strings.insert(existing_version->GetString()); |
681 | 681 |
682 // Make sure not to delete any version dir that is "referenced" by an existing | 682 // Make sure not to delete any version dir that is "referenced" by an existing |
683 // Chrome executable. | 683 // Chrome executable. |
684 GetExistingExeVersions(&existing_version_strings); | 684 GetExistingExeVersions(&existing_version_strings); |
685 | 685 |
686 // Try to delete all directories that are not in the set we care to keep. | 686 // Try to delete all directories that are not in the set we care to keep. |
687 base::FileEnumerator version_enum(target_path(), false, | 687 base::FileEnumerator version_enum(target_path(), false, |
688 base::FileEnumerator::DIRECTORIES); | 688 base::FileEnumerator::DIRECTORIES); |
689 for (base::FilePath next_version = version_enum.Next(); !next_version.empty(); | 689 for (base::FilePath next_version = version_enum.Next(); !next_version.empty(); |
690 next_version = version_enum.Next()) { | 690 next_version = version_enum.Next()) { |
691 base::FilePath dir_name(next_version.BaseName()); | 691 base::FilePath dir_name(next_version.BaseName()); |
692 version = base::Version(WideToASCII(dir_name.value())); | 692 version = Version(WideToASCII(dir_name.value())); |
693 // Delete the version folder if it is less than the new version and not | 693 // Delete the version folder if it is less than the new version and not |
694 // equal to the old version (if we have an old version). | 694 // equal to the old version (if we have an old version). |
695 if (version.IsValid() && | 695 if (version.IsValid() && |
696 existing_version_strings.count(version.GetString()) == 0) { | 696 existing_version_strings.count(version.GetString()) == 0) { |
697 // Note: temporarily log old version deletion at ERROR level to make it | 697 // Note: temporarily log old version deletion at ERROR level to make it |
698 // more likely we see this in the installer log. | 698 // more likely we see this in the installer log. |
699 LOG(ERROR) << "Deleting old version directory: " << next_version.value(); | 699 LOG(ERROR) << "Deleting old version directory: " << next_version.value(); |
700 | 700 |
701 // Attempt to recursively delete the old version dir. | 701 // Attempt to recursively delete the old version dir. |
702 bool delete_succeeded = base::DeleteFile(next_version, true); | 702 bool delete_succeeded = base::DeleteFile(next_version, true); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 } | 823 } |
824 if (!install_list->Do()) | 824 if (!install_list->Do()) |
825 LOG(ERROR) << "Failed to record installer error information in registry."; | 825 LOG(ERROR) << "Failed to record installer error information in registry."; |
826 } | 826 } |
827 | 827 |
828 bool InstallerState::RequiresActiveSetup() const { | 828 bool InstallerState::RequiresActiveSetup() const { |
829 return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); | 829 return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); |
830 } | 830 } |
831 | 831 |
832 } // namespace installer | 832 } // namespace installer |
OLD | NEW |