Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: chrome/installer/setup/install_worker.cc

Issue 2589753002: Remove multi-install from chrome/installer/setup. (Closed)
Patch Set: jwd comments Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
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, 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) {
robertshield 2017/01/04 14:23:18 Do we still need this function at all? Since we're
grt (UTC plus 2) 2017/01/05 13:08:29 Nope; removed.
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
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
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
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
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
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.
robertshield 2017/01/04 14:23:18 Can this be removed now?
grt (UTC plus 2) 2017/01/05 13:08:29 While the cleanup shipped in M49, we still have ov
robertshield 2017/01/05 14:20:59 SGTM, maybe update the comment?
grt (UTC plus 2) 2017/01/06 10:25:53 What a good idea! Done! :-)
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
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
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
OLDNEW
« no previous file with comments | « chrome/installer/setup/install_worker.h ('k') | chrome/installer/setup/install_worker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698