| 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 BrowserDistribution::CHROME_BROWSER : | 152 BrowserDistribution::CHROME_BROWSER : |
| 153 BrowserDistribution::CHROME_BINARIES); | 153 BrowserDistribution::CHROME_BINARIES); |
| 154 } | 154 } |
| 155 | 155 |
| 156 state_key_ = operand->GetStateKey(); | 156 state_key_ = operand->GetStateKey(); |
| 157 state_type_ = operand->GetType(); | 157 state_type_ = operand->GetType(); |
| 158 | 158 |
| 159 // Parse --critical-update-version=W.X.Y.Z | 159 // Parse --critical-update-version=W.X.Y.Z |
| 160 std::string critical_version_value( | 160 std::string critical_version_value( |
| 161 command_line.GetSwitchValueASCII(switches::kCriticalUpdateVersion)); | 161 command_line.GetSwitchValueASCII(switches::kCriticalUpdateVersion)); |
| 162 critical_update_version_ = base::Version(critical_version_value); | 162 critical_update_version_ = Version(critical_version_value); |
| 163 } | 163 } |
| 164 | 164 |
| 165 void InstallerState::set_level(Level level) { | 165 void InstallerState::set_level(Level level) { |
| 166 level_ = level; | 166 level_ = level; |
| 167 switch (level) { | 167 switch (level) { |
| 168 case USER_LEVEL: | 168 case USER_LEVEL: |
| 169 root_key_ = HKEY_CURRENT_USER; | 169 root_key_ = HKEY_CURRENT_USER; |
| 170 break; | 170 break; |
| 171 case SYSTEM_LEVEL: | 171 case SYSTEM_LEVEL: |
| 172 root_key_ = HKEY_LOCAL_MACHINE; | 172 root_key_ = HKEY_LOCAL_MACHINE; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 const Product* InstallerState::FindProduct( | 360 const Product* InstallerState::FindProduct( |
| 361 BrowserDistribution::Type distribution_type) const { | 361 BrowserDistribution::Type distribution_type) const { |
| 362 for (Products::const_iterator scan = products_.begin(), end = products_.end(); | 362 for (Products::const_iterator scan = products_.begin(), end = products_.end(); |
| 363 scan != end; ++scan) { | 363 scan != end; ++scan) { |
| 364 if ((*scan)->is_type(distribution_type)) | 364 if ((*scan)->is_type(distribution_type)) |
| 365 return *scan; | 365 return *scan; |
| 366 } | 366 } |
| 367 return NULL; | 367 return NULL; |
| 368 } | 368 } |
| 369 | 369 |
| 370 base::Version* InstallerState::GetCurrentVersion( | 370 Version* InstallerState::GetCurrentVersion( |
| 371 const InstallationState& machine_state) const { | 371 const InstallationState& machine_state) const { |
| 372 DCHECK(!products_.empty()); | 372 DCHECK(!products_.empty()); |
| 373 scoped_ptr<base::Version> current_version; | 373 scoped_ptr<Version> current_version; |
| 374 // If we're doing a multi-install, the current version may be either an | 374 // If we're doing a multi-install, the current version may be either an |
| 375 // existing multi or an existing single product that is being migrated | 375 // existing multi or an existing single product that is being migrated |
| 376 // in place (i.e., Chrome). In the latter case, there is no existing | 376 // in place (i.e., Chrome). In the latter case, there is no existing |
| 377 // CHROME_BINARIES installation so we need to search for the product. | 377 // CHROME_BINARIES installation so we need to search for the product. |
| 378 BrowserDistribution::Type prod_type; | 378 BrowserDistribution::Type prod_type; |
| 379 if (package_type_ == MULTI_PACKAGE) { | 379 if (package_type_ == MULTI_PACKAGE) { |
| 380 prod_type = BrowserDistribution::CHROME_BINARIES; | 380 prod_type = BrowserDistribution::CHROME_BINARIES; |
| 381 if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, | 381 if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, |
| 382 prod_type) == NULL) { | 382 prod_type) == NULL) { |
| 383 // Search for a product on which we're operating that is installed in our | 383 // Search for a product on which we're operating that is installed in our |
| (...skipping 11 matching lines...) Expand all Loading... |
| 395 } | 395 } |
| 396 } | 396 } |
| 397 } | 397 } |
| 398 } else { | 398 } else { |
| 399 prod_type = products_[0]->distribution()->GetType(); | 399 prod_type = products_[0]->distribution()->GetType(); |
| 400 } | 400 } |
| 401 const ProductState* product_state = | 401 const ProductState* product_state = |
| 402 machine_state.GetProductState(level_ == SYSTEM_LEVEL, prod_type); | 402 machine_state.GetProductState(level_ == SYSTEM_LEVEL, prod_type); |
| 403 | 403 |
| 404 if (product_state != NULL) { | 404 if (product_state != NULL) { |
| 405 const base::Version* version = NULL; | 405 const Version* version = NULL; |
| 406 | 406 |
| 407 // Be aware that there might be a pending "new_chrome.exe" already in the | 407 // Be aware that there might be a pending "new_chrome.exe" already in the |
| 408 // installation path. If so, we use old_version, which holds the version of | 408 // installation path. If so, we use old_version, which holds the version of |
| 409 // "chrome.exe" itself. | 409 // "chrome.exe" itself. |
| 410 if (base::PathExists(target_path().Append(kChromeNewExe))) | 410 if (base::PathExists(target_path().Append(kChromeNewExe))) |
| 411 version = product_state->old_version(); | 411 version = product_state->old_version(); |
| 412 | 412 |
| 413 if (version == NULL) | 413 if (version == NULL) |
| 414 version = &product_state->version(); | 414 version = &product_state->version(); |
| 415 | 415 |
| 416 current_version.reset(new base::Version(*version)); | 416 current_version.reset(new Version(*version)); |
| 417 } | 417 } |
| 418 | 418 |
| 419 return current_version.release(); | 419 return current_version.release(); |
| 420 } | 420 } |
| 421 | 421 |
| 422 base::Version InstallerState::DetermineCriticalVersion( | 422 Version InstallerState::DetermineCriticalVersion( |
| 423 const base::Version* current_version, | 423 const Version* current_version, |
| 424 const base::Version& new_version) const { | 424 const Version& new_version) const { |
| 425 DCHECK(current_version == NULL || current_version->IsValid()); | 425 DCHECK(current_version == NULL || current_version->IsValid()); |
| 426 DCHECK(new_version.IsValid()); | 426 DCHECK(new_version.IsValid()); |
| 427 if (critical_update_version_.IsValid() && | 427 if (critical_update_version_.IsValid() && |
| 428 (current_version == NULL || | 428 (current_version == NULL || |
| 429 (current_version->CompareTo(critical_update_version_) < 0)) && | 429 (current_version->CompareTo(critical_update_version_) < 0)) && |
| 430 new_version.CompareTo(critical_update_version_) >= 0) { | 430 new_version.CompareTo(critical_update_version_) >= 0) { |
| 431 return critical_update_version_; | 431 return critical_update_version_; |
| 432 } | 432 } |
| 433 return base::Version(); | 433 return Version(); |
| 434 } | 434 } |
| 435 | 435 |
| 436 bool InstallerState::IsChromeFrameRunning( | 436 bool InstallerState::IsChromeFrameRunning( |
| 437 const InstallationState& machine_state) const { | 437 const InstallationState& machine_state) const { |
| 438 return AnyExistsAndIsInUse(machine_state, CHROME_FRAME_DLL); | 438 return AnyExistsAndIsInUse(machine_state, CHROME_FRAME_DLL); |
| 439 } | 439 } |
| 440 | 440 |
| 441 bool InstallerState::AreBinariesInUse( | 441 bool InstallerState::AreBinariesInUse( |
| 442 const InstallationState& machine_state) const { | 442 const InstallationState& machine_state) const { |
| 443 return AnyExistsAndIsInUse( | 443 return AnyExistsAndIsInUse( |
| 444 machine_state, | 444 machine_state, |
| 445 (CHROME_FRAME_HELPER_EXE | CHROME_FRAME_HELPER_DLL | | 445 (CHROME_FRAME_HELPER_EXE | CHROME_FRAME_HELPER_DLL | |
| 446 CHROME_FRAME_DLL | CHROME_DLL)); | 446 CHROME_FRAME_DLL | CHROME_DLL)); |
| 447 } | 447 } |
| 448 | 448 |
| 449 base::FilePath InstallerState::GetInstallerDirectory( | 449 base::FilePath InstallerState::GetInstallerDirectory( |
| 450 const base::Version& version) const { | 450 const Version& version) const { |
| 451 return target_path().AppendASCII(version.GetString()).Append(kInstallerDir); | 451 return target_path().AppendASCII(version.GetString()).Append(kInstallerDir); |
| 452 } | 452 } |
| 453 | 453 |
| 454 // static | 454 // static |
| 455 bool InstallerState::IsFileInUse(const base::FilePath& file) { | 455 bool InstallerState::IsFileInUse(const base::FilePath& file) { |
| 456 // Call CreateFile with a share mode of 0 which should cause this to fail | 456 // Call CreateFile with a share mode of 0 which should cause this to fail |
| 457 // with ERROR_SHARING_VIOLATION if the file exists and is in-use. | 457 // with ERROR_SHARING_VIOLATION if the file exists and is in-use. |
| 458 return !base::win::ScopedHandle(CreateFile(file.value().c_str(), | 458 return !base::win::ScopedHandle(CreateFile(file.value().c_str(), |
| 459 GENERIC_WRITE, 0, NULL, | 459 GENERIC_WRITE, 0, NULL, |
| 460 OPEN_EXISTING, 0, 0)).IsValid(); | 460 OPEN_EXISTING, 0, 0)).IsValid(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 487 DCHECK_NE(file_bits, 0U); | 487 DCHECK_NE(file_bits, 0U); |
| 488 DCHECK_LT(file_bits, 1U << NUM_BINARIES); | 488 DCHECK_LT(file_bits, 1U << NUM_BINARIES); |
| 489 COMPILE_ASSERT(CHROME_DLL == 1, no_youre_out_of_order); | 489 COMPILE_ASSERT(CHROME_DLL == 1, no_youre_out_of_order); |
| 490 COMPILE_ASSERT(CHROME_FRAME_DLL == 2, no_youre_out_of_order); | 490 COMPILE_ASSERT(CHROME_FRAME_DLL == 2, no_youre_out_of_order); |
| 491 COMPILE_ASSERT(CHROME_FRAME_HELPER_DLL == 4, no_youre_out_of_order); | 491 COMPILE_ASSERT(CHROME_FRAME_HELPER_DLL == 4, no_youre_out_of_order); |
| 492 COMPILE_ASSERT(CHROME_FRAME_HELPER_EXE == 8, no_youre_out_of_order); | 492 COMPILE_ASSERT(CHROME_FRAME_HELPER_EXE == 8, no_youre_out_of_order); |
| 493 | 493 |
| 494 // Check only for the current version (i.e., the version we are upgrading | 494 // Check only for the current version (i.e., the version we are upgrading |
| 495 // _from_). Later versions from pending in-use updates need not be checked | 495 // _from_). Later versions from pending in-use updates need not be checked |
| 496 // since the current version is guaranteed to be in use if any such are. | 496 // since the current version is guaranteed to be in use if any such are. |
| 497 scoped_ptr<base::Version> current_version(GetCurrentVersion(machine_state)); | 497 scoped_ptr<Version> current_version(GetCurrentVersion(machine_state)); |
| 498 if (!current_version) | 498 if (!current_version) |
| 499 return false; | 499 return false; |
| 500 base::FilePath directory( | 500 base::FilePath directory( |
| 501 target_path().AppendASCII(current_version->GetString())); | 501 target_path().AppendASCII(current_version->GetString())); |
| 502 for (int i = 0; i < NUM_BINARIES; ++i) { | 502 for (int i = 0; i < NUM_BINARIES; ++i) { |
| 503 if (!(file_bits & (1U << i))) | 503 if (!(file_bits & (1U << i))) |
| 504 continue; | 504 continue; |
| 505 base::FilePath file(directory.Append(kBinaryFileNames[i])); | 505 base::FilePath file(directory.Append(kBinaryFileNames[i])); |
| 506 if (base::PathExists(file) && IsFileInUse(file)) | 506 if (base::PathExists(file) && IsFileInUse(file)) |
| 507 return true; | 507 return true; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 524 FileVersionInfo::CreateFileVersionInfo(chrome_exe)); | 524 FileVersionInfo::CreateFileVersionInfo(chrome_exe)); |
| 525 if (file_version_info) { | 525 if (file_version_info) { |
| 526 base::string16 version_string = file_version_info->file_version(); | 526 base::string16 version_string = file_version_info->file_version(); |
| 527 if (!version_string.empty() && base::IsStringASCII(version_string)) | 527 if (!version_string.empty() && base::IsStringASCII(version_string)) |
| 528 existing_versions->insert(base::UTF16ToASCII(version_string)); | 528 existing_versions->insert(base::UTF16ToASCII(version_string)); |
| 529 } | 529 } |
| 530 } | 530 } |
| 531 } | 531 } |
| 532 | 532 |
| 533 void InstallerState::RemoveOldVersionDirectories( | 533 void InstallerState::RemoveOldVersionDirectories( |
| 534 const base::Version& new_version, | 534 const Version& new_version, |
| 535 base::Version* existing_version, | 535 Version* existing_version, |
| 536 const base::FilePath& temp_path) const { | 536 const base::FilePath& temp_path) const { |
| 537 base::Version version; | 537 Version version; |
| 538 scoped_ptr<WorkItem> item; | 538 scoped_ptr<WorkItem> item; |
| 539 | 539 |
| 540 std::set<std::string> existing_version_strings; | 540 std::set<std::string> existing_version_strings; |
| 541 existing_version_strings.insert(new_version.GetString()); | 541 existing_version_strings.insert(new_version.GetString()); |
| 542 if (existing_version) | 542 if (existing_version) |
| 543 existing_version_strings.insert(existing_version->GetString()); | 543 existing_version_strings.insert(existing_version->GetString()); |
| 544 | 544 |
| 545 // Make sure not to delete any version dir that is "referenced" by an existing | 545 // Make sure not to delete any version dir that is "referenced" by an existing |
| 546 // Chrome executable. | 546 // Chrome executable. |
| 547 GetExistingExeVersions(&existing_version_strings); | 547 GetExistingExeVersions(&existing_version_strings); |
| 548 | 548 |
| 549 // Try to delete all directories that are not in the set we care to keep. | 549 // Try to delete all directories that are not in the set we care to keep. |
| 550 base::FileEnumerator version_enum(target_path(), false, | 550 base::FileEnumerator version_enum(target_path(), false, |
| 551 base::FileEnumerator::DIRECTORIES); | 551 base::FileEnumerator::DIRECTORIES); |
| 552 for (base::FilePath next_version = version_enum.Next(); !next_version.empty(); | 552 for (base::FilePath next_version = version_enum.Next(); !next_version.empty(); |
| 553 next_version = version_enum.Next()) { | 553 next_version = version_enum.Next()) { |
| 554 base::FilePath dir_name(next_version.BaseName()); | 554 base::FilePath dir_name(next_version.BaseName()); |
| 555 version = base::Version(base::UTF16ToASCII(dir_name.value())); | 555 version = Version(base::UTF16ToASCII(dir_name.value())); |
| 556 // Delete the version folder if it is less than the new version and not | 556 // Delete the version folder if it is less than the new version and not |
| 557 // equal to the old version (if we have an old version). | 557 // equal to the old version (if we have an old version). |
| 558 if (version.IsValid() && | 558 if (version.IsValid() && |
| 559 existing_version_strings.count(version.GetString()) == 0) { | 559 existing_version_strings.count(version.GetString()) == 0) { |
| 560 // Note: temporarily log old version deletion at ERROR level to make it | 560 // Note: temporarily log old version deletion at ERROR level to make it |
| 561 // more likely we see this in the installer log. | 561 // more likely we see this in the installer log. |
| 562 LOG(ERROR) << "Deleting old version directory: " << next_version.value(); | 562 LOG(ERROR) << "Deleting old version directory: " << next_version.value(); |
| 563 | 563 |
| 564 // Attempt to recursively delete the old version dir. | 564 // Attempt to recursively delete the old version dir. |
| 565 bool delete_succeeded = base::DeleteFile(next_version, true); | 565 bool delete_succeeded = base::DeleteFile(next_version, true); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 } | 686 } |
| 687 if (!install_list->Do()) | 687 if (!install_list->Do()) |
| 688 LOG(ERROR) << "Failed to record installer error information in registry."; | 688 LOG(ERROR) << "Failed to record installer error information in registry."; |
| 689 } | 689 } |
| 690 | 690 |
| 691 bool InstallerState::RequiresActiveSetup() const { | 691 bool InstallerState::RequiresActiveSetup() const { |
| 692 return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); | 692 return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); |
| 693 } | 693 } |
| 694 | 694 |
| 695 } // namespace installer | 695 } // namespace installer |
| OLD | NEW |