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