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 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1200 | 1200 |
| 1201 bool ShortcutOpDelete(const base::FilePath& shortcut_path) { | 1201 bool ShortcutOpDelete(const base::FilePath& shortcut_path) { |
| 1202 bool ret = file_util::Delete(shortcut_path, false); | 1202 bool ret = file_util::Delete(shortcut_path, false); |
| 1203 LOG_IF(ERROR, !ret) << "Failed to remove " << shortcut_path.value(); | 1203 LOG_IF(ERROR, !ret) << "Failed to remove " << shortcut_path.value(); |
| 1204 return ret; | 1204 return ret; |
| 1205 } | 1205 } |
| 1206 | 1206 |
| 1207 bool ShortcutOpUpdate(const base::win::ShortcutProperties& shortcut_properties, | 1207 bool ShortcutOpUpdate(const base::win::ShortcutProperties& shortcut_properties, |
| 1208 const base::FilePath& shortcut_path) { | 1208 const base::FilePath& shortcut_path) { |
| 1209 bool ret = base::win::CreateOrUpdateShortcutLink( | 1209 bool ret = base::win::CreateOrUpdateShortcutLink( |
| 1210 shortcut_path, shortcut_properties, base::win::SHORTCUT_REPLACE_EXISTING); | 1210 shortcut_path, shortcut_properties, base::win::SHORTCUT_UPDATE_EXISTING); |
| 1211 LOG_IF(ERROR, !ret) << "Failed to update " << shortcut_path.value(); | 1211 LOG_IF(ERROR, !ret) << "Failed to update " << shortcut_path.value(); |
| 1212 return ret; | 1212 return ret; |
| 1213 } | 1213 } |
| 1214 | 1214 |
| 1215 // {|location|, |dist|, |level|} determine |shortcut_folder|. | 1215 // {|location|, |dist|, |level|} determine |shortcut_folder|. |
| 1216 // Applies |shortcut_operation| to each shortcut in |shortcut_folder| that | 1216 // Applies |shortcut_operation| to shortcuts in |shortcut_folder| that |
| 1217 // targets |target_exe|. | 1217 // targets |target_exe|, and have filenames matching |filename_filter|. |
| 1218 // Returns true if all operations are successful. All intended operations are | 1218 // Returns true if all operations are successful. All intended operations are |
| 1219 // attempted even if failures occur. | 1219 // attempted even if failures occur. |
| 1220 bool BatchShortcutAction(const FileOperationCallback& shortcut_operation, | 1220 bool BatchShortcutActionFilteredByName( |
| 1221 ShellUtil::ShortcutLocation location, | 1221 const FileOperationCallback& shortcut_operation, |
| 1222 BrowserDistribution* dist, | 1222 ShellUtil::ShortcutLocation location, |
| 1223 ShellUtil::ShellChange level, | 1223 BrowserDistribution* dist, |
| 1224 const base::FilePath& target_exe) { | 1224 ShellUtil::ShellChange level, |
| 1225 const base::FilePath& target_exe, | |
| 1226 const string16& filename_filter) { | |
| 1225 DCHECK(!shortcut_operation.is_null()); | 1227 DCHECK(!shortcut_operation.is_null()); |
| 1226 base::FilePath shortcut_folder; | 1228 base::FilePath shortcut_folder; |
| 1227 if (!ShellUtil::GetShortcutPath(location, dist, level, &shortcut_folder)) { | 1229 if (!ShellUtil::GetShortcutPath(location, dist, level, &shortcut_folder)) { |
| 1228 LOG(WARNING) << "Cannot find path at location " << location; | 1230 LOG(WARNING) << "Cannot find path at location " << location; |
| 1229 return false; | 1231 return false; |
| 1230 } | 1232 } |
| 1231 | 1233 |
| 1232 bool success = true; | 1234 bool success = true; |
| 1233 InstallUtil::ProgramCompare target_compare(target_exe); | 1235 InstallUtil::ProgramCompare target_compare(target_exe); |
| 1234 file_util::FileEnumerator enumerator( | 1236 file_util::FileEnumerator enumerator( |
| 1235 shortcut_folder, false, file_util::FileEnumerator::FILES, | 1237 shortcut_folder, false, file_util::FileEnumerator::FILES, |
| 1236 string16(L"*") + installer::kLnkExt); | 1238 filename_filter); |
| 1237 base::FilePath target_path; | 1239 base::FilePath original_target_exe; |
| 1238 for (base::FilePath shortcut_path = enumerator.Next(); | 1240 for (base::FilePath shortcut_file = enumerator.Next(); |
| 1239 !shortcut_path.empty(); | 1241 !shortcut_file.empty(); |
| 1240 shortcut_path = enumerator.Next()) { | 1242 shortcut_file = enumerator.Next()) { |
| 1241 if (base::win::ResolveShortcut(shortcut_path, &target_path, NULL)) { | 1243 if (base::win::ResolveShortcut(shortcut_file, &original_target_exe, NULL)) { |
| 1242 if (target_compare.EvaluatePath(target_path) && | 1244 if (target_compare.EvaluatePath(original_target_exe) && |
| 1243 !shortcut_operation.Run(shortcut_path)) { | 1245 !shortcut_operation.Run(shortcut_file)) { |
| 1244 success = false; | 1246 success = false; |
| 1245 } | 1247 } |
| 1246 } else { | 1248 } else { |
| 1247 LOG(ERROR) << "Cannot resolve shortcut at " << shortcut_path.value(); | 1249 LOG(ERROR) << "Cannot resolve shortcut at " << shortcut_file.value(); |
| 1248 success = false; | 1250 success = false; |
| 1249 } | 1251 } |
| 1250 } | 1252 } |
| 1251 return success; | 1253 return success; |
| 1252 } | 1254 } |
| 1253 | 1255 |
| 1256 // Adaptor to FilteredBatchShortcutAction(), to process all files. | |
|
gab
2013/05/15 22:42:20
Remove comma.
huangs
2013/05/17 20:59:24
Done.
| |
| 1257 bool BatchShortcutAction(const FileOperationCallback& shortcut_operation, | |
| 1258 ShellUtil::ShortcutLocation location, | |
| 1259 BrowserDistribution* dist, | |
| 1260 ShellUtil::ShellChange level, | |
| 1261 const base::FilePath& target_exe) { | |
| 1262 return BatchShortcutActionFilteredByName( | |
| 1263 shortcut_operation, location, dist, level, target_exe, | |
| 1264 string16(L"*") + installer::kLnkExt); | |
| 1265 } | |
| 1266 | |
| 1254 // Removes folder spsecified by {|location|, |dist|, |level|}. | 1267 // Removes folder spsecified by {|location|, |dist|, |level|}. |
| 1255 bool RemoveShortcutFolder(ShellUtil::ShortcutLocation location, | 1268 bool RemoveShortcutFolder(ShellUtil::ShortcutLocation location, |
| 1256 BrowserDistribution* dist, | 1269 BrowserDistribution* dist, |
| 1257 ShellUtil::ShellChange level) { | 1270 ShellUtil::ShellChange level) { |
| 1258 | 1271 |
| 1259 // Explicitly whitelist locations, since accidental calls can be very harmful. | 1272 // Explicitly whitelist locations, since accidental calls can be very harmful. |
| 1260 if (location != ShellUtil::SHORTCUT_LOCATION_START_MENU && | 1273 if (location != ShellUtil::SHORTCUT_LOCATION_START_MENU && |
| 1261 location != ShellUtil::SHORTCUT_LOCATION_APP_SHORTCUTS) { | 1274 location != ShellUtil::SHORTCUT_LOCATION_APP_SHORTCUTS) { |
| 1262 NOTREACHED(); | 1275 NOTREACHED(); |
| 1263 return false; | 1276 return false; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1341 | 1354 |
| 1342 bool ShellUtil::ShortcutLocationIsSupported( | 1355 bool ShellUtil::ShortcutLocationIsSupported( |
| 1343 ShellUtil::ShortcutLocation location) { | 1356 ShellUtil::ShortcutLocation location) { |
| 1344 switch (location) { | 1357 switch (location) { |
| 1345 case SHORTCUT_LOCATION_DESKTOP: | 1358 case SHORTCUT_LOCATION_DESKTOP: |
| 1346 return true; | 1359 return true; |
| 1347 case SHORTCUT_LOCATION_QUICK_LAUNCH: | 1360 case SHORTCUT_LOCATION_QUICK_LAUNCH: |
| 1348 return true; | 1361 return true; |
| 1349 case SHORTCUT_LOCATION_START_MENU: | 1362 case SHORTCUT_LOCATION_START_MENU: |
| 1350 return true; | 1363 return true; |
| 1364 case SHORTCUT_LOCATION_START_MENU_ROOT: | |
| 1365 return true; | |
| 1351 case SHORTCUT_LOCATION_TASKBAR_PINS: | 1366 case SHORTCUT_LOCATION_TASKBAR_PINS: |
| 1352 return base::win::GetVersion() >= base::win::VERSION_WIN7; | 1367 return base::win::GetVersion() >= base::win::VERSION_WIN7; |
| 1353 case SHORTCUT_LOCATION_APP_SHORTCUTS: | 1368 case SHORTCUT_LOCATION_APP_SHORTCUTS: |
| 1354 return base::win::GetVersion() >= base::win::VERSION_WIN8; | 1369 return base::win::GetVersion() >= base::win::VERSION_WIN8; |
| 1355 default: | 1370 default: |
| 1356 NOTREACHED(); | 1371 NOTREACHED(); |
| 1357 return false; | 1372 return false; |
| 1358 } | 1373 } |
| 1359 } | 1374 } |
| 1360 | 1375 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1372 break; | 1387 break; |
| 1373 case SHORTCUT_LOCATION_QUICK_LAUNCH: | 1388 case SHORTCUT_LOCATION_QUICK_LAUNCH: |
| 1374 dir_key = (level == CURRENT_USER) ? base::DIR_USER_QUICK_LAUNCH : | 1389 dir_key = (level == CURRENT_USER) ? base::DIR_USER_QUICK_LAUNCH : |
| 1375 base::DIR_DEFAULT_USER_QUICK_LAUNCH; | 1390 base::DIR_DEFAULT_USER_QUICK_LAUNCH; |
| 1376 break; | 1391 break; |
| 1377 case SHORTCUT_LOCATION_START_MENU: | 1392 case SHORTCUT_LOCATION_START_MENU: |
| 1378 dir_key = (level == CURRENT_USER) ? base::DIR_START_MENU : | 1393 dir_key = (level == CURRENT_USER) ? base::DIR_START_MENU : |
| 1379 base::DIR_COMMON_START_MENU; | 1394 base::DIR_COMMON_START_MENU; |
| 1380 add_folder_for_dist = true; | 1395 add_folder_for_dist = true; |
| 1381 break; | 1396 break; |
| 1397 case SHORTCUT_LOCATION_START_MENU_ROOT: | |
|
gab
2013/05/15 22:42:20
Coordinate with https://codereview.chromium.org/13
huangs
2013/05/17 20:59:24
Deleted for now.
| |
| 1398 dir_key = (level == CURRENT_USER) ? base::DIR_START_MENU : | |
| 1399 base::DIR_COMMON_START_MENU; | |
| 1400 break; | |
| 1382 case SHORTCUT_LOCATION_TASKBAR_PINS: | 1401 case SHORTCUT_LOCATION_TASKBAR_PINS: |
| 1383 dir_key = base::DIR_TASKBAR_PINS; | 1402 dir_key = base::DIR_TASKBAR_PINS; |
| 1384 break; | 1403 break; |
| 1385 case SHORTCUT_LOCATION_APP_SHORTCUTS: | 1404 case SHORTCUT_LOCATION_APP_SHORTCUTS: |
| 1386 // TODO(huangs): Move GetAppShortcutsFolder() logic into base_paths_win. | 1405 // TODO(huangs): Move GetAppShortcutsFolder() logic into base_paths_win. |
| 1387 return GetAppShortcutsFolder(dist, level, path); | 1406 return GetAppShortcutsFolder(dist, level, path); |
| 1388 | 1407 |
| 1389 default: | 1408 default: |
| 1390 NOTREACHED(); | 1409 NOTREACHED(); |
| 1391 return false; | 1410 return false; |
| 1392 } | 1411 } |
| 1393 | 1412 |
| 1394 if (!PathService::Get(dir_key, path) || path->empty()) { | 1413 if (!PathService::Get(dir_key, path) || path->empty()) { |
| 1395 NOTREACHED() << dir_key; | 1414 NOTREACHED() << dir_key; |
| 1396 return false; | 1415 return false; |
| 1397 } | 1416 } |
| 1398 | 1417 |
| 1399 if (add_folder_for_dist) | 1418 if (add_folder_for_dist) |
| 1400 *path = path->Append(dist->GetAppShortCutName()); | 1419 *path = path->Append(dist->GetAppShortCutFolderName()); |
| 1401 | 1420 |
| 1402 return true; | 1421 return true; |
| 1403 } | 1422 } |
| 1404 | 1423 |
| 1405 bool ShellUtil::CreateOrUpdateShortcut( | 1424 bool ShellUtil::CreateOrUpdateShortcut( |
| 1406 ShellUtil::ShortcutLocation location, | 1425 ShellUtil::ShortcutLocation location, |
| 1407 BrowserDistribution* dist, | 1426 BrowserDistribution* dist, |
| 1408 const ShellUtil::ShortcutProperties& properties, | 1427 const ShellUtil::ShortcutProperties& properties, |
| 1409 ShellUtil::ShortcutOperation operation) { | 1428 ShellUtil::ShortcutOperation operation) { |
| 1410 // Explicitly whitelist locations to which this is applicable. | 1429 // Explicitly whitelist locations to which this is applicable. |
| 1411 if (location != SHORTCUT_LOCATION_DESKTOP && | 1430 if (location != SHORTCUT_LOCATION_DESKTOP && |
| 1412 location != SHORTCUT_LOCATION_QUICK_LAUNCH && | 1431 location != SHORTCUT_LOCATION_QUICK_LAUNCH && |
| 1413 location != SHORTCUT_LOCATION_START_MENU) { | 1432 location != SHORTCUT_LOCATION_START_MENU && |
| 1433 location != SHORTCUT_LOCATION_START_MENU_ROOT) { | |
| 1414 NOTREACHED(); | 1434 NOTREACHED(); |
| 1415 return false; | 1435 return false; |
| 1416 } | 1436 } |
| 1417 | 1437 |
| 1418 DCHECK(dist); | 1438 DCHECK(dist); |
| 1419 // |pin_to_taskbar| is only acknowledged when first creating the shortcut. | 1439 // |pin_to_taskbar| is only acknowledged when first creating the shortcut. |
| 1420 DCHECK(!properties.pin_to_taskbar || | 1440 DCHECK(!properties.pin_to_taskbar || |
| 1421 operation == SHELL_SHORTCUT_CREATE_ALWAYS || | 1441 operation == SHELL_SHORTCUT_CREATE_ALWAYS || |
| 1422 operation == SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL); | 1442 operation == SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL); |
| 1423 | 1443 |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1991 | 2011 |
| 1992 switch (location) { | 2012 switch (location) { |
| 1993 case SHORTCUT_LOCATION_START_MENU: // Falls through. | 2013 case SHORTCUT_LOCATION_START_MENU: // Falls through. |
| 1994 case SHORTCUT_LOCATION_APP_SHORTCUTS: | 2014 case SHORTCUT_LOCATION_APP_SHORTCUTS: |
| 1995 return RemoveShortcutFolder(location, dist, level); | 2015 return RemoveShortcutFolder(location, dist, level); |
| 1996 | 2016 |
| 1997 case SHORTCUT_LOCATION_TASKBAR_PINS: | 2017 case SHORTCUT_LOCATION_TASKBAR_PINS: |
| 1998 return BatchShortcutAction(base::Bind(&ShortcutOpUnpin), location, dist, | 2018 return BatchShortcutAction(base::Bind(&ShortcutOpUnpin), location, dist, |
| 1999 level, target_exe); | 2019 level, target_exe); |
| 2000 | 2020 |
| 2021 case SHORTCUT_LOCATION_START_MENU_ROOT: // For emphasis; falls through. | |
|
gab
2013/05/15 22:42:20
See https://codereview.chromium.org/13864015/ (I t
huangs
2013/05/17 20:59:24
Deleted.
| |
| 2001 default: | 2022 default: |
| 2002 return BatchShortcutAction(base::Bind(&ShortcutOpDelete), location, dist, | 2023 return BatchShortcutAction(base::Bind(&ShortcutOpDelete), location, dist, |
| 2003 level, target_exe); | 2024 level, target_exe); |
| 2004 } | 2025 } |
| 2005 } | 2026 } |
| 2006 | 2027 |
| 2007 // static | 2028 // static |
| 2008 bool ShellUtil::UpdateShortcuts( | 2029 bool ShellUtil::UpdateShortcuts( |
| 2009 ShellUtil::ShortcutLocation location, | 2030 ShellUtil::ShortcutLocation location, |
| 2010 BrowserDistribution* dist, | 2031 BrowserDistribution* dist, |
| 2011 ShellChange level, | 2032 ShellChange level, |
| 2012 const base::FilePath& target_exe, | 2033 const base::FilePath& target_exe, |
| 2013 const ShellUtil::ShortcutProperties& properties) { | 2034 const ShellUtil::ShortcutProperties& properties) { |
| 2014 if (!ShellUtil::ShortcutLocationIsSupported(location)) | 2035 if (!ShellUtil::ShortcutLocationIsSupported(location)) |
| 2015 return true; // Vacuous success. | 2036 return true; // Vacuous success. |
| 2016 | 2037 |
| 2017 base::win::ShortcutProperties shortcut_properties( | 2038 base::win::ShortcutProperties shortcut_properties( |
| 2018 TranslateShortcutProperties(properties)); | 2039 TranslateShortcutProperties(properties)); |
| 2019 return BatchShortcutAction(base::Bind(&ShortcutOpUpdate, shortcut_properties), | 2040 return BatchShortcutAction(base::Bind(&ShortcutOpUpdate, shortcut_properties), |
| 2020 location, dist, level, target_exe); | 2041 location, dist, level, target_exe); |
| 2021 } | 2042 } |
| 2022 | 2043 |
| 2044 // static | |
| 2045 bool ShellUtil::UpdateShortcutsFilteredByName( | |
| 2046 ShellUtil::ShortcutLocation location, | |
| 2047 BrowserDistribution* dist, | |
| 2048 ShellChange level, | |
| 2049 const string16& name_filter, | |
| 2050 const base::FilePath& target_exe, | |
| 2051 const ShellUtil::ShortcutProperties& properties) { | |
| 2052 DCHECK(EndsWith(name_filter, installer::kLnkExt, false)); | |
| 2053 | |
| 2054 if (!ShellUtil::ShortcutLocationIsSupported(location)) | |
| 2055 return true; // Vacuous success. | |
| 2056 | |
| 2057 base::win::ShortcutProperties shortcut_properties( | |
| 2058 TranslateShortcutProperties(properties)); | |
| 2059 return BatchShortcutActionFilteredByName( | |
| 2060 base::Bind(&ShortcutOpUpdate, shortcut_properties), | |
| 2061 location, dist, level, target_exe, name_filter); | |
| 2062 } | |
| 2063 | |
| 2023 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) { | 2064 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) { |
| 2024 // Use a thread-safe cache for the user's suffix. | 2065 // Use a thread-safe cache for the user's suffix. |
| 2025 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance = | 2066 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance = |
| 2026 LAZY_INSTANCE_INITIALIZER; | 2067 LAZY_INSTANCE_INITIALIZER; |
| 2027 return suffix_instance.Get().GetSuffix(suffix); | 2068 return suffix_instance.Get().GetSuffix(suffix); |
| 2028 } | 2069 } |
| 2029 | 2070 |
| 2030 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) { | 2071 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) { |
| 2031 wchar_t user_name[256]; | 2072 wchar_t user_name[256]; |
| 2032 DWORD size = arraysize(user_name); | 2073 DWORD size = arraysize(user_name); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2080 // are any left...). | 2121 // are any left...). |
| 2081 if (free_bits >= 8 && next_byte_index < size) { | 2122 if (free_bits >= 8 && next_byte_index < size) { |
| 2082 free_bits -= 8; | 2123 free_bits -= 8; |
| 2083 bit_stream += bytes[next_byte_index++] << free_bits; | 2124 bit_stream += bytes[next_byte_index++] << free_bits; |
| 2084 } | 2125 } |
| 2085 } | 2126 } |
| 2086 | 2127 |
| 2087 DCHECK_EQ(ret.length(), encoded_length); | 2128 DCHECK_EQ(ret.length(), encoded_length); |
| 2088 return ret; | 2129 return ret; |
| 2089 } | 2130 } |
| OLD | NEW |