| 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 // This file contains the definitions of the installer functions that build | 5 // This file contains the definitions of the installer functions that build |
| 6 // the WorkItemList used to install the application. | 6 // the WorkItemList used to install the application. |
| 7 | 7 |
| 8 #include "chrome/installer/setup/install_worker.h" | 8 #include "chrome/installer/setup/install_worker.h" |
| 9 | 9 |
| 10 #include <oaidl.h> | 10 #include <oaidl.h> |
| 11 #include <shlobj.h> | 11 #include <shlobj.h> |
| 12 #include <time.h> | 12 #include <time.h> |
| 13 | 13 |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 17 #include "base/file_path.h" | 17 #include "base/file_path.h" |
| 18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
| 19 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
| 21 #include "base/string_util.h" | 21 #include "base/string_util.h" |
| 22 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
| 23 #include "base/version.h" | 23 #include "base/version.h" |
| 24 #include "base/win/registry.h" | 24 #include "base/win/registry.h" |
| 25 #include "base/win/windows_version.h" | 25 #include "base/win/windows_version.h" |
| 26 #include "chrome/common/chrome_constants.h" | 26 #include "chrome/common/chrome_constants.h" |
| 27 #include "chrome/common/chrome_switches.h" |
| 27 #include "chrome/installer/setup/install.h" | 28 #include "chrome/installer/setup/install.h" |
| 28 #include "chrome/installer/setup/setup_constants.h" | 29 #include "chrome/installer/setup/setup_constants.h" |
| 29 #include "chrome/installer/util/conditional_work_item_list.h" | 30 #include "chrome/installer/util/conditional_work_item_list.h" |
| 30 #include "chrome/installer/util/create_reg_key_work_item.h" | 31 #include "chrome/installer/util/create_reg_key_work_item.h" |
| 31 #include "chrome/installer/util/google_update_constants.h" | 32 #include "chrome/installer/util/google_update_constants.h" |
| 32 #include "chrome/installer/util/helper.h" | 33 #include "chrome/installer/util/helper.h" |
| 33 #include "chrome/installer/util/installation_state.h" | 34 #include "chrome/installer/util/installation_state.h" |
| 34 #include "chrome/installer/util/installer_state.h" | 35 #include "chrome/installer/util/installer_state.h" |
| 35 #include "chrome/installer/util/install_util.h" | 36 #include "chrome/installer/util/install_util.h" |
| 36 #include "chrome/installer/util/l10n_string_util.h" | 37 #include "chrome/installer/util/l10n_string_util.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 // locate the setup.exe instance used for binary patching. | 134 // locate the setup.exe instance used for binary patching. |
| 134 // Do not quote the command line for the MSI invocation. | 135 // Do not quote the command line for the MSI invocation. |
| 135 FilePath install_path(installer_state.target_path()); | 136 FilePath install_path(installer_state.target_path()); |
| 136 FilePath installer_path(installer_state.GetInstallerDirectory(new_version)); | 137 FilePath installer_path(installer_state.GetInstallerDirectory(new_version)); |
| 137 installer_path = installer_path.Append(setup_path.BaseName()); | 138 installer_path = installer_path.Append(setup_path.BaseName()); |
| 138 | 139 |
| 139 CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); | 140 CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); |
| 140 AppendUninstallCommandLineFlags(installer_state, product, | 141 AppendUninstallCommandLineFlags(installer_state, product, |
| 141 &uninstall_arguments); | 142 &uninstall_arguments); |
| 142 | 143 |
| 143 // The Chrome uninstallation command serves as the master uninstall command | 144 // If Chrome Frame is installed in Ready Mode, add --chrome-frame to Chrome's |
| 144 // for Chrome + all other products (i.e. Chrome Frame) that do not have an | 145 // uninstall entry. We skip this processing in case of uninstall since this |
| 145 // uninstall entry in the Add/Remove Programs dialog. We skip this processing | 146 // means that Chrome Frame is being uninstalled, so there's no need to do any |
| 146 // in case of uninstall since this means that Chrome Frame is being | 147 // looping. |
| 147 // uninstalled, so there's no need to do any looping. | |
| 148 if (product.is_chrome() && | 148 if (product.is_chrome() && |
| 149 installer_state.operation() != InstallerState::UNINSTALL) { | 149 installer_state.operation() != InstallerState::UNINSTALL) { |
| 150 const Products& products = installer_state.products(); | 150 const Product* chrome_frame = |
| 151 for (size_t i = 0; i < products.size(); ++i) { | 151 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); |
| 152 const Product& p = *products[i]; | 152 if (chrome_frame && chrome_frame->HasOption(kOptionReadyMode)) |
| 153 if (!p.is_chrome() && !p.ShouldCreateUninstallEntry()) | 153 chrome_frame->AppendProductFlags(&uninstall_arguments); |
| 154 p.AppendProductFlags(&uninstall_arguments); | |
| 155 } | |
| 156 } | 154 } |
| 157 | 155 |
| 158 std::wstring update_state_key(browser_dist->GetStateKey()); | 156 std::wstring update_state_key(browser_dist->GetStateKey()); |
| 159 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); | 157 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); |
| 160 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, | 158 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, |
| 161 installer::kUninstallStringField, installer_path.value(), true); | 159 installer::kUninstallStringField, installer_path.value(), true); |
| 162 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, | 160 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, |
| 163 installer::kUninstallArgumentsField, | 161 installer::kUninstallArgumentsField, |
| 164 uninstall_arguments.GetCommandLineString(), true); | 162 uninstall_arguments.GetCommandLineString(), true); |
| 165 | 163 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 if (version_components.size() == 4) { | 216 if (version_components.size() == 4) { |
| 219 // Our version should be in major.minor.build.rev. | 217 // Our version should be in major.minor.build.rev. |
| 220 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, | 218 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, |
| 221 L"VersionMajor", static_cast<DWORD>(version_components[2]), true); | 219 L"VersionMajor", static_cast<DWORD>(version_components[2]), true); |
| 222 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, | 220 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, |
| 223 L"VersionMinor", static_cast<DWORD>(version_components[3]), true); | 221 L"VersionMinor", static_cast<DWORD>(version_components[3]), true); |
| 224 } | 222 } |
| 225 } | 223 } |
| 226 } | 224 } |
| 227 | 225 |
| 228 // Add uninstall-related work items for multi-install scenarios. | |
| 229 void AddMultiUninstallWorkItems(const InstallerState& installer_state, | |
| 230 const FilePath& setup_path, | |
| 231 const Version& new_version, | |
| 232 WorkItemList* install_list) { | |
| 233 DCHECK(installer_state.is_multi_install()); | |
| 234 | |
| 235 // The mini_installer needs a reliable way to locate setup.exe for diff | |
| 236 // updates. For single-installs, the product's ClientState key is consulted | |
| 237 // (Chrome's or Chrome Frame's). For multi-installs, the binaries' key is | |
| 238 // used. | |
| 239 const HKEY reg_root = installer_state.root_key(); | |
| 240 std::wstring binaries_state_key( | |
| 241 installer_state.multi_package_binaries_distribution()->GetStateKey()); | |
| 242 FilePath installer_path( | |
| 243 installer_state.GetInstallerDirectory(new_version) | |
| 244 .Append(setup_path.BaseName())); | |
| 245 install_list->AddCreateRegKeyWorkItem(reg_root, binaries_state_key); | |
| 246 install_list->AddSetRegValueWorkItem(reg_root, binaries_state_key, | |
| 247 installer::kUninstallStringField, installer_path.value(), true); | |
| 248 } | |
| 249 | |
| 250 // Create Version key for a product (if not already present) and sets the new | 226 // Create Version key for a product (if not already present) and sets the new |
| 251 // product version as the last step. | 227 // product version as the last step. |
| 252 void AddVersionKeyWorkItems(HKEY root, | 228 void AddVersionKeyWorkItems(HKEY root, |
| 253 BrowserDistribution* dist, | 229 BrowserDistribution* dist, |
| 254 const Version& new_version, | 230 const Version& new_version, |
| 255 bool add_language_identifier, | 231 bool add_language_identifier, |
| 256 WorkItemList* list) { | 232 WorkItemList* list) { |
| 257 // Create Version key for each distribution (if not already present) and set | 233 // Create Version key for each distribution (if not already present) and set |
| 258 // the new product version as the last step. | 234 // the new product version as the last step. |
| 259 std::wstring version_key(dist->GetVersionKey()); | 235 std::wstring version_key(dist->GetVersionKey()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 276 list->AddSetRegValueWorkItem(root, version_key, | 252 list->AddSetRegValueWorkItem(root, version_key, |
| 277 google_update::kRegLangField, language, | 253 google_update::kRegLangField, language, |
| 278 false); // do not overwrite language | 254 false); // do not overwrite language |
| 279 } | 255 } |
| 280 list->AddSetRegValueWorkItem(root, version_key, | 256 list->AddSetRegValueWorkItem(root, version_key, |
| 281 google_update::kRegVersionField, | 257 google_update::kRegVersionField, |
| 282 ASCIIToWide(new_version.GetString()), | 258 ASCIIToWide(new_version.GetString()), |
| 283 true); // overwrite version | 259 true); // overwrite version |
| 284 } | 260 } |
| 285 | 261 |
| 262 void AddInstallAppCommandWorkItems(const InstallerState& installer_state, |
| 263 const InstallationState& machine_state, |
| 264 const FilePath* setup_path, |
| 265 const Version* new_version, |
| 266 const Product& product, |
| 267 WorkItemList* work_item_list) { |
| 268 DCHECK(product.is_chrome_app_host()); |
| 269 |
| 270 std::wstring cmd_key(product.distribution()->GetVersionKey()); |
| 271 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey) |
| 272 .append(1, L'\\').append(kCmdInstallApp); |
| 273 |
| 274 if (installer_state.operation() != InstallerState::UNINSTALL) { |
| 275 FilePath target_path(installer_state.target_path()); |
| 276 CommandLine cmd_line(target_path.Append(installer::kChromeAppHostExe)); |
| 277 cmd_line.AppendSwitchASCII(::switches::kAppsInstallFromManifestURL, "$1"); |
| 278 |
| 279 AppCommand cmd(cmd_line.GetCommandLineString(), true, true); |
| 280 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); |
| 281 } else { |
| 282 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), |
| 283 cmd_key)->set_log_message( |
| 284 "removing install-application command"); |
| 285 } |
| 286 } |
| 287 |
| 286 void AddProductSpecificWorkItems(const InstallationState& original_state, | 288 void AddProductSpecificWorkItems(const InstallationState& original_state, |
| 287 const InstallerState& installer_state, | 289 const InstallerState& installer_state, |
| 288 const FilePath& setup_path, | 290 const FilePath& setup_path, |
| 289 const Version& new_version, | 291 const Version& new_version, |
| 290 WorkItemList* list) { | 292 WorkItemList* list) { |
| 291 const Products& products = installer_state.products(); | 293 const Products& products = installer_state.products(); |
| 292 for (size_t i = 0; i < products.size(); ++i) { | 294 for (size_t i = 0; i < products.size(); ++i) { |
| 293 const Product& p = *products[i]; | 295 const Product& p = *products[i]; |
| 294 if (p.is_chrome_frame()) { | 296 if (p.is_chrome_frame()) { |
| 295 AddChromeFrameWorkItems(original_state, installer_state, setup_path, | 297 AddChromeFrameWorkItems(original_state, installer_state, setup_path, |
| 296 new_version, p, list); | 298 new_version, p, list); |
| 297 } | 299 } |
| 300 if (p.is_chrome_app_host()) { |
| 301 AddInstallAppCommandWorkItems(installer_state, original_state, |
| 302 &setup_path, &new_version, p, list); |
| 303 } |
| 298 } | 304 } |
| 299 } | 305 } |
| 300 | 306 |
| 301 // Mirror oeminstall the first time anything is installed multi. There is no | 307 // Mirror oeminstall the first time anything is installed multi. There is no |
| 302 // need to update the value on future install/update runs since this value never | 308 // need to update the value on future install/update runs since this value never |
| 303 // changes. Note that the value is removed by Google Update after EULA | 309 // changes. Note that the value is removed by Google Update after EULA |
| 304 // acceptance is processed. | 310 // acceptance is processed. |
| 305 void AddOemInstallWorkItems(const InstallationState& original_state, | 311 void AddOemInstallWorkItems(const InstallationState& original_state, |
| 306 const InstallerState& installer_state, | 312 const InstallerState& installer_state, |
| 307 WorkItemList* install_list) { | 313 WorkItemList* install_list) { |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 // do a few post install tasks: | 562 // do a few post install tasks: |
| 557 // - Handle the case of in-use-update by updating "opv" (old version) key or | 563 // - Handle the case of in-use-update by updating "opv" (old version) key or |
| 558 // deleting it if not required. | 564 // deleting it if not required. |
| 559 // - Register any new dlls and unregister old dlls. | 565 // - Register any new dlls and unregister old dlls. |
| 560 // - If this is an MSI install, ensures that the MSI marker is set, and sets | 566 // - If this is an MSI install, ensures that the MSI marker is set, and sets |
| 561 // it if not. | 567 // it if not. |
| 562 // If these operations are successful, the function returns true, otherwise | 568 // If these operations are successful, the function returns true, otherwise |
| 563 // false. | 569 // false. |
| 564 bool AppendPostInstallTasks(const InstallerState& installer_state, | 570 bool AppendPostInstallTasks(const InstallerState& installer_state, |
| 565 const FilePath& setup_path, | 571 const FilePath& setup_path, |
| 566 const FilePath& new_chrome_exe, | |
| 567 const Version* current_version, | 572 const Version* current_version, |
| 568 const Version& new_version, | 573 const Version& new_version, |
| 569 const FilePath& temp_path, | 574 const FilePath& temp_path, |
| 570 WorkItemList* post_install_task_list) { | 575 WorkItemList* post_install_task_list) { |
| 571 DCHECK(post_install_task_list); | 576 DCHECK(post_install_task_list); |
| 572 | 577 |
| 573 HKEY root = installer_state.root_key(); | 578 HKEY root = installer_state.root_key(); |
| 574 const Products& products = installer_state.products(); | 579 const Products& products = installer_state.products(); |
| 580 FilePath new_chrome_exe( |
| 581 installer_state.target_path().Append(installer::kChromeNewExe)); |
| 575 | 582 |
| 576 // Append work items that will only be executed if this was an update. | 583 // Append work items that will only be executed if this was an update. |
| 577 // We update the 'opv' value with the current version that is active, | 584 // We update the 'opv' value with the current version that is active, |
| 578 // the 'cpv' value with the critical update version (if present), and the | 585 // the 'cpv' value with the critical update version (if present), and the |
| 579 // 'cmd' value with the rename command to run. | 586 // 'cmd' value with the rename command to run. |
| 580 { | 587 { |
| 581 scoped_ptr<WorkItemList> in_use_update_work_items( | 588 scoped_ptr<WorkItemList> in_use_update_work_items( |
| 582 WorkItem::CreateConditionalWorkItemList( | 589 WorkItem::CreateConditionalWorkItemList( |
| 583 new ConditionRunIfFileExists(new_chrome_exe))); | 590 new ConditionRunIfFileExists(new_chrome_exe))); |
| 584 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); | 591 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 if (installer_state.is_multi_install()) { | 712 if (installer_state.is_multi_install()) { |
| 706 AddSetMsiMarkerWorkItem(installer_state, | 713 AddSetMsiMarkerWorkItem(installer_state, |
| 707 installer_state.multi_package_binaries_distribution(), true, | 714 installer_state.multi_package_binaries_distribution(), true, |
| 708 post_install_task_list); | 715 post_install_task_list); |
| 709 } | 716 } |
| 710 } | 717 } |
| 711 | 718 |
| 712 return true; | 719 return true; |
| 713 } | 720 } |
| 714 | 721 |
| 715 void AddInstallWorkItems(const InstallationState& original_state, | 722 void AddChromeWorkItems(const InstallationState& original_state, |
| 716 const InstallerState& installer_state, | 723 const InstallerState& installer_state, |
| 717 const FilePath& setup_path, | 724 const FilePath& setup_path, |
| 718 const FilePath& archive_path, | 725 const FilePath& archive_path, |
| 719 const FilePath& src_path, | 726 const FilePath& src_path, |
| 720 const FilePath& temp_path, | 727 const FilePath& temp_path, |
| 721 const Version& new_version, | 728 const Version& new_version, |
| 722 scoped_ptr<Version>* current_version, | 729 scoped_ptr<Version>* current_version, |
| 723 WorkItemList* install_list) { | 730 WorkItemList* install_list) { |
| 724 DCHECK(install_list); | |
| 725 | |
| 726 const FilePath& target_path = installer_state.target_path(); | 731 const FilePath& target_path = installer_state.target_path(); |
| 727 | 732 |
| 728 // A temp directory that work items need and the actual install directory. | |
| 729 install_list->AddCreateDirWorkItem(temp_path); | |
| 730 install_list->AddCreateDirWorkItem(target_path); | |
| 731 | |
| 732 if (current_version != NULL && current_version->get() != NULL) { | 733 if (current_version != NULL && current_version->get() != NULL) { |
| 733 // Delete the archive from an existing install to save some disk space. We | 734 // Delete the archive from an existing install to save some disk space. We |
| 734 // make this an unconditional work item since there's no need to roll this | 735 // make this an unconditional work item since there's no need to roll this |
| 735 // back; if installation fails we'll be moved to the "-full" channel anyway. | 736 // back; if installation fails we'll be moved to the "-full" channel anyway. |
| 736 FilePath old_installer_dir( | 737 FilePath old_installer_dir( |
| 737 installer_state.GetInstallerDirectory(**current_version)); | 738 installer_state.GetInstallerDirectory(**current_version)); |
| 738 FilePath old_archive(old_installer_dir.Append(archive_path.BaseName())); | 739 FilePath old_archive(old_installer_dir.Append(archive_path.BaseName())); |
| 739 install_list->AddDeleteTreeWorkItem(old_archive, temp_path) | 740 install_list->AddDeleteTreeWorkItem(old_archive, temp_path) |
| 740 ->set_ignore_failure(true); | 741 ->set_ignore_failure(true); |
| 741 } | 742 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 // Delete any old_chrome.exe if present (ignore failure if it's in use). | 834 // Delete any old_chrome.exe if present (ignore failure if it's in use). |
| 834 install_list->AddDeleteTreeWorkItem( | 835 install_list->AddDeleteTreeWorkItem( |
| 835 target_path.Append(installer::kChromeOldExe), temp_path) | 836 target_path.Append(installer::kChromeOldExe), temp_path) |
| 836 ->set_ignore_failure(true); | 837 ->set_ignore_failure(true); |
| 837 | 838 |
| 838 // Copy installer in install directory and | 839 // Copy installer in install directory and |
| 839 // add shortcut in Control Panel->Add/Remove Programs. | 840 // add shortcut in Control Panel->Add/Remove Programs. |
| 840 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, | 841 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, |
| 841 new_version, install_list); | 842 new_version, install_list); |
| 842 | 843 |
| 844 } |
| 845 |
| 846 void AddInstallWorkItems(const InstallationState& original_state, |
| 847 const InstallerState& installer_state, |
| 848 const FilePath& setup_path, |
| 849 const FilePath& archive_path, |
| 850 const FilePath& src_path, |
| 851 const FilePath& temp_path, |
| 852 const Version& new_version, |
| 853 scoped_ptr<Version>* current_version, |
| 854 WorkItemList* install_list) { |
| 855 DCHECK(install_list); |
| 856 |
| 857 const FilePath& target_path = installer_state.target_path(); |
| 858 |
| 859 // A temp directory that work items need and the actual install directory. |
| 860 install_list->AddCreateDirWorkItem(temp_path); |
| 861 install_list->AddCreateDirWorkItem(target_path); |
| 862 |
| 863 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER) || |
| 864 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) || |
| 865 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES)) { |
| 866 AddChromeWorkItems(original_state, |
| 867 installer_state, |
| 868 setup_path, |
| 869 archive_path, |
| 870 src_path, |
| 871 temp_path, |
| 872 new_version, |
| 873 current_version, |
| 874 install_list); |
| 875 } |
| 876 |
| 877 if (installer_state.FindProduct(BrowserDistribution::CHROME_APP_HOST)) { |
| 878 install_list->AddCopyTreeWorkItem( |
| 879 src_path.Append(installer::kChromeAppHostExe).value(), |
| 880 target_path.Append(installer::kChromeAppHostExe).value(), |
| 881 temp_path.value(), |
| 882 WorkItem::ALWAYS, |
| 883 L""); |
| 884 } |
| 885 |
| 843 const HKEY root = installer_state.root_key(); | 886 const HKEY root = installer_state.root_key(); |
| 844 // Only set "lang" for user-level installs since for system-level, the install | 887 // Only set "lang" for user-level installs since for system-level, the install |
| 845 // language may not be related to a given user's runtime language. | 888 // language may not be related to a given user's runtime language. |
| 846 const bool add_language_identifier = !installer_state.system_install(); | 889 const bool add_language_identifier = !installer_state.system_install(); |
| 847 | 890 |
| 848 const Products& products = installer_state.products(); | 891 const Products& products = installer_state.products(); |
| 849 for (size_t i = 0; i < products.size(); ++i) { | 892 for (size_t i = 0; i < products.size(); ++i) { |
| 850 const Product* product = products[i]; | 893 const Product* product = products[i]; |
| 851 | 894 |
| 852 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, | 895 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, |
| 853 install_list, *product); | 896 install_list, *product); |
| 854 | 897 |
| 855 AddVersionKeyWorkItems(root, product->distribution(), new_version, | 898 AddVersionKeyWorkItems(root, product->distribution(), new_version, |
| 856 add_language_identifier, install_list); | 899 add_language_identifier, install_list); |
| 857 | 900 |
| 858 AddDelegateExecuteWorkItems(installer_state, src_path, new_version, | 901 AddDelegateExecuteWorkItems(installer_state, src_path, new_version, |
| 859 *product, install_list); | 902 *product, install_list); |
| 860 } | 903 } |
| 861 | 904 |
| 862 if (installer_state.is_multi_install()) { | |
| 863 AddMultiUninstallWorkItems(installer_state, setup_path, new_version, | |
| 864 install_list); | |
| 865 | |
| 866 AddVersionKeyWorkItems(root, | |
| 867 installer_state.multi_package_binaries_distribution(), new_version, | |
| 868 add_language_identifier, install_list); | |
| 869 } | |
| 870 | |
| 871 // Add any remaining work items that involve special settings for | 905 // Add any remaining work items that involve special settings for |
| 872 // each product. | 906 // each product. |
| 873 AddProductSpecificWorkItems(original_state, installer_state, setup_path, | 907 AddProductSpecificWorkItems(original_state, installer_state, setup_path, |
| 874 new_version, install_list); | 908 new_version, install_list); |
| 875 | 909 |
| 876 // Copy over brand, usagestats, and other values. | 910 // Copy over brand, usagestats, and other values. |
| 877 AddGoogleUpdateWorkItems(original_state, installer_state, install_list); | 911 AddGoogleUpdateWorkItems(original_state, installer_state, install_list); |
| 878 | 912 |
| 879 AddQuickEnableWorkItems(installer_state, original_state, &setup_path, | 913 AddQuickEnableApplicationHostWorkItems(installer_state, original_state, |
| 880 &new_version, install_list); | 914 &setup_path, &new_version, |
| 915 install_list); |
| 916 |
| 917 AddQuickEnableChromeFrameWorkItems(installer_state, original_state, |
| 918 &setup_path, &new_version, install_list); |
| 881 | 919 |
| 882 // Append the tasks that run after the installation. | 920 // Append the tasks that run after the installation. |
| 883 AppendPostInstallTasks(installer_state, | 921 AppendPostInstallTasks(installer_state, |
| 884 setup_path, | 922 setup_path, |
| 885 new_chrome_exe, | |
| 886 current_version->get(), | 923 current_version->get(), |
| 887 new_version, | 924 new_version, |
| 888 temp_path, | 925 temp_path, |
| 889 install_list); | 926 install_list); |
| 890 } | 927 } |
| 891 | 928 |
| 892 void AddRegisterComDllWorkItems(const FilePath& dll_folder, | 929 void AddRegisterComDllWorkItems(const FilePath& dll_folder, |
| 893 const std::vector<FilePath>& dll_list, | 930 const std::vector<FilePath>& dll_list, |
| 894 bool system_level, | 931 bool system_level, |
| 895 bool do_register, | 932 bool do_register, |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 } else { | 1326 } else { |
| 1290 VLOG(1) << kIERefreshPolicy << " not supported."; | 1327 VLOG(1) << kIERefreshPolicy << " not supported."; |
| 1291 } | 1328 } |
| 1292 | 1329 |
| 1293 FreeLibrary(ieframe); | 1330 FreeLibrary(ieframe); |
| 1294 } else { | 1331 } else { |
| 1295 VLOG(1) << "Cannot load " << kIEFrameDll; | 1332 VLOG(1) << "Cannot load " << kIEFrameDll; |
| 1296 } | 1333 } |
| 1297 } | 1334 } |
| 1298 | 1335 |
| 1299 void AddQuickEnableWorkItems(const InstallerState& installer_state, | 1336 void AddGenericQuickEnableWorkItems(const InstallerState& installer_state, |
| 1300 const InstallationState& machine_state, | 1337 const InstallationState& machine_state, |
| 1301 const FilePath* setup_path, | 1338 const FilePath* setup_path, |
| 1302 const Version* new_version, | 1339 const Version* new_version, |
| 1303 WorkItemList* work_item_list) { | 1340 WorkItemList* work_item_list, |
| 1341 bool have_child_product, |
| 1342 const CommandLine& child_product_switches, |
| 1343 const std::wstring& command_id) { |
| 1304 DCHECK(setup_path || | 1344 DCHECK(setup_path || |
| 1305 installer_state.operation() == InstallerState::UNINSTALL); | 1345 installer_state.operation() == InstallerState::UNINSTALL); |
| 1306 DCHECK(new_version || | 1346 DCHECK(new_version || |
| 1307 installer_state.operation() == InstallerState::UNINSTALL); | 1347 installer_state.operation() == InstallerState::UNINSTALL); |
| 1308 DCHECK(work_item_list); | 1348 DCHECK(work_item_list); |
| 1309 | 1349 |
| 1310 const bool system_install = installer_state.system_install(); | 1350 const bool system_install = installer_state.system_install(); |
| 1311 bool have_multi_chrome = false; | 1351 bool have_chrome_binaries = false; |
| 1312 bool have_chrome_frame = false; | |
| 1313 | 1352 |
| 1314 // STEP 1: Figure out the state of the machine before the operation. | 1353 // STEP 1: Figure out the state of the machine before the operation. |
| 1315 const ProductState* product_state = NULL; | 1354 const ProductState* product_state = NULL; |
| 1316 | 1355 |
| 1317 // Is multi-install Chrome already on the machine? | 1356 // Are the Chrome Binaries already on the machine? |
| 1318 product_state = | 1357 product_state = |
| 1319 machine_state.GetProductState(system_install, | 1358 machine_state.GetProductState(system_install, |
| 1320 BrowserDistribution::CHROME_BROWSER); | 1359 BrowserDistribution::CHROME_BINARIES); |
| 1321 if (product_state != NULL && product_state->is_multi_install()) | 1360 if (product_state != NULL && product_state->is_multi_install()) |
| 1322 have_multi_chrome = true; | 1361 have_chrome_binaries = true; |
| 1323 | |
| 1324 // Is Chrome Frame !ready-mode already on the machine? | |
| 1325 product_state = | |
| 1326 machine_state.GetProductState(system_install, | |
| 1327 BrowserDistribution::CHROME_FRAME); | |
| 1328 if (product_state != NULL && | |
| 1329 !product_state->uninstall_command().HasSwitch( | |
| 1330 switches::kChromeFrameReadyMode)) | |
| 1331 have_chrome_frame = true; | |
| 1332 | 1362 |
| 1333 // STEP 2: Now take into account the current operation. | 1363 // STEP 2: Now take into account the current operation. |
| 1334 const Product* product = NULL; | 1364 const Product* product = NULL; |
| 1335 | 1365 |
| 1336 if (installer_state.operation() == InstallerState::UNINSTALL) { | 1366 if (installer_state.operation() == InstallerState::UNINSTALL) { |
| 1337 // Forget about multi-install Chrome if it is being uninstalled. | 1367 // Forget about multi-install Chrome if it is being uninstalled. |
| 1338 product = | 1368 product = |
| 1339 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); | 1369 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES); |
| 1340 if (product != NULL && installer_state.is_multi_install()) | 1370 if (product != NULL && installer_state.is_multi_install()) |
| 1341 have_multi_chrome = false; | 1371 have_chrome_binaries = false; |
| 1342 | |
| 1343 // Forget about Chrome Frame if it is being uninstalled. Note that we don't | |
| 1344 // bother to check !HasOption(kOptionReadyMode) since have_chrome_frame | |
| 1345 // should have been false for that case in the first place. It's odd if it | |
| 1346 // wasn't, but the right thing to do in that case is to proceed with the | |
| 1347 // thought that CF will not be installed in any sense when we reach the | |
| 1348 // finish line. | |
| 1349 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) != NULL) | |
| 1350 have_chrome_frame = false; | |
| 1351 } else { | 1372 } else { |
| 1352 // Check if we're installing multi-install Chrome. | 1373 // Check if we're installing Chrome Binaries |
| 1353 product = | 1374 product = |
| 1354 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); | 1375 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES); |
| 1355 if (product != NULL && installer_state.is_multi_install()) | 1376 if (product != NULL && installer_state.is_multi_install()) |
| 1356 have_multi_chrome = true; | 1377 have_chrome_binaries = true; |
| 1357 | |
| 1358 // Check if we're installing Chrome Frame !ready-mode. | |
| 1359 product = installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); | |
| 1360 if (product != NULL && !product->HasOption(kOptionReadyMode)) | |
| 1361 have_chrome_frame = true; | |
| 1362 } | 1378 } |
| 1363 | 1379 |
| 1364 // STEP 3: Decide what to do based on the final state of things. | 1380 // STEP 3: Decide what to do based on the final state of things. |
| 1365 enum QuickEnableOperation { | 1381 enum QuickEnableOperation { |
| 1366 DO_NOTHING, | 1382 DO_NOTHING, |
| 1367 ADD_COMMAND, | 1383 ADD_COMMAND, |
| 1368 REMOVE_COMMAND | 1384 REMOVE_COMMAND |
| 1369 } operation = DO_NOTHING; | 1385 } operation = DO_NOTHING; |
| 1370 FilePath binaries_setup_path; | 1386 FilePath binaries_setup_path; |
| 1371 | 1387 |
| 1372 if (have_chrome_frame) { | 1388 if (have_child_product) { |
| 1373 // Chrome Frame !ready-mode is or will be installed. Unconditionally remove | 1389 // Child product is being uninstalled. Unconditionally remove the Quick |
| 1374 // the quick-enable-cf command from the binaries. We do this even if | 1390 // Enable command from the binaries. We do this even if multi-install Chrome |
| 1375 // multi-install Chrome isn't installed since we don't want them left | 1391 // isn't installed since we don't want them left behind in any case. |
| 1376 // behind in any case. | |
| 1377 operation = REMOVE_COMMAND; | 1392 operation = REMOVE_COMMAND; |
| 1378 } else if (have_multi_chrome) { | 1393 } else if (have_chrome_binaries) { |
| 1379 // Chrome Frame isn't (to be) installed or is (to be) installed only in | 1394 // Child product isn't (to be) installed while multi-install Chrome is (to |
| 1380 // ready-mode, while multi-install Chrome is (to be) installed. Add the | 1395 // be) installed. Add the Quick Enable command to the binaries. |
| 1381 // quick-enable-cf command to the binaries. | |
| 1382 operation = ADD_COMMAND; | 1396 operation = ADD_COMMAND; |
| 1383 // The path to setup.exe contains the version of the Chrome binaries, so it | 1397 // The path to setup.exe contains the version of the Chrome binaries, so it |
| 1384 // takes a little work to get it right. | 1398 // takes a little work to get it right. |
| 1385 if (installer_state.operation() == InstallerState::UNINSTALL) { | 1399 if (installer_state.operation() == InstallerState::UNINSTALL) { |
| 1386 // Chrome Frame is being uninstalled. Use the path to the currently | 1400 // One or more products are being uninstalled, but not the binaries. Use |
| 1387 // installed Chrome setup.exe. | 1401 // the path to the currently installed Chrome setup.exe. |
| 1388 product_state = | 1402 product_state = |
| 1389 machine_state.GetProductState(system_install, | 1403 machine_state.GetProductState(system_install, |
| 1390 BrowserDistribution::CHROME_BROWSER); | 1404 BrowserDistribution::CHROME_BINARIES); |
| 1391 DCHECK(product_state); | 1405 DCHECK(product_state); |
| 1392 binaries_setup_path = product_state->uninstall_command().GetProgram(); | 1406 binaries_setup_path = product_state->uninstall_command().GetProgram(); |
| 1393 } else { | 1407 } else { |
| 1394 // Chrome is being installed, updated, or otherwise being operated on. | 1408 // Chrome Binaries are being installed, updated, or otherwise operated on. |
| 1395 // Use the path to the given |setup_path| in the normal location of | 1409 // Use the path to the given |setup_path| in the normal location of |
| 1396 // multi-install Chrome of the given |version|. | 1410 // multi-install Chrome Binaries of the given |version|. |
| 1397 DCHECK(installer_state.is_multi_install()); | 1411 DCHECK(installer_state.is_multi_install()); |
| 1398 binaries_setup_path = | 1412 binaries_setup_path = |
| 1399 installer_state.GetInstallerDirectory(*new_version).Append( | 1413 installer_state.GetInstallerDirectory(*new_version).Append( |
| 1400 setup_path->BaseName()); | 1414 setup_path->BaseName()); |
| 1401 } | 1415 } |
| 1402 } | 1416 } |
| 1403 | 1417 |
| 1404 // STEP 4: Take action. | 1418 // STEP 4: Take action. |
| 1405 if (operation != DO_NOTHING) { | 1419 if (operation != DO_NOTHING) { |
| 1406 // Get the path to the quick-enable-cf command for the binaries. | 1420 // Get the path to the quick-enable-cf command for the binaries. |
| 1407 BrowserDistribution* binaries = | 1421 BrowserDistribution* binaries = |
| 1408 BrowserDistribution::GetSpecificDistribution( | 1422 BrowserDistribution::GetSpecificDistribution( |
| 1409 BrowserDistribution::CHROME_BINARIES); | 1423 BrowserDistribution::CHROME_BINARIES); |
| 1410 std::wstring cmd_key(binaries->GetVersionKey()); | 1424 std::wstring cmd_key(binaries->GetVersionKey()); |
| 1411 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey) | 1425 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey) |
| 1412 .append(1, L'\\').append(kCmdQuickEnableCf); | 1426 .append(1, L'\\').append(command_id); |
| 1413 | 1427 |
| 1414 if (operation == ADD_COMMAND) { | 1428 if (operation == ADD_COMMAND) { |
| 1415 DCHECK(!binaries_setup_path.empty()); | 1429 DCHECK(!binaries_setup_path.empty()); |
| 1416 CommandLine cmd_line(binaries_setup_path); | 1430 CommandLine cmd_line(binaries_setup_path); |
| 1417 cmd_line.AppendSwitch(switches::kMultiInstall); | 1431 cmd_line.AppendArguments(child_product_switches, |
| 1418 if (installer_state.system_install()) | 1432 false); // include_program |
| 1419 cmd_line.AppendSwitch(switches::kSystemLevel); | |
| 1420 if (installer_state.verbose_logging()) | 1433 if (installer_state.verbose_logging()) |
| 1421 cmd_line.AppendSwitch(switches::kVerboseLogging); | 1434 cmd_line.AppendSwitch(switches::kVerboseLogging); |
| 1422 cmd_line.AppendSwitch(switches::kChromeFrameQuickEnable); | |
| 1423 AppCommand cmd(cmd_line.GetCommandLineString(), true, true); | 1435 AppCommand cmd(cmd_line.GetCommandLineString(), true, true); |
| 1424 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); | 1436 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); |
| 1425 } else { | 1437 } else { |
| 1426 DCHECK(operation == REMOVE_COMMAND); | 1438 DCHECK(operation == REMOVE_COMMAND); |
| 1427 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), | 1439 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), |
| 1428 cmd_key)->set_log_message( | 1440 cmd_key)->set_log_message( |
| 1429 "removing quick-enable-cf command"); | 1441 "removing " + WideToASCII(command_id) + " command"); |
| 1430 } | 1442 } |
| 1431 } | 1443 } |
| 1432 } | 1444 } |
| 1433 | 1445 |
| 1446 void AddQuickEnableChromeFrameWorkItems(const InstallerState& installer_state, |
| 1447 const InstallationState& machine_state, |
| 1448 const FilePath* setup_path, |
| 1449 const Version* new_version, |
| 1450 WorkItemList* work_item_list) { |
| 1451 DCHECK(setup_path || |
| 1452 installer_state.operation() == InstallerState::UNINSTALL); |
| 1453 DCHECK(new_version || |
| 1454 installer_state.operation() == InstallerState::UNINSTALL); |
| 1455 DCHECK(work_item_list); |
| 1456 |
| 1457 const bool system_install = installer_state.system_install(); |
| 1458 bool have_chrome_frame = false; |
| 1459 |
| 1460 // STEP 1: Figure out the state of the machine before the operation. |
| 1461 const ProductState* product_state = NULL; |
| 1462 |
| 1463 // Is Chrome Frame !ready-mode already on the machine? |
| 1464 product_state = |
| 1465 machine_state.GetProductState(system_install, |
| 1466 BrowserDistribution::CHROME_FRAME); |
| 1467 if (product_state != NULL && |
| 1468 !product_state->uninstall_command().HasSwitch( |
| 1469 switches::kChromeFrameReadyMode)) |
| 1470 have_chrome_frame = true; |
| 1471 |
| 1472 // STEP 2: Now take into account the current operation. |
| 1473 const Product* product = NULL; |
| 1474 |
| 1475 if (installer_state.operation() == InstallerState::UNINSTALL) { |
| 1476 // Forget about Chrome Frame if it is being uninstalled. Note that we don't |
| 1477 // bother to check !HasOption(kOptionReadyMode) since have_chrome_frame |
| 1478 // should have been false for that case in the first place. It's odd if it |
| 1479 // wasn't, but the right thing to do in that case is to proceed with the |
| 1480 // thought that CF will not be installed in any sense when we reach the |
| 1481 // finish line. |
| 1482 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) != NULL) |
| 1483 have_chrome_frame = false; |
| 1484 } else { |
| 1485 // Check if we're installing Chrome Frame !ready-mode. |
| 1486 product = installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); |
| 1487 if (product != NULL && !product->HasOption(kOptionReadyMode)) |
| 1488 have_chrome_frame = true; |
| 1489 } |
| 1490 |
| 1491 CommandLine cmd_line(CommandLine::NO_PROGRAM); |
| 1492 cmd_line.AppendSwitch(switches::kMultiInstall); |
| 1493 if (installer_state.system_install()) |
| 1494 cmd_line.AppendSwitch(switches::kSystemLevel); |
| 1495 cmd_line.AppendSwitch(switches::kChromeFrameQuickEnable); |
| 1496 |
| 1497 AddGenericQuickEnableWorkItems(installer_state, |
| 1498 machine_state, |
| 1499 setup_path, |
| 1500 new_version, |
| 1501 work_item_list, |
| 1502 have_chrome_frame, |
| 1503 cmd_line, |
| 1504 kCmdQuickEnableCf); |
| 1505 } |
| 1506 |
| 1507 void AddQuickEnableApplicationHostWorkItems( |
| 1508 const InstallerState& installer_state, |
| 1509 const InstallationState& machine_state, |
| 1510 const FilePath* setup_path, |
| 1511 const Version* new_version, |
| 1512 WorkItemList* work_item_list) { |
| 1513 DCHECK(setup_path || |
| 1514 installer_state.operation() == InstallerState::UNINSTALL); |
| 1515 DCHECK(new_version || |
| 1516 installer_state.operation() == InstallerState::UNINSTALL); |
| 1517 DCHECK(work_item_list); |
| 1518 |
| 1519 CommandLine cmd_line(CommandLine::NO_PROGRAM); |
| 1520 cmd_line.AppendSwitch(switches::kMultiInstall); |
| 1521 cmd_line.AppendSwitch(switches::kChromeAppHost); |
| 1522 |
| 1523 // For system-level binaries there is no way to keep the command state in sync |
| 1524 // with the installation/uninstallation of the Application Host (which is |
| 1525 // always at user-level). |
| 1526 // So we pass false for 'have_child_product' to cause this command to always |
| 1527 // be installed if the Chrome Binaries are installed. |
| 1528 AddGenericQuickEnableWorkItems(installer_state, |
| 1529 machine_state, |
| 1530 setup_path, |
| 1531 new_version, |
| 1532 work_item_list, |
| 1533 false, // have_child_product |
| 1534 cmd_line, |
| 1535 kCmdQuickEnableApplicationHost); |
| 1536 } |
| 1537 |
| 1434 } // namespace installer | 1538 } // namespace installer |
| OLD | NEW |