| 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 |