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 <windows.h> // NOLINT | 10 #include <windows.h> // NOLINT |
11 #include <atlsecurity.h> | 11 #include <atlsecurity.h> |
12 #include <oaidl.h> | 12 #include <oaidl.h> |
13 #include <shlobj.h> | 13 #include <shlobj.h> |
14 #include <stddef.h> | 14 #include <stddef.h> |
15 #include <stdint.h> | 15 #include <stdint.h> |
16 #include <time.h> | 16 #include <time.h> |
17 | 17 |
18 #include <memory> | 18 #include <memory> |
19 #include <vector> | 19 #include <vector> |
20 | 20 |
21 #include "base/bind.h" | 21 #include "base/bind.h" |
22 #include "base/command_line.h" | 22 #include "base/command_line.h" |
23 #include "base/files/file_path.h" | 23 #include "base/files/file_path.h" |
24 #include "base/files/file_util.h" | 24 #include "base/files/file_util.h" |
25 #include "base/logging.h" | 25 #include "base/logging.h" |
26 #include "base/macros.h" | |
27 #include "base/path_service.h" | |
28 #include "base/strings/string_util.h" | 26 #include "base/strings/string_util.h" |
29 #include "base/strings/utf_string_conversions.h" | 27 #include "base/strings/utf_string_conversions.h" |
30 #include "base/version.h" | 28 #include "base/version.h" |
31 #include "base/win/registry.h" | 29 #include "base/win/registry.h" |
32 #include "base/win/windows_version.h" | |
33 #include "chrome/common/chrome_constants.h" | |
34 #include "chrome/common/chrome_switches.h" | |
35 #include "chrome/installer/setup/app_launcher_installer.h" | |
36 #include "chrome/installer/setup/install.h" | |
37 #include "chrome/installer/setup/installer_state.h" | 30 #include "chrome/installer/setup/installer_state.h" |
38 #include "chrome/installer/setup/persistent_histogram_storage.h" | 31 #include "chrome/installer/setup/persistent_histogram_storage.h" |
39 #include "chrome/installer/setup/setup_constants.h" | 32 #include "chrome/installer/setup/setup_constants.h" |
40 #include "chrome/installer/setup/setup_util.h" | 33 #include "chrome/installer/setup/setup_util.h" |
41 #include "chrome/installer/setup/update_active_setup_version_work_item.h" | 34 #include "chrome/installer/setup/update_active_setup_version_work_item.h" |
42 #include "chrome/installer/util/app_registration_data.h" | 35 #include "chrome/installer/util/app_registration_data.h" |
43 #include "chrome/installer/util/browser_distribution.h" | 36 #include "chrome/installer/util/browser_distribution.h" |
44 #include "chrome/installer/util/callback_work_item.h" | 37 #include "chrome/installer/util/callback_work_item.h" |
45 #include "chrome/installer/util/conditional_work_item_list.h" | 38 #include "chrome/installer/util/conditional_work_item_list.h" |
46 #include "chrome/installer/util/create_reg_key_work_item.h" | 39 #include "chrome/installer/util/create_reg_key_work_item.h" |
47 #include "chrome/installer/util/firewall_manager_win.h" | 40 #include "chrome/installer/util/firewall_manager_win.h" |
48 #include "chrome/installer/util/google_update_constants.h" | 41 #include "chrome/installer/util/google_update_constants.h" |
49 #include "chrome/installer/util/helper.h" | |
50 #include "chrome/installer/util/install_util.h" | 42 #include "chrome/installer/util/install_util.h" |
51 #include "chrome/installer/util/installation_state.h" | 43 #include "chrome/installer/util/installation_state.h" |
52 #include "chrome/installer/util/l10n_string_util.h" | 44 #include "chrome/installer/util/l10n_string_util.h" |
| 45 #include "chrome/installer/util/non_updating_app_registration_data.h" |
53 #include "chrome/installer/util/product.h" | 46 #include "chrome/installer/util/product.h" |
54 #include "chrome/installer/util/set_reg_value_work_item.h" | 47 #include "chrome/installer/util/set_reg_value_work_item.h" |
55 #include "chrome/installer/util/shell_util.h" | 48 #include "chrome/installer/util/shell_util.h" |
| 49 #include "chrome/installer/util/updating_app_registration_data.h" |
56 #include "chrome/installer/util/util_constants.h" | 50 #include "chrome/installer/util/util_constants.h" |
57 #include "chrome/installer/util/work_item_list.h" | 51 #include "chrome/installer/util/work_item_list.h" |
58 | 52 |
59 using base::ASCIIToUTF16; | 53 using base::ASCIIToUTF16; |
60 using base::win::RegKey; | 54 using base::win::RegKey; |
61 | 55 |
62 namespace installer { | 56 namespace installer { |
63 | 57 |
64 namespace { | 58 namespace { |
65 | 59 |
66 // Although the UUID of the ChromeFrame class is used for the "current" value, | |
67 // this is done only as a convenience; there is no need for the GUID of the Low | |
68 // Rights policies to match the ChromeFrame class's GUID. Hence, it is safe to | |
69 // use this completely unrelated GUID for the "old" policies. | |
70 const wchar_t kIELowRightsPolicyOldGuid[] = | |
71 L"{6C288DD7-76FB-4721-B628-56FAC252E199}"; | |
72 | |
73 const wchar_t kElevationPolicyKeyPath[] = | |
74 L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\"; | |
75 | |
76 void GetOldIELowRightsElevationPolicyKeyPath(base::string16* key_path) { | |
77 key_path->assign(kElevationPolicyKeyPath, | |
78 arraysize(kElevationPolicyKeyPath) - 1); | |
79 key_path->append(kIELowRightsPolicyOldGuid, | |
80 arraysize(kIELowRightsPolicyOldGuid)- 1); | |
81 } | |
82 | |
83 // Local helper to call AddRegisterComDllWorkItems for all DLLs in a set of | |
84 // products managed by a given package. | |
85 // |old_version| can be NULL to indicate no Chrome is currently installed. | |
86 void AddRegisterComDllWorkItemsForPackage(const InstallerState& installer_state, | |
87 const base::Version* old_version, | |
88 const base::Version& new_version, | |
89 WorkItemList* work_item_list) { | |
90 // First collect the list of DLLs to be registered from each product. | |
91 std::vector<base::FilePath> com_dll_list; | |
92 installer_state.AddComDllList(&com_dll_list); | |
93 | |
94 // Then, if we got some, attempt to unregister the DLLs from the old | |
95 // version directory and then re-register them in the new one. | |
96 // Note that if we are migrating the install directory then we will not | |
97 // successfully unregister the old DLLs. | |
98 // TODO(robertshield): See whether we need to fix the migration case. | |
99 // TODO(robertshield): If we ever remove a DLL from a product, this will | |
100 // not unregister it on update. We should build the unregistration list from | |
101 // saved state instead of assuming it is the same as the registration list. | |
102 if (!com_dll_list.empty()) { | |
103 if (old_version) { | |
104 base::FilePath old_dll_path(installer_state.target_path().AppendASCII( | |
105 old_version->GetString())); | |
106 | |
107 installer::AddRegisterComDllWorkItems(old_dll_path, | |
108 com_dll_list, | |
109 installer_state.system_install(), | |
110 false, // Unregister | |
111 true, // May fail | |
112 work_item_list); | |
113 } | |
114 | |
115 base::FilePath dll_path(installer_state.target_path().AppendASCII( | |
116 new_version.GetString())); | |
117 installer::AddRegisterComDllWorkItems(dll_path, | |
118 com_dll_list, | |
119 installer_state.system_install(), | |
120 true, // Register | |
121 false, // Must succeed. | |
122 work_item_list); | |
123 } | |
124 } | |
125 | |
126 void AddInstallerCopyTasks(const InstallerState& installer_state, | 60 void AddInstallerCopyTasks(const InstallerState& installer_state, |
127 const base::FilePath& setup_path, | 61 const base::FilePath& setup_path, |
128 const base::FilePath& archive_path, | 62 const base::FilePath& archive_path, |
129 const base::FilePath& temp_path, | 63 const base::FilePath& temp_path, |
130 const base::Version& new_version, | 64 const base::Version& new_version, |
131 WorkItemList* install_list) { | 65 WorkItemList* install_list) { |
132 DCHECK(install_list); | 66 DCHECK(install_list); |
133 base::FilePath installer_dir( | 67 base::FilePath installer_dir( |
134 installer_state.GetInstallerDirectory(new_version)); | 68 installer_state.GetInstallerDirectory(new_version)); |
135 install_list->AddCreateDirWorkItem(installer_dir); | 69 install_list->AddCreateDirWorkItem(installer_dir); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 is_new_install)); | 161 is_new_install)); |
228 } | 162 } |
229 | 163 |
230 void AddProductSpecificWorkItems(const InstallationState& original_state, | 164 void AddProductSpecificWorkItems(const InstallationState& original_state, |
231 const InstallerState& installer_state, | 165 const InstallerState& installer_state, |
232 const base::FilePath& setup_path, | 166 const base::FilePath& setup_path, |
233 const base::Version& new_version, | 167 const base::Version& new_version, |
234 const base::Version* current_version, | 168 const base::Version* current_version, |
235 bool add_language_identifier, | 169 bool add_language_identifier, |
236 WorkItemList* list) { | 170 WorkItemList* list) { |
237 const Products& products = installer_state.products(); | 171 const Product& p = installer_state.product(); |
238 for (Products::const_iterator it = products.begin(); it < products.end(); | 172 AddOsUpgradeWorkItems(installer_state, setup_path, new_version, p, list); |
239 ++it) { | 173 AddFirewallRulesWorkItems(installer_state, p.distribution(), |
240 const Product& p = **it; | 174 current_version == nullptr, list); |
241 if (p.is_chrome()) { | |
242 AddOsUpgradeWorkItems(installer_state, setup_path, new_version, p, | |
243 list); | |
244 AddFirewallRulesWorkItems(installer_state, p.distribution(), | |
245 current_version == nullptr, list); | |
246 | 175 |
247 #if defined(GOOGLE_CHROME_BUILD) | 176 InstallUtil::AddUpdateDowngradeVersionItem(installer_state.system_install(), |
248 if (!InstallUtil::IsChromeSxSProcess()) { | 177 current_version, new_version, |
249 // Remove the app launcher key as it has been deprecated. | 178 p.distribution(), list); |
250 RemoveAppLauncherVersionKey(installer_state.root_key()); | |
251 } | |
252 #endif // GOOGLE_CHROME_BUILD | |
253 InstallUtil::AddUpdateDowngradeVersionItem( | |
254 installer_state.system_install(), current_version, new_version, | |
255 p.distribution(), list); | |
256 } | |
257 if (p.is_chrome_binaries()) | |
258 AddQuickEnableChromeFrameWorkItems(installer_state, list); | |
259 } | |
260 } | 179 } |
261 | 180 |
262 // This is called when an MSI installation is run. It may be that a user is | 181 // This is called when an MSI installation is run. It may be that a user is |
263 // attempting to install the MSI on top of a non-MSI managed installation. If | 182 // attempting to install the MSI on top of a non-MSI managed installation. If |
264 // so, try and remove any existing "Add/Remove Programs" entry, as we want the | 183 // so, try and remove any existing "Add/Remove Programs" entry, as we want the |
265 // uninstall to be managed entirely by the MSI machinery (accessible via the | 184 // uninstall to be managed entirely by the MSI machinery (accessible via the |
266 // Add/Remove programs dialog). | 185 // Add/Remove programs dialog). |
267 void AddDeleteUninstallEntryForMSIWorkItems( | 186 void AddDeleteUninstallEntryForMSIWorkItems( |
268 const InstallerState& installer_state, | 187 const InstallerState& installer_state, |
269 const Product& product, | 188 const Product& product, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 delete_old_archive_work_item->set_rollback_enabled(false); | 228 delete_old_archive_work_item->set_rollback_enabled(false); |
310 } | 229 } |
311 } | 230 } |
312 | 231 |
313 // Delete any new_chrome.exe if present (we will end up creating a new one | 232 // Delete any new_chrome.exe if present (we will end up creating a new one |
314 // if required) and then copy chrome.exe | 233 // if required) and then copy chrome.exe |
315 base::FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe)); | 234 base::FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe)); |
316 | 235 |
317 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); | 236 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); |
318 | 237 |
319 // TODO(grt): Remove this check in M35. | 238 install_list->AddCopyTreeWorkItem( |
320 if (installer_state.IsChromeFrameRunning(original_state)) { | 239 src_path.Append(installer::kChromeExe).value(), |
321 VLOG(1) << "Chrome Frame in use. Copying to new_chrome.exe"; | 240 target_path.Append(installer::kChromeExe).value(), temp_path.value(), |
322 install_list->AddCopyTreeWorkItem( | 241 WorkItem::NEW_NAME_IF_IN_USE, new_chrome_exe.value()); |
323 src_path.Append(installer::kChromeExe).value(), | |
324 new_chrome_exe.value(), | |
325 temp_path.value(), | |
326 WorkItem::ALWAYS); | |
327 } else { | |
328 install_list->AddCopyTreeWorkItem( | |
329 src_path.Append(installer::kChromeExe).value(), | |
330 target_path.Append(installer::kChromeExe).value(), | |
331 temp_path.value(), | |
332 WorkItem::NEW_NAME_IF_IN_USE, | |
333 new_chrome_exe.value()); | |
334 } | |
335 | 242 |
336 // Install kVisualElementsManifest if it is present in |src_path|. No need to | 243 // Install kVisualElementsManifest if it is present in |src_path|. No need to |
337 // make this a conditional work item as if the file is not there now, it will | 244 // make this a conditional work item as if the file is not there now, it will |
338 // never be. | 245 // never be. |
339 if (base::PathExists( | 246 if (base::PathExists( |
340 src_path.Append(installer::kVisualElementsManifest))) { | 247 src_path.Append(installer::kVisualElementsManifest))) { |
341 install_list->AddMoveTreeWorkItem( | 248 install_list->AddMoveTreeWorkItem( |
342 src_path.Append(installer::kVisualElementsManifest).value(), | 249 src_path.Append(installer::kVisualElementsManifest).value(), |
343 target_path.Append(installer::kVisualElementsManifest).value(), | 250 target_path.Append(installer::kVisualElementsManifest).value(), |
344 temp_path.value(), | 251 temp_path.value(), |
(...skipping 26 matching lines...) Expand all Loading... |
371 ->AddDeleteTreeWorkItem(target_path.Append(installer::kChromeOldExe), | 278 ->AddDeleteTreeWorkItem(target_path.Append(installer::kChromeOldExe), |
372 temp_path) | 279 temp_path) |
373 ->set_best_effort(true); | 280 ->set_best_effort(true); |
374 } | 281 } |
375 | 282 |
376 // Adds work items to remove COM registration for |product|'s deprecated | 283 // Adds work items to remove COM registration for |product|'s deprecated |
377 // DelegateExecute verb handler. | 284 // DelegateExecute verb handler. |
378 void AddCleanupDelegateExecuteWorkItems(const InstallerState& installer_state, | 285 void AddCleanupDelegateExecuteWorkItems(const InstallerState& installer_state, |
379 const Product& product, | 286 const Product& product, |
380 WorkItemList* list) { | 287 WorkItemList* list) { |
381 if (product.is_chrome()) { | 288 VLOG(1) << "Adding unregistration items for DelegateExecute verb handler."; |
382 VLOG(1) << "Adding unregistration items for DelegateExecute verb handler."; | 289 const base::string16 handler_class_uuid = |
383 const base::string16 handler_class_uuid = | 290 product.distribution()->GetCommandExecuteImplClsid(); |
384 product.distribution()->GetCommandExecuteImplClsid(); | 291 DCHECK(!handler_class_uuid.empty()); |
385 DCHECK(!handler_class_uuid.empty()); | |
386 | 292 |
387 const HKEY root = installer_state.root_key(); | 293 const HKEY root = installer_state.root_key(); |
388 base::string16 delegate_execute_path(L"Software\\Classes\\CLSID\\"); | 294 base::string16 delegate_execute_path(L"Software\\Classes\\CLSID\\"); |
389 delegate_execute_path.append(handler_class_uuid); | 295 delegate_execute_path.append(handler_class_uuid); |
390 // Delete both 64 and 32 keys to handle 32->64 or 64->32 migration. | 296 // Delete both 64 and 32 keys to handle 32->64 or 64->32 migration. |
391 list->AddDeleteRegKeyWorkItem(root, delegate_execute_path, KEY_WOW64_32KEY); | 297 list->AddDeleteRegKeyWorkItem(root, delegate_execute_path, KEY_WOW64_32KEY); |
392 list->AddDeleteRegKeyWorkItem(root, delegate_execute_path, KEY_WOW64_64KEY); | 298 list->AddDeleteRegKeyWorkItem(root, delegate_execute_path, KEY_WOW64_64KEY); |
393 } | |
394 } | 299 } |
395 | 300 |
396 // Add to the ACL of an object on disk. This follows the method from MSDN: | 301 // Add to the ACL of an object on disk. This follows the method from MSDN: |
397 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa379283.aspx | 302 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa379283.aspx |
398 // This is done using explicit flags rather than the "security string" format | 303 // This is done using explicit flags rather than the "security string" format |
399 // because strings do not necessarily read what is written which makes it | 304 // because strings do not necessarily read what is written which makes it |
400 // difficult to de-dup. Working with the binary format is always exact and the | 305 // difficult to de-dup. Working with the binary format is always exact and the |
401 // system libraries will properly ignore duplicate ACL entries. | 306 // system libraries will properly ignore duplicate ACL entries. |
402 bool AddAclToPath(const base::FilePath& path, | 307 bool AddAclToPath(const base::FilePath& path, |
403 const CSid& trustee, | 308 const CSid& trustee, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 340 |
436 // Attach the updated ACL as the object's DACL. | 341 // Attach the updated ACL as the object's DACL. |
437 if (!ATL::AtlSetDacl(path.value().c_str(), SE_FILE_OBJECT, dacl)) { | 342 if (!ATL::AtlSetDacl(path.value().c_str(), SE_FILE_OBJECT, dacl)) { |
438 DPLOG(ERROR) << "Failed setting DACL for path \"" << path.value() << "\""; | 343 DPLOG(ERROR) << "Failed setting DACL for path \"" << path.value() << "\""; |
439 return false; | 344 return false; |
440 } | 345 } |
441 | 346 |
442 return true; | 347 return true; |
443 } | 348 } |
444 | 349 |
| 350 // Migrates the usagestats value from the binaries to Chrome when migrating |
| 351 // multi-install Chrome to single-install. |
| 352 void AddMigrateUsageStatsWorkItems(const InstallationState& original_state, |
| 353 const InstallerState& installer_state, |
| 354 WorkItemList* install_list) { |
| 355 // This operation doesn't apply to SxS Chrome. |
| 356 if (InstallUtil::IsChromeSxSProcess()) |
| 357 return; |
| 358 |
| 359 // Bail out if an existing multi-install Chrome is not being migrated to |
| 360 // single-install. |
| 361 if (!installer_state.is_migrating_to_single()) { |
| 362 VLOG(1) << "No multi-install Chrome found to migrate to single-install."; |
| 363 return; |
| 364 } |
| 365 |
| 366 const ProductState* binaries_state = original_state.GetProductState( |
| 367 installer_state.system_install(), BrowserDistribution::CHROME_BINARIES); |
| 368 |
| 369 // There is nothing to be done if the binaries do not have stats. |
| 370 DWORD usagestats = 0; |
| 371 if (!binaries_state || !binaries_state->GetUsageStats(&usagestats)) { |
| 372 VLOG(1) << "No usagestats value found to migrate to single-install."; |
| 373 return; |
| 374 } |
| 375 |
| 376 VLOG(1) << "Migrating usagestats value from multi-install to single-install."; |
| 377 |
| 378 // Write the value that was read to Chrome's ClientState key. |
| 379 install_list->AddSetRegValueWorkItem( |
| 380 installer_state.root_key(), |
| 381 installer_state.product().distribution()->GetStateKey(), KEY_WOW64_32KEY, |
| 382 google_update::kRegUsageStatsField, usagestats, true); |
| 383 } |
| 384 |
445 } // namespace | 385 } // namespace |
446 | 386 |
447 // This method adds work items to create (or update) Chrome uninstall entry in | 387 // This method adds work items to create (or update) Chrome uninstall entry in |
448 // either the Control Panel->Add/Remove Programs list or in the Omaha client | 388 // either the Control Panel->Add/Remove Programs list or in the Omaha client |
449 // state key if running under an MSI installer. | 389 // state key if running under an MSI installer. |
450 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, | 390 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, |
451 const base::FilePath& setup_path, | 391 const base::FilePath& setup_path, |
452 const base::Version& new_version, | 392 const base::Version& new_version, |
453 const Product& product, | 393 const Product& product, |
454 WorkItemList* install_list) { | 394 WorkItemList* install_list) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 false); // do not overwrite language | 567 false); // do not overwrite language |
628 } | 568 } |
629 list->AddSetRegValueWorkItem(root, | 569 list->AddSetRegValueWorkItem(root, |
630 version_key, | 570 version_key, |
631 KEY_WOW64_32KEY, | 571 KEY_WOW64_32KEY, |
632 google_update::kRegVersionField, | 572 google_update::kRegVersionField, |
633 ASCIIToUTF16(new_version.GetString()), | 573 ASCIIToUTF16(new_version.GetString()), |
634 true); // overwrite version | 574 true); // overwrite version |
635 } | 575 } |
636 | 576 |
637 // Mirror oeminstall the first time anything is installed multi. There is no | |
638 // need to update the value on future install/update runs since this value never | |
639 // changes. Note that the value is removed by Google Update after EULA | |
640 // acceptance is processed. | |
641 void AddOemInstallWorkItems(const InstallationState& original_state, | |
642 const InstallerState& installer_state, | |
643 WorkItemList* install_list) { | |
644 DCHECK(installer_state.is_multi_install()); | |
645 const bool system_install = installer_state.system_install(); | |
646 if (!original_state.GetProductState(system_install, | |
647 BrowserDistribution::CHROME_BINARIES)) { | |
648 const HKEY root_key = installer_state.root_key(); | |
649 base::string16 multi_key( | |
650 installer_state.multi_package_binaries_distribution()->GetStateKey()); | |
651 | |
652 // Copy the value from Chrome unless Chrome isn't installed or being | |
653 // installed. | |
654 BrowserDistribution::Type source_type; | |
655 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER)) { | |
656 source_type = BrowserDistribution::CHROME_BROWSER; | |
657 } else if (!installer_state.products().empty()) { | |
658 // Pick a product, any product. | |
659 source_type = installer_state.products()[0]->distribution()->GetType(); | |
660 } else { | |
661 // Nothing is being installed? Entirely unexpected, so do no harm. | |
662 LOG(ERROR) << "No products found in AddOemInstallWorkItems"; | |
663 return; | |
664 } | |
665 const ProductState* source_product = | |
666 original_state.GetNonVersionedProductState(system_install, source_type); | |
667 | |
668 base::string16 oem_install; | |
669 if (source_product->GetOemInstall(&oem_install)) { | |
670 VLOG(1) << "Mirroring oeminstall=\"" << oem_install << "\" from " | |
671 << BrowserDistribution::GetSpecificDistribution(source_type)-> | |
672 GetDisplayName(); | |
673 install_list->AddCreateRegKeyWorkItem( | |
674 root_key, multi_key, KEY_WOW64_32KEY); | |
675 // Always overwrite an old value. | |
676 install_list->AddSetRegValueWorkItem(root_key, | |
677 multi_key, | |
678 KEY_WOW64_32KEY, | |
679 google_update::kRegOemInstallField, | |
680 oem_install, | |
681 true); | |
682 } else { | |
683 // Clear any old value. | |
684 install_list->AddDeleteRegValueWorkItem( | |
685 root_key, | |
686 multi_key, | |
687 KEY_WOW64_32KEY, | |
688 google_update::kRegOemInstallField); | |
689 } | |
690 } | |
691 } | |
692 | |
693 // Mirror eulaaccepted the first time anything is installed multi. There is no | |
694 // need to update the value on future install/update runs since | |
695 // GoogleUpdateSettings::SetEULAConsent will modify the value for both the | |
696 // relevant product and for the binaries. | |
697 void AddEulaAcceptedWorkItems(const InstallationState& original_state, | |
698 const InstallerState& installer_state, | |
699 WorkItemList* install_list) { | |
700 DCHECK(installer_state.is_multi_install()); | |
701 const bool system_install = installer_state.system_install(); | |
702 if (!original_state.GetProductState(system_install, | |
703 BrowserDistribution::CHROME_BINARIES)) { | |
704 const HKEY root_key = installer_state.root_key(); | |
705 base::string16 multi_key( | |
706 installer_state.multi_package_binaries_distribution()->GetStateKey()); | |
707 | |
708 // Copy the value from the product with the greatest value. | |
709 bool have_eula_accepted = false; | |
710 BrowserDistribution::Type product_type = BrowserDistribution::NUM_TYPES; | |
711 DWORD eula_accepted = 0; | |
712 const Products& products = installer_state.products(); | |
713 for (Products::const_iterator it = products.begin(); it < products.end(); | |
714 ++it) { | |
715 const Product& product = **it; | |
716 if (product.is_chrome_binaries()) | |
717 continue; | |
718 DWORD dword_value = 0; | |
719 BrowserDistribution::Type this_type = product.distribution()->GetType(); | |
720 const ProductState* product_state = | |
721 original_state.GetNonVersionedProductState( | |
722 system_install, this_type); | |
723 if (product_state->GetEulaAccepted(&dword_value) && | |
724 (!have_eula_accepted || dword_value > eula_accepted)) { | |
725 have_eula_accepted = true; | |
726 eula_accepted = dword_value; | |
727 product_type = this_type; | |
728 } | |
729 } | |
730 | |
731 if (have_eula_accepted) { | |
732 VLOG(1) << "Mirroring eulaaccepted=" << eula_accepted << " from " | |
733 << BrowserDistribution::GetSpecificDistribution(product_type)-> | |
734 GetDisplayName(); | |
735 install_list->AddCreateRegKeyWorkItem( | |
736 root_key, multi_key, KEY_WOW64_32KEY); | |
737 install_list->AddSetRegValueWorkItem(root_key, | |
738 multi_key, | |
739 KEY_WOW64_32KEY, | |
740 google_update::kRegEULAAceptedField, | |
741 eula_accepted, | |
742 true); | |
743 } else { | |
744 // Clear any old value. | |
745 install_list->AddDeleteRegValueWorkItem( | |
746 root_key, | |
747 multi_key, | |
748 KEY_WOW64_32KEY, | |
749 google_update::kRegEULAAceptedField); | |
750 } | |
751 } | |
752 } | |
753 | |
754 // Adds work items that make registry adjustments for Google Update. | |
755 void AddGoogleUpdateWorkItems(const InstallationState& original_state, | |
756 const InstallerState& installer_state, | |
757 WorkItemList* install_list) { | |
758 // Is a multi-install product being installed or over-installed? | |
759 if (installer_state.operation() != InstallerState::MULTI_INSTALL && | |
760 installer_state.operation() != InstallerState::MULTI_UPDATE) { | |
761 VLOG(1) << "AddGoogleUpdateWorkItems noop: " << installer_state.operation(); | |
762 return; | |
763 } | |
764 | |
765 const bool system_install = installer_state.system_install(); | |
766 const HKEY root_key = installer_state.root_key(); | |
767 base::string16 multi_key( | |
768 installer_state.multi_package_binaries_distribution()->GetStateKey()); | |
769 | |
770 // For system-level installs, make sure the ClientStateMedium key for the | |
771 // binaries exists. | |
772 if (system_install) { | |
773 install_list->AddCreateRegKeyWorkItem( | |
774 root_key, | |
775 installer_state.multi_package_binaries_distribution() | |
776 ->GetStateMediumKey() | |
777 .c_str(), | |
778 KEY_WOW64_32KEY); | |
779 } | |
780 | |
781 // Creating the ClientState key for binaries, if we're migrating to multi then | |
782 // copy over Chrome's brand code if it has one. | |
783 if (installer_state.state_type() != BrowserDistribution::CHROME_BINARIES) { | |
784 const ProductState* chrome_product_state = | |
785 original_state.GetNonVersionedProductState( | |
786 system_install, BrowserDistribution::CHROME_BROWSER); | |
787 | |
788 const base::string16& brand(chrome_product_state->brand()); | |
789 if (!brand.empty()) { | |
790 install_list->AddCreateRegKeyWorkItem( | |
791 root_key, multi_key, KEY_WOW64_32KEY); | |
792 // Write Chrome's brand code to the multi key. Never overwrite the value | |
793 // if one is already present (although this shouldn't happen). | |
794 install_list->AddSetRegValueWorkItem(root_key, | |
795 multi_key, | |
796 KEY_WOW64_32KEY, | |
797 google_update::kRegBrandField, | |
798 brand, | |
799 false); | |
800 } | |
801 } | |
802 | |
803 AddOemInstallWorkItems(original_state, installer_state, install_list); | |
804 AddEulaAcceptedWorkItems(original_state, installer_state, install_list); | |
805 AddUsageStatsWorkItems(original_state, installer_state, install_list); | |
806 | |
807 // TODO(grt): check for other keys/values we should put in the package's | |
808 // ClientState and/or Clients key. | |
809 } | |
810 | |
811 void AddUsageStatsWorkItems(const InstallationState& original_state, | |
812 const InstallerState& installer_state, | |
813 WorkItemList* install_list) { | |
814 DCHECK(installer_state.operation() == InstallerState::MULTI_INSTALL || | |
815 installer_state.operation() == InstallerState::MULTI_UPDATE); | |
816 | |
817 HKEY root_key = installer_state.root_key(); | |
818 bool value_found = false; | |
819 DWORD usagestats = 0; | |
820 const Products& products = installer_state.products(); | |
821 | |
822 // Search for an existing usagestats value for any product. | |
823 for (Products::const_iterator scan = products.begin(), end = products.end(); | |
824 !value_found && scan != end; ++scan) { | |
825 if ((*scan)->is_chrome_binaries()) | |
826 continue; | |
827 BrowserDistribution* dist = (*scan)->distribution(); | |
828 const ProductState* product_state = | |
829 original_state.GetNonVersionedProductState( | |
830 installer_state.system_install(), dist->GetType()); | |
831 value_found = product_state->GetUsageStats(&usagestats); | |
832 } | |
833 | |
834 // If a value was found, write it in the appropriate location for the | |
835 // binaries and remove all values from the products. | |
836 if (value_found) { | |
837 base::string16 state_key( | |
838 installer_state.multi_package_binaries_distribution()->GetStateKey()); | |
839 install_list->AddCreateRegKeyWorkItem(root_key, state_key, KEY_WOW64_32KEY); | |
840 // Overwrite any existing value so that overinstalls (where Omaha writes a | |
841 // new value into a product's state key) pick up the correct value. | |
842 install_list->AddSetRegValueWorkItem(root_key, | |
843 state_key, | |
844 KEY_WOW64_32KEY, | |
845 google_update::kRegUsageStatsField, | |
846 usagestats, | |
847 true); | |
848 | |
849 for (Products::const_iterator scan = products.begin(), end = products.end(); | |
850 scan != end; ++scan) { | |
851 if ((*scan)->is_chrome_binaries()) | |
852 continue; | |
853 BrowserDistribution* dist = (*scan)->distribution(); | |
854 if (installer_state.system_install()) { | |
855 install_list->AddDeleteRegValueWorkItem( | |
856 root_key, | |
857 dist->GetStateMediumKey(), | |
858 KEY_WOW64_32KEY, | |
859 google_update::kRegUsageStatsField); | |
860 // Previous versions of Chrome also wrote a value in HKCU even for | |
861 // system-level installs, so clean that up. | |
862 install_list->AddDeleteRegValueWorkItem( | |
863 HKEY_CURRENT_USER, | |
864 dist->GetStateKey(), | |
865 KEY_WOW64_32KEY, | |
866 google_update::kRegUsageStatsField); | |
867 } | |
868 install_list->AddDeleteRegValueWorkItem( | |
869 root_key, | |
870 dist->GetStateKey(), | |
871 KEY_WOW64_32KEY, | |
872 google_update::kRegUsageStatsField); | |
873 } | |
874 } | |
875 } | |
876 | |
877 // Migrates the usagestats value from the binaries to Chrome when migrating | |
878 // multi-install Chrome to single-install. | |
879 void AddMigrateUsageStatesWorkItems(const InstallationState& original_state, | |
880 const InstallerState& installer_state, | |
881 WorkItemList* install_list) { | |
882 // Ensure that a non-multi install or update is being processed (i.e., | |
883 // no "--multi-install" on the command line). | |
884 if (installer_state.is_multi_install()) | |
885 return; | |
886 | |
887 // This operation doesn't apply to SxS Chrome. | |
888 if (InstallUtil::IsChromeSxSProcess()) | |
889 return; | |
890 | |
891 // Ensure that Chrome is the product being installed or updated (there are no | |
892 // other products, so it is especially unexpected for this to fail). | |
893 const Product* chrome_product = | |
894 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); | |
895 if (!chrome_product) { | |
896 LOG(DFATAL) << "Not operating on Chrome while migrating to single-install."; | |
897 return; | |
898 } | |
899 | |
900 // Bail out if an existing multi-install Chrome is not being migrated to | |
901 // single-install. | |
902 if (!installer_state.is_migrating_to_single()) { | |
903 VLOG(1) << "No multi-install Chrome found to migrate to single-install."; | |
904 return; | |
905 } | |
906 | |
907 const ProductState* binaries_state = original_state.GetProductState( | |
908 installer_state.system_install(), | |
909 BrowserDistribution::CHROME_BINARIES); | |
910 | |
911 // There is nothing to be done if the binaries do not have stats. | |
912 DWORD usagestats = 0; | |
913 if (!binaries_state || !binaries_state->GetUsageStats(&usagestats)) { | |
914 VLOG(1) << "No usagestats value found to migrate to single-install."; | |
915 return; | |
916 } | |
917 | |
918 VLOG(1) << "Migrating usagestats value from multi-install to single-install."; | |
919 | |
920 // Write the value that was read to Chrome's ClientState key. | |
921 install_list->AddSetRegValueWorkItem( | |
922 installer_state.root_key(), | |
923 chrome_product->distribution()->GetStateKey(), | |
924 KEY_WOW64_32KEY, | |
925 google_update::kRegUsageStatsField, | |
926 usagestats, | |
927 true); | |
928 } | |
929 | |
930 bool AppendPostInstallTasks(const InstallerState& installer_state, | 577 bool AppendPostInstallTasks(const InstallerState& installer_state, |
931 const base::FilePath& setup_path, | 578 const base::FilePath& setup_path, |
932 const base::Version* current_version, | 579 const base::Version* current_version, |
933 const base::Version& new_version, | 580 const base::Version& new_version, |
934 WorkItemList* post_install_task_list) { | 581 WorkItemList* post_install_task_list) { |
935 DCHECK(post_install_task_list); | 582 DCHECK(post_install_task_list); |
936 | 583 |
937 HKEY root = installer_state.root_key(); | 584 HKEY root = installer_state.root_key(); |
938 const Products& products = installer_state.products(); | |
939 base::FilePath new_chrome_exe( | 585 base::FilePath new_chrome_exe( |
940 installer_state.target_path().Append(installer::kChromeNewExe)); | 586 installer_state.target_path().Append(installer::kChromeNewExe)); |
941 | 587 |
942 // 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. |
943 // 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, |
944 // 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 |
945 // 'cmd' value with the rename command to run. | 591 // 'cmd' value with the rename command to run. |
946 { | 592 { |
947 std::unique_ptr<WorkItemList> in_use_update_work_items( | 593 std::unique_ptr<WorkItemList> in_use_update_work_items( |
948 WorkItem::CreateConditionalWorkItemList( | 594 WorkItem::CreateConditionalWorkItemList( |
949 new ConditionRunIfFileExists(new_chrome_exe))); | 595 new ConditionRunIfFileExists(new_chrome_exe))); |
950 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); | 596 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); |
951 | 597 |
952 // |critical_version| will be valid only if this in-use update includes a | 598 // |critical_version| will be valid only if this in-use update includes a |
953 // version considered critical relative to the version being updated. | 599 // version considered critical relative to the version being updated. |
954 base::Version critical_version(installer_state.DetermineCriticalVersion( | 600 base::Version critical_version(installer_state.DetermineCriticalVersion( |
955 current_version, new_version)); | 601 current_version, new_version)); |
956 base::FilePath installer_path( | 602 base::FilePath installer_path( |
957 installer_state.GetInstallerDirectory(new_version).Append( | 603 installer_state.GetInstallerDirectory(new_version).Append( |
958 setup_path.BaseName())); | 604 setup_path.BaseName())); |
959 | 605 |
960 base::CommandLine rename(installer_path); | 606 base::CommandLine rename(installer_path); |
961 rename.AppendSwitch(switches::kRenameChromeExe); | 607 rename.AppendSwitch(switches::kRenameChromeExe); |
962 if (installer_state.system_install()) | 608 if (installer_state.system_install()) |
963 rename.AppendSwitch(switches::kSystemLevel); | 609 rename.AppendSwitch(switches::kSystemLevel); |
964 | 610 |
965 if (installer_state.verbose_logging()) | 611 if (installer_state.verbose_logging()) |
966 rename.AppendSwitch(switches::kVerboseLogging); | 612 rename.AppendSwitch(switches::kVerboseLogging); |
967 | 613 |
968 base::string16 version_key; | 614 BrowserDistribution* dist = installer_state.product().distribution(); |
969 for (size_t i = 0; i < products.size(); ++i) { | 615 const base::string16 version_key = dist->GetVersionKey(); |
970 BrowserDistribution* dist = products[i]->distribution(); | |
971 version_key = dist->GetVersionKey(); | |
972 | 616 |
973 if (current_version) { | 617 if (current_version) { |
974 in_use_update_work_items->AddSetRegValueWorkItem( | 618 in_use_update_work_items->AddSetRegValueWorkItem( |
975 root, | 619 root, version_key, KEY_WOW64_32KEY, |
976 version_key, | 620 google_update::kRegOldVersionField, |
977 KEY_WOW64_32KEY, | 621 ASCIIToUTF16(current_version->GetString()), true); |
978 google_update::kRegOldVersionField, | 622 } |
979 ASCIIToUTF16(current_version->GetString()), | 623 if (critical_version.IsValid()) { |
980 true); | 624 in_use_update_work_items->AddSetRegValueWorkItem( |
981 } | 625 root, version_key, KEY_WOW64_32KEY, |
982 if (critical_version.IsValid()) { | 626 google_update::kRegCriticalVersionField, |
983 in_use_update_work_items->AddSetRegValueWorkItem( | 627 ASCIIToUTF16(critical_version.GetString()), true); |
984 root, | 628 } else { |
985 version_key, | 629 in_use_update_work_items->AddDeleteRegValueWorkItem( |
986 KEY_WOW64_32KEY, | 630 root, version_key, KEY_WOW64_32KEY, |
987 google_update::kRegCriticalVersionField, | 631 google_update::kRegCriticalVersionField); |
988 ASCIIToUTF16(critical_version.GetString()), | 632 } |
989 true); | |
990 } else { | |
991 in_use_update_work_items->AddDeleteRegValueWorkItem( | |
992 root, | |
993 version_key, | |
994 KEY_WOW64_32KEY, | |
995 google_update::kRegCriticalVersionField); | |
996 } | |
997 | 633 |
998 // Adding this registry entry for all products (but the binaries) is | 634 // Append the distribution-specific flags to the command line (e.g., |
999 // overkill. However, as it stands, we don't have a way to know which | 635 // "--chrome-sxs" for SxS/canary). |
1000 // product will check the key and run the command, so we add it for all. | 636 base::CommandLine product_rename_cmd(rename); |
1001 // The first to run it will perform the operation and clean up the other | 637 installer_state.product().AppendRenameFlags(&product_rename_cmd); |
1002 // values. | 638 in_use_update_work_items->AddSetRegValueWorkItem( |
1003 if (dist->GetType() != BrowserDistribution::CHROME_BINARIES) { | 639 root, version_key, KEY_WOW64_32KEY, google_update::kRegRenameCmdField, |
1004 base::CommandLine product_rename_cmd(rename); | 640 product_rename_cmd.GetCommandLineString(), true); |
1005 products[i]->AppendRenameFlags(&product_rename_cmd); | |
1006 in_use_update_work_items->AddSetRegValueWorkItem( | |
1007 root, | |
1008 version_key, | |
1009 KEY_WOW64_32KEY, | |
1010 google_update::kRegRenameCmdField, | |
1011 product_rename_cmd.GetCommandLineString(), | |
1012 true); | |
1013 } | |
1014 } | |
1015 | 641 |
1016 post_install_task_list->AddWorkItem(in_use_update_work_items.release()); | 642 post_install_task_list->AddWorkItem(in_use_update_work_items.release()); |
1017 } | 643 } |
1018 | 644 |
1019 // Append work items that will be executed if this was NOT an in-use update. | 645 // Append work items that will be executed if this was NOT an in-use update. |
1020 { | 646 { |
1021 std::unique_ptr<WorkItemList> regular_update_work_items( | 647 std::unique_ptr<WorkItemList> regular_update_work_items( |
1022 WorkItem::CreateConditionalWorkItemList( | 648 WorkItem::CreateConditionalWorkItemList( |
1023 new Not(new ConditionRunIfFileExists(new_chrome_exe)))); | 649 new Not(new ConditionRunIfFileExists(new_chrome_exe)))); |
1024 regular_update_work_items->set_log_message("RegularUpdateWorkItemList"); | 650 regular_update_work_items->set_log_message("RegularUpdateWorkItemList"); |
1025 | 651 |
1026 // Since this was not an in-use-update, delete 'opv', 'cpv', and 'cmd' keys. | 652 // Since this was not an in-use-update, delete 'opv', 'cpv', and 'cmd' keys. |
1027 for (size_t i = 0; i < products.size(); ++i) { | 653 BrowserDistribution* dist = installer_state.product().distribution(); |
1028 BrowserDistribution* dist = products[i]->distribution(); | 654 const base::string16 version_key(dist->GetVersionKey()); |
1029 base::string16 version_key(dist->GetVersionKey()); | 655 regular_update_work_items->AddDeleteRegValueWorkItem( |
1030 regular_update_work_items->AddDeleteRegValueWorkItem( | 656 root, version_key, KEY_WOW64_32KEY, google_update::kRegOldVersionField); |
1031 root, | 657 regular_update_work_items->AddDeleteRegValueWorkItem( |
1032 version_key, | 658 root, version_key, KEY_WOW64_32KEY, |
1033 KEY_WOW64_32KEY, | 659 google_update::kRegCriticalVersionField); |
1034 google_update::kRegOldVersionField); | 660 regular_update_work_items->AddDeleteRegValueWorkItem( |
1035 regular_update_work_items->AddDeleteRegValueWorkItem( | 661 root, version_key, KEY_WOW64_32KEY, google_update::kRegRenameCmdField); |
1036 root, | |
1037 version_key, | |
1038 KEY_WOW64_32KEY, | |
1039 google_update::kRegCriticalVersionField); | |
1040 regular_update_work_items->AddDeleteRegValueWorkItem( | |
1041 root, | |
1042 version_key, | |
1043 KEY_WOW64_32KEY, | |
1044 google_update::kRegRenameCmdField); | |
1045 } | |
1046 | 662 |
1047 post_install_task_list->AddWorkItem(regular_update_work_items.release()); | 663 post_install_task_list->AddWorkItem(regular_update_work_items.release()); |
1048 } | 664 } |
1049 | 665 |
1050 AddRegisterComDllWorkItemsForPackage(installer_state, current_version, | |
1051 new_version, post_install_task_list); | |
1052 | |
1053 // If we're told that we're an MSI install, make sure to set the marker | 666 // If we're told that we're an MSI install, make sure to set the marker |
1054 // in the client state key so that future updates do the right thing. | 667 // in the client state key so that future updates do the right thing. |
1055 if (installer_state.is_msi()) { | 668 if (installer_state.is_msi()) { |
1056 for (size_t i = 0; i < products.size(); ++i) { | 669 const Product& product = installer_state.product(); |
1057 const Product* product = products[i]; | 670 AddSetMsiMarkerWorkItem(installer_state, product.distribution(), true, |
1058 AddSetMsiMarkerWorkItem(installer_state, product->distribution(), true, | 671 post_install_task_list); |
1059 post_install_task_list); | |
1060 | 672 |
1061 // We want MSI installs to take over the Add/Remove Programs entry. Make a | 673 // We want MSI installs to take over the Add/Remove Programs entry. Make a |
1062 // best-effort attempt to delete any entry left over from previous non-MSI | 674 // best-effort attempt to delete any entry left over from previous non-MSI |
1063 // installations for the same type of install (system or per user). | 675 // installations for the same type of install (system or per user). |
1064 if (product->ShouldCreateUninstallEntry()) { | 676 if (product.ShouldCreateUninstallEntry()) { |
1065 AddDeleteUninstallEntryForMSIWorkItems(installer_state, *product, | 677 AddDeleteUninstallEntryForMSIWorkItems(installer_state, product, |
1066 post_install_task_list); | 678 post_install_task_list); |
1067 } | |
1068 } | 679 } |
1069 } | 680 } |
1070 | 681 |
1071 return true; | 682 return true; |
1072 } | 683 } |
1073 | 684 |
1074 void AddInstallWorkItems(const InstallationState& original_state, | 685 void AddInstallWorkItems(const InstallationState& original_state, |
1075 const InstallerState& installer_state, | 686 const InstallerState& installer_state, |
1076 const base::FilePath& setup_path, | 687 const base::FilePath& setup_path, |
1077 const base::FilePath& archive_path, | 688 const base::FilePath& archive_path, |
(...skipping 24 matching lines...) Expand all Loading... |
1102 return AddAclToPath(histogram_storage_dir, | 713 return AddAclToPath(histogram_storage_dir, |
1103 ATL::Sids::AuthenticatedUser(), | 714 ATL::Sids::AuthenticatedUser(), |
1104 FILE_GENERIC_READ | FILE_DELETE_CHILD, | 715 FILE_GENERIC_READ | FILE_DELETE_CHILD, |
1105 CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE); | 716 CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE); |
1106 }, | 717 }, |
1107 histogram_storage_dir)); | 718 histogram_storage_dir)); |
1108 add_acl_to_histogram_storage_dir_work_item->set_best_effort(true); | 719 add_acl_to_histogram_storage_dir_work_item->set_best_effort(true); |
1109 add_acl_to_histogram_storage_dir_work_item->set_rollback_enabled(false); | 720 add_acl_to_histogram_storage_dir_work_item->set_rollback_enabled(false); |
1110 } | 721 } |
1111 | 722 |
1112 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER) || | 723 AddChromeWorkItems(original_state, installer_state, setup_path, archive_path, |
1113 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES)) { | 724 src_path, temp_path, current_version, new_version, |
1114 AddChromeWorkItems(original_state, | 725 install_list); |
1115 installer_state, | |
1116 setup_path, | |
1117 archive_path, | |
1118 src_path, | |
1119 temp_path, | |
1120 current_version, | |
1121 new_version, | |
1122 install_list); | |
1123 } | |
1124 | |
1125 #if defined(GOOGLE_CHROME_BUILD) | |
1126 // For Chrome, unconditionally remove the legacy app_host.exe. | |
1127 if (!InstallUtil::IsChromeSxSProcess()) | |
1128 AddRemoveLegacyAppHostExeWorkItems(target_path, temp_path, install_list); | |
1129 #endif // GOOGLE_CHROME_BUILD | |
1130 | 726 |
1131 // Copy installer in install directory | 727 // Copy installer in install directory |
1132 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, | 728 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, |
1133 new_version, install_list); | 729 new_version, install_list); |
1134 | 730 |
1135 const HKEY root = installer_state.root_key(); | 731 const HKEY root = installer_state.root_key(); |
1136 // Only set "lang" for user-level installs since for system-level, the install | 732 // Only set "lang" for user-level installs since for system-level, the install |
1137 // language may not be related to a given user's runtime language. | 733 // language may not be related to a given user's runtime language. |
1138 const bool add_language_identifier = !installer_state.system_install(); | 734 const bool add_language_identifier = !installer_state.system_install(); |
1139 | 735 |
1140 const Products& products = installer_state.products(); | 736 const Product& product = installer_state.product(); |
1141 for (Products::const_iterator it = products.begin(); it < products.end(); | 737 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, |
1142 ++it) { | 738 product, install_list); |
1143 const Product& product = **it; | |
1144 | 739 |
1145 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, | 740 BrowserDistribution* dist = product.distribution(); |
1146 product, install_list); | 741 AddVersionKeyWorkItems(root, dist->GetVersionKey(), dist->GetDisplayName(), |
| 742 new_version, add_language_identifier, install_list); |
1147 | 743 |
1148 BrowserDistribution* dist = product.distribution(); | 744 AddCleanupDelegateExecuteWorkItems(installer_state, product, install_list); |
1149 AddVersionKeyWorkItems(root, | 745 AddCleanupDeprecatedPerUserRegistrationsWorkItems(product, install_list); |
1150 dist->GetVersionKey(), | |
1151 dist->GetDisplayName(), | |
1152 new_version, | |
1153 add_language_identifier, | |
1154 install_list); | |
1155 | 746 |
1156 AddCleanupDelegateExecuteWorkItems(installer_state, product, install_list); | 747 AddActiveSetupWorkItems(installer_state, new_version, product, install_list); |
1157 AddCleanupDeprecatedPerUserRegistrationsWorkItems(product, install_list); | |
1158 | |
1159 AddActiveSetupWorkItems(installer_state, new_version, product, | |
1160 install_list); | |
1161 } | |
1162 | |
1163 // Ensure that the Clients key for the binaries is gone for single installs | |
1164 // (but not for SxS Chrome). | |
1165 if (!installer_state.is_multi_install() && | |
1166 !InstallUtil::IsChromeSxSProcess()) { | |
1167 BrowserDistribution* binaries_dist = | |
1168 BrowserDistribution::GetSpecificDistribution( | |
1169 BrowserDistribution::CHROME_BINARIES); | |
1170 install_list->AddDeleteRegKeyWorkItem(root, | |
1171 binaries_dist->GetVersionKey(), | |
1172 KEY_WOW64_32KEY); | |
1173 } | |
1174 | |
1175 #if defined(GOOGLE_CHROME_BUILD) | |
1176 if (!InstallUtil::IsChromeSxSProcess()) | |
1177 AddRemoveLegacyAppCommandsWorkItems(installer_state, install_list); | |
1178 #endif // GOOGLE_CHROME_BUILD | |
1179 | 748 |
1180 // Add any remaining work items that involve special settings for | 749 // Add any remaining work items that involve special settings for |
1181 // each product. | 750 // each product. |
1182 AddProductSpecificWorkItems(original_state, installer_state, setup_path, | 751 AddProductSpecificWorkItems(original_state, installer_state, setup_path, |
1183 new_version, current_version, | 752 new_version, current_version, |
1184 add_language_identifier, install_list); | 753 add_language_identifier, install_list); |
1185 | 754 |
1186 // Copy over brand, usagestats, and other values. | |
1187 AddGoogleUpdateWorkItems(original_state, installer_state, install_list); | |
1188 | |
1189 // Migrate usagestats back to Chrome. | 755 // Migrate usagestats back to Chrome. |
1190 AddMigrateUsageStatesWorkItems(original_state, installer_state, install_list); | 756 AddMigrateUsageStatsWorkItems(original_state, installer_state, install_list); |
1191 | 757 |
1192 // Append the tasks that run after the installation. | 758 // Append the tasks that run after the installation. |
1193 AppendPostInstallTasks(installer_state, | 759 AppendPostInstallTasks(installer_state, |
1194 setup_path, | 760 setup_path, |
1195 current_version, | 761 current_version, |
1196 new_version, | 762 new_version, |
1197 install_list); | 763 install_list); |
1198 } | 764 } |
1199 | 765 |
1200 void AddRegisterComDllWorkItems(const base::FilePath& dll_folder, | |
1201 const std::vector<base::FilePath>& dll_list, | |
1202 bool system_level, | |
1203 bool do_register, | |
1204 bool best_effort, | |
1205 WorkItemList* work_item_list) { | |
1206 DCHECK(work_item_list); | |
1207 if (dll_list.empty()) { | |
1208 VLOG(1) << "No COM DLLs to register"; | |
1209 } else { | |
1210 std::vector<base::FilePath>::const_iterator dll_iter(dll_list.begin()); | |
1211 for (; dll_iter != dll_list.end(); ++dll_iter) { | |
1212 base::FilePath dll_path = dll_folder.Append(*dll_iter); | |
1213 WorkItem* work_item = work_item_list->AddSelfRegWorkItem( | |
1214 dll_path.value(), do_register, !system_level); | |
1215 DCHECK(work_item); | |
1216 work_item->set_best_effort(best_effort); | |
1217 } | |
1218 } | |
1219 } | |
1220 | |
1221 void AddSetMsiMarkerWorkItem(const InstallerState& installer_state, | 766 void AddSetMsiMarkerWorkItem(const InstallerState& installer_state, |
1222 BrowserDistribution* dist, | 767 BrowserDistribution* dist, |
1223 bool set, | 768 bool set, |
1224 WorkItemList* work_item_list) { | 769 WorkItemList* work_item_list) { |
1225 DCHECK(work_item_list); | 770 DCHECK(work_item_list); |
1226 DWORD msi_value = set ? 1 : 0; | 771 DWORD msi_value = set ? 1 : 0; |
1227 WorkItem* set_msi_work_item = | 772 WorkItem* set_msi_work_item = |
1228 work_item_list->AddSetRegValueWorkItem(installer_state.root_key(), | 773 work_item_list->AddSetRegValueWorkItem(installer_state.root_key(), |
1229 dist->GetStateKey(), | 774 dist->GetStateKey(), |
1230 KEY_WOW64_32KEY, | 775 KEY_WOW64_32KEY, |
1231 google_update::kRegMSIField, | 776 google_update::kRegMSIField, |
1232 msi_value, | 777 msi_value, |
1233 true); | 778 true); |
1234 DCHECK(set_msi_work_item); | 779 DCHECK(set_msi_work_item); |
1235 set_msi_work_item->set_best_effort(true); | 780 set_msi_work_item->set_best_effort(true); |
1236 set_msi_work_item->set_log_message("Could not write MSI marker!"); | 781 set_msi_work_item->set_log_message("Could not write MSI marker!"); |
1237 } | 782 } |
1238 | 783 |
1239 void AddCleanupDeprecatedPerUserRegistrationsWorkItems(const Product& product, | 784 void AddCleanupDeprecatedPerUserRegistrationsWorkItems(const Product& product, |
1240 WorkItemList* list) { | 785 WorkItemList* list) { |
1241 if (product.is_chrome()) { | 786 BrowserDistribution* dist = product.distribution(); |
1242 BrowserDistribution* dist = product.distribution(); | |
1243 | 787 |
1244 // TODO(gab): Remove cleanup code for Metro after M53. | 788 // TODO(gab): Remove cleanup code for Metro after M53. |
1245 VLOG(1) << "Adding unregistration items for per-user Metro keys."; | 789 VLOG(1) << "Adding unregistration items for per-user Metro keys."; |
1246 list->AddDeleteRegKeyWorkItem(HKEY_CURRENT_USER, | 790 list->AddDeleteRegKeyWorkItem( |
1247 dist->GetRegistryPath() + L"\\Metro", | 791 HKEY_CURRENT_USER, dist->GetRegistryPath() + L"\\Metro", KEY_WOW64_32KEY); |
1248 KEY_WOW64_32KEY); | 792 list->AddDeleteRegKeyWorkItem( |
1249 list->AddDeleteRegKeyWorkItem(HKEY_CURRENT_USER, | 793 HKEY_CURRENT_USER, dist->GetRegistryPath() + L"\\Metro", KEY_WOW64_64KEY); |
1250 dist->GetRegistryPath() + L"\\Metro", | |
1251 KEY_WOW64_64KEY); | |
1252 } | |
1253 } | 794 } |
1254 | 795 |
1255 void AddActiveSetupWorkItems(const InstallerState& installer_state, | 796 void AddActiveSetupWorkItems(const InstallerState& installer_state, |
1256 const base::Version& new_version, | 797 const base::Version& new_version, |
1257 const Product& product, | 798 const Product& product, |
1258 WorkItemList* list) { | 799 WorkItemList* list) { |
1259 DCHECK(installer_state.operation() != InstallerState::UNINSTALL); | 800 DCHECK(installer_state.operation() != InstallerState::UNINSTALL); |
1260 BrowserDistribution* dist = product.distribution(); | 801 BrowserDistribution* dist = product.distribution(); |
1261 | 802 |
1262 if (!product.is_chrome() || !installer_state.system_install()) { | 803 if (!installer_state.system_install()) { |
1263 const char* install_level = | 804 const char* install_level = |
1264 installer_state.system_install() ? "system" : "user"; | 805 installer_state.system_install() ? "system" : "user"; |
1265 VLOG(1) << "No Active Setup processing to do for " << install_level | 806 VLOG(1) << "No Active Setup processing to do for " << install_level |
1266 << "-level " << dist->GetDisplayName(); | 807 << "-level " << dist->GetDisplayName(); |
1267 return; | 808 return; |
1268 } | 809 } |
1269 DCHECK(installer_state.RequiresActiveSetup()); | 810 DCHECK(installer_state.RequiresActiveSetup()); |
1270 | 811 |
1271 const HKEY root = HKEY_LOCAL_MACHINE; | 812 const HKEY root = HKEY_LOCAL_MACHINE; |
1272 const base::string16 active_setup_path(InstallUtil::GetActiveSetupPath(dist)); | 813 const base::string16 active_setup_path(InstallUtil::GetActiveSetupPath(dist)); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 active_setup_path, | 849 active_setup_path, |
1309 WorkItem::kWow64Default, | 850 WorkItem::kWow64Default, |
1310 L"IsInstalled", | 851 L"IsInstalled", |
1311 static_cast<DWORD>(1U), | 852 static_cast<DWORD>(1U), |
1312 true); | 853 true); |
1313 | 854 |
1314 list->AddWorkItem(new UpdateActiveSetupVersionWorkItem( | 855 list->AddWorkItem(new UpdateActiveSetupVersionWorkItem( |
1315 active_setup_path, UpdateActiveSetupVersionWorkItem::UPDATE)); | 856 active_setup_path, UpdateActiveSetupVersionWorkItem::UPDATE)); |
1316 } | 857 } |
1317 | 858 |
1318 void AddDeleteOldIELowRightsPolicyWorkItems( | |
1319 const InstallerState& installer_state, | |
1320 WorkItemList* install_list) { | |
1321 DCHECK(install_list); | |
1322 | |
1323 base::string16 key_path; | |
1324 GetOldIELowRightsElevationPolicyKeyPath(&key_path); | |
1325 install_list->AddDeleteRegKeyWorkItem( | |
1326 installer_state.root_key(), key_path, WorkItem::kWow64Default); | |
1327 } | |
1328 | |
1329 void AppendUninstallCommandLineFlags(const InstallerState& installer_state, | 859 void AppendUninstallCommandLineFlags(const InstallerState& installer_state, |
1330 const Product& product, | 860 const Product& product, |
1331 base::CommandLine* uninstall_cmd) { | 861 base::CommandLine* uninstall_cmd) { |
1332 DCHECK(uninstall_cmd); | 862 DCHECK(uninstall_cmd); |
1333 | 863 |
1334 uninstall_cmd->AppendSwitch(installer::switches::kUninstall); | 864 uninstall_cmd->AppendSwitch(installer::switches::kUninstall); |
1335 | 865 |
1336 // Append the product-specific uninstall flags. | 866 // Append the product-specific uninstall flags. |
1337 product.AppendProductFlags(uninstall_cmd); | 867 product.AppendProductFlags(uninstall_cmd); |
1338 if (installer_state.is_msi()) | 868 if (installer_state.is_msi()) |
1339 uninstall_cmd->AppendSwitch(installer::switches::kMsi); | 869 uninstall_cmd->AppendSwitch(installer::switches::kMsi); |
1340 if (installer_state.system_install()) | 870 if (installer_state.system_install()) |
1341 uninstall_cmd->AppendSwitch(installer::switches::kSystemLevel); | 871 uninstall_cmd->AppendSwitch(installer::switches::kSystemLevel); |
1342 if (installer_state.verbose_logging()) | 872 if (installer_state.verbose_logging()) |
1343 uninstall_cmd->AppendSwitch(installer::switches::kVerboseLogging); | 873 uninstall_cmd->AppendSwitch(installer::switches::kVerboseLogging); |
1344 } | 874 } |
1345 | 875 |
1346 void RefreshElevationPolicy() { | |
1347 const wchar_t kIEFrameDll[] = L"ieframe.dll"; | |
1348 const char kIERefreshPolicy[] = "IERefreshElevationPolicy"; | |
1349 | |
1350 HMODULE ieframe = LoadLibrary(kIEFrameDll); | |
1351 if (ieframe) { | |
1352 typedef HRESULT (__stdcall *IERefreshPolicy)(); | |
1353 IERefreshPolicy ie_refresh_policy = reinterpret_cast<IERefreshPolicy>( | |
1354 GetProcAddress(ieframe, kIERefreshPolicy)); | |
1355 | |
1356 if (ie_refresh_policy) { | |
1357 ie_refresh_policy(); | |
1358 } else { | |
1359 VLOG(1) << kIERefreshPolicy << " not supported."; | |
1360 } | |
1361 | |
1362 FreeLibrary(ieframe); | |
1363 } else { | |
1364 VLOG(1) << "Cannot load " << kIEFrameDll; | |
1365 } | |
1366 } | |
1367 | |
1368 void AddOsUpgradeWorkItems(const InstallerState& installer_state, | 876 void AddOsUpgradeWorkItems(const InstallerState& installer_state, |
1369 const base::FilePath& setup_path, | 877 const base::FilePath& setup_path, |
1370 const base::Version& new_version, | 878 const base::Version& new_version, |
1371 const Product& product, | 879 const Product& product, |
1372 WorkItemList* install_list) { | 880 WorkItemList* install_list) { |
1373 const HKEY root_key = installer_state.root_key(); | 881 const HKEY root_key = installer_state.root_key(); |
1374 base::string16 cmd_key( | 882 base::string16 cmd_key( |
1375 GetRegCommandKey(product.distribution(), kCmdOnOsUpgrade)); | 883 GetRegCommandKey(product.distribution(), kCmdOnOsUpgrade)); |
1376 | 884 |
1377 if (installer_state.operation() == InstallerState::UNINSTALL) { | 885 if (installer_state.operation() == InstallerState::UNINSTALL) { |
(...skipping 13 matching lines...) Expand all Loading... |
1391 cmd_line.AppendSwitch(installer::switches::kSystemLevel); | 899 cmd_line.AppendSwitch(installer::switches::kSystemLevel); |
1392 // Log everything for now. | 900 // Log everything for now. |
1393 cmd_line.AppendSwitch(installer::switches::kVerboseLogging); | 901 cmd_line.AppendSwitch(installer::switches::kVerboseLogging); |
1394 | 902 |
1395 AppCommand cmd(cmd_line.GetCommandLineString()); | 903 AppCommand cmd(cmd_line.GetCommandLineString()); |
1396 cmd.set_is_auto_run_on_os_upgrade(true); | 904 cmd.set_is_auto_run_on_os_upgrade(true); |
1397 cmd.AddWorkItems(installer_state.root_key(), cmd_key, install_list); | 905 cmd.AddWorkItems(installer_state.root_key(), cmd_key, install_list); |
1398 } | 906 } |
1399 } | 907 } |
1400 | 908 |
1401 void AddQuickEnableChromeFrameWorkItems(const InstallerState& installer_state, | |
1402 WorkItemList* work_item_list) { | |
1403 DCHECK(work_item_list); | |
1404 | |
1405 base::string16 cmd_key( | |
1406 GetRegCommandKey(BrowserDistribution::GetSpecificDistribution( | |
1407 BrowserDistribution::CHROME_BINARIES), | |
1408 kCmdQuickEnableCf)); | |
1409 | |
1410 // Unconditionally remove the legacy Quick Enable command from the binaries. | |
1411 // Do this even if multi-install Chrome isn't installed to ensure that it is | |
1412 // not left behind in any case. | |
1413 work_item_list->AddDeleteRegKeyWorkItem( | |
1414 installer_state.root_key(), cmd_key, KEY_WOW64_32KEY) | |
1415 ->set_log_message("removing " + base::UTF16ToASCII(kCmdQuickEnableCf) + | |
1416 " command"); | |
1417 } | |
1418 | |
1419 } // namespace installer | 909 } // namespace installer |
OLD | NEW |