| 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 |