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