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

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

Issue 749133003: Add fixing of MSI DisplayVersion to Chrome installs/updates. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Pre-review cleanup. Created 6 years 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 <oaidl.h> 10 #include <oaidl.h>
11 #include <shlobj.h> 11 #include <shlobj.h>
12 #include <time.h> 12 #include <time.h>
13 13
14 #include <algorithm>
14 #include <vector> 15 #include <vector>
15 16
16 #include "base/bind.h" 17 #include "base/bind.h"
17 #include "base/command_line.h" 18 #include "base/command_line.h"
18 #include "base/files/file_path.h" 19 #include "base/files/file_path.h"
19 #include "base/files/file_util.h" 20 #include "base/files/file_util.h"
20 #include "base/logging.h" 21 #include "base/logging.h"
21 #include "base/memory/scoped_ptr.h" 22 #include "base/memory/scoped_ptr.h"
22 #include "base/path_service.h" 23 #include "base/path_service.h"
24 #include "base/strings/string_tokenizer.h"
23 #include "base/strings/string_util.h" 25 #include "base/strings/string_util.h"
26 #include "base/strings/stringprintf.h"
24 #include "base/strings/utf_string_conversions.h" 27 #include "base/strings/utf_string_conversions.h"
25 #include "base/version.h" 28 #include "base/version.h"
26 #include "base/win/registry.h" 29 #include "base/win/registry.h"
27 #include "base/win/scoped_comptr.h" 30 #include "base/win/scoped_comptr.h"
28 #include "base/win/windows_version.h" 31 #include "base/win/windows_version.h"
29 #include "chrome/common/chrome_constants.h" 32 #include "chrome/common/chrome_constants.h"
30 #include "chrome/common/chrome_switches.h" 33 #include "chrome/common/chrome_switches.h"
31 #include "chrome/installer/setup/install.h" 34 #include "chrome/installer/setup/install.h"
32 #include "chrome/installer/setup/setup_constants.h" 35 #include "chrome/installer/setup/setup_constants.h"
33 #include "chrome/installer/setup/setup_util.h" 36 #include "chrome/installer/setup/setup_util.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 L"{6C288DD7-76FB-4721-B628-56FAC252E199}"; 74 L"{6C288DD7-76FB-4721-B628-56FAC252E199}";
72 75
73 const wchar_t kElevationPolicyKeyPath[] = 76 const wchar_t kElevationPolicyKeyPath[] =
74 L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\"; 77 L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\";
75 78
76 // The legacy command ids for installing an application or extension. These are 79 // The legacy command ids for installing an application or extension. These are
77 // only here so they can be removed from the registry. 80 // only here so they can be removed from the registry.
78 const wchar_t kLegacyCmdInstallApp[] = L"install-application"; 81 const wchar_t kLegacyCmdInstallApp[] = L"install-application";
79 const wchar_t kLegacyCmdInstallExtension[] = L"install-extension"; 82 const wchar_t kLegacyCmdInstallExtension[] = L"install-extension";
80 83
84 // The prefix of the ClientState value that contains the MSI product id in the
85 // format "<kMSIProductIdPrefix><PRODUCTID>".
86 const wchar_t kMSIProductIdPrefix[] = L"EnterpriseProduct";
87
88 // The common path for uninstall registry entries that show up in the
89 // "Add/Remove Programs" dialog and its later incarnations.
90 const wchar_t kUninstallRegPathRoot[] =
91 L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
92
93 // This is the path to the MSI user data cache, which should probably never be
94 // tampered with but which we'll try tweaking anyway. Other items of note here
95 // are that this hard-codes the Local System SID meaning that this is strictly
96 // only usable for system-level installs. This would need to change for
97 // http://crbug.com/111058 to be fixed.
grt (UTC plus 2) 2014/11/27 19:42:04 please add to the doc comment that this is a forma
robertshield 2014/11/27 22:25:57 Done.
98 const wchar_t kMSIUserDataCacheRoot[] =
99 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"
100 L"S-1-5-18\\Products\\%ls\\InstallProperties";
101
81 void GetOldIELowRightsElevationPolicyKeyPath(base::string16* key_path) { 102 void GetOldIELowRightsElevationPolicyKeyPath(base::string16* key_path) {
82 key_path->assign(kElevationPolicyKeyPath, 103 key_path->assign(kElevationPolicyKeyPath,
83 arraysize(kElevationPolicyKeyPath) - 1); 104 arraysize(kElevationPolicyKeyPath) - 1);
84 key_path->append(kIELowRightsPolicyOldGuid, 105 key_path->append(kIELowRightsPolicyOldGuid,
85 arraysize(kIELowRightsPolicyOldGuid)- 1); 106 arraysize(kIELowRightsPolicyOldGuid)- 1);
86 } 107 }
87 108
88 // Local helper to call AddRegisterComDllWorkItems for all DLLs in a set of 109 // Local helper to call AddRegisterComDllWorkItems for all DLLs in a set of
89 // products managed by a given package. 110 // products managed by a given package.
90 // |old_version| can be NULL to indicate no Chrome is currently installed. 111 // |old_version| can be NULL to indicate no Chrome is currently installed.
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 scoped_ptr<WorkItemList> no_rollback_list( 686 scoped_ptr<WorkItemList> no_rollback_list(
666 WorkItem::CreateNoRollbackWorkItemList()); 687 WorkItem::CreateNoRollbackWorkItemList());
667 AddUninstallDelegateExecuteWorkItems( 688 AddUninstallDelegateExecuteWorkItems(
668 HKEY_CURRENT_USER, google_chrome_delegate_execute_path, 689 HKEY_CURRENT_USER, google_chrome_delegate_execute_path,
669 no_rollback_list.get()); 690 no_rollback_list.get());
670 list->AddWorkItem(no_rollback_list.release()); 691 list->AddWorkItem(no_rollback_list.release());
671 VLOG(1) << "Added deletion items for bad Canary registrations."; 692 VLOG(1) << "Added deletion items for bad Canary registrations.";
672 } 693 }
673 } 694 }
674 695
696 // Returns the MSI product ID from the ClientState key that is populated for MSI
697 // installs. This property is encoded in a value name whose format is
698 // "EnterpriseId<GUID>" where <GUID> is the MSI product id. <GUID> is in the
699 // format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. The id will be placed in
700 // |product_id| if the latter is non-null.
701 //
702 // This format is strange and its provenance is shrouded in mystery but it has
703 // the data we need, so use it.
704 bool ExtractMSIProductId(const InstallerState& installer_state,
705 const Product& product,
706 base::string16* product_id) {
grt (UTC plus 2) 2014/11/27 19:42:04 why the out param for this? why not return the pro
robertshield 2014/11/27 22:25:57 The result of pruning an earlier API and not pruni
707 HKEY reg_root = installer_state.root_key();
708 BrowserDistribution* dist = product.distribution();
709 DCHECK(dist);
710
711 base::win::RegistryValueIterator value_iter(reg_root,
712 dist->GetStateKey().c_str());
713 while (value_iter.Valid()) {
grt (UTC plus 2) 2014/11/27 19:42:04 nit: for (; value_iter.Valid(); ++value_iter) {
robertshield 2014/11/27 22:25:57 Done.
714 base::string16 value_name(value_iter.Name());
715 if (StartsWith(value_name, kMSIProductIdPrefix, false)) {
716 if (product_id) {
717 *product_id += value_name.substr(arraysize(kMSIProductIdPrefix) - 1);
grt (UTC plus 2) 2014/11/27 19:42:04 why append?
robertshield 2014/11/27 22:25:57 Done.
718 }
719 return true;
720 }
721 ++value_iter;
722 }
723 return false;
724 }
725
675 } // namespace 726 } // namespace
676 727
728 // Converts a correctly formatted guid thusly:
729 // 12345678-90ab-cdef-ghij-klmnopqrstuv -> 87654321ba09fedchgjilknmporqtsvu
730 // This reverses the string of the first three terms and inverts the bytes of
731 // the last two. It also removes the dashes. It expects the input to NOT be
732 // wrapped in braces.
733 // Returns an empty string on failure.
734 base::string16 ConvertGUIDToMSIUserDataFormat(const base::string16& guid) {
grt (UTC plus 2) 2014/11/27 19:42:04 please keep the definition order here in the .cc f
robertshield 2014/11/27 22:25:57 Done.
735 // Perform some very mild validation of the input.
736 if (guid.size() != 36)
737 return base::string16();
738
739 base::string16 msi_formatted_guid;
740 int token_count = 0;
741 base::WStringTokenizer t(guid, L"-");
grt (UTC plus 2) 2014/11/27 19:42:04 t -> tokenizer ("Function names, variable names, a
robertshield 2014/11/27 22:25:57 Done.
742 while (t.GetNext()) {
743 // There should be exactly five tokens, bail if not.
744 if (token_count >= 5)
745 return base::string16();
746
747 base::string16 token(t.token());
748 if (token_count < 3) {
749 // For the first three tokens, just reverse the characters.
750 std::reverse(token.begin(), token.end());
751 msi_formatted_guid += token;
752 } else {
753 // The last two tokens need to be of even length.
754 if (token.size() % 2)
755 return base::string16();
756 // Swap the halves of each byte (i.e. pair of chars). I don't even.
757 for (size_t i = 0; i < token.size(); i += 2) {
758 msi_formatted_guid += token[i+1];
759 msi_formatted_guid += token[i];
760 }
761 }
762 token_count++;
763 }
764
765 if (token_count == 5)
grt (UTC plus 2) 2014/11/27 19:42:04 nit: more shorter? return (token_count == 5) ? m
robertshield 2014/11/27 22:25:57 Done.
766 return msi_formatted_guid;
767 else
768 return base::string16();
769 }
770
677 // This method adds work items to create (or update) Chrome uninstall entry in 771 // This method adds work items to create (or update) Chrome uninstall entry in
678 // either the Control Panel->Add/Remove Programs list or in the Omaha client 772 // either the Control Panel->Add/Remove Programs list or in the Omaha client
679 // state key if running under an MSI installer. 773 // state key if running under an MSI installer.
680 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, 774 void AddUninstallShortcutWorkItems(const InstallerState& installer_state,
681 const base::FilePath& setup_path, 775 const base::FilePath& setup_path,
682 const Version& new_version, 776 const Version& new_version,
683 const Product& product, 777 const Product& product,
684 WorkItemList* install_list) { 778 WorkItemList* install_list) {
685 HKEY reg_root = installer_state.root_key(); 779 HKEY reg_root = installer_state.root_key();
686 BrowserDistribution* browser_dist = product.distribution(); 780 BrowserDistribution* browser_dist = product.distribution();
(...skipping 27 matching lines...) Expand all
714 true); 808 true);
715 install_list->AddSetRegValueWorkItem( 809 install_list->AddSetRegValueWorkItem(
716 reg_root, 810 reg_root,
717 update_state_key, 811 update_state_key,
718 KEY_WOW64_32KEY, 812 KEY_WOW64_32KEY,
719 installer::kUninstallArgumentsField, 813 installer::kUninstallArgumentsField,
720 uninstall_arguments.GetCommandLineString(), 814 uninstall_arguments.GetCommandLineString(),
721 true); 815 true);
722 816
723 // MSI installations will manage their own uninstall shortcuts. 817 // MSI installations will manage their own uninstall shortcuts.
724 if (!installer_state.is_msi() && product.ShouldCreateUninstallEntry()) { 818 if (product.ShouldCreateUninstallEntry()) {
725 // We need to quote the command line for the Add/Remove Programs dialog. 819 if (!installer_state.is_msi()) {
726 CommandLine quoted_uninstall_cmd(installer_path); 820 // We need to quote the command line for the Add/Remove Programs dialog.
727 DCHECK_EQ(quoted_uninstall_cmd.GetCommandLineString()[0], '"'); 821 CommandLine quoted_uninstall_cmd(installer_path);
728 quoted_uninstall_cmd.AppendArguments(uninstall_arguments, false); 822 DCHECK_EQ(quoted_uninstall_cmd.GetCommandLineString()[0], '"');
823 quoted_uninstall_cmd.AppendArguments(uninstall_arguments, false);
729 824
730 base::string16 uninstall_reg = browser_dist->GetUninstallRegPath(); 825 base::string16 uninstall_reg = browser_dist->GetUninstallRegPath();
731 install_list->AddCreateRegKeyWorkItem( 826 install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg,
732 reg_root, uninstall_reg, KEY_WOW64_32KEY); 827 KEY_WOW64_32KEY);
733 install_list->AddSetRegValueWorkItem(reg_root,
734 uninstall_reg,
735 KEY_WOW64_32KEY,
736 installer::kUninstallDisplayNameField,
737 browser_dist->GetDisplayName(),
738 true);
739 install_list->AddSetRegValueWorkItem(
740 reg_root,
741 uninstall_reg,
742 KEY_WOW64_32KEY,
743 installer::kUninstallStringField,
744 quoted_uninstall_cmd.GetCommandLineString(),
745 true);
746 install_list->AddSetRegValueWorkItem(reg_root,
747 uninstall_reg,
748 KEY_WOW64_32KEY,
749 L"InstallLocation",
750 install_path.value(),
751 true);
752
753 BrowserDistribution* dist = product.distribution();
754 base::string16 chrome_icon = ShellUtil::FormatIconLocation(
755 install_path.Append(dist->GetIconFilename()).value(),
756 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME));
757 install_list->AddSetRegValueWorkItem(reg_root,
758 uninstall_reg,
759 KEY_WOW64_32KEY,
760 L"DisplayIcon",
761 chrome_icon,
762 true);
763 install_list->AddSetRegValueWorkItem(reg_root,
764 uninstall_reg,
765 KEY_WOW64_32KEY,
766 L"NoModify",
767 static_cast<DWORD>(1),
768 true);
769 install_list->AddSetRegValueWorkItem(reg_root,
770 uninstall_reg,
771 KEY_WOW64_32KEY,
772 L"NoRepair",
773 static_cast<DWORD>(1),
774 true);
775
776 install_list->AddSetRegValueWorkItem(reg_root,
777 uninstall_reg,
778 KEY_WOW64_32KEY,
779 L"Publisher",
780 browser_dist->GetPublisherName(),
781 true);
782 install_list->AddSetRegValueWorkItem(reg_root,
783 uninstall_reg,
784 KEY_WOW64_32KEY,
785 L"Version",
786 ASCIIToUTF16(new_version.GetString()),
787 true);
788 install_list->AddSetRegValueWorkItem(reg_root,
789 uninstall_reg,
790 KEY_WOW64_32KEY,
791 L"DisplayVersion",
792 ASCIIToUTF16(new_version.GetString()),
793 true);
794 // TODO(wfh): Ensure that this value is preserved in the 64-bit hive when
795 // 64-bit installs place the uninstall information into the 64-bit registry.
796 install_list->AddSetRegValueWorkItem(reg_root,
797 uninstall_reg,
798 KEY_WOW64_32KEY,
799 L"InstallDate",
800 InstallUtil::GetCurrentDate(),
801 false);
802
803 const std::vector<uint16>& version_components = new_version.components();
804 if (version_components.size() == 4) {
805 // Our version should be in major.minor.build.rev.
806 install_list->AddSetRegValueWorkItem( 828 install_list->AddSetRegValueWorkItem(
807 reg_root, 829 reg_root, uninstall_reg, KEY_WOW64_32KEY,
808 uninstall_reg, 830 installer::kUninstallDisplayNameField, browser_dist->GetDisplayName(),
809 KEY_WOW64_32KEY,
810 L"VersionMajor",
811 static_cast<DWORD>(version_components[2]),
812 true); 831 true);
813 install_list->AddSetRegValueWorkItem( 832 install_list->AddSetRegValueWorkItem(
814 reg_root, 833 reg_root, uninstall_reg, KEY_WOW64_32KEY,
815 uninstall_reg, 834 installer::kUninstallStringField,
816 KEY_WOW64_32KEY, 835 quoted_uninstall_cmd.GetCommandLineString(), true);
817 L"VersionMinor", 836 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
818 static_cast<DWORD>(version_components[3]), 837 KEY_WOW64_32KEY, L"InstallLocation",
819 true); 838 install_path.value(), true);
839
840 BrowserDistribution* dist = product.distribution();
841 base::string16 chrome_icon = ShellUtil::FormatIconLocation(
842 install_path.Append(dist->GetIconFilename()).value(),
843 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME));
844 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
845 KEY_WOW64_32KEY, L"DisplayIcon",
846 chrome_icon, true);
847 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
848 KEY_WOW64_32KEY, L"NoModify",
849 static_cast<DWORD>(1), true);
850 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
851 KEY_WOW64_32KEY, L"NoRepair",
852 static_cast<DWORD>(1), true);
853
854 install_list->AddSetRegValueWorkItem(
855 reg_root, uninstall_reg, KEY_WOW64_32KEY, L"Publisher",
856 browser_dist->GetPublisherName(), true);
857 install_list->AddSetRegValueWorkItem(
858 reg_root, uninstall_reg, KEY_WOW64_32KEY, L"Version",
859 ASCIIToUTF16(new_version.GetString()), true);
860 install_list->AddSetRegValueWorkItem(
861 reg_root, uninstall_reg, KEY_WOW64_32KEY, L"DisplayVersion",
862 ASCIIToUTF16(new_version.GetString()), true);
863 // TODO(wfh): Ensure that this value is preserved in the 64-bit hive when
864 // 64-bit installs place the uninstall information into the 64-bit
865 // registry.
866 install_list->AddSetRegValueWorkItem(
867 reg_root, uninstall_reg, KEY_WOW64_32KEY, L"InstallDate",
868 InstallUtil::GetCurrentDate(), false);
869
870 const std::vector<uint16>& version_components = new_version.components();
871 if (version_components.size() == 4) {
872 // Our version should be in major.minor.build.rev.
873 install_list->AddSetRegValueWorkItem(
874 reg_root, uninstall_reg, KEY_WOW64_32KEY, L"VersionMajor",
875 static_cast<DWORD>(version_components[2]), true);
876 install_list->AddSetRegValueWorkItem(
877 reg_root, uninstall_reg, KEY_WOW64_32KEY, L"VersionMinor",
878 static_cast<DWORD>(version_components[3]), true);
879 }
880 } else {
881 // This is an MSI install. Largely, leave all uninstall shortcuts and the
882 // like up to the MSI machinery EXCEPT for the DisplayVersion property.
883 //
884 // Due to reasons, the Chrome version number is wider than can fit inside
885 // the <8bits>.<16bits>.<8bits> allotted to MSI version numbers. To make
886 // things work the A.B.C.D Chrome version is lossily encoded into an X.Y.Z
887 // version, dropping the unneeded A and B terms. For full details, see
888 // https://code.google.com/p/chromium/issues/detail?id=67348#c62
889 //
890 // The upshot of this is that Chrome MSIs have a different visible version
891 // than actual Chrome releases which causes trouble with some workflows.
892 // To help mitigate this, attempt to keep the DisplayVersion property in
893 // sync for MSI installs in both the Add/Remove Programs dialog and the
894 // corresponding MSI user data cache.
895
896 // Figure out MSI ProductID by looking in ClientState.
897 // The ProductID is encoded as a key named "EnterpriseProduct<ProductID>".
898 base::string16 msi_product_id;
899 if (ExtractMSIProductId(installer_state, product, &msi_product_id)) {
900 base::string16 uninstall_reg_path(kUninstallRegPathRoot);
901 uninstall_reg_path.append(L"{");
902 uninstall_reg_path.append(msi_product_id);
903 uninstall_reg_path.append(L"}");
904
905 install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg_path,
grt (UTC plus 2) 2014/11/27 19:42:04 this key is owned by Windows, no? if so, it isn't
robertshield 2014/11/27 22:25:57 Hrmm, that's not unreasonable: the key is owned by
906 WorkItem::kWow64Default);
907 install_list->AddSetRegValueWorkItem(
908 reg_root, uninstall_reg_path, WorkItem::kWow64Default,
909 installer::kUninstallDisplayVersionField,
910 base::ASCIIToWide(new_version.GetString()), true);
grt (UTC plus 2) 2014/11/27 19:42:04 please use base::ASCIIToUTF16 here and on line 931
grt (UTC plus 2) 2014/11/27 19:42:04 should failures here not also be ignored?
robertshield 2014/11/27 22:25:57 Done.
robertshield 2014/11/27 22:25:57 Ok. <grump> If ASCIIToWide is deprecated, it shou
grt (UTC plus 2) 2014/12/01 16:19:30 Agreed.
911
912 // Also fix up the MSI user data cache. This is a little hacky, there
913 // may be a better way and I am not certain this won't cause undesired
914 // side-effects. Note that the user data cache registry path includes
915 // the product id without dashes. Also note that the
916 // kMSIUserDataCacheRoot currently hardcodes the local system SID, which
917 // will need to be changed for user-level MSI installs to happen as
918 // tracked by http://crbug.com/111058. Leave a DCHECK here to warn those
919 // who next venture here to use a correct SID in kMSIUserDataCacheRoot.
920 DCHECK(installer_state.system_install());
921
922 base::string16 msi_user_data_product_id(
923 ConvertGUIDToMSIUserDataFormat(msi_product_id));
924 if (!msi_user_data_product_id.empty()) {
925 base::string16 msi_cache_reg_path(base::StringPrintf(
926 kMSIUserDataCacheRoot, msi_user_data_product_id.c_str()));
927
928 install_list->AddSetRegValueWorkItem(
929 reg_root, msi_cache_reg_path, KEY_WOW64_64KEY,
930 installer::kUninstallDisplayVersionField,
931 base::ASCIIToWide(new_version.GetString()), true)->
932 set_ignore_failure(true);
933 } else {
934 VLOG(1) << "Failed to convert MSI user data id.";
grt (UTC plus 2) 2014/11/27 19:42:04 suggestion: LOG(DFATAL) and include msi_product_id
robertshield 2014/11/27 22:25:57 I had picked VLOG since we always run the installe
grt (UTC plus 2) 2014/12/01 16:19:30 This new code runs on all updates following an MSI
935 }
936 } else {
937 VLOG(1) << "Failed to extract MSI product id.";
938 }
820 } 939 }
821 } 940 }
822 } 941 }
823 942
824 // Create Version key for a product (if not already present) and sets the new 943 // Create Version key for a product (if not already present) and sets the new
825 // product version as the last step. 944 // product version as the last step.
826 void AddVersionKeyWorkItems(HKEY root, 945 void AddVersionKeyWorkItems(HKEY root,
827 const base::string16& version_key, 946 const base::string16& version_key,
828 const base::string16& product_name, 947 const base::string16& product_name,
829 const Version& new_version, 948 const Version& new_version,
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 // Unconditionally remove the legacy Quick Enable command from the binaries. 1783 // Unconditionally remove the legacy Quick Enable command from the binaries.
1665 // Do this even if multi-install Chrome isn't installed to ensure that it is 1784 // Do this even if multi-install Chrome isn't installed to ensure that it is
1666 // not left behind in any case. 1785 // not left behind in any case.
1667 work_item_list->AddDeleteRegKeyWorkItem( 1786 work_item_list->AddDeleteRegKeyWorkItem(
1668 installer_state.root_key(), cmd_key, KEY_WOW64_32KEY) 1787 installer_state.root_key(), cmd_key, KEY_WOW64_32KEY)
1669 ->set_log_message("removing " + base::UTF16ToASCII(kCmdQuickEnableCf) + 1788 ->set_log_message("removing " + base::UTF16ToASCII(kCmdQuickEnableCf) +
1670 " command"); 1789 " command");
1671 } 1790 }
1672 1791
1673 } // namespace installer 1792 } // 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