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

Side by Side Diff: chrome/installer/util/shell_util.cc

Issue 2910743002: Do not elevate to register Chrome for system-level Win7 installs. (Closed)
Patch Set: Created 3 years, 7 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 defines functions that integrate Chrome in Windows shell. These 5 // This file defines functions that integrate Chrome in Windows shell. These
6 // functions can be used by Chrome as well as Chrome installer. All of the 6 // functions can be used by Chrome as well as Chrome installer. All of the
7 // work is done by the local functions defined in anonymous namespace in 7 // work is done by the local functions defined in anonymous namespace in
8 // this class. 8 // this class.
9 9
10 #include "chrome/installer/util/shell_util.h" 10 #include "chrome/installer/util/shell_util.h"
11 11
12 #include <windows.h> 12 #include <windows.h>
13 #include <shlobj.h> 13 #include <shlobj.h>
14 #include <shobjidl.h> 14 #include <shobjidl.h>
15 15
16 #include <algorithm> 16 #include <algorithm>
17 #include <iterator> 17 #include <iterator>
18 #include <limits> 18 #include <limits>
19 #include <memory> 19 #include <memory>
20 #include <string> 20 #include <string>
21 #include <utility> 21 #include <utility>
22 22
23 #include "base/bind.h" 23 #include "base/bind.h"
24 #include "base/callback_helpers.h"
24 #include "base/command_line.h" 25 #include "base/command_line.h"
25 #include "base/files/file_enumerator.h" 26 #include "base/files/file_enumerator.h"
26 #include "base/files/file_path.h" 27 #include "base/files/file_path.h"
27 #include "base/files/file_util.h" 28 #include "base/files/file_util.h"
28 #include "base/lazy_instance.h" 29 #include "base/lazy_instance.h"
29 #include "base/logging.h" 30 #include "base/logging.h"
30 #include "base/macros.h" 31 #include "base/macros.h"
31 #include "base/md5.h" 32 #include "base/md5.h"
32 #include "base/memory/ptr_util.h" 33 #include "base/memory/ptr_util.h"
33 #include "base/metrics/histogram_macros.h" 34 #include "base/metrics/histogram_macros.h"
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 uint32_t look_for_in) { 676 uint32_t look_for_in) {
676 std::vector<std::unique_ptr<RegistryEntry>> entries; 677 std::vector<std::unique_ptr<RegistryEntry>> entries;
677 GetProtocolCapabilityEntries(suffix, protocol, &entries); 678 GetProtocolCapabilityEntries(suffix, protocol, &entries);
678 return AreEntriesAsDesired(entries, look_for_in); 679 return AreEntriesAsDesired(entries, look_for_in);
679 } 680 }
680 681
681 // This method registers Chrome by launching an elevated setup.exe. That will 682 // This method registers Chrome by launching an elevated setup.exe. That will
682 // show the user the standard elevation prompt. If the user accepts it the new 683 // show the user the standard elevation prompt. If the user accepts it the new
683 // process will make the necessary changes and return SUCCESS that we capture 684 // process will make the necessary changes and return SUCCESS that we capture
684 // and return. If protocol is non-empty we will also register Chrome as being 685 // and return. If protocol is non-empty we will also register Chrome as being
685 // capable of handling the protocol. This is most commonly used on per-user 686 // capable of handling the protocol. This is used for general browser
686 // installs on Windows 7 where setup.exe did not have permission to register 687 // registration on Windows 7 for per-user installs where setup.exe did not have
687 // Chrome during install. It may also be used on all OSs for system-level 688 // permission to register Chrome during install. It may also be used on Windows
688 // installs in case Chrome's registration is somehow broken or missing. 689 // 7 for system-level installs to register Chrome for a specific protocol.
689 bool ElevateAndRegisterChrome(BrowserDistribution* dist, 690 bool ElevateAndRegisterChrome(BrowserDistribution* dist,
690 const base::FilePath& chrome_exe, 691 const base::FilePath& chrome_exe,
691 const base::string16& suffix, 692 const base::string16& suffix,
692 const base::string16& protocol) { 693 const base::string16& protocol) {
693 // Check for setup.exe in the same directory as chrome.exe, as is the case 694 // Check for setup.exe in the same directory as chrome.exe, as is the case
694 // when running out of a build output directory. 695 // when running out of a build output directory.
695 base::FilePath exe_path = chrome_exe.DirName().Append(installer::kSetupExe); 696 base::FilePath exe_path = chrome_exe.DirName().Append(installer::kSetupExe);
696 697
697 // Failing that, read the path to setup.exe from Chrome's ClientState key, 698 // Failing that, read the path to setup.exe from Chrome's ClientState key,
698 // which is the canonical location of the installer for all types of installs 699 // which is the canonical location of the installer for all types of installs
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 // install is also present, it will lead IsChromeRegistered() to think this 2082 // install is also present, it will lead IsChromeRegistered() to think this
2082 // system-level install isn't registered properly as it is shadowed by the 2083 // system-level install isn't registered properly as it is shadowed by the
2083 // user-level install's registrations). 2084 // user-level install's registrations).
2084 uint32_t look_for_in = user_level ? RegistryEntry::LOOK_IN_HKCU_THEN_HKLM 2085 uint32_t look_for_in = user_level ? RegistryEntry::LOOK_IN_HKCU_THEN_HKLM
2085 : RegistryEntry::LOOK_IN_HKLM; 2086 : RegistryEntry::LOOK_IN_HKLM;
2086 2087
2087 // Check if chrome is already registered with this suffix. 2088 // Check if chrome is already registered with this suffix.
2088 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) 2089 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in))
2089 return true; 2090 return true;
2090 2091
2091 bool result = true; 2092 // Ensure that the shell is notified of the mutations below. Specific exit
2093 // points may disable this if no mutations are made.
2094 base::ScopedClosureRunner notify_on_exit(base::Bind([] {
2095 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
2096 }));
2097
2098 // Do the full registration at user-level or if the user is an admin.
2092 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { 2099 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
2093 // Do the full registration if we can do it at user-level or if the user is
2094 // an admin.
2095 std::vector<std::unique_ptr<RegistryEntry>> progid_and_appreg_entries; 2100 std::vector<std::unique_ptr<RegistryEntry>> progid_and_appreg_entries;
2096 std::vector<std::unique_ptr<RegistryEntry>> shell_entries; 2101 std::vector<std::unique_ptr<RegistryEntry>> shell_entries;
2097 GetChromeProgIdEntries(dist, chrome_exe, suffix, 2102 GetChromeProgIdEntries(dist, chrome_exe, suffix,
2098 &progid_and_appreg_entries); 2103 &progid_and_appreg_entries);
2099 GetChromeAppRegistrationEntries(chrome_exe, suffix, 2104 GetChromeAppRegistrationEntries(chrome_exe, suffix,
2100 &progid_and_appreg_entries); 2105 &progid_and_appreg_entries);
2101 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries); 2106 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries);
2102 result = (AddRegistryEntries(root, progid_and_appreg_entries) && 2107 return AddRegistryEntries(root, progid_and_appreg_entries) &&
2103 AddRegistryEntries(root, shell_entries)); 2108 AddRegistryEntries(root, shell_entries);
2104 } else if (elevate_if_not_admin && 2109 }
2105 base::win::GetVersion() >= base::win::VERSION_VISTA && 2110 // The installer is responsible for registration for system-level installs, so
2111 // never try to do it here. Getting to this point for a system-level install
2112 // likely means that IsChromeRegistered thinks registration is broken due to
2113 // localization issues (see https://crbug.com/717913#c18). It likely is not,
2114 // so return success to allow Chrome to be made default.
2115 if (!user_level) {
2116 notify_on_exit.Release().Reset();
2117 return true;
2118 }
2119 // Try to elevate and register if requested for per-user installs if the user
2120 // is not an admin.
2121 if (elevate_if_not_admin &&
2106 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { 2122 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) {
2107 // If the user is not an admin and OS is between Vista and Windows 7 2123 return true;
2108 // inclusively, try to elevate and register. This is only intended for 2124 }
2109 // user-level installs as system-level installs should always be run with 2125 // If we got to this point then all we can do is create ProgId and basic app
2110 // admin rights. 2126 // registrations under HKCU.
2111 result = true; 2127 std::vector<std::unique_ptr<RegistryEntry>> entries;
2112 } else { 2128 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries);
2113 // If we got to this point then all we can do is create ProgId and basic app 2129 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered with
2114 // registrations under HKCU. 2130 // no suffix (as per the old registration style): in which case some other
2115 std::vector<std::unique_ptr<RegistryEntry>> entries; 2131 // registry entries could refer to them and since we were not able to set our
2116 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries); 2132 // HKLM entries above, we are better off not altering these here.
2117 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered 2133 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) {
2118 // with no suffix (as per the old registration style): in which case some 2134 if (!suffix.empty()) {
2119 // other registry entries could refer to them and since we were not able to
2120 // set our HKLM entries above, we are better off not altering these here.
2121 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) {
2122 if (!suffix.empty()) {
2123 entries.clear();
2124 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
2125 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
2126 }
2127 result = AddRegistryEntries(HKEY_CURRENT_USER, entries);
2128 } else {
2129 // The ProgId is registered unsuffixed in HKCU, also register the app with
2130 // Windows in HKCU (this was not done in the old registration style and
2131 // thus needs to be done after the above check for the unsuffixed
2132 // registration).
2133 entries.clear(); 2135 entries.clear();
2134 GetChromeAppRegistrationEntries(chrome_exe, base::string16(), &entries); 2136 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
2135 result = AddRegistryEntries(HKEY_CURRENT_USER, entries); 2137 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
2136 } 2138 }
2139 return AddRegistryEntries(HKEY_CURRENT_USER, entries);
2137 } 2140 }
2138 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); 2141 // The ProgId is registered unsuffixed in HKCU, also register the app with
2139 return result; 2142 // Windows in HKCU (this was not done in the old registration style and thus
2143 // needs to be done after the above check for the unsuffixed registration).
2144 entries.clear();
2145 GetChromeAppRegistrationEntries(chrome_exe, base::string16(), &entries);
2146 return AddRegistryEntries(HKEY_CURRENT_USER, entries);
2140 } 2147 }
2141 2148
2142 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, 2149 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist,
2143 const base::FilePath& chrome_exe, 2150 const base::FilePath& chrome_exe,
2144 const base::string16& unique_suffix, 2151 const base::string16& unique_suffix,
2145 const base::string16& protocol, 2152 const base::string16& protocol,
2146 bool elevate_if_not_admin) { 2153 bool elevate_if_not_admin) {
2147 // Assert that this is only called with the one relevant distribution. 2154 // Assert that this is only called with the one relevant distribution.
2148 // TODO(grt): Remove this when BrowserDistribution goes away. 2155 // TODO(grt): Remove this when BrowserDistribution goes away.
2149 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); 2156 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist);
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2343 for (const auto& entry : entries) 2350 for (const auto& entry : entries)
2344 entry->AddToWorkItemList(root, items.get()); 2351 entry->AddToWorkItemList(root, items.get());
2345 2352
2346 // Apply all the registry changes and if there is a problem, rollback 2353 // Apply all the registry changes and if there is a problem, rollback
2347 if (!items->Do()) { 2354 if (!items->Do()) {
2348 items->Rollback(); 2355 items->Rollback();
2349 return false; 2356 return false;
2350 } 2357 }
2351 return true; 2358 return true;
2352 } 2359 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698