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

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

Issue 1548153002: Switch to standard integer types in chrome/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 12 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 | « chrome/installer/util/shell_util.h ('k') | chrome/installer/util/shell_util_unittest.cc » ('j') | 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 <limits> 16 #include <limits>
17 #include <string> 17 #include <string>
18 18
19 #include "base/bind.h" 19 #include "base/bind.h"
20 #include "base/command_line.h" 20 #include "base/command_line.h"
21 #include "base/files/file_enumerator.h" 21 #include "base/files/file_enumerator.h"
22 #include "base/files/file_path.h" 22 #include "base/files/file_path.h"
23 #include "base/files/file_util.h" 23 #include "base/files/file_util.h"
24 #include "base/lazy_instance.h" 24 #include "base/lazy_instance.h"
25 #include "base/logging.h" 25 #include "base/logging.h"
26 #include "base/macros.h"
26 #include "base/md5.h" 27 #include "base/md5.h"
27 #include "base/memory/scoped_ptr.h" 28 #include "base/memory/scoped_ptr.h"
28 #include "base/memory/scoped_vector.h" 29 #include "base/memory/scoped_vector.h"
29 #include "base/path_service.h" 30 #include "base/path_service.h"
30 #include "base/strings/string16.h" 31 #include "base/strings/string16.h"
31 #include "base/strings/string_number_conversions.h" 32 #include "base/strings/string_number_conversions.h"
32 #include "base/strings/string_split.h" 33 #include "base/strings/string_split.h"
33 #include "base/strings/string_util.h" 34 #include "base/strings/string_util.h"
34 #include "base/strings/stringprintf.h" 35 #include "base/strings/stringprintf.h"
35 #include "base/strings/utf_string_conversions.h" 36 #include "base/strings/utf_string_conversions.h"
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 // start->Internet shortcut. 612 // start->Internet shortcut.
612 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); 613 base::string16 start_menu(ShellUtil::kRegStartMenuInternet);
613 base::string16 app_name = dist->GetBaseAppName() + suffix; 614 base::string16 app_name = dist->GetBaseAppName() + suffix;
614 entries->push_back(new RegistryEntry(start_menu, app_name)); 615 entries->push_back(new RegistryEntry(start_menu, app_name));
615 } 616 }
616 617
617 // Checks that all |entries| are present on this computer (or absent if their 618 // Checks that all |entries| are present on this computer (or absent if their
618 // |removal_flag_| is set). |look_for_in| is passed to 619 // |removal_flag_| is set). |look_for_in| is passed to
619 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there. 620 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there.
620 bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries, 621 bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries,
621 uint32 look_for_in) { 622 uint32_t look_for_in) {
622 for (const auto* entry : entries) { 623 for (const auto* entry : entries) {
623 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval()) 624 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval())
624 return false; 625 return false;
625 } 626 }
626 return true; 627 return true;
627 } 628 }
628 629
629 // Checks that all required registry entries for Chrome are already present on 630 // Checks that all required registry entries for Chrome are already present on
630 // this computer (or absent if their |removal_flag_| is set). 631 // this computer (or absent if their |removal_flag_| is set).
631 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. 632 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|.
632 // Note: between r133333 and r154145 we were registering parts of Chrome in HKCU 633 // Note: between r133333 and r154145 we were registering parts of Chrome in HKCU
633 // and parts in HKLM for user-level installs; we now always register everything 634 // and parts in HKLM for user-level installs; we now always register everything
634 // under a single registry root. Not doing so caused http://crbug.com/144910 for 635 // under a single registry root. Not doing so caused http://crbug.com/144910 for
635 // users who first-installed Chrome in that revision range (those users are 636 // users who first-installed Chrome in that revision range (those users are
636 // still impacted by http://crbug.com/144910). This method will keep returning 637 // still impacted by http://crbug.com/144910). This method will keep returning
637 // true for affected users (i.e. who have all the registrations, but over both 638 // true for affected users (i.e. who have all the registrations, but over both
638 // registry roots). 639 // registry roots).
639 bool IsChromeRegistered(BrowserDistribution* dist, 640 bool IsChromeRegistered(BrowserDistribution* dist,
640 const base::FilePath& chrome_exe, 641 const base::FilePath& chrome_exe,
641 const base::string16& suffix, 642 const base::string16& suffix,
642 uint32 look_for_in) { 643 uint32_t look_for_in) {
643 ScopedVector<RegistryEntry> entries; 644 ScopedVector<RegistryEntry> entries;
644 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); 645 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
645 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); 646 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries);
646 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); 647 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
647 return AreEntriesAsDesired(entries, look_for_in); 648 return AreEntriesAsDesired(entries, look_for_in);
648 } 649 }
649 650
650 // This method checks if Chrome is already registered on the local machine 651 // This method checks if Chrome is already registered on the local machine
651 // for the requested protocol. It just checks the one value required for this. 652 // for the requested protocol. It just checks the one value required for this.
652 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. 653 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|.
653 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist, 654 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist,
654 const base::string16& suffix, 655 const base::string16& suffix,
655 const base::string16& protocol, 656 const base::string16& protocol,
656 uint32 look_for_in) { 657 uint32_t look_for_in) {
657 ScopedVector<RegistryEntry> entries; 658 ScopedVector<RegistryEntry> entries;
658 GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); 659 GetProtocolCapabilityEntries(dist, suffix, protocol, &entries);
659 return AreEntriesAsDesired(entries, look_for_in); 660 return AreEntriesAsDesired(entries, look_for_in);
660 } 661 }
661 662
662 // This method registers Chrome on Vista by launching an elevated setup.exe. 663 // This method registers Chrome on Vista by launching an elevated setup.exe.
663 // That will show the user the standard Vista elevation prompt. If the user 664 // That will show the user the standard Vista elevation prompt. If the user
664 // accepts it the new process will make the necessary changes and return SUCCESS 665 // accepts it the new process will make the necessary changes and return SUCCESS
665 // that we capture and return. 666 // that we capture and return.
666 // If protocol is non-empty we will also register Chrome as being capable of 667 // If protocol is non-empty we will also register Chrome as being capable of
(...skipping 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2026 2027
2027 RemoveRunVerbOnWindows8(dist, chrome_exe); 2028 RemoveRunVerbOnWindows8(dist, chrome_exe);
2028 2029
2029 bool user_level = InstallUtil::IsPerUserInstall(chrome_exe); 2030 bool user_level = InstallUtil::IsPerUserInstall(chrome_exe);
2030 HKEY root = DetermineRegistrationRoot(user_level); 2031 HKEY root = DetermineRegistrationRoot(user_level);
2031 2032
2032 // Look only in HKLM for system-level installs (otherwise, if a user-level 2033 // Look only in HKLM for system-level installs (otherwise, if a user-level
2033 // install is also present, it will lead IsChromeRegistered() to think this 2034 // install is also present, it will lead IsChromeRegistered() to think this
2034 // system-level install isn't registered properly as it is shadowed by the 2035 // system-level install isn't registered properly as it is shadowed by the
2035 // user-level install's registrations). 2036 // user-level install's registrations).
2036 uint32 look_for_in = user_level ? 2037 uint32_t look_for_in = user_level ? RegistryEntry::LOOK_IN_HKCU_THEN_HKLM
2037 RegistryEntry::LOOK_IN_HKCU_THEN_HKLM : RegistryEntry::LOOK_IN_HKLM; 2038 : RegistryEntry::LOOK_IN_HKLM;
2038 2039
2039 // Check if chrome is already registered with this suffix. 2040 // Check if chrome is already registered with this suffix.
2040 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) 2041 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in))
2041 return true; 2042 return true;
2042 2043
2043 bool result = true; 2044 bool result = true;
2044 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { 2045 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
2045 // Do the full registration if we can do it at user-level or if the user is 2046 // Do the full registration if we can do it at user-level or if the user is
2046 // an admin. 2047 // an admin.
2047 ScopedVector<RegistryEntry> progid_and_appreg_entries; 2048 ScopedVector<RegistryEntry> progid_and_appreg_entries;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2108 return false; 2109 return false;
2109 } 2110 }
2110 2111
2111 bool user_level = InstallUtil::IsPerUserInstall(chrome_exe); 2112 bool user_level = InstallUtil::IsPerUserInstall(chrome_exe);
2112 HKEY root = DetermineRegistrationRoot(user_level); 2113 HKEY root = DetermineRegistrationRoot(user_level);
2113 2114
2114 // Look only in HKLM for system-level installs (otherwise, if a user-level 2115 // Look only in HKLM for system-level installs (otherwise, if a user-level
2115 // install is also present, it could lead IsChromeRegisteredForProtocol() to 2116 // install is also present, it could lead IsChromeRegisteredForProtocol() to
2116 // think this system-level install isn't registered properly as it may be 2117 // think this system-level install isn't registered properly as it may be
2117 // shadowed by the user-level install's registrations). 2118 // shadowed by the user-level install's registrations).
2118 uint32 look_for_in = user_level ? 2119 uint32_t look_for_in = user_level ? RegistryEntry::LOOK_IN_HKCU_THEN_HKLM
2119 RegistryEntry::LOOK_IN_HKCU_THEN_HKLM : RegistryEntry::LOOK_IN_HKLM; 2120 : RegistryEntry::LOOK_IN_HKLM;
2120 2121
2121 // Check if chrome is already registered with this suffix. 2122 // Check if chrome is already registered with this suffix.
2122 if (IsChromeRegisteredForProtocol(dist, suffix, protocol, look_for_in)) 2123 if (IsChromeRegisteredForProtocol(dist, suffix, protocol, look_for_in))
2123 return true; 2124 return true;
2124 2125
2125 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { 2126 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
2126 // We can do this operation directly. 2127 // We can do this operation directly.
2127 // First, make sure Chrome is fully registered on this machine. 2128 // First, make sure Chrome is fully registered on this machine.
2128 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) 2129 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false))
2129 return false; 2130 return false;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 if (::GetUserName(user_name, &size) == 0 || size < 1) { 2219 if (::GetUserName(user_name, &size) == 0 || size < 1) {
2219 NOTREACHED(); 2220 NOTREACHED();
2220 return false; 2221 return false;
2221 } 2222 }
2222 suffix->reserve(size); 2223 suffix->reserve(size);
2223 suffix->assign(1, L'.'); 2224 suffix->assign(1, L'.');
2224 suffix->append(user_name, size - 1); 2225 suffix->append(user_name, size - 1);
2225 return true; 2226 return true;
2226 } 2227 }
2227 2228
2228 base::string16 ShellUtil::ByteArrayToBase32(const uint8* bytes, size_t size) { 2229 base::string16 ShellUtil::ByteArrayToBase32(const uint8_t* bytes, size_t size) {
2229 static const char kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 2230 static const char kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
2230 2231
2231 // Eliminate special cases first. 2232 // Eliminate special cases first.
2232 if (size == 0) { 2233 if (size == 0) {
2233 return base::string16(); 2234 return base::string16();
2234 } else if (size == 1) { 2235 } else if (size == 1) {
2235 base::string16 ret; 2236 base::string16 ret;
2236 ret.push_back(kEncoding[(bytes[0] & 0xf8) >> 3]); 2237 ret.push_back(kEncoding[(bytes[0] & 0xf8) >> 3]);
2237 ret.push_back(kEncoding[(bytes[0] & 0x07) << 2]); 2238 ret.push_back(kEncoding[(bytes[0] & 0x07) << 2]);
2238 return ret; 2239 return ret;
2239 } else if (size >= std::numeric_limits<size_t>::max() / 8) { 2240 } else if (size >= std::numeric_limits<size_t>::max() / 8) {
2240 // If |size| is too big, the calculation of |encoded_length| below will 2241 // If |size| is too big, the calculation of |encoded_length| below will
2241 // overflow. 2242 // overflow.
2242 NOTREACHED(); 2243 NOTREACHED();
2243 return base::string16(); 2244 return base::string16();
2244 } 2245 }
2245 2246
2246 // Overestimate the number of bits in the string by 4 so that dividing by 5 2247 // Overestimate the number of bits in the string by 4 so that dividing by 5
2247 // is the equivalent of rounding up the actual number of bits divided by 5. 2248 // is the equivalent of rounding up the actual number of bits divided by 5.
2248 const size_t encoded_length = (size * 8 + 4) / 5; 2249 const size_t encoded_length = (size * 8 + 4) / 5;
2249 2250
2250 base::string16 ret; 2251 base::string16 ret;
2251 ret.reserve(encoded_length); 2252 ret.reserve(encoded_length);
2252 2253
2253 // A bit stream which will be read from the left and appended to from the 2254 // A bit stream which will be read from the left and appended to from the
2254 // right as it's emptied. 2255 // right as it's emptied.
2255 uint16 bit_stream = (bytes[0] << 8) + bytes[1]; 2256 uint16_t bit_stream = (bytes[0] << 8) + bytes[1];
2256 size_t next_byte_index = 2; 2257 size_t next_byte_index = 2;
2257 int free_bits = 0; 2258 int free_bits = 0;
2258 while (free_bits < 16) { 2259 while (free_bits < 16) {
2259 // Extract the 5 leftmost bits in the stream 2260 // Extract the 5 leftmost bits in the stream
2260 ret.push_back(kEncoding[(bit_stream & 0xf800) >> 11]); 2261 ret.push_back(kEncoding[(bit_stream & 0xf800) >> 11]);
2261 bit_stream <<= 5; 2262 bit_stream <<= 5;
2262 free_bits += 5; 2263 free_bits += 5;
2263 2264
2264 // If there is enough room in the bit stream, inject another byte (if there 2265 // If there is enough room in the bit stream, inject another byte (if there
2265 // are any left...). 2266 // are any left...).
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2336 itr != entries.end(); ++itr) 2337 itr != entries.end(); ++itr)
2337 (*itr)->AddToWorkItemList(root, items.get()); 2338 (*itr)->AddToWorkItemList(root, items.get());
2338 2339
2339 // Apply all the registry changes and if there is a problem, rollback 2340 // Apply all the registry changes and if there is a problem, rollback
2340 if (!items->Do()) { 2341 if (!items->Do()) {
2341 items->Rollback(); 2342 items->Rollback();
2342 return false; 2343 return false;
2343 } 2344 }
2344 return true; 2345 return true;
2345 } 2346 }
OLDNEW
« no previous file with comments | « chrome/installer/util/shell_util.h ('k') | chrome/installer/util/shell_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698