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&, const string16&)> | |
1192 FileFilterCallback; | |
gab
2013/08/09 13:40:47
I don't think it makes sense to make these generic
huangs
2013/08/09 15:06:20
Done. Also added variable names in side /* comment
| |
1193 | |
1194 // FilterTargetEq is a shortcut filter that matches only shortcuts that have a | |
1195 // specific target. | |
1196 class FilterTargetEq { | |
1197 public: | |
1198 explicit FilterTargetEq(const base::FilePath& filt_target_exe); | |
gab
2013/08/09 13:40:47
Abbreviations are frowned upon in chrome.
Use som
huangs
2013/08/09 15:06:20
Done.
| |
1199 | |
1200 // Returns true if |target_path| matches the arget stored. | |
gab
2013/08/09 13:40:47
s/arget/target
huangs
2013/08/09 15:06:20
Done; elaborated a bit more (this will be extended
| |
1201 bool Match(const base::FilePath& target_path, const string16& args) const; | |
1202 | |
1203 // A convenience routine that creates a callback to call Match(). | |
1204 FileFilterCallback Bind(); | |
gab
2013/08/09 13:40:47
Rename this method to AsShortcutFilterCallback(),
huangs
2013/08/09 15:06:20
Also copied comments regarding lifetime.
| |
1205 | |
1206 private: | |
1207 InstallUtil::ProgramCompare filt_target_compare_; | |
1208 }; | |
1209 | |
1210 FilterTargetEq::FilterTargetEq(const base::FilePath& filt_target_exe) | |
1211 : filt_target_compare_(filt_target_exe) {} | |
1212 | |
1213 bool FilterTargetEq::Match(const base::FilePath& target_path, | |
1214 const string16& args) const { | |
1215 return filt_target_compare_.EvaluatePath(target_path); | |
1216 } | |
1217 | |
1218 FileFilterCallback FilterTargetEq::Bind() { | |
1219 return base::Bind(&FilterTargetEq::Match, base::Unretained(this)); | |
1220 } | |
1190 | 1221 |
1191 // Shortcut operations for BatchShortcutAction(). | 1222 // Shortcut operations for BatchShortcutAction(). |
1192 | 1223 |
1224 typedef base::Callback<bool(const base::FilePath&)> FileOperationCallback; | |
gab
2013/08/09 13:40:47
This one is fine as a general "File operation" I g
huangs
2013/08/09 15:06:20
Done.
| |
1225 | |
1193 bool ShortcutOpUnpin(const base::FilePath& shortcut_path) { | 1226 bool ShortcutOpUnpin(const base::FilePath& shortcut_path) { |
1194 VLOG(1) << "Trying to unpin " << shortcut_path.value(); | 1227 VLOG(1) << "Trying to unpin " << shortcut_path.value(); |
1195 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str())) { | 1228 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str())) { |
1196 VLOG(1) << shortcut_path.value() << " wasn't pinned (or the unpin failed)."; | 1229 VLOG(1) << shortcut_path.value() << " wasn't pinned (or the unpin failed)."; |
1197 // No error, since shortcut might not be pinned. | 1230 // No error, since shortcut might not be pinned. |
1198 } | 1231 } |
1199 return true; | 1232 return true; |
1200 } | 1233 } |
1201 | 1234 |
1202 bool ShortcutOpDelete(const base::FilePath& shortcut_path) { | 1235 bool ShortcutOpDelete(const base::FilePath& shortcut_path) { |
1203 bool ret = base::DeleteFile(shortcut_path, false); | 1236 bool ret = base::DeleteFile(shortcut_path, false); |
1204 LOG_IF(ERROR, !ret) << "Failed to remove " << shortcut_path.value(); | 1237 LOG_IF(ERROR, !ret) << "Failed to remove " << shortcut_path.value(); |
1205 return ret; | 1238 return ret; |
1206 } | 1239 } |
1207 | 1240 |
1208 bool ShortcutOpUpdate(const base::win::ShortcutProperties& shortcut_properties, | 1241 bool ShortcutOpUpdate(const base::win::ShortcutProperties& shortcut_properties, |
1209 const base::FilePath& shortcut_path) { | 1242 const base::FilePath& shortcut_path) { |
1210 bool ret = base::win::CreateOrUpdateShortcutLink( | 1243 bool ret = base::win::CreateOrUpdateShortcutLink( |
1211 shortcut_path, shortcut_properties, base::win::SHORTCUT_UPDATE_EXISTING); | 1244 shortcut_path, shortcut_properties, base::win::SHORTCUT_UPDATE_EXISTING); |
1212 LOG_IF(ERROR, !ret) << "Failed to update " << shortcut_path.value(); | 1245 LOG_IF(ERROR, !ret) << "Failed to update " << shortcut_path.value(); |
1213 return ret; | 1246 return ret; |
1214 } | 1247 } |
1215 | 1248 |
1216 // {|location|, |dist|, |level|} determine |shortcut_folder|. | 1249 // {|location|, |dist|, |level|} determine |shortcut_folder|. |
1217 // Applies |shortcut_operation| to each shortcut in |shortcut_folder| that | 1250 // For each shortcut in |shortcut_folder| that match |shortcut_filter|, apply |
1218 // targets |target_exe|. | 1251 // |shortcut_operation|. Returns true if all operations are successful. |
1219 // Returns true if all operations are successful. All intended operations are | 1252 // All intended operations are attempted, even if failures occur. |
1220 // attempted even if failures occur. | 1253 bool BatchShortcutAction(const FileFilterCallback& shortcut_filter, |
1221 bool BatchShortcutAction(const FileOperationCallback& shortcut_operation, | 1254 const FileOperationCallback& shortcut_operation, |
1222 ShellUtil::ShortcutLocation location, | 1255 ShellUtil::ShortcutLocation location, |
1223 BrowserDistribution* dist, | 1256 BrowserDistribution* dist, |
1224 ShellUtil::ShellChange level, | 1257 ShellUtil::ShellChange level) { |
1225 const base::FilePath& target_exe) { | |
1226 DCHECK(!shortcut_operation.is_null()); | 1258 DCHECK(!shortcut_operation.is_null()); |
1227 base::FilePath shortcut_folder; | 1259 base::FilePath shortcut_folder; |
1228 if (!ShellUtil::GetShortcutPath(location, dist, level, &shortcut_folder)) { | 1260 if (!ShellUtil::GetShortcutPath(location, dist, level, &shortcut_folder)) { |
1229 LOG(WARNING) << "Cannot find path at location " << location; | 1261 LOG(WARNING) << "Cannot find path at location " << location; |
1230 return false; | 1262 return false; |
1231 } | 1263 } |
1232 | 1264 |
1233 bool success = true; | 1265 bool success = true; |
1234 InstallUtil::ProgramCompare target_compare(target_exe); | |
1235 base::FileEnumerator enumerator( | 1266 base::FileEnumerator enumerator( |
1236 shortcut_folder, false, base::FileEnumerator::FILES, | 1267 shortcut_folder, false, base::FileEnumerator::FILES, |
1237 string16(L"*") + installer::kLnkExt); | 1268 string16(L"*") + installer::kLnkExt); |
1238 base::FilePath target_path; | 1269 base::FilePath target_path; |
1270 string16 args; | |
1239 for (base::FilePath shortcut_path = enumerator.Next(); | 1271 for (base::FilePath shortcut_path = enumerator.Next(); |
1240 !shortcut_path.empty(); | 1272 !shortcut_path.empty(); |
1241 shortcut_path = enumerator.Next()) { | 1273 shortcut_path = enumerator.Next()) { |
1242 if (base::win::ResolveShortcut(shortcut_path, &target_path, NULL)) { | 1274 if (base::win::ResolveShortcut(shortcut_path, &target_path, &args)) { |
1243 if (target_compare.EvaluatePath(target_path) && | 1275 if (shortcut_filter.Run(target_path, args) && |
1244 !shortcut_operation.Run(shortcut_path)) { | 1276 !shortcut_operation.Run(shortcut_path)) { |
1245 success = false; | 1277 success = false; |
1246 } | 1278 } |
1247 } else { | 1279 } else { |
1248 LOG(ERROR) << "Cannot resolve shortcut at " << shortcut_path.value(); | 1280 LOG(ERROR) << "Cannot resolve shortcut at " << shortcut_path.value(); |
1249 success = false; | 1281 success = false; |
1250 } | 1282 } |
1251 } | 1283 } |
1252 return success; | 1284 return success; |
1253 } | 1285 } |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1989 const base::FilePath& target_exe) { | 2021 const base::FilePath& target_exe) { |
1990 if (!ShellUtil::ShortcutLocationIsSupported(location)) | 2022 if (!ShellUtil::ShortcutLocationIsSupported(location)) |
1991 return true; // Vacuous success. | 2023 return true; // Vacuous success. |
1992 | 2024 |
1993 switch (location) { | 2025 switch (location) { |
1994 case SHORTCUT_LOCATION_START_MENU: // Falls through. | 2026 case SHORTCUT_LOCATION_START_MENU: // Falls through. |
1995 case SHORTCUT_LOCATION_APP_SHORTCUTS: | 2027 case SHORTCUT_LOCATION_APP_SHORTCUTS: |
1996 return RemoveShortcutFolder(location, dist, level); | 2028 return RemoveShortcutFolder(location, dist, level); |
1997 | 2029 |
1998 case SHORTCUT_LOCATION_TASKBAR_PINS: | 2030 case SHORTCUT_LOCATION_TASKBAR_PINS: |
1999 return BatchShortcutAction(base::Bind(&ShortcutOpUnpin), location, dist, | 2031 return BatchShortcutAction(FilterTargetEq(target_exe).Bind(), |
2000 level, target_exe); | 2032 base::Bind(&ShortcutOpUnpin), |
2033 location, | |
2034 dist, | |
2035 level); | |
2001 | 2036 |
2002 default: | 2037 default: |
2003 return BatchShortcutAction(base::Bind(&ShortcutOpDelete), location, dist, | 2038 return BatchShortcutAction(FilterTargetEq(target_exe).Bind(), |
2004 level, target_exe); | 2039 base::Bind(&ShortcutOpDelete), |
gab
2013/08/09 13:40:47
I overall like this refactoring very much since it
huangs
2013/08/09 15:06:20
Done. :)
| |
2040 location, | |
2041 dist, | |
2042 level); | |
2005 } | 2043 } |
2006 } | 2044 } |
2007 | 2045 |
2008 // static | 2046 // static |
2009 bool ShellUtil::UpdateShortcuts( | 2047 bool ShellUtil::UpdateShortcuts( |
2010 ShellUtil::ShortcutLocation location, | 2048 ShellUtil::ShortcutLocation location, |
2011 BrowserDistribution* dist, | 2049 BrowserDistribution* dist, |
2012 ShellChange level, | 2050 ShellChange level, |
2013 const base::FilePath& target_exe, | 2051 const base::FilePath& target_exe, |
2014 const ShellUtil::ShortcutProperties& properties) { | 2052 const ShellUtil::ShortcutProperties& properties) { |
2015 if (!ShellUtil::ShortcutLocationIsSupported(location)) | 2053 if (!ShellUtil::ShortcutLocationIsSupported(location)) |
2016 return true; // Vacuous success. | 2054 return true; // Vacuous success. |
2017 | 2055 |
2018 base::win::ShortcutProperties shortcut_properties( | 2056 base::win::ShortcutProperties shortcut_properties( |
2019 TranslateShortcutProperties(properties)); | 2057 TranslateShortcutProperties(properties)); |
2020 return BatchShortcutAction(base::Bind(&ShortcutOpUpdate, shortcut_properties), | 2058 return BatchShortcutAction(FilterTargetEq(target_exe).Bind(), |
2021 location, dist, level, target_exe); | 2059 base::Bind(&ShortcutOpUpdate, shortcut_properties), |
2060 location, | |
2061 dist, | |
2062 level); | |
2022 } | 2063 } |
2023 | 2064 |
2024 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) { | 2065 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) { |
2025 // Use a thread-safe cache for the user's suffix. | 2066 // Use a thread-safe cache for the user's suffix. |
2026 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance = | 2067 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance = |
2027 LAZY_INSTANCE_INITIALIZER; | 2068 LAZY_INSTANCE_INITIALIZER; |
2028 return suffix_instance.Get().GetSuffix(suffix); | 2069 return suffix_instance.Get().GetSuffix(suffix); |
2029 } | 2070 } |
2030 | 2071 |
2031 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) { | 2072 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2081 // are any left...). | 2122 // are any left...). |
2082 if (free_bits >= 8 && next_byte_index < size) { | 2123 if (free_bits >= 8 && next_byte_index < size) { |
2083 free_bits -= 8; | 2124 free_bits -= 8; |
2084 bit_stream += bytes[next_byte_index++] << free_bits; | 2125 bit_stream += bytes[next_byte_index++] << free_bits; |
2085 } | 2126 } |
2086 } | 2127 } |
2087 | 2128 |
2088 DCHECK_EQ(ret.length(), encoded_length); | 2129 DCHECK_EQ(ret.length(), encoded_length); |
2089 return ret; | 2130 return ret; |
2090 } | 2131 } |
OLD | NEW |