| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <functional> | 10 #include <functional> |
| 11 #include <memory> |
| 11 #include <utility> | 12 #include <utility> |
| 12 | 13 |
| 13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 14 #include "base/file_version_info.h" | 15 #include "base/file_version_info.h" |
| 15 #include "base/files/file_enumerator.h" | 16 #include "base/files/file_enumerator.h" |
| 16 #include "base/files/file_util.h" | 17 #include "base/files/file_util.h" |
| 17 #include "base/logging.h" | 18 #include "base/logging.h" |
| 18 #include "base/macros.h" | 19 #include "base/macros.h" |
| 19 #include "base/memory/scoped_ptr.h" | |
| 20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 21 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 22 #include "base/win/registry.h" | 22 #include "base/win/registry.h" |
| 23 #include "base/win/scoped_handle.h" | 23 #include "base/win/scoped_handle.h" |
| 24 #include "chrome/installer/util/delete_tree_work_item.h" | 24 #include "chrome/installer/util/delete_tree_work_item.h" |
| 25 #include "chrome/installer/util/helper.h" | 25 #include "chrome/installer/util/helper.h" |
| 26 #include "chrome/installer/util/install_util.h" | 26 #include "chrome/installer/util/install_util.h" |
| 27 #include "chrome/installer/util/installation_state.h" | 27 #include "chrome/installer/util/installation_state.h" |
| 28 #include "chrome/installer/util/master_preferences.h" | 28 #include "chrome/installer/util/master_preferences.h" |
| 29 #include "chrome/installer/util/master_preferences_constants.h" | 29 #include "chrome/installer/util/master_preferences_constants.h" |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 } | 258 } |
| 259 return true; | 259 return true; |
| 260 } | 260 } |
| 261 | 261 |
| 262 // Adds |product|, installed in |product_dir| to this object's collection. If | 262 // Adds |product|, installed in |product_dir| to this object's collection. If |
| 263 // |product_dir| is NULL, the product's default install location is used. | 263 // |product_dir| is NULL, the product's default install location is used. |
| 264 // Returns NULL if |product| is incompatible with this object. Otherwise, | 264 // Returns NULL if |product| is incompatible with this object. Otherwise, |
| 265 // returns a pointer to the product (ownership is held by this object). | 265 // returns a pointer to the product (ownership is held by this object). |
| 266 Product* InstallerState::AddProductInDirectory( | 266 Product* InstallerState::AddProductInDirectory( |
| 267 const base::FilePath* product_dir, | 267 const base::FilePath* product_dir, |
| 268 scoped_ptr<Product>* product) { | 268 std::unique_ptr<Product>* product) { |
| 269 DCHECK(product != NULL); | 269 DCHECK(product != NULL); |
| 270 DCHECK(product->get() != NULL); | 270 DCHECK(product->get() != NULL); |
| 271 const Product& the_product = *product->get(); | 271 const Product& the_product = *product->get(); |
| 272 | 272 |
| 273 if (!CanAddProduct(the_product, product_dir)) | 273 if (!CanAddProduct(the_product, product_dir)) |
| 274 return NULL; | 274 return NULL; |
| 275 | 275 |
| 276 if (package_type_ == UNKNOWN_PACKAGE_TYPE) { | 276 if (package_type_ == UNKNOWN_PACKAGE_TYPE) { |
| 277 set_package_type(the_product.HasOption(kOptionMultiInstall) ? | 277 set_package_type(the_product.HasOption(kOptionMultiInstall) ? |
| 278 MULTI_PACKAGE : SINGLE_PACKAGE); | 278 MULTI_PACKAGE : SINGLE_PACKAGE); |
| 279 } | 279 } |
| 280 | 280 |
| 281 if (target_path_.empty()) { | 281 if (target_path_.empty()) { |
| 282 if (product_dir == NULL) | 282 if (product_dir == NULL) |
| 283 target_path_ = GetDefaultProductInstallPath(the_product.distribution()); | 283 target_path_ = GetDefaultProductInstallPath(the_product.distribution()); |
| 284 else | 284 else |
| 285 target_path_ = *product_dir; | 285 target_path_ = *product_dir; |
| 286 } | 286 } |
| 287 | 287 |
| 288 if (state_key_.empty()) | 288 if (state_key_.empty()) |
| 289 state_key_ = the_product.distribution()->GetStateKey(); | 289 state_key_ = the_product.distribution()->GetStateKey(); |
| 290 | 290 |
| 291 products_.push_back(product->release()); | 291 products_.push_back(product->release()); |
| 292 return products_[products_.size() - 1]; | 292 return products_[products_.size() - 1]; |
| 293 } | 293 } |
| 294 | 294 |
| 295 Product* InstallerState::AddProduct(scoped_ptr<Product>* product) { | 295 Product* InstallerState::AddProduct(std::unique_ptr<Product>* product) { |
| 296 return AddProductInDirectory(NULL, product); | 296 return AddProductInDirectory(NULL, product); |
| 297 } | 297 } |
| 298 | 298 |
| 299 // Adds a product of type |distribution_type| constructed on the basis of | 299 // Adds a product of type |distribution_type| constructed on the basis of |
| 300 // |prefs|, setting this object's msi flag if the product is represented in | 300 // |prefs|, setting this object's msi flag if the product is represented in |
| 301 // |machine_state| and is msi-installed. Returns the product that was added, | 301 // |machine_state| and is msi-installed. Returns the product that was added, |
| 302 // or NULL if |state| is incompatible with this object. Ownership is not passed | 302 // or NULL if |state| is incompatible with this object. Ownership is not passed |
| 303 // to the caller. | 303 // to the caller. |
| 304 Product* InstallerState::AddProductFromPreferences( | 304 Product* InstallerState::AddProductFromPreferences( |
| 305 BrowserDistribution::Type distribution_type, | 305 BrowserDistribution::Type distribution_type, |
| 306 const MasterPreferences& prefs, | 306 const MasterPreferences& prefs, |
| 307 const InstallationState& machine_state) { | 307 const InstallationState& machine_state) { |
| 308 scoped_ptr<Product> product_ptr( | 308 std::unique_ptr<Product> product_ptr(new Product( |
| 309 new Product(BrowserDistribution::GetSpecificDistribution( | 309 BrowserDistribution::GetSpecificDistribution(distribution_type))); |
| 310 distribution_type))); | |
| 311 product_ptr->InitializeFromPreferences(prefs); | 310 product_ptr->InitializeFromPreferences(prefs); |
| 312 | 311 |
| 313 Product* product = AddProductInDirectory(NULL, &product_ptr); | 312 Product* product = AddProductInDirectory(NULL, &product_ptr); |
| 314 | 313 |
| 315 if (product != NULL && !msi_) { | 314 if (product != NULL && !msi_) { |
| 316 const ProductState* product_state = machine_state.GetProductState( | 315 const ProductState* product_state = machine_state.GetProductState( |
| 317 system_install(), distribution_type); | 316 system_install(), distribution_type); |
| 318 if (product_state != NULL) | 317 if (product_state != NULL) |
| 319 msi_ = product_state->is_msi(); | 318 msi_ = product_state->is_msi(); |
| 320 } | 319 } |
| 321 | 320 |
| 322 return product; | 321 return product; |
| 323 } | 322 } |
| 324 | 323 |
| 325 Product* InstallerState::AddProductFromState( | 324 Product* InstallerState::AddProductFromState( |
| 326 BrowserDistribution::Type type, | 325 BrowserDistribution::Type type, |
| 327 const ProductState& state) { | 326 const ProductState& state) { |
| 328 scoped_ptr<Product> product_ptr( | 327 std::unique_ptr<Product> product_ptr( |
| 329 new Product(BrowserDistribution::GetSpecificDistribution(type))); | 328 new Product(BrowserDistribution::GetSpecificDistribution(type))); |
| 330 product_ptr->InitializeFromUninstallCommand(state.uninstall_command()); | 329 product_ptr->InitializeFromUninstallCommand(state.uninstall_command()); |
| 331 | 330 |
| 332 // Strip off <version>/Installer/setup.exe; see GetInstallerDirectory(). | 331 // Strip off <version>/Installer/setup.exe; see GetInstallerDirectory(). |
| 333 base::FilePath product_dir = | 332 base::FilePath product_dir = |
| 334 state.GetSetupPath().DirName().DirName().DirName(); | 333 state.GetSetupPath().DirName().DirName().DirName(); |
| 335 | 334 |
| 336 Product* product = AddProductInDirectory(&product_dir, &product_ptr); | 335 Product* product = AddProductInDirectory(&product_dir, &product_ptr); |
| 337 | 336 |
| 338 if (product != NULL) | 337 if (product != NULL) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 367 scan != end; ++scan) { | 366 scan != end; ++scan) { |
| 368 if ((*scan)->is_type(distribution_type)) | 367 if ((*scan)->is_type(distribution_type)) |
| 369 return *scan; | 368 return *scan; |
| 370 } | 369 } |
| 371 return NULL; | 370 return NULL; |
| 372 } | 371 } |
| 373 | 372 |
| 374 Version* InstallerState::GetCurrentVersion( | 373 Version* InstallerState::GetCurrentVersion( |
| 375 const InstallationState& machine_state) const { | 374 const InstallationState& machine_state) const { |
| 376 DCHECK(!products_.empty()); | 375 DCHECK(!products_.empty()); |
| 377 scoped_ptr<Version> current_version; | 376 std::unique_ptr<Version> current_version; |
| 378 // If we're doing a multi-install, the current version may be either an | 377 // If we're doing a multi-install, the current version may be either an |
| 379 // existing multi or an existing single product that is being migrated | 378 // existing multi or an existing single product that is being migrated |
| 380 // in place (i.e., Chrome). In the latter case, there is no existing | 379 // in place (i.e., Chrome). In the latter case, there is no existing |
| 381 // CHROME_BINARIES installation so we need to search for the product. | 380 // CHROME_BINARIES installation so we need to search for the product. |
| 382 BrowserDistribution::Type prod_type; | 381 BrowserDistribution::Type prod_type; |
| 383 if (package_type_ == MULTI_PACKAGE) { | 382 if (package_type_ == MULTI_PACKAGE) { |
| 384 prod_type = BrowserDistribution::CHROME_BINARIES; | 383 prod_type = BrowserDistribution::CHROME_BINARIES; |
| 385 if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, | 384 if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, |
| 386 prod_type) == NULL) { | 385 prod_type) == NULL) { |
| 387 // Search for a product on which we're operating that is installed in our | 386 // Search for a product on which we're operating that is installed in our |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 static_assert(CHROME_FRAME_DLL == 2, | 492 static_assert(CHROME_FRAME_DLL == 2, |
| 494 "binary file names and values must match"); | 493 "binary file names and values must match"); |
| 495 static_assert(CHROME_FRAME_HELPER_DLL == 4, | 494 static_assert(CHROME_FRAME_HELPER_DLL == 4, |
| 496 "binary file names and values must match"); | 495 "binary file names and values must match"); |
| 497 static_assert(CHROME_FRAME_HELPER_EXE == 8, | 496 static_assert(CHROME_FRAME_HELPER_EXE == 8, |
| 498 "binary file names and values must match"); | 497 "binary file names and values must match"); |
| 499 | 498 |
| 500 // Check only for the current version (i.e., the version we are upgrading | 499 // Check only for the current version (i.e., the version we are upgrading |
| 501 // _from_). Later versions from pending in-use updates need not be checked | 500 // _from_). Later versions from pending in-use updates need not be checked |
| 502 // since the current version is guaranteed to be in use if any such are. | 501 // since the current version is guaranteed to be in use if any such are. |
| 503 scoped_ptr<Version> current_version(GetCurrentVersion(machine_state)); | 502 std::unique_ptr<Version> current_version(GetCurrentVersion(machine_state)); |
| 504 if (!current_version) | 503 if (!current_version) |
| 505 return false; | 504 return false; |
| 506 base::FilePath directory( | 505 base::FilePath directory( |
| 507 target_path().AppendASCII(current_version->GetString())); | 506 target_path().AppendASCII(current_version->GetString())); |
| 508 for (int i = 0; i < NUM_BINARIES; ++i) { | 507 for (int i = 0; i < NUM_BINARIES; ++i) { |
| 509 if (!(file_bits & (1U << i))) | 508 if (!(file_bits & (1U << i))) |
| 510 continue; | 509 continue; |
| 511 base::FilePath file(directory.Append(kBinaryFileNames[i])); | 510 base::FilePath file(directory.Append(kBinaryFileNames[i])); |
| 512 if (base::PathExists(file) && IsFileInUse(file)) | 511 if (base::PathExists(file) && IsFileInUse(file)) |
| 513 return true; | 512 return true; |
| 514 } | 513 } |
| 515 return false; | 514 return false; |
| 516 } | 515 } |
| 517 | 516 |
| 518 void InstallerState::GetExistingExeVersions( | 517 void InstallerState::GetExistingExeVersions( |
| 519 std::set<std::string>* existing_versions) const { | 518 std::set<std::string>* existing_versions) const { |
| 520 | 519 |
| 521 static const wchar_t* const kChromeFilenames[] = { | 520 static const wchar_t* const kChromeFilenames[] = { |
| 522 installer::kChromeExe, | 521 installer::kChromeExe, |
| 523 installer::kChromeNewExe, | 522 installer::kChromeNewExe, |
| 524 installer::kChromeOldExe, | 523 installer::kChromeOldExe, |
| 525 }; | 524 }; |
| 526 | 525 |
| 527 for (size_t i = 0; i < arraysize(kChromeFilenames); ++i) { | 526 for (size_t i = 0; i < arraysize(kChromeFilenames); ++i) { |
| 528 base::FilePath chrome_exe(target_path().Append(kChromeFilenames[i])); | 527 base::FilePath chrome_exe(target_path().Append(kChromeFilenames[i])); |
| 529 scoped_ptr<FileVersionInfo> file_version_info( | 528 std::unique_ptr<FileVersionInfo> file_version_info( |
| 530 FileVersionInfo::CreateFileVersionInfo(chrome_exe)); | 529 FileVersionInfo::CreateFileVersionInfo(chrome_exe)); |
| 531 if (file_version_info) { | 530 if (file_version_info) { |
| 532 base::string16 version_string = file_version_info->file_version(); | 531 base::string16 version_string = file_version_info->file_version(); |
| 533 if (!version_string.empty() && base::IsStringASCII(version_string)) | 532 if (!version_string.empty() && base::IsStringASCII(version_string)) |
| 534 existing_versions->insert(base::UTF16ToASCII(version_string)); | 533 existing_versions->insert(base::UTF16ToASCII(version_string)); |
| 535 } | 534 } |
| 536 } | 535 } |
| 537 } | 536 } |
| 538 | 537 |
| 539 void InstallerState::RemoveOldVersionDirectories( | 538 void InstallerState::RemoveOldVersionDirectories( |
| 540 const Version& new_version, | 539 const Version& new_version, |
| 541 Version* existing_version, | 540 Version* existing_version, |
| 542 const base::FilePath& temp_path) const { | 541 const base::FilePath& temp_path) const { |
| 543 Version version; | 542 Version version; |
| 544 scoped_ptr<WorkItem> item; | 543 std::unique_ptr<WorkItem> item; |
| 545 | 544 |
| 546 std::set<std::string> existing_version_strings; | 545 std::set<std::string> existing_version_strings; |
| 547 existing_version_strings.insert(new_version.GetString()); | 546 existing_version_strings.insert(new_version.GetString()); |
| 548 if (existing_version) | 547 if (existing_version) |
| 549 existing_version_strings.insert(existing_version->GetString()); | 548 existing_version_strings.insert(existing_version->GetString()); |
| 550 | 549 |
| 551 // Make sure not to delete any version dir that is "referenced" by an existing | 550 // Make sure not to delete any version dir that is "referenced" by an existing |
| 552 // Chrome executable. | 551 // Chrome executable. |
| 553 GetExistingExeVersions(&existing_version_strings); | 552 GetExistingExeVersions(&existing_version_strings); |
| 554 | 553 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 LOG(ERROR) << "Failed opening key " << state_key_ | 664 LOG(ERROR) << "Failed opening key " << state_key_ |
| 666 << " to update app channels; result: " << result; | 665 << " to update app channels; result: " << result; |
| 667 } | 666 } |
| 668 } | 667 } |
| 669 | 668 |
| 670 void InstallerState::WriteInstallerResult( | 669 void InstallerState::WriteInstallerResult( |
| 671 InstallStatus status, | 670 InstallStatus status, |
| 672 int string_resource_id, | 671 int string_resource_id, |
| 673 const std::wstring* const launch_cmd) const { | 672 const std::wstring* const launch_cmd) const { |
| 674 // Use a no-rollback list since this is a best-effort deal. | 673 // Use a no-rollback list since this is a best-effort deal. |
| 675 scoped_ptr<WorkItemList> install_list( | 674 std::unique_ptr<WorkItemList> install_list( |
| 676 WorkItem::CreateNoRollbackWorkItemList()); | 675 WorkItem::CreateNoRollbackWorkItemList()); |
| 677 const bool system_install = this->system_install(); | 676 const bool system_install = this->system_install(); |
| 678 // Write the value for all products upon which we're operating. | 677 // Write the value for all products upon which we're operating. |
| 679 Products::const_iterator end = products().end(); | 678 Products::const_iterator end = products().end(); |
| 680 for (Products::const_iterator scan = products().begin(); scan != end; | 679 for (Products::const_iterator scan = products().begin(); scan != end; |
| 681 ++scan) { | 680 ++scan) { |
| 682 InstallUtil::AddInstallerResultItems( | 681 InstallUtil::AddInstallerResultItems( |
| 683 system_install, (*scan)->distribution()->GetStateKey(), status, | 682 system_install, (*scan)->distribution()->GetStateKey(), status, |
| 684 string_resource_id, launch_cmd, install_list.get()); | 683 string_resource_id, launch_cmd, install_list.get()); |
| 685 } | 684 } |
| 686 // And for the binaries if this is a multi-install. | 685 // And for the binaries if this is a multi-install. |
| 687 if (is_multi_install()) { | 686 if (is_multi_install()) { |
| 688 InstallUtil::AddInstallerResultItems( | 687 InstallUtil::AddInstallerResultItems( |
| 689 system_install, multi_package_binaries_distribution()->GetStateKey(), | 688 system_install, multi_package_binaries_distribution()->GetStateKey(), |
| 690 status, string_resource_id, launch_cmd, install_list.get()); | 689 status, string_resource_id, launch_cmd, install_list.get()); |
| 691 } | 690 } |
| 692 if (!install_list->Do()) | 691 if (!install_list->Do()) |
| 693 LOG(ERROR) << "Failed to record installer error information in registry."; | 692 LOG(ERROR) << "Failed to record installer error information in registry."; |
| 694 } | 693 } |
| 695 | 694 |
| 696 bool InstallerState::RequiresActiveSetup() const { | 695 bool InstallerState::RequiresActiveSetup() const { |
| 697 return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); | 696 return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); |
| 698 } | 697 } |
| 699 | 698 |
| 700 } // namespace installer | 699 } // namespace installer |
| OLD | NEW |