Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: chrome/installer/util/shell_util.cc

Issue 14031025: Implementing unified Chrome / App Launcher flow, and migrating old stand-alone App Launcher. (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Feature-complete (except for unit tests for ShellUtil shortcut update code). Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698