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

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

Issue 10836247: Refactor ShellUtil shortcut code -- single multi-purpose methods as opposed to many slighlty diffe… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: brand new shell_util shortcut API + TESTS :)! Created 8 years, 2 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 | Annotate | Revision Log
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"
(...skipping 28 matching lines...) Expand all
39 #include "chrome/common/chrome_switches.h" 39 #include "chrome/common/chrome_switches.h"
40 #include "chrome/installer/util/browser_distribution.h" 40 #include "chrome/installer/util/browser_distribution.h"
41 #include "chrome/installer/util/install_util.h" 41 #include "chrome/installer/util/install_util.h"
42 #include "chrome/installer/util/master_preferences.h" 42 #include "chrome/installer/util/master_preferences.h"
43 #include "chrome/installer/util/master_preferences_constants.h" 43 #include "chrome/installer/util/master_preferences_constants.h"
44 44
45 using base::win::RegKey; 45 using base::win::RegKey;
46 46
47 namespace { 47 namespace {
48 48
49 typedef ShellUtil::ChromeShortcutProperties ChromeShortcutProperties;
50
49 // An enum used to tell QuickIsChromeRegistered() which level of registration 51 // An enum used to tell QuickIsChromeRegistered() which level of registration
50 // the caller wants to confirm. 52 // the caller wants to confirm.
51 enum RegistrationConfirmationLevel { 53 enum RegistrationConfirmationLevel {
52 // Only look for Chrome's ProgIds. 54 // Only look for Chrome's ProgIds.
53 // This is sufficient when we are trying to determine the suffix of the 55 // This is sufficient when we are trying to determine the suffix of the
54 // currently running Chrome as shell integration registrations might not be 56 // currently running Chrome as shell integration registrations might not be
55 // present. 57 // present.
56 CONFIRM_PROGID_REGISTRATION = 0, 58 CONFIRM_PROGID_REGISTRATION = 0,
57 // Confirm that Chrome is fully integrated with Windows (i.e. registered with 59 // Confirm that Chrome is fully integrated with Windows (i.e. registered with
58 // Defaut Programs). These registrations can be in HKCU as of Windows 8. 60 // Defaut Programs). These registrations can be in HKCU as of Windows 8.
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 &entries); 932 &entries);
931 // Change the default protocol handler for current user. 933 // Change the default protocol handler for current user.
932 if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) { 934 if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
933 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; 935 LOG(ERROR) << "Could not make Chrome default protocol client (XP).";
934 return false; 936 return false;
935 } 937 }
936 938
937 return true; 939 return true;
938 } 940 }
939 941
942 // Returns |properties.shortcut_name| if the property is set, otherwise it
943 // returns dist->GetAppShortcutName(). In any case, it makes sure the
944 // return value is suffixed with ".lnk".
945 string16 ExtractShortcutNameFromProperties(
946 BrowserDistribution* dist,
947 const ChromeShortcutProperties& properties) {
948 DCHECK(dist);
949 string16 shortcut_name;
950 if (properties.options & ChromeShortcutProperties::PROPERTIES_SHORTCUT_NAME)
951 shortcut_name = properties.shortcut_name;
952 else
953 shortcut_name = dist->GetAppShortCutName();
954
955 static const wchar_t lnk_ext[] = L".lnk";
grt (UTC plus 2) 2012/10/02 13:22:30 although the style guide doesn't call it out, i th
gab 2012/10/03 15:14:59 Adding L".lnk" in a bunch of places has been buggi
956 if (!EndsWith(shortcut_name, lnk_ext, false))
957 shortcut_name.append(lnk_ext);
958
959 return shortcut_name;
960 }
961
962 // Returns a ShortcutProperties struct containing the properties to set on the
963 // shortcut based on the provided ChromeShortcutProperties. If |operation| is
964 // to create, some properties (e.g. icon, app_id) might be given a default if
965 // not set in |properties| (see individual ChromeShortcutProperties for
966 // details).
967 base::win::ShortcutProperties GetShortcutPropertiesFromChromeShortcutProperties(
968 BrowserDistribution* dist,
969 const ChromeShortcutProperties& properties,
970 base::win::ShortcutOperation operation) {
971 bool create = (operation == base::win::SHORTCUT_CREATE_ALWAYS ||
972 operation == base::win::SHORTCUT_REPLACE_EXISTING);
973 // |target| is mandatory when creating the shortcut.
974 DCHECK(!create ||
975 (properties.options & ChromeShortcutProperties::PROPERTIES_TARGET));
976
977 base::win::ShortcutProperties shortcut_properties;
978
979 bool target_is_chrome_exe = false;
grt (UTC plus 2) 2012/10/02 13:22:30 i wonder if there's a better way to handle default
gab 2012/10/03 15:14:59 As discussed the target is now always chrome.exe w
980 if (properties.options & ChromeShortcutProperties::PROPERTIES_TARGET) {
981 shortcut_properties.set_target(properties.target);
982 DCHECK(!properties.target.DirName().empty());
983 shortcut_properties.set_working_dir(properties.target.DirName());
984
985 if (properties.target.BaseName() == FilePath(installer::kChromeExe))
grt (UTC plus 2) 2012/10/02 13:22:30 BaseName().value() == installer.kChromeExe to avoi
gab 2012/10/03 15:14:59 I also debated doing that and decided not to given
986 target_is_chrome_exe = true;
987 }
988
989 if (properties.options & ChromeShortcutProperties::PROPERTIES_ARGUMENTS)
990 shortcut_properties.set_arguments(properties.arguments);
991
992 if (properties.options & ChromeShortcutProperties::PROPERTIES_DESCRIPTION)
993 shortcut_properties.set_description(properties.description);
994 else if (create && target_is_chrome_exe)
995 shortcut_properties.set_description(dist->GetAppDescription());
996
997 if (properties.options & ChromeShortcutProperties::PROPERTIES_ICON) {
998 shortcut_properties.set_icon(properties.icon, 0);
grt (UTC plus 2) 2012/10/02 13:22:30 the icon index can't be set by users of ChromeShor
gab 2012/10/03 15:14:59 No current caller required it, i.e. either callers
999 } else if (create) {
1000 // Set the icon to |properties.target| by default when creating a shortcut.
1001 // If |properties.target| is chrome.exe, set |icon_index| as per the
1002 // master_preferences if specified or as per the default icon index for this
1003 // distribution.
1004 int icon_index = 0;
1005 if (target_is_chrome_exe) {
1006 installer::MasterPreferences prefs(
grt (UTC plus 2) 2012/10/02 13:22:30 this scares me a little bit. let's talk about it.
gab 2012/10/03 15:14:59 Yea it's ugly, just copying the old behavior from
1007 properties.target.DirName().AppendASCII(
1008 installer::kDefaultMasterPrefs));
1009 if (!prefs.GetInt(installer::master_preferences::kChromeShortcutIconIndex,
1010 &icon_index)) {
1011 icon_index = dist->GetIconIndex();
1012 }
1013 }
1014 shortcut_properties.set_icon(properties.target, icon_index);
1015 }
1016
1017 if (properties.options & ChromeShortcutProperties::PROPERTIES_APP_ID) {
1018 shortcut_properties.set_app_id(properties.app_id);
1019 } else if (create && target_is_chrome_exe) {
1020 // Set the AppUserModelId to this distribution's AppId by default when
1021 // creating the shortcut and the target is chrome.exe.
1022 bool is_per_user_install =
1023 InstallUtil::IsPerUserInstall(properties.target.value().c_str());
1024 shortcut_properties.set_app_id(
1025 ShellUtil::GetBrowserModelId(dist, is_per_user_install));
1026 }
1027
1028 if (properties.options & ChromeShortcutProperties::PROPERTIES_DUAL_MODE)
1029 shortcut_properties.set_dual_mode(properties.dual_mode);
1030
1031 return shortcut_properties;
1032 }
1033
940 } // namespace 1034 } // namespace
941 1035
942 const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon"; 1036 const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon";
943 const wchar_t* ShellUtil::kRegShellPath = L"\\shell"; 1037 const wchar_t* ShellUtil::kRegShellPath = L"\\shell";
944 const wchar_t* ShellUtil::kRegShellOpen = L"\\shell\\open\\command"; 1038 const wchar_t* ShellUtil::kRegShellOpen = L"\\shell\\open\\command";
945 const wchar_t* ShellUtil::kRegStartMenuInternet = 1039 const wchar_t* ShellUtil::kRegStartMenuInternet =
946 L"Software\\Clients\\StartMenuInternet"; 1040 L"Software\\Clients\\StartMenuInternet";
947 const wchar_t* ShellUtil::kRegClasses = L"Software\\Classes"; 1041 const wchar_t* ShellUtil::kRegClasses = L"Software\\Classes";
948 const wchar_t* ShellUtil::kRegRegisteredApplications = 1042 const wchar_t* ShellUtil::kRegRegisteredApplications =
949 L"Software\\RegisteredApplications"; 1043 L"Software\\RegisteredApplications";
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 const wchar_t* ShellUtil::kRegDelegateExecute = L"DelegateExecute"; 1079 const wchar_t* ShellUtil::kRegDelegateExecute = L"DelegateExecute";
986 const wchar_t* ShellUtil::kRegOpenWithProgids = L"OpenWithProgids"; 1080 const wchar_t* ShellUtil::kRegOpenWithProgids = L"OpenWithProgids";
987 1081
988 bool ShellUtil::QuickIsChromeRegisteredInHKLM(BrowserDistribution* dist, 1082 bool ShellUtil::QuickIsChromeRegisteredInHKLM(BrowserDistribution* dist,
989 const string16& chrome_exe, 1083 const string16& chrome_exe,
990 const string16& suffix) { 1084 const string16& suffix) {
991 return QuickIsChromeRegistered(dist, chrome_exe, suffix, 1085 return QuickIsChromeRegistered(dist, chrome_exe, suffix,
992 CONFIRM_SHELL_REGISTRATION_IN_HKLM); 1086 CONFIRM_SHELL_REGISTRATION_IN_HKLM);
993 } 1087 }
994 1088
995 bool ShellUtil::CreateChromeDesktopShortcut(BrowserDistribution* dist, 1089 bool ShellUtil::GetShortcutPath(ChromeShortcutLocation location,
996 const string16& chrome_exe, 1090 BrowserDistribution* dist,
robertshield 2012/10/02 13:08:04 this doesn't use the dist parameter
gab 2012/10/03 15:14:59 Oops, I added this with the intent of removing Get
997 const string16& description, 1091 bool system_level,
998 const string16& appended_name, 1092 FilePath* path) {
999 const string16& arguments, 1093 int dir_key = -1;
1000 const string16& icon_path, 1094 bool add_folder_for_dist = false;
1001 int icon_index, 1095 switch (location) {
1002 ShellChange shell_change, 1096 case SHORTCUT_DESKTOP:
1003 uint32 options) { 1097 dir_key = system_level ? base::DIR_COMMON_DESKTOP :
1004 string16 shortcut_name; 1098 base::DIR_USER_DESKTOP;
1005 bool alternate = (options & ShellUtil::SHORTCUT_ALTERNATE) != 0; 1099 break;
1006 if (!ShellUtil::GetChromeShortcutName(dist, alternate, appended_name, 1100 case SHORTCUT_QUICK_LAUNCH:
1007 &shortcut_name)) 1101 dir_key = system_level ? base::DIR_DEFAULT_USER_QUICK_LAUNCH :
1102 base::DIR_USER_QUICK_LAUNCH;
1103 break;
1104 case SHORTCUT_START_MENU:
1105 dir_key = system_level ? base::DIR_COMMON_START_MENU :
1106 base::DIR_START_MENU;
1107 add_folder_for_dist = true;
1108 break;
1109 default:
1110 NOTREACHED();
1111 return false;
1112 }
1113
1114 if (dir_key == -1 || !PathService::Get(dir_key, path) || path->empty()) {
1115 NOTREACHED() << dir_key;
1008 return false; 1116 return false;
1117 }
1009 1118
1010 bool ret = false; 1119 if (add_folder_for_dist) {
1011 if (shell_change == ShellUtil::CURRENT_USER) { 1120 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
1012 FilePath shortcut_path; 1121 *path = path->Append(dist->GetAppShortCutName());
1013 // We do not want to create a desktop shortcut to Chrome in the current
1014 // user's desktop folder if there is already one in the "All Users"
1015 // desktop folder.
1016 bool got_system_desktop = ShellUtil::GetDesktopPath(true, &shortcut_path);
1017 FilePath shortcut = shortcut_path.Append(shortcut_name);
1018 if (!got_system_desktop || !file_util::PathExists(shortcut)) {
1019 // Either we couldn't query the "All Users" Desktop folder or there's
1020 // nothing in it, so let's continue.
1021 if (ShellUtil::GetDesktopPath(false, &shortcut_path)) {
1022 shortcut = shortcut_path.Append(shortcut_name);
1023 ret = ShellUtil::UpdateChromeShortcut(dist,
1024 chrome_exe,
1025 shortcut.value(),
1026 arguments,
1027 description,
1028 icon_path,
1029 icon_index,
1030 options);
1031 }
1032 }
1033 } else if (shell_change == ShellUtil::SYSTEM_LEVEL) {
1034 FilePath shortcut_path;
1035 if (ShellUtil::GetDesktopPath(true, &shortcut_path)) {
1036 FilePath shortcut = shortcut_path.Append(shortcut_name);
1037 ret = ShellUtil::UpdateChromeShortcut(dist,
1038 chrome_exe,
1039 shortcut.value(),
1040 arguments,
1041 description,
1042 icon_path,
1043 icon_index,
1044 options);
1045 }
1046 } else {
1047 NOTREACHED();
1048 } 1122 }
1049 return ret; 1123
1124 return true;
1050 } 1125 }
1051 1126
1052 bool ShellUtil::CreateChromeQuickLaunchShortcut(BrowserDistribution* dist, 1127 bool ShellUtil::CreateOrUpdateChromeShortcut(
1053 const string16& chrome_exe, 1128 ShellUtil::ChromeShortcutLocation location,
1054 int shell_change, 1129 BrowserDistribution* dist,
1055 uint32 options) { 1130 const ChromeShortcutProperties& properties,
1056 string16 shortcut_name; 1131 ChromeShortcutOperation operation) {
1057 if (!ShellUtil::GetChromeShortcutName(dist, false, L"", &shortcut_name)) 1132 DCHECK(dist);
1133 // |pin_to_taskbar| is only acknowledged when first creating the shortcut.
1134 DCHECK(!properties.pin_to_taskbar ||
1135 operation == base::win::SHORTCUT_CREATE_ALWAYS);
1136
1137 FilePath user_shortcut_path;
1138 FilePath system_shortcut_path;
1139 if (!GetShortcutPath(location, dist, false, &user_shortcut_path) ||
1140 !GetShortcutPath(location, dist, true, &system_shortcut_path) ||
1141 user_shortcut_path.empty() ||
1142 system_shortcut_path.empty()) {
1143 NOTREACHED();
1058 return false; 1144 return false;
1145 }
1059 1146
1060 bool ret = true; 1147 string16 shortcut_name(ExtractShortcutNameFromProperties(dist, properties));
1061 // First create shortcut for the current user. 1148 user_shortcut_path = user_shortcut_path.Append(shortcut_name);
1062 if (shell_change & ShellUtil::CURRENT_USER) { 1149 system_shortcut_path = system_shortcut_path.Append(shortcut_name);
1063 FilePath user_ql_path; 1150
1064 if (ShellUtil::GetQuickLaunchPath(false, &user_ql_path)) { 1151 FilePath *chosen_path;
1065 user_ql_path = user_ql_path.Append(shortcut_name); 1152 if (properties.system_level) {
1066 ret = ShellUtil::UpdateChromeShortcut(dist, chrome_exe, 1153 // Install the system-level shortcut if requested.
1067 user_ql_path.value(), 1154 chosen_path = &system_shortcut_path;
1068 L"", L"", chrome_exe, 1155 } else if (operation != SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL ||
1069 dist->GetIconIndex(), 1156 !file_util::PathExists(system_shortcut_path)){
1070 options); 1157 // Otherwise install the user-level shortcut, unless the system-level
1071 } else { 1158 // variant of this shortcut is present on the machine and |operation| states
1072 ret = false; 1159 // not to create a user-level shortcut in that case.
1160 chosen_path = &user_shortcut_path;
1161 } else {
1162 // Do not install anything if we are told to install a user-level shortcut,
1163 // but the system-level variant of that shortcut is present.
1164 chosen_path = &FilePath();
1165 }
1166
1167 // No shortcut needs to be created/updated.
1168 if (chosen_path->empty())
1169 return true;
1170
1171 // Make sure the parent directories exist when creating the shortcut.
1172 if (operation == SHORTCUT_CREATE_ALWAYS &&
1173 !file_util::CreateDirectory(chosen_path->DirName())) {
1174 NOTREACHED();
1175 return false;
1176 }
1177
1178 base::win::ShortcutOperation shortcut_operation =
1179 (operation == SHORTCUT_UPDATE_EXISTING ?
1180 base::win::SHORTCUT_UPDATE_EXISTING :
1181 (operation == SHORTCUT_REPLACE_EXISTING ?
1182 base::win::SHORTCUT_REPLACE_EXISTING :
1183 base::win::SHORTCUT_CREATE_ALWAYS));
1184 base::win::ShortcutProperties shortcut_properties(
1185 GetShortcutPropertiesFromChromeShortcutProperties(dist, properties,
1186 shortcut_operation));
1187 bool ret = base::win::CreateOrUpdateShortcutLink(
1188 *chosen_path, shortcut_properties, shortcut_operation);
1189
1190 if (ret && operation == SHORTCUT_CREATE_ALWAYS && properties.pin_to_taskbar &&
1191 base::win::GetVersion() >= base::win::VERSION_WIN7) {
1192 ret = base::win::TaskbarPinShortcutLink(chosen_path->value().c_str());
1193 if (!ret) {
1194 LOG(ERROR) << "The shorcut at " << chosen_path->value()
1195 << " was created, but the taskbar pin failed.";
1073 } 1196 }
1074 } 1197 }
1075 1198
1076 // Add a shortcut to Default User's profile so that all new user profiles
1077 // get it.
1078 if (shell_change & ShellUtil::SYSTEM_LEVEL) {
1079 FilePath default_ql_path;
1080 if (ShellUtil::GetQuickLaunchPath(true, &default_ql_path)) {
1081 default_ql_path = default_ql_path.Append(shortcut_name);
1082 ret = ShellUtil::UpdateChromeShortcut(dist, chrome_exe,
1083 default_ql_path.value(),
1084 L"", L"", chrome_exe,
1085 dist->GetIconIndex(),
1086 options) && ret;
1087 } else {
1088 ret = false;
1089 }
1090 }
1091
1092 return ret; 1199 return ret;
1093 } 1200 }
1094 1201
1095 string16 ShellUtil::GetChromeIcon(BrowserDistribution* dist, 1202 string16 ShellUtil::GetChromeIcon(BrowserDistribution* dist,
1096 const string16& chrome_exe) { 1203 const string16& chrome_exe) {
1097 string16 chrome_icon(chrome_exe); 1204 string16 chrome_icon(chrome_exe);
1098 chrome_icon.append(L","); 1205 chrome_icon.append(L",");
1099 chrome_icon.append(base::IntToString16(dist->GetIconIndex())); 1206 chrome_icon.append(base::IntToString16(dist->GetIconIndex()));
1100 return chrome_icon; 1207 return chrome_icon;
1101 } 1208 }
1102 1209
1103 string16 ShellUtil::GetChromeShellOpenCmd(const string16& chrome_exe) { 1210 string16 ShellUtil::GetChromeShellOpenCmd(const string16& chrome_exe) {
1104 return L"\"" + chrome_exe + L"\" -- \"%1\""; 1211 return L"\"" + chrome_exe + L"\" -- \"%1\"";
1105 } 1212 }
1106 1213
1107 string16 ShellUtil::GetChromeDelegateCommand(const string16& chrome_exe) { 1214 string16 ShellUtil::GetChromeDelegateCommand(const string16& chrome_exe) {
1108 return L"\"" + chrome_exe + L"\" -- %*"; 1215 return L"\"" + chrome_exe + L"\" -- %*";
1109 } 1216 }
1110 1217
1111 bool ShellUtil::GetChromeShortcutName(BrowserDistribution* dist,
1112 bool alternate,
1113 const string16& appended_name,
1114 string16* shortcut) {
1115 shortcut->assign(alternate ? dist->GetAlternateApplicationName() :
1116 dist->GetAppShortCutName());
1117 if (!appended_name.empty()) {
1118 shortcut->append(L" (");
1119 shortcut->append(appended_name);
1120 shortcut->append(L")");
1121 }
1122 shortcut->append(L".lnk");
1123 return true;
1124 }
1125
1126 bool ShellUtil::GetDesktopPath(bool system_level, FilePath* path) {
1127 int dir_key = system_level ? base::DIR_COMMON_DESKTOP :
1128 base::DIR_USER_DESKTOP;
1129 return PathService::Get(dir_key, path);
1130 }
1131
1132 bool ShellUtil::GetQuickLaunchPath(bool system_level, FilePath* path) {
1133 int dir_key = system_level ? base::DIR_DEFAULT_USER_QUICK_LAUNCH :
1134 base::DIR_USER_QUICK_LAUNCH;
1135 return PathService::Get(dir_key, path);
1136 }
1137
1138 void ShellUtil::GetRegisteredBrowsers( 1218 void ShellUtil::GetRegisteredBrowsers(
1139 BrowserDistribution* dist, 1219 BrowserDistribution* dist,
1140 std::map<string16, string16>* browsers) { 1220 std::map<string16, string16>* browsers) {
1141 DCHECK(dist); 1221 DCHECK(dist);
1142 DCHECK(browsers); 1222 DCHECK(browsers);
1143 1223
1144 const string16 base_key(ShellUtil::kRegStartMenuInternet); 1224 const string16 base_key(ShellUtil::kRegStartMenuInternet);
1145 string16 client_path; 1225 string16 client_path;
1146 RegKey key; 1226 RegKey key;
1147 string16 name; 1227 string16 name;
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 } else if (elevate_if_not_admin && 1624 } else if (elevate_if_not_admin &&
1545 base::win::GetVersion() >= base::win::VERSION_VISTA) { 1625 base::win::GetVersion() >= base::win::VERSION_VISTA) {
1546 // Elevate to do the whole job 1626 // Elevate to do the whole job
1547 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); 1627 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol);
1548 } else { 1628 } else {
1549 // Admin rights are required to register capabilities before Windows 8. 1629 // Admin rights are required to register capabilities before Windows 8.
1550 return false; 1630 return false;
1551 } 1631 }
1552 } 1632 }
1553 1633
1554 bool ShellUtil::RemoveChromeDesktopShortcut(BrowserDistribution* dist, 1634 bool ShellUtil::RemoveChromeShortcut(
1555 int shell_change, uint32 options) { 1635 ChromeShortcutLocation location,
1556 // Only SHORTCUT_ALTERNATE is a valid option for this function. 1636 BrowserDistribution* dist,
1557 DCHECK(!options || options == ShellUtil::SHORTCUT_ALTERNATE); 1637 const ChromeShortcutProperties& properties) {
1638 bool delete_folder = (location == SHORTCUT_START_MENU);
1558 1639
1559 string16 shortcut_name; 1640 FilePath shortcut_folder;
1560 bool alternate = (options & ShellUtil::SHORTCUT_ALTERNATE) != 0; 1641 if (!GetShortcutPath(location, dist, properties.system_level,
1561 if (!ShellUtil::GetChromeShortcutName(dist, alternate, L"", 1642 &shortcut_folder) ||
1562 &shortcut_name)) 1643 shortcut_folder.empty()) {
1644 NOTREACHED();
1563 return false; 1645 return false;
1564
1565 bool ret = true;
1566 if (shell_change & ShellUtil::CURRENT_USER) {
1567 FilePath shortcut_path;
1568 if (ShellUtil::GetDesktopPath(false, &shortcut_path)) {
1569 FilePath shortcut = shortcut_path.Append(shortcut_name);
1570 ret = file_util::Delete(shortcut, false);
1571 } else {
1572 ret = false;
1573 }
1574 } 1646 }
1575 1647
1576 if (shell_change & ShellUtil::SYSTEM_LEVEL) { 1648 FilePath shortcut_path(shortcut_folder.Append(
1577 FilePath shortcut_path; 1649 ExtractShortcutNameFromProperties(dist, properties)));
1578 if (ShellUtil::GetDesktopPath(true, &shortcut_path)) {
1579 FilePath shortcut = shortcut_path.Append(shortcut_name);
1580 ret = file_util::Delete(shortcut, false) && ret;
1581 } else {
1582 ret = false;
1583 }
1584 }
1585 return ret;
1586 }
1587 1650
1588 bool ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames( 1651 // Unpin the shortcut if it was ever pinned by the user or the installer.
1589 const std::vector<string16>& appended_names) { 1652 VLOG(1) << "Trying to unpin " << shortcut_path.value();
1590 FilePath shortcut_path; 1653 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str()))
1591 bool ret = true; 1654 VLOG(1) << shortcut_path.value() << " wasn't pinned (or the unpin failed).";
1592 if (ShellUtil::GetDesktopPath(false, &shortcut_path)) {
1593 for (std::vector<string16>::const_iterator it =
1594 appended_names.begin();
1595 it != appended_names.end();
1596 ++it) {
1597 FilePath delete_shortcut = shortcut_path.Append(*it);
1598 ret = ret && file_util::Delete(delete_shortcut, false);
1599 }
1600 } else {
1601 ret = false;
1602 }
1603 return ret;
1604 }
1605 1655
1606 bool ShellUtil::RemoveChromeQuickLaunchShortcut(BrowserDistribution* dist, 1656 if (delete_folder)
1607 int shell_change) { 1657 return file_util::Delete(shortcut_folder, true);
1608 string16 shortcut_name; 1658 else
1609 if (!ShellUtil::GetChromeShortcutName(dist, false, L"", &shortcut_name)) 1659 return file_util::Delete(shortcut_path, false);
1610 return false;
1611
1612 bool ret = true;
1613 // First remove shortcut for the current user.
1614 if (shell_change & ShellUtil::CURRENT_USER) {
1615 FilePath user_ql_path;
1616 if (ShellUtil::GetQuickLaunchPath(false, &user_ql_path)) {
1617 user_ql_path = user_ql_path.Append(shortcut_name);
1618 ret = file_util::Delete(user_ql_path, false);
1619 } else {
1620 ret = false;
1621 }
1622 }
1623
1624 // Delete shortcut in Default User's profile
1625 if (shell_change & ShellUtil::SYSTEM_LEVEL) {
1626 FilePath default_ql_path;
1627 if (ShellUtil::GetQuickLaunchPath(true, &default_ql_path)) {
1628 default_ql_path = default_ql_path.Append(shortcut_name);
1629 ret = file_util::Delete(default_ql_path, false) && ret;
1630 } else {
1631 ret = false;
1632 }
1633 }
1634
1635 return ret;
1636 } 1660 }
1637 1661
1638 void ShellUtil::RemoveChromeStartScreenShortcuts(BrowserDistribution* dist, 1662 void ShellUtil::RemoveChromeStartScreenShortcuts(BrowserDistribution* dist,
1639 const string16& chrome_exe) { 1663 const string16& chrome_exe) {
1640 if (base::win::GetVersion() < base::win::VERSION_WIN8) 1664 if (base::win::GetVersion() < base::win::VERSION_WIN8)
1641 return; 1665 return;
1642 1666
1643 FilePath app_shortcuts_path; 1667 FilePath app_shortcuts_path;
1644 if (!PathService::Get(base::DIR_APP_SHORTCUTS, &app_shortcuts_path)) { 1668 if (!PathService::Get(base::DIR_APP_SHORTCUTS, &app_shortcuts_path)) {
1645 LOG(ERROR) << "Could not get application shortcuts location to delete" 1669 LOG(ERROR) << "Could not get application shortcuts location to delete"
(...skipping 10 matching lines...) Expand all
1656 } 1680 }
1657 1681
1658 VLOG(1) << "Removing start screen shortcuts from " 1682 VLOG(1) << "Removing start screen shortcuts from "
1659 << app_shortcuts_path.value(); 1683 << app_shortcuts_path.value();
1660 if (!file_util::Delete(app_shortcuts_path, true)) { 1684 if (!file_util::Delete(app_shortcuts_path, true)) {
1661 LOG(ERROR) << "Failed to remove start screen shortcuts from " 1685 LOG(ERROR) << "Failed to remove start screen shortcuts from "
1662 << app_shortcuts_path.value(); 1686 << app_shortcuts_path.value();
1663 } 1687 }
1664 } 1688 }
1665 1689
1666 bool ShellUtil::UpdateChromeShortcut(BrowserDistribution* dist,
1667 const string16& chrome_exe,
1668 const string16& shortcut,
1669 const string16& arguments,
1670 const string16& description,
1671 const string16& icon_path,
1672 int icon_index,
1673 uint32 options) {
1674 const FilePath chrome_path(FilePath(chrome_exe).DirName());
1675
1676 installer::MasterPreferences prefs(
1677 chrome_path.AppendASCII(installer::kDefaultMasterPrefs));
1678 if (FilePath::CompareEqualIgnoreCase(icon_path, chrome_exe)) {
1679 prefs.GetInt(installer::master_preferences::kChromeShortcutIconIndex,
1680 &icon_index);
1681 }
1682
1683 const string16 app_id(
1684 GetBrowserModelId(dist,
1685 InstallUtil::IsPerUserInstall(chrome_exe.c_str())));
1686 const bool is_dual_mode = ((options & ShellUtil::SHORTCUT_DUAL_MODE) != 0);
1687 const base::win::ShortcutOperation operation =
1688 (options & ShellUtil::SHORTCUT_CREATE_ALWAYS) != 0 ?
1689 base::win::SHORTCUT_CREATE_ALWAYS :
1690 base::win::SHORTCUT_UPDATE_EXISTING;
1691
1692 // TODO(gab): The shell_util interface will also be refactored in an upcoming
1693 // CL to use a ShortcutProperties like interface for its shortcut methods.
1694 base::win::ShortcutProperties shortcut_properties;
1695 shortcut_properties.set_target(FilePath(chrome_exe));
1696 shortcut_properties.set_working_dir(chrome_path);
1697 shortcut_properties.set_arguments(arguments);
1698 shortcut_properties.set_description(description);
1699 shortcut_properties.set_icon(FilePath(icon_path), icon_index);
1700 shortcut_properties.set_app_id(app_id);
1701 shortcut_properties.set_dual_mode(is_dual_mode);
1702 return base::win::CreateOrUpdateShortcutLink(
1703 FilePath(shortcut), shortcut_properties, operation);
1704 }
1705
1706 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) { 1690 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) {
1707 // Use a thread-safe cache for the user's suffix. 1691 // Use a thread-safe cache for the user's suffix.
1708 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance = 1692 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance =
1709 LAZY_INSTANCE_INITIALIZER; 1693 LAZY_INSTANCE_INITIALIZER;
1710 return suffix_instance.Get().GetSuffix(suffix); 1694 return suffix_instance.Get().GetSuffix(suffix);
1711 } 1695 }
1712 1696
1713 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) { 1697 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) {
1714 wchar_t user_name[256]; 1698 wchar_t user_name[256];
1715 DWORD size = arraysize(user_name); 1699 DWORD size = arraysize(user_name);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 // are any left...). 1747 // are any left...).
1764 if (free_bits >= 8 && next_byte_index < size) { 1748 if (free_bits >= 8 && next_byte_index < size) {
1765 free_bits -= 8; 1749 free_bits -= 8;
1766 bit_stream += bytes[next_byte_index++] << free_bits; 1750 bit_stream += bytes[next_byte_index++] << free_bits;
1767 } 1751 }
1768 } 1752 }
1769 1753
1770 DCHECK_EQ(ret.length(), encoded_length); 1754 DCHECK_EQ(ret.length(), encoded_length);
1771 return ret; 1755 return ret;
1772 } 1756 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698