Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |