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