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

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

Issue 2878953003: Do not elevate to register Chrome for system-level Win7 installs. (Closed)
Patch Set: reset the released callback 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 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 // install is also present, it will lead IsChromeRegistered() to think this 2083 // install is also present, it will lead IsChromeRegistered() to think this
2083 // system-level install isn't registered properly as it is shadowed by the 2084 // system-level install isn't registered properly as it is shadowed by the
2084 // user-level install's registrations). 2085 // user-level install's registrations).
2085 uint32_t look_for_in = user_level ? RegistryEntry::LOOK_IN_HKCU_THEN_HKLM 2086 uint32_t look_for_in = user_level ? RegistryEntry::LOOK_IN_HKCU_THEN_HKLM
2086 : RegistryEntry::LOOK_IN_HKLM; 2087 : RegistryEntry::LOOK_IN_HKLM;
2087 2088
2088 // Check if chrome is already registered with this suffix. 2089 // Check if chrome is already registered with this suffix.
2089 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) 2090 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in))
2090 return true; 2091 return true;
2091 2092
2092 bool result = true; 2093 // Ensure that the shell is notified of the mutations below. Specific exit
2094 // points may disable this if no mutations are made.
2095 base::ScopedClosureRunner notify_on_exit(base::Bind([] {
2096 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
2097 }));
2098
2099 // Do the full registration at user-level or if the user is an admin.
2093 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { 2100 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
2094 // Do the full registration if we can do it at user-level or if the user is
2095 // an admin.
2096 std::vector<std::unique_ptr<RegistryEntry>> progid_and_appreg_entries; 2101 std::vector<std::unique_ptr<RegistryEntry>> progid_and_appreg_entries;
2097 std::vector<std::unique_ptr<RegistryEntry>> shell_entries; 2102 std::vector<std::unique_ptr<RegistryEntry>> shell_entries;
2098 GetChromeProgIdEntries(dist, chrome_exe, suffix, 2103 GetChromeProgIdEntries(dist, chrome_exe, suffix,
2099 &progid_and_appreg_entries); 2104 &progid_and_appreg_entries);
2100 GetChromeAppRegistrationEntries(chrome_exe, suffix, 2105 GetChromeAppRegistrationEntries(chrome_exe, suffix,
2101 &progid_and_appreg_entries); 2106 &progid_and_appreg_entries);
2102 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries); 2107 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries);
2103 result = (AddRegistryEntries(root, progid_and_appreg_entries) && 2108 return AddRegistryEntries(root, progid_and_appreg_entries) &&
2104 AddRegistryEntries(root, shell_entries)); 2109 AddRegistryEntries(root, shell_entries);
2105 } else if (elevate_if_not_admin && 2110 }
2106 base::win::GetVersion() >= base::win::VERSION_VISTA && 2111 // The installer is responsible for registration for system-level installs, so
2112 // never try to do it here. Getting to this point for a system-level install
2113 // likely means that IsChromeRegistered thinks registration is broken due to
2114 // localization issues (see https://crbug.com/717913#c18). It likely is not,
2115 // so return success to allow Chrome to be made default.
2116 if (!user_level) {
2117 notify_on_exit.Release().Reset();
2118 return true;
2119 }
2120 // Try to elevate and register if requested for per-user installs if the user
2121 // is not an admin.
2122 if (elevate_if_not_admin &&
2107 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { 2123 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) {
2108 // If the user is not an admin and OS is between Vista and Windows 7 2124 return true;
2109 // inclusively, try to elevate and register. This is only intended for 2125 }
2110 // user-level installs as system-level installs should always be run with 2126 // If we got to this point then all we can do is create ProgId and basic app
2111 // admin rights. 2127 // registrations under HKCU.
2112 result = true; 2128 std::vector<std::unique_ptr<RegistryEntry>> entries;
2113 } else { 2129 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries);
2114 // If we got to this point then all we can do is create ProgId and basic app 2130 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered with
2115 // registrations under HKCU. 2131 // no suffix (as per the old registration style): in which case some other
2116 std::vector<std::unique_ptr<RegistryEntry>> entries; 2132 // registry entries could refer to them and since we were not able to set our
2117 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries); 2133 // HKLM entries above, we are better off not altering these here.
2118 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered 2134 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) {
2119 // with no suffix (as per the old registration style): in which case some 2135 if (!suffix.empty()) {
2120 // other registry entries could refer to them and since we were not able to
2121 // set our HKLM entries above, we are better off not altering these here.
2122 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) {
2123 if (!suffix.empty()) {
2124 entries.clear();
2125 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
2126 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
2127 }
2128 result = AddRegistryEntries(HKEY_CURRENT_USER, entries);
2129 } else {
2130 // The ProgId is registered unsuffixed in HKCU, also register the app with
2131 // Windows in HKCU (this was not done in the old registration style and
2132 // thus needs to be done after the above check for the unsuffixed
2133 // registration).
2134 entries.clear(); 2136 entries.clear();
2135 GetChromeAppRegistrationEntries(chrome_exe, base::string16(), &entries); 2137 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
2136 result = AddRegistryEntries(HKEY_CURRENT_USER, entries); 2138 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
2137 } 2139 }
2140 return AddRegistryEntries(HKEY_CURRENT_USER, entries);
2138 } 2141 }
2139 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); 2142 // The ProgId is registered unsuffixed in HKCU, also register the app with
2140 return result; 2143 // Windows in HKCU (this was not done in the old registration style and thus
2144 // needs to be done after the above check for the unsuffixed registration).
2145 entries.clear();
2146 GetChromeAppRegistrationEntries(chrome_exe, base::string16(), &entries);
2147 return AddRegistryEntries(HKEY_CURRENT_USER, entries);
2141 } 2148 }
2142 2149
2143 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, 2150 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist,
2144 const base::FilePath& chrome_exe, 2151 const base::FilePath& chrome_exe,
2145 const base::string16& unique_suffix, 2152 const base::string16& unique_suffix,
2146 const base::string16& protocol, 2153 const base::string16& protocol,
2147 bool elevate_if_not_admin) { 2154 bool elevate_if_not_admin) {
2148 // Assert that this is only called with the one relevant distribution. 2155 // Assert that this is only called with the one relevant distribution.
2149 // TODO(grt): Remove this when BrowserDistribution goes away. 2156 // TODO(grt): Remove this when BrowserDistribution goes away.
2150 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); 2157 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist);
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2344 for (const auto& entry : entries) 2351 for (const auto& entry : entries)
2345 entry->AddToWorkItemList(root, items.get()); 2352 entry->AddToWorkItemList(root, items.get());
2346 2353
2347 // Apply all the registry changes and if there is a problem, rollback 2354 // Apply all the registry changes and if there is a problem, rollback
2348 if (!items->Do()) { 2355 if (!items->Do()) {
2349 items->Rollback(); 2356 items->Rollback();
2350 return false; 2357 return false;
2351 } 2358 }
2352 return true; 2359 return true;
2353 } 2360 }
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