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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 bool is_new_install, | 154 bool is_new_install, |
221 WorkItemList* list) { | 155 WorkItemList* list) { |
222 list->AddCallbackWorkItem( | 156 list->AddCallbackWorkItem( |
223 base::Bind(&AddFirewallRulesCallback, | 157 base::Bind(&AddFirewallRulesCallback, |
224 installer_state.system_install(), | 158 installer_state.system_install(), |
225 dist, | 159 dist, |
226 installer_state.target_path().Append(kChromeExe), | 160 installer_state.target_path().Append(kChromeExe), |
227 is_new_install)); | 161 is_new_install)); |
228 } | 162 } |
229 | 163 |
230 void AddProductSpecificWorkItems(const InstallationState& original_state, | |
231 const InstallerState& installer_state, | |
232 const base::FilePath& setup_path, | |
233 const base::Version& new_version, | |
234 const base::Version* current_version, | |
235 bool add_language_identifier, | |
236 WorkItemList* list) { | |
237 const Products& products = installer_state.products(); | |
238 for (Products::const_iterator it = products.begin(); it < products.end(); | |
239 ++it) { | |
240 const Product& p = **it; | |
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 | |
247 #if defined(GOOGLE_CHROME_BUILD) | |
248 if (!InstallUtil::IsChromeSxSProcess()) { | |
249 // Remove the app launcher key as it has been deprecated. | |
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 } | |
261 | |
262 // This is called when an MSI installation is run. It may be that a user is | 164 // 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 | 165 // 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 | 166 // 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 | 167 // uninstall to be managed entirely by the MSI machinery (accessible via the |
266 // Add/Remove programs dialog). | 168 // Add/Remove programs dialog). |
267 void AddDeleteUninstallEntryForMSIWorkItems( | 169 void AddDeleteUninstallEntryForMSIWorkItems( |
268 const InstallerState& installer_state, | 170 const InstallerState& installer_state, |
269 const Product& product, | 171 const Product& product, |
270 WorkItemList* work_item_list) { | 172 WorkItemList* work_item_list) { |
271 DCHECK(installer_state.is_msi()) | 173 DCHECK(installer_state.is_msi()) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 delete_old_archive_work_item->set_rollback_enabled(false); | 211 delete_old_archive_work_item->set_rollback_enabled(false); |
310 } | 212 } |
311 } | 213 } |
312 | 214 |
313 // Delete any new_chrome.exe if present (we will end up creating a new one | 215 // Delete any new_chrome.exe if present (we will end up creating a new one |
314 // if required) and then copy chrome.exe | 216 // if required) and then copy chrome.exe |
315 base::FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe)); | 217 base::FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe)); |
316 | 218 |
317 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); | 219 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); |
318 | 220 |
319 // TODO(grt): Remove this check in M35. | 221 install_list->AddCopyTreeWorkItem( |
320 if (installer_state.IsChromeFrameRunning(original_state)) { | 222 src_path.Append(installer::kChromeExe).value(), |
321 VLOG(1) << "Chrome Frame in use. Copying to new_chrome.exe"; | 223 target_path.Append(installer::kChromeExe).value(), temp_path.value(), |
322 install_list->AddCopyTreeWorkItem( | 224 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 | 225 |
336 // Install kVisualElementsManifest if it is present in |src_path|. No need to | 226 // 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 | 227 // make this a conditional work item as if the file is not there now, it will |
338 // never be. | 228 // never be. |
339 if (base::PathExists( | 229 if (base::PathExists( |
340 src_path.Append(installer::kVisualElementsManifest))) { | 230 src_path.Append(installer::kVisualElementsManifest))) { |
341 install_list->AddMoveTreeWorkItem( | 231 install_list->AddMoveTreeWorkItem( |
342 src_path.Append(installer::kVisualElementsManifest).value(), | 232 src_path.Append(installer::kVisualElementsManifest).value(), |
343 target_path.Append(installer::kVisualElementsManifest).value(), | 233 target_path.Append(installer::kVisualElementsManifest).value(), |
344 temp_path.value(), | 234 temp_path.value(), |
(...skipping 26 matching lines...) Expand all Loading... | |
371 ->AddDeleteTreeWorkItem(target_path.Append(installer::kChromeOldExe), | 261 ->AddDeleteTreeWorkItem(target_path.Append(installer::kChromeOldExe), |
372 temp_path) | 262 temp_path) |
373 ->set_best_effort(true); | 263 ->set_best_effort(true); |
374 } | 264 } |
375 | 265 |
376 // Adds work items to remove COM registration for |product|'s deprecated | 266 // Adds work items to remove COM registration for |product|'s deprecated |
377 // DelegateExecute verb handler. | 267 // DelegateExecute verb handler. |
378 void AddCleanupDelegateExecuteWorkItems(const InstallerState& installer_state, | 268 void AddCleanupDelegateExecuteWorkItems(const InstallerState& installer_state, |
379 const Product& product, | 269 const Product& product, |
380 WorkItemList* list) { | 270 WorkItemList* list) { |
381 if (product.is_chrome()) { | 271 VLOG(1) << "Adding unregistration items for DelegateExecute verb handler."; |
382 VLOG(1) << "Adding unregistration items for DelegateExecute verb handler."; | 272 const base::string16 handler_class_uuid = |
383 const base::string16 handler_class_uuid = | 273 product.distribution()->GetCommandExecuteImplClsid(); |
384 product.distribution()->GetCommandExecuteImplClsid(); | 274 DCHECK(!handler_class_uuid.empty()); |
385 DCHECK(!handler_class_uuid.empty()); | |
386 | 275 |
387 const HKEY root = installer_state.root_key(); | 276 const HKEY root = installer_state.root_key(); |
388 base::string16 delegate_execute_path(L"Software\\Classes\\CLSID\\"); | 277 base::string16 delegate_execute_path(L"Software\\Classes\\CLSID\\"); |
389 delegate_execute_path.append(handler_class_uuid); | 278 delegate_execute_path.append(handler_class_uuid); |
390 // Delete both 64 and 32 keys to handle 32->64 or 64->32 migration. | 279 // Delete both 64 and 32 keys to handle 32->64 or 64->32 migration. |
391 list->AddDeleteRegKeyWorkItem(root, delegate_execute_path, KEY_WOW64_32KEY); | 280 list->AddDeleteRegKeyWorkItem(root, delegate_execute_path, KEY_WOW64_32KEY); |
392 list->AddDeleteRegKeyWorkItem(root, delegate_execute_path, KEY_WOW64_64KEY); | 281 list->AddDeleteRegKeyWorkItem(root, delegate_execute_path, KEY_WOW64_64KEY); |
393 } | |
394 } | 282 } |
395 | 283 |
396 // Add to the ACL of an object on disk. This follows the method from MSDN: | 284 // 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 | 285 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa379283.aspx |
398 // This is done using explicit flags rather than the "security string" format | 286 // 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 | 287 // 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 | 288 // difficult to de-dup. Working with the binary format is always exact and the |
401 // system libraries will properly ignore duplicate ACL entries. | 289 // system libraries will properly ignore duplicate ACL entries. |
402 bool AddAclToPath(const base::FilePath& path, | 290 bool AddAclToPath(const base::FilePath& path, |
403 const CSid& trustee, | 291 const CSid& trustee, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 | 323 |
436 // Attach the updated ACL as the object's DACL. | 324 // Attach the updated ACL as the object's DACL. |
437 if (!ATL::AtlSetDacl(path.value().c_str(), SE_FILE_OBJECT, dacl)) { | 325 if (!ATL::AtlSetDacl(path.value().c_str(), SE_FILE_OBJECT, dacl)) { |
438 DPLOG(ERROR) << "Failed setting DACL for path \"" << path.value() << "\""; | 326 DPLOG(ERROR) << "Failed setting DACL for path \"" << path.value() << "\""; |
439 return false; | 327 return false; |
440 } | 328 } |
441 | 329 |
442 return true; | 330 return true; |
443 } | 331 } |
444 | 332 |
333 // Migrates the usagestats value from the binaries to Chrome when migrating | |
334 // multi-install Chrome to single-install. | |
335 void AddMigrateUsageStatsWorkItems(const InstallationState& original_state, | |
336 const InstallerState& installer_state, | |
337 WorkItemList* install_list) { | |
338 // This operation doesn't apply to SxS Chrome. | |
339 if (InstallUtil::IsChromeSxSProcess()) | |
340 return; | |
341 | |
342 // Bail out if an existing multi-install Chrome is not being migrated to | |
343 // single-install. | |
344 if (!installer_state.is_migrating_to_single()) { | |
345 VLOG(1) << "No multi-install Chrome found to migrate to single-install."; | |
346 return; | |
347 } | |
348 | |
349 const ProductState* binaries_state = original_state.GetProductState( | |
350 installer_state.system_install(), BrowserDistribution::CHROME_BINARIES); | |
351 | |
352 // There is nothing to be done if the binaries do not have stats. | |
353 DWORD usagestats = 0; | |
354 if (!binaries_state || !binaries_state->GetUsageStats(&usagestats)) { | |
355 VLOG(1) << "No usagestats value found to migrate to single-install."; | |
356 return; | |
357 } | |
358 | |
359 VLOG(1) << "Migrating usagestats value from multi-install to single-install."; | |
360 | |
361 // Write the value that was read to Chrome's ClientState key. | |
362 install_list->AddSetRegValueWorkItem( | |
363 installer_state.root_key(), | |
364 installer_state.product().distribution()->GetStateKey(), KEY_WOW64_32KEY, | |
365 google_update::kRegUsageStatsField, usagestats, true); | |
366 } | |
367 | |
445 } // namespace | 368 } // namespace |
446 | 369 |
447 // This method adds work items to create (or update) Chrome uninstall entry in | 370 // 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 | 371 // either the Control Panel->Add/Remove Programs list or in the Omaha client |
449 // state key if running under an MSI installer. | 372 // state key if running under an MSI installer. |
450 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, | 373 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, |
451 const base::FilePath& setup_path, | 374 const base::FilePath& setup_path, |
452 const base::Version& new_version, | 375 const base::Version& new_version, |
453 const Product& product, | 376 const Product& product, |
454 WorkItemList* install_list) { | 377 WorkItemList* install_list) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
627 false); // do not overwrite language | 550 false); // do not overwrite language |
628 } | 551 } |
629 list->AddSetRegValueWorkItem(root, | 552 list->AddSetRegValueWorkItem(root, |
630 version_key, | 553 version_key, |
631 KEY_WOW64_32KEY, | 554 KEY_WOW64_32KEY, |
632 google_update::kRegVersionField, | 555 google_update::kRegVersionField, |
633 ASCIIToUTF16(new_version.GetString()), | 556 ASCIIToUTF16(new_version.GetString()), |
634 true); // overwrite version | 557 true); // overwrite version |
635 } | 558 } |
636 | 559 |
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, | 560 bool AppendPostInstallTasks(const InstallerState& installer_state, |
931 const base::FilePath& setup_path, | 561 const base::FilePath& setup_path, |
932 const base::Version* current_version, | 562 const base::Version* current_version, |
933 const base::Version& new_version, | 563 const base::Version& new_version, |
934 WorkItemList* post_install_task_list) { | 564 WorkItemList* post_install_task_list) { |
935 DCHECK(post_install_task_list); | 565 DCHECK(post_install_task_list); |
936 | 566 |
937 HKEY root = installer_state.root_key(); | 567 HKEY root = installer_state.root_key(); |
938 const Products& products = installer_state.products(); | |
939 base::FilePath new_chrome_exe( | 568 base::FilePath new_chrome_exe( |
940 installer_state.target_path().Append(installer::kChromeNewExe)); | 569 installer_state.target_path().Append(installer::kChromeNewExe)); |
941 | 570 |
942 // Append work items that will only be executed if this was an update. | 571 // 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, | 572 // 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 | 573 // the 'cpv' value with the critical update version (if present), and the |
945 // 'cmd' value with the rename command to run. | 574 // 'cmd' value with the rename command to run. |
946 { | 575 { |
947 std::unique_ptr<WorkItemList> in_use_update_work_items( | 576 std::unique_ptr<WorkItemList> in_use_update_work_items( |
948 WorkItem::CreateConditionalWorkItemList( | 577 WorkItem::CreateConditionalWorkItemList( |
949 new ConditionRunIfFileExists(new_chrome_exe))); | 578 new ConditionRunIfFileExists(new_chrome_exe))); |
950 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); | 579 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); |
951 | 580 |
952 // |critical_version| will be valid only if this in-use update includes a | 581 // |critical_version| will be valid only if this in-use update includes a |
953 // version considered critical relative to the version being updated. | 582 // version considered critical relative to the version being updated. |
954 base::Version critical_version(installer_state.DetermineCriticalVersion( | 583 base::Version critical_version(installer_state.DetermineCriticalVersion( |
955 current_version, new_version)); | 584 current_version, new_version)); |
956 base::FilePath installer_path( | 585 base::FilePath installer_path( |
957 installer_state.GetInstallerDirectory(new_version).Append( | 586 installer_state.GetInstallerDirectory(new_version).Append( |
958 setup_path.BaseName())); | 587 setup_path.BaseName())); |
959 | 588 |
960 base::CommandLine rename(installer_path); | 589 base::CommandLine rename(installer_path); |
961 rename.AppendSwitch(switches::kRenameChromeExe); | 590 rename.AppendSwitch(switches::kRenameChromeExe); |
962 if (installer_state.system_install()) | 591 if (installer_state.system_install()) |
963 rename.AppendSwitch(switches::kSystemLevel); | 592 rename.AppendSwitch(switches::kSystemLevel); |
964 | 593 |
965 if (installer_state.verbose_logging()) | 594 if (installer_state.verbose_logging()) |
966 rename.AppendSwitch(switches::kVerboseLogging); | 595 rename.AppendSwitch(switches::kVerboseLogging); |
967 | 596 |
968 base::string16 version_key; | 597 BrowserDistribution* dist = installer_state.product().distribution(); |
969 for (size_t i = 0; i < products.size(); ++i) { | 598 const base::string16 version_key = dist->GetVersionKey(); |
huangs
2017/01/06 17:57:17
NIT: Does same thing as line 637 but looks differe
grt (UTC plus 2)
2017/01/06 21:15:46
Done.
| |
970 BrowserDistribution* dist = products[i]->distribution(); | |
971 version_key = dist->GetVersionKey(); | |
972 | 599 |
973 if (current_version) { | 600 if (current_version) { |
974 in_use_update_work_items->AddSetRegValueWorkItem( | 601 in_use_update_work_items->AddSetRegValueWorkItem( |
975 root, | 602 root, version_key, KEY_WOW64_32KEY, |
976 version_key, | 603 google_update::kRegOldVersionField, |
977 KEY_WOW64_32KEY, | 604 ASCIIToUTF16(current_version->GetString()), true); |
978 google_update::kRegOldVersionField, | 605 } |
979 ASCIIToUTF16(current_version->GetString()), | 606 if (critical_version.IsValid()) { |
980 true); | 607 in_use_update_work_items->AddSetRegValueWorkItem( |
981 } | 608 root, version_key, KEY_WOW64_32KEY, |
982 if (critical_version.IsValid()) { | 609 google_update::kRegCriticalVersionField, |
983 in_use_update_work_items->AddSetRegValueWorkItem( | 610 ASCIIToUTF16(critical_version.GetString()), true); |
984 root, | 611 } else { |
985 version_key, | 612 in_use_update_work_items->AddDeleteRegValueWorkItem( |
986 KEY_WOW64_32KEY, | 613 root, version_key, KEY_WOW64_32KEY, |
987 google_update::kRegCriticalVersionField, | 614 google_update::kRegCriticalVersionField); |
988 ASCIIToUTF16(critical_version.GetString()), | 615 } |
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 | 616 |
998 // Adding this registry entry for all products (but the binaries) is | 617 // 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 | 618 // "--chrome-sxs" for SxS/canary). |
1000 // product will check the key and run the command, so we add it for all. | 619 base::CommandLine product_rename_cmd(rename); |
1001 // The first to run it will perform the operation and clean up the other | 620 installer_state.product().AppendRenameFlags(&product_rename_cmd); |
1002 // values. | 621 in_use_update_work_items->AddSetRegValueWorkItem( |
1003 if (dist->GetType() != BrowserDistribution::CHROME_BINARIES) { | 622 root, version_key, KEY_WOW64_32KEY, google_update::kRegRenameCmdField, |
1004 base::CommandLine product_rename_cmd(rename); | 623 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 | 624 |
1016 post_install_task_list->AddWorkItem(in_use_update_work_items.release()); | 625 post_install_task_list->AddWorkItem(in_use_update_work_items.release()); |
1017 } | 626 } |
1018 | 627 |
1019 // Append work items that will be executed if this was NOT an in-use update. | 628 // Append work items that will be executed if this was NOT an in-use update. |
1020 { | 629 { |
1021 std::unique_ptr<WorkItemList> regular_update_work_items( | 630 std::unique_ptr<WorkItemList> regular_update_work_items( |
1022 WorkItem::CreateConditionalWorkItemList( | 631 WorkItem::CreateConditionalWorkItemList( |
1023 new Not(new ConditionRunIfFileExists(new_chrome_exe)))); | 632 new Not(new ConditionRunIfFileExists(new_chrome_exe)))); |
1024 regular_update_work_items->set_log_message("RegularUpdateWorkItemList"); | 633 regular_update_work_items->set_log_message("RegularUpdateWorkItemList"); |
1025 | 634 |
1026 // Since this was not an in-use-update, delete 'opv', 'cpv', and 'cmd' keys. | 635 // Since this was not an in-use-update, delete 'opv', 'cpv', and 'cmd' keys. |
1027 for (size_t i = 0; i < products.size(); ++i) { | 636 BrowserDistribution* dist = installer_state.product().distribution(); |
1028 BrowserDistribution* dist = products[i]->distribution(); | 637 const base::string16 version_key(dist->GetVersionKey()); |
1029 base::string16 version_key(dist->GetVersionKey()); | 638 regular_update_work_items->AddDeleteRegValueWorkItem( |
1030 regular_update_work_items->AddDeleteRegValueWorkItem( | 639 root, version_key, KEY_WOW64_32KEY, google_update::kRegOldVersionField); |
1031 root, | 640 regular_update_work_items->AddDeleteRegValueWorkItem( |
1032 version_key, | 641 root, version_key, KEY_WOW64_32KEY, |
1033 KEY_WOW64_32KEY, | 642 google_update::kRegCriticalVersionField); |
1034 google_update::kRegOldVersionField); | 643 regular_update_work_items->AddDeleteRegValueWorkItem( |
1035 regular_update_work_items->AddDeleteRegValueWorkItem( | 644 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 | 645 |
1047 post_install_task_list->AddWorkItem(regular_update_work_items.release()); | 646 post_install_task_list->AddWorkItem(regular_update_work_items.release()); |
1048 } | 647 } |
1049 | 648 |
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 | 649 // 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. | 650 // in the client state key so that future updates do the right thing. |
1055 if (installer_state.is_msi()) { | 651 if (installer_state.is_msi()) { |
1056 for (size_t i = 0; i < products.size(); ++i) { | 652 const Product& product = installer_state.product(); |
1057 const Product* product = products[i]; | 653 AddSetMsiMarkerWorkItem(installer_state, product.distribution(), true, |
1058 AddSetMsiMarkerWorkItem(installer_state, product->distribution(), true, | 654 post_install_task_list); |
1059 post_install_task_list); | |
1060 | 655 |
1061 // We want MSI installs to take over the Add/Remove Programs entry. Make a | 656 // 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 | 657 // 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). | 658 // installations for the same type of install (system or per user). |
1064 if (product->ShouldCreateUninstallEntry()) { | 659 if (product.ShouldCreateUninstallEntry()) { |
1065 AddDeleteUninstallEntryForMSIWorkItems(installer_state, *product, | 660 AddDeleteUninstallEntryForMSIWorkItems(installer_state, product, |
1066 post_install_task_list); | 661 post_install_task_list); |
1067 } | |
1068 } | 662 } |
1069 } | 663 } |
1070 | 664 |
1071 return true; | 665 return true; |
1072 } | 666 } |
1073 | 667 |
1074 void AddInstallWorkItems(const InstallationState& original_state, | 668 void AddInstallWorkItems(const InstallationState& original_state, |
1075 const InstallerState& installer_state, | 669 const InstallerState& installer_state, |
1076 const base::FilePath& setup_path, | 670 const base::FilePath& setup_path, |
1077 const base::FilePath& archive_path, | 671 const base::FilePath& archive_path, |
(...skipping 24 matching lines...) Expand all Loading... | |
1102 return AddAclToPath(histogram_storage_dir, | 696 return AddAclToPath(histogram_storage_dir, |
1103 ATL::Sids::AuthenticatedUser(), | 697 ATL::Sids::AuthenticatedUser(), |
1104 FILE_GENERIC_READ | FILE_DELETE_CHILD, | 698 FILE_GENERIC_READ | FILE_DELETE_CHILD, |
1105 CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE); | 699 CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE); |
1106 }, | 700 }, |
1107 histogram_storage_dir)); | 701 histogram_storage_dir)); |
1108 add_acl_to_histogram_storage_dir_work_item->set_best_effort(true); | 702 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); | 703 add_acl_to_histogram_storage_dir_work_item->set_rollback_enabled(false); |
1110 } | 704 } |
1111 | 705 |
1112 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER) || | 706 AddChromeWorkItems(original_state, installer_state, setup_path, archive_path, |
1113 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES)) { | 707 src_path, temp_path, current_version, new_version, |
1114 AddChromeWorkItems(original_state, | 708 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 | 709 |
1131 // Copy installer in install directory | 710 // Copy installer in install directory |
1132 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, | 711 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, |
1133 new_version, install_list); | 712 new_version, install_list); |
1134 | 713 |
1135 const HKEY root = installer_state.root_key(); | 714 const HKEY root = installer_state.root_key(); |
1136 // Only set "lang" for user-level installs since for system-level, the install | 715 // 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. | 716 // language may not be related to a given user's runtime language. |
1138 const bool add_language_identifier = !installer_state.system_install(); | 717 const bool add_language_identifier = !installer_state.system_install(); |
1139 | 718 |
1140 const Products& products = installer_state.products(); | 719 const Product& product = installer_state.product(); |
1141 for (Products::const_iterator it = products.begin(); it < products.end(); | 720 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, |
1142 ++it) { | 721 product, install_list); |
1143 const Product& product = **it; | |
1144 | 722 |
1145 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, | 723 BrowserDistribution* dist = product.distribution(); |
1146 product, install_list); | 724 AddVersionKeyWorkItems(root, dist->GetVersionKey(), dist->GetDisplayName(), |
725 new_version, add_language_identifier, install_list); | |
1147 | 726 |
1148 BrowserDistribution* dist = product.distribution(); | 727 AddCleanupDelegateExecuteWorkItems(installer_state, product, install_list); |
1149 AddVersionKeyWorkItems(root, | 728 AddCleanupDeprecatedPerUserRegistrationsWorkItems(product, install_list); |
1150 dist->GetVersionKey(), | |
1151 dist->GetDisplayName(), | |
1152 new_version, | |
1153 add_language_identifier, | |
1154 install_list); | |
1155 | 729 |
1156 AddCleanupDelegateExecuteWorkItems(installer_state, product, install_list); | 730 AddActiveSetupWorkItems(installer_state, new_version, product, install_list); |
1157 AddCleanupDeprecatedPerUserRegistrationsWorkItems(product, install_list); | |
1158 | 731 |
1159 AddActiveSetupWorkItems(installer_state, new_version, product, | 732 AddOsUpgradeWorkItems(installer_state, setup_path, new_version, product, |
733 install_list); | |
734 AddFirewallRulesWorkItems(installer_state, dist, current_version == nullptr, | |
1160 install_list); | 735 install_list); |
1161 } | |
1162 | 736 |
1163 // Ensure that the Clients key for the binaries is gone for single installs | 737 InstallUtil::AddUpdateDowngradeVersionItem(installer_state.system_install(), |
1164 // (but not for SxS Chrome). | 738 current_version, new_version, dist, |
1165 if (!installer_state.is_multi_install() && | 739 install_list); |
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 | |
1180 // Add any remaining work items that involve special settings for | |
1181 // each product. | |
1182 AddProductSpecificWorkItems(original_state, installer_state, setup_path, | |
1183 new_version, current_version, | |
1184 add_language_identifier, install_list); | |
1185 | |
1186 // Copy over brand, usagestats, and other values. | |
1187 AddGoogleUpdateWorkItems(original_state, installer_state, install_list); | |
1188 | 740 |
1189 // Migrate usagestats back to Chrome. | 741 // Migrate usagestats back to Chrome. |
1190 AddMigrateUsageStatesWorkItems(original_state, installer_state, install_list); | 742 AddMigrateUsageStatsWorkItems(original_state, installer_state, install_list); |
1191 | 743 |
1192 // Append the tasks that run after the installation. | 744 // Append the tasks that run after the installation. |
1193 AppendPostInstallTasks(installer_state, | 745 AppendPostInstallTasks(installer_state, |
1194 setup_path, | 746 setup_path, |
1195 current_version, | 747 current_version, |
1196 new_version, | 748 new_version, |
1197 install_list); | 749 install_list); |
1198 } | 750 } |
1199 | 751 |
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, | 752 void AddSetMsiMarkerWorkItem(const InstallerState& installer_state, |
1222 BrowserDistribution* dist, | 753 BrowserDistribution* dist, |
1223 bool set, | 754 bool set, |
1224 WorkItemList* work_item_list) { | 755 WorkItemList* work_item_list) { |
1225 DCHECK(work_item_list); | 756 DCHECK(work_item_list); |
1226 DWORD msi_value = set ? 1 : 0; | 757 DWORD msi_value = set ? 1 : 0; |
1227 WorkItem* set_msi_work_item = | 758 WorkItem* set_msi_work_item = |
1228 work_item_list->AddSetRegValueWorkItem(installer_state.root_key(), | 759 work_item_list->AddSetRegValueWorkItem(installer_state.root_key(), |
1229 dist->GetStateKey(), | 760 dist->GetStateKey(), |
1230 KEY_WOW64_32KEY, | 761 KEY_WOW64_32KEY, |
1231 google_update::kRegMSIField, | 762 google_update::kRegMSIField, |
1232 msi_value, | 763 msi_value, |
1233 true); | 764 true); |
1234 DCHECK(set_msi_work_item); | 765 DCHECK(set_msi_work_item); |
1235 set_msi_work_item->set_best_effort(true); | 766 set_msi_work_item->set_best_effort(true); |
1236 set_msi_work_item->set_log_message("Could not write MSI marker!"); | 767 set_msi_work_item->set_log_message("Could not write MSI marker!"); |
1237 } | 768 } |
1238 | 769 |
1239 void AddCleanupDeprecatedPerUserRegistrationsWorkItems(const Product& product, | 770 void AddCleanupDeprecatedPerUserRegistrationsWorkItems(const Product& product, |
1240 WorkItemList* list) { | 771 WorkItemList* list) { |
1241 if (product.is_chrome()) { | 772 BrowserDistribution* dist = product.distribution(); |
1242 BrowserDistribution* dist = product.distribution(); | |
1243 | 773 |
1244 // TODO(gab): Remove cleanup code for Metro after M53. | 774 // This cleanup was added in M49. There are still enough active users on M48 |
1245 VLOG(1) << "Adding unregistration items for per-user Metro keys."; | 775 // and earlier today (M55 timeframe) to justify keeping this cleanup in-place. |
1246 list->AddDeleteRegKeyWorkItem(HKEY_CURRENT_USER, | 776 // Remove this when that population stops shrinking. |
1247 dist->GetRegistryPath() + L"\\Metro", | 777 VLOG(1) << "Adding unregistration items for per-user Metro keys."; |
1248 KEY_WOW64_32KEY); | 778 list->AddDeleteRegKeyWorkItem( |
1249 list->AddDeleteRegKeyWorkItem(HKEY_CURRENT_USER, | 779 HKEY_CURRENT_USER, dist->GetRegistryPath() + L"\\Metro", KEY_WOW64_32KEY); |
1250 dist->GetRegistryPath() + L"\\Metro", | 780 list->AddDeleteRegKeyWorkItem( |
1251 KEY_WOW64_64KEY); | 781 HKEY_CURRENT_USER, dist->GetRegistryPath() + L"\\Metro", KEY_WOW64_64KEY); |
1252 } | |
1253 } | 782 } |
1254 | 783 |
1255 void AddActiveSetupWorkItems(const InstallerState& installer_state, | 784 void AddActiveSetupWorkItems(const InstallerState& installer_state, |
1256 const base::Version& new_version, | 785 const base::Version& new_version, |
1257 const Product& product, | 786 const Product& product, |
1258 WorkItemList* list) { | 787 WorkItemList* list) { |
1259 DCHECK(installer_state.operation() != InstallerState::UNINSTALL); | 788 DCHECK(installer_state.operation() != InstallerState::UNINSTALL); |
1260 BrowserDistribution* dist = product.distribution(); | 789 BrowserDistribution* dist = product.distribution(); |
1261 | 790 |
1262 if (!product.is_chrome() || !installer_state.system_install()) { | 791 if (!installer_state.system_install()) { |
1263 const char* install_level = | 792 const char* install_level = |
huangs
2017/01/06 17:57:17
|install_level| = "user" always.
grt (UTC plus 2)
2017/01/06 21:15:46
Done.
| |
1264 installer_state.system_install() ? "system" : "user"; | 793 installer_state.system_install() ? "system" : "user"; |
1265 VLOG(1) << "No Active Setup processing to do for " << install_level | 794 VLOG(1) << "No Active Setup processing to do for " << install_level |
1266 << "-level " << dist->GetDisplayName(); | 795 << "-level " << dist->GetDisplayName(); |
1267 return; | 796 return; |
1268 } | 797 } |
1269 DCHECK(installer_state.RequiresActiveSetup()); | 798 DCHECK(installer_state.RequiresActiveSetup()); |
1270 | 799 |
1271 const HKEY root = HKEY_LOCAL_MACHINE; | 800 const HKEY root = HKEY_LOCAL_MACHINE; |
1272 const base::string16 active_setup_path(InstallUtil::GetActiveSetupPath(dist)); | 801 const base::string16 active_setup_path(InstallUtil::GetActiveSetupPath(dist)); |
1273 | 802 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1308 active_setup_path, | 837 active_setup_path, |
1309 WorkItem::kWow64Default, | 838 WorkItem::kWow64Default, |
1310 L"IsInstalled", | 839 L"IsInstalled", |
1311 static_cast<DWORD>(1U), | 840 static_cast<DWORD>(1U), |
1312 true); | 841 true); |
1313 | 842 |
1314 list->AddWorkItem(new UpdateActiveSetupVersionWorkItem( | 843 list->AddWorkItem(new UpdateActiveSetupVersionWorkItem( |
1315 active_setup_path, UpdateActiveSetupVersionWorkItem::UPDATE)); | 844 active_setup_path, UpdateActiveSetupVersionWorkItem::UPDATE)); |
1316 } | 845 } |
1317 | 846 |
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, | 847 void AppendUninstallCommandLineFlags(const InstallerState& installer_state, |
1330 const Product& product, | 848 const Product& product, |
1331 base::CommandLine* uninstall_cmd) { | 849 base::CommandLine* uninstall_cmd) { |
1332 DCHECK(uninstall_cmd); | 850 DCHECK(uninstall_cmd); |
1333 | 851 |
1334 uninstall_cmd->AppendSwitch(installer::switches::kUninstall); | 852 uninstall_cmd->AppendSwitch(installer::switches::kUninstall); |
1335 | 853 |
1336 // Append the product-specific uninstall flags. | 854 // Append the product-specific uninstall flags. |
1337 product.AppendProductFlags(uninstall_cmd); | 855 product.AppendProductFlags(uninstall_cmd); |
1338 if (installer_state.is_msi()) | 856 if (installer_state.is_msi()) |
1339 uninstall_cmd->AppendSwitch(installer::switches::kMsi); | 857 uninstall_cmd->AppendSwitch(installer::switches::kMsi); |
1340 if (installer_state.system_install()) | 858 if (installer_state.system_install()) |
1341 uninstall_cmd->AppendSwitch(installer::switches::kSystemLevel); | 859 uninstall_cmd->AppendSwitch(installer::switches::kSystemLevel); |
1342 if (installer_state.verbose_logging()) | 860 if (installer_state.verbose_logging()) |
1343 uninstall_cmd->AppendSwitch(installer::switches::kVerboseLogging); | 861 uninstall_cmd->AppendSwitch(installer::switches::kVerboseLogging); |
1344 } | 862 } |
1345 | 863 |
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, | 864 void AddOsUpgradeWorkItems(const InstallerState& installer_state, |
1369 const base::FilePath& setup_path, | 865 const base::FilePath& setup_path, |
1370 const base::Version& new_version, | 866 const base::Version& new_version, |
1371 const Product& product, | 867 const Product& product, |
1372 WorkItemList* install_list) { | 868 WorkItemList* install_list) { |
1373 const HKEY root_key = installer_state.root_key(); | 869 const HKEY root_key = installer_state.root_key(); |
1374 base::string16 cmd_key( | 870 base::string16 cmd_key( |
1375 GetRegCommandKey(product.distribution(), kCmdOnOsUpgrade)); | 871 GetRegCommandKey(product.distribution(), kCmdOnOsUpgrade)); |
1376 | 872 |
1377 if (installer_state.operation() == InstallerState::UNINSTALL) { | 873 if (installer_state.operation() == InstallerState::UNINSTALL) { |
(...skipping 13 matching lines...) Expand all Loading... | |
1391 cmd_line.AppendSwitch(installer::switches::kSystemLevel); | 887 cmd_line.AppendSwitch(installer::switches::kSystemLevel); |
1392 // Log everything for now. | 888 // Log everything for now. |
1393 cmd_line.AppendSwitch(installer::switches::kVerboseLogging); | 889 cmd_line.AppendSwitch(installer::switches::kVerboseLogging); |
1394 | 890 |
1395 AppCommand cmd(cmd_line.GetCommandLineString()); | 891 AppCommand cmd(cmd_line.GetCommandLineString()); |
1396 cmd.set_is_auto_run_on_os_upgrade(true); | 892 cmd.set_is_auto_run_on_os_upgrade(true); |
1397 cmd.AddWorkItems(installer_state.root_key(), cmd_key, install_list); | 893 cmd.AddWorkItems(installer_state.root_key(), cmd_key, install_list); |
1398 } | 894 } |
1399 } | 895 } |
1400 | 896 |
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 | 897 } // namespace installer |
OLD | NEW |