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 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 ShellUtil::GetBrowserModelId(dist, level == ShellUtil::CURRENT_USER)); | 1179 ShellUtil::GetBrowserModelId(dist, level == ShellUtil::CURRENT_USER)); |
1180 if (!base::DirectoryExists(folder)) { | 1180 if (!base::DirectoryExists(folder)) { |
1181 VLOG(1) << "No start screen shortcuts."; | 1181 VLOG(1) << "No start screen shortcuts."; |
1182 return false; | 1182 return false; |
1183 } | 1183 } |
1184 | 1184 |
1185 *path = folder; | 1185 *path = folder; |
1186 return true; | 1186 return true; |
1187 } | 1187 } |
1188 | 1188 |
1189 typedef base::Callback<bool(const base::FilePath&)> FileOperationCallback; | 1189 // Shortcut filters for BatchShortcutAction(). |
| 1190 |
| 1191 typedef base::Callback<bool(const base::FilePath& /*shortcut_path*/, |
| 1192 const string16& /*args*/)> |
| 1193 ShortcutFilterCallback; |
| 1194 |
| 1195 // FilterTargetEq is a shortcut filter that matches only shortcuts that have a |
| 1196 // specific target. |
| 1197 class FilterTargetEq { |
| 1198 public: |
| 1199 explicit FilterTargetEq(const base::FilePath& desired_target_exe); |
| 1200 |
| 1201 // Returns true if filter rules are satisfied, i.e.: |
| 1202 // - |target_path| matches |desired_target_compare_|. |
| 1203 bool Match(const base::FilePath& target_path, const string16& args) const; |
| 1204 |
| 1205 // A convenience routine to create a callback to call Match(). |
| 1206 // The callback is only valid during the lifetime of the FilterTargetEq |
| 1207 // instance. |
| 1208 ShortcutFilterCallback AsShortcutFilterCallback(); |
| 1209 |
| 1210 private: |
| 1211 InstallUtil::ProgramCompare desired_target_compare_; |
| 1212 }; |
| 1213 |
| 1214 FilterTargetEq::FilterTargetEq(const base::FilePath& desired_target_exe) |
| 1215 : desired_target_compare_(desired_target_exe) {} |
| 1216 |
| 1217 bool FilterTargetEq::Match(const base::FilePath& target_path, |
| 1218 const string16& args) const { |
| 1219 return desired_target_compare_.EvaluatePath(target_path); |
| 1220 } |
| 1221 |
| 1222 ShortcutFilterCallback FilterTargetEq::AsShortcutFilterCallback() { |
| 1223 return base::Bind(&FilterTargetEq::Match, base::Unretained(this)); |
| 1224 } |
1190 | 1225 |
1191 // Shortcut operations for BatchShortcutAction(). | 1226 // Shortcut operations for BatchShortcutAction(). |
1192 | 1227 |
| 1228 typedef base::Callback<bool(const base::FilePath& /*shortcut_path*/)> |
| 1229 ShortcutOperationCallback; |
| 1230 |
1193 bool ShortcutOpUnpin(const base::FilePath& shortcut_path) { | 1231 bool ShortcutOpUnpin(const base::FilePath& shortcut_path) { |
1194 VLOG(1) << "Trying to unpin " << shortcut_path.value(); | 1232 VLOG(1) << "Trying to unpin " << shortcut_path.value(); |
1195 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str())) { | 1233 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str())) { |
1196 VLOG(1) << shortcut_path.value() << " wasn't pinned (or the unpin failed)."; | 1234 VLOG(1) << shortcut_path.value() << " wasn't pinned (or the unpin failed)."; |
1197 // No error, since shortcut might not be pinned. | 1235 // No error, since shortcut might not be pinned. |
1198 } | 1236 } |
1199 return true; | 1237 return true; |
1200 } | 1238 } |
1201 | 1239 |
1202 bool ShortcutOpDelete(const base::FilePath& shortcut_path) { | 1240 bool ShortcutOpDelete(const base::FilePath& shortcut_path) { |
1203 bool ret = base::DeleteFile(shortcut_path, false); | 1241 bool ret = base::DeleteFile(shortcut_path, false); |
1204 LOG_IF(ERROR, !ret) << "Failed to remove " << shortcut_path.value(); | 1242 LOG_IF(ERROR, !ret) << "Failed to remove " << shortcut_path.value(); |
1205 return ret; | 1243 return ret; |
1206 } | 1244 } |
1207 | 1245 |
1208 bool ShortcutOpUpdate(const base::win::ShortcutProperties& shortcut_properties, | 1246 bool ShortcutOpUpdate(const base::win::ShortcutProperties& shortcut_properties, |
1209 const base::FilePath& shortcut_path) { | 1247 const base::FilePath& shortcut_path) { |
1210 bool ret = base::win::CreateOrUpdateShortcutLink( | 1248 bool ret = base::win::CreateOrUpdateShortcutLink( |
1211 shortcut_path, shortcut_properties, base::win::SHORTCUT_UPDATE_EXISTING); | 1249 shortcut_path, shortcut_properties, base::win::SHORTCUT_UPDATE_EXISTING); |
1212 LOG_IF(ERROR, !ret) << "Failed to update " << shortcut_path.value(); | 1250 LOG_IF(ERROR, !ret) << "Failed to update " << shortcut_path.value(); |
1213 return ret; | 1251 return ret; |
1214 } | 1252 } |
1215 | 1253 |
1216 // {|location|, |dist|, |level|} determine |shortcut_folder|. | 1254 // {|location|, |dist|, |level|} determine |shortcut_folder|. |
1217 // Applies |shortcut_operation| to each shortcut in |shortcut_folder| that | 1255 // For each shortcut in |shortcut_folder| that match |shortcut_filter|, apply |
1218 // targets |target_exe|. | 1256 // |shortcut_operation|. Returns true if all operations are successful. |
1219 // Returns true if all operations are successful. All intended operations are | 1257 // All intended operations are attempted, even if failures occur. |
1220 // attempted even if failures occur. | 1258 bool BatchShortcutAction(const ShortcutFilterCallback& shortcut_filter, |
1221 bool BatchShortcutAction(const FileOperationCallback& shortcut_operation, | 1259 const ShortcutOperationCallback& shortcut_operation, |
1222 ShellUtil::ShortcutLocation location, | 1260 ShellUtil::ShortcutLocation location, |
1223 BrowserDistribution* dist, | 1261 BrowserDistribution* dist, |
1224 ShellUtil::ShellChange level, | 1262 ShellUtil::ShellChange level) { |
1225 const base::FilePath& target_exe) { | |
1226 DCHECK(!shortcut_operation.is_null()); | 1263 DCHECK(!shortcut_operation.is_null()); |
1227 base::FilePath shortcut_folder; | 1264 base::FilePath shortcut_folder; |
1228 if (!ShellUtil::GetShortcutPath(location, dist, level, &shortcut_folder)) { | 1265 if (!ShellUtil::GetShortcutPath(location, dist, level, &shortcut_folder)) { |
1229 LOG(WARNING) << "Cannot find path at location " << location; | 1266 LOG(WARNING) << "Cannot find path at location " << location; |
1230 return false; | 1267 return false; |
1231 } | 1268 } |
1232 | 1269 |
1233 bool success = true; | 1270 bool success = true; |
1234 InstallUtil::ProgramCompare target_compare(target_exe); | |
1235 base::FileEnumerator enumerator( | 1271 base::FileEnumerator enumerator( |
1236 shortcut_folder, false, base::FileEnumerator::FILES, | 1272 shortcut_folder, false, base::FileEnumerator::FILES, |
1237 string16(L"*") + installer::kLnkExt); | 1273 string16(L"*") + installer::kLnkExt); |
1238 base::FilePath target_path; | 1274 base::FilePath target_path; |
| 1275 string16 args; |
1239 for (base::FilePath shortcut_path = enumerator.Next(); | 1276 for (base::FilePath shortcut_path = enumerator.Next(); |
1240 !shortcut_path.empty(); | 1277 !shortcut_path.empty(); |
1241 shortcut_path = enumerator.Next()) { | 1278 shortcut_path = enumerator.Next()) { |
1242 if (base::win::ResolveShortcut(shortcut_path, &target_path, NULL)) { | 1279 if (base::win::ResolveShortcut(shortcut_path, &target_path, &args)) { |
1243 if (target_compare.EvaluatePath(target_path) && | 1280 if (shortcut_filter.Run(target_path, args) && |
1244 !shortcut_operation.Run(shortcut_path)) { | 1281 !shortcut_operation.Run(shortcut_path)) { |
1245 success = false; | 1282 success = false; |
1246 } | 1283 } |
1247 } else { | 1284 } else { |
1248 LOG(ERROR) << "Cannot resolve shortcut at " << shortcut_path.value(); | 1285 LOG(ERROR) << "Cannot resolve shortcut at " << shortcut_path.value(); |
1249 success = false; | 1286 success = false; |
1250 } | 1287 } |
1251 } | 1288 } |
1252 return success; | 1289 return success; |
1253 } | 1290 } |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1989 const base::FilePath& target_exe) { | 2026 const base::FilePath& target_exe) { |
1990 if (!ShellUtil::ShortcutLocationIsSupported(location)) | 2027 if (!ShellUtil::ShortcutLocationIsSupported(location)) |
1991 return true; // Vacuous success. | 2028 return true; // Vacuous success. |
1992 | 2029 |
1993 switch (location) { | 2030 switch (location) { |
1994 case SHORTCUT_LOCATION_START_MENU: // Falls through. | 2031 case SHORTCUT_LOCATION_START_MENU: // Falls through. |
1995 case SHORTCUT_LOCATION_APP_SHORTCUTS: | 2032 case SHORTCUT_LOCATION_APP_SHORTCUTS: |
1996 return RemoveShortcutFolder(location, dist, level); | 2033 return RemoveShortcutFolder(location, dist, level); |
1997 | 2034 |
1998 case SHORTCUT_LOCATION_TASKBAR_PINS: | 2035 case SHORTCUT_LOCATION_TASKBAR_PINS: |
1999 return BatchShortcutAction(base::Bind(&ShortcutOpUnpin), location, dist, | 2036 return BatchShortcutAction(FilterTargetEq(target_exe). |
2000 level, target_exe); | 2037 AsShortcutFilterCallback(), |
| 2038 base::Bind(&ShortcutOpUnpin), |
| 2039 location, |
| 2040 dist, |
| 2041 level); |
2001 | 2042 |
2002 default: | 2043 default: |
2003 return BatchShortcutAction(base::Bind(&ShortcutOpDelete), location, dist, | 2044 return BatchShortcutAction(FilterTargetEq(target_exe). |
2004 level, target_exe); | 2045 AsShortcutFilterCallback(), |
| 2046 base::Bind(&ShortcutOpDelete), |
| 2047 location, |
| 2048 dist, |
| 2049 level); |
2005 } | 2050 } |
2006 } | 2051 } |
2007 | 2052 |
2008 // static | 2053 // static |
2009 bool ShellUtil::UpdateShortcuts( | 2054 bool ShellUtil::UpdateShortcuts( |
2010 ShellUtil::ShortcutLocation location, | 2055 ShellUtil::ShortcutLocation location, |
2011 BrowserDistribution* dist, | 2056 BrowserDistribution* dist, |
2012 ShellChange level, | 2057 ShellChange level, |
2013 const base::FilePath& target_exe, | 2058 const base::FilePath& target_exe, |
2014 const ShellUtil::ShortcutProperties& properties) { | 2059 const ShellUtil::ShortcutProperties& properties) { |
2015 if (!ShellUtil::ShortcutLocationIsSupported(location)) | 2060 if (!ShellUtil::ShortcutLocationIsSupported(location)) |
2016 return true; // Vacuous success. | 2061 return true; // Vacuous success. |
2017 | 2062 |
2018 base::win::ShortcutProperties shortcut_properties( | 2063 base::win::ShortcutProperties shortcut_properties( |
2019 TranslateShortcutProperties(properties)); | 2064 TranslateShortcutProperties(properties)); |
2020 return BatchShortcutAction(base::Bind(&ShortcutOpUpdate, shortcut_properties), | 2065 return BatchShortcutAction(FilterTargetEq(target_exe). |
2021 location, dist, level, target_exe); | 2066 AsShortcutFilterCallback(), |
| 2067 base::Bind(&ShortcutOpUpdate, shortcut_properties), |
| 2068 location, |
| 2069 dist, |
| 2070 level); |
2022 } | 2071 } |
2023 | 2072 |
2024 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) { | 2073 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) { |
2025 // Use a thread-safe cache for the user's suffix. | 2074 // Use a thread-safe cache for the user's suffix. |
2026 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance = | 2075 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance = |
2027 LAZY_INSTANCE_INITIALIZER; | 2076 LAZY_INSTANCE_INITIALIZER; |
2028 return suffix_instance.Get().GetSuffix(suffix); | 2077 return suffix_instance.Get().GetSuffix(suffix); |
2029 } | 2078 } |
2030 | 2079 |
2031 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) { | 2080 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2081 // are any left...). | 2130 // are any left...). |
2082 if (free_bits >= 8 && next_byte_index < size) { | 2131 if (free_bits >= 8 && next_byte_index < size) { |
2083 free_bits -= 8; | 2132 free_bits -= 8; |
2084 bit_stream += bytes[next_byte_index++] << free_bits; | 2133 bit_stream += bytes[next_byte_index++] << free_bits; |
2085 } | 2134 } |
2086 } | 2135 } |
2087 | 2136 |
2088 DCHECK_EQ(ret.length(), encoded_length); | 2137 DCHECK_EQ(ret.length(), encoded_length); |
2089 return ret; | 2138 return ret; |
2090 } | 2139 } |
OLD | NEW |