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

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

Issue 14287008: Refactoring installer shortcut deletion; adding dedicated shortcut update feature. (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync; fixing .git/config to allow CQ to commit. 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"
11 11
12 #include <windows.h> 12 #include <windows.h>
13 #include <shlobj.h> 13 #include <shlobj.h>
14 14
15 #include <limits> 15 #include <limits>
16 #include <string> 16 #include <string>
17 17
18 #include "base/bind.h"
18 #include "base/command_line.h" 19 #include "base/command_line.h"
19 #include "base/file_util.h" 20 #include "base/file_util.h"
20 #include "base/files/file_path.h" 21 #include "base/files/file_path.h"
21 #include "base/lazy_instance.h" 22 #include "base/lazy_instance.h"
22 #include "base/logging.h" 23 #include "base/logging.h"
23 #include "base/md5.h" 24 #include "base/md5.h"
24 #include "base/memory/scoped_ptr.h" 25 #include "base/memory/scoped_ptr.h"
25 #include "base/memory/scoped_vector.h" 26 #include "base/memory/scoped_vector.h"
26 #include "base/path_service.h" 27 #include "base/path_service.h"
27 #include "base/string16.h" 28 #include "base/string16.h"
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 const base::win::Version windows_version = base::win::GetVersion(); 1153 const base::win::Version windows_version = base::win::GetVersion();
1153 1154
1154 if (windows_version >= base::win::VERSION_WIN8) 1155 if (windows_version >= base::win::VERSION_WIN8)
1155 return ProbeCurrentDefaultHandlers(protocols, num_protocols); 1156 return ProbeCurrentDefaultHandlers(protocols, num_protocols);
1156 else if (windows_version >= base::win::VERSION_VISTA) 1157 else if (windows_version >= base::win::VERSION_VISTA)
1157 return ProbeAppIsDefaultHandlers(protocols, num_protocols); 1158 return ProbeAppIsDefaultHandlers(protocols, num_protocols);
1158 1159
1159 return ProbeOpenCommandHandlers(protocols, num_protocols); 1160 return ProbeOpenCommandHandlers(protocols, num_protocols);
1160 } 1161 }
1161 1162
1162 // Removes shortcut at |shortcut_path| if it is a shortcut that points to 1163 // (Windows 8+) Finds and stores an app shortcuts folder path in *|path|.
1163 // |target_exe|. If |delete_folder| is true, deletes the parent folder of 1164 // Returns true on success.
1164 // the shortcut completely. Returns true if either the shortcut was deleted 1165 bool GetAppShortcutsFolder(BrowserDistribution* dist,
1165 // successfully or if the shortcut did not point to |target_exe|. 1166 ShellUtil::ShellChange level,
1166 bool MaybeRemoveShortcutAtPath(const base::FilePath& shortcut_path, 1167 base::FilePath *path) {
1167 const base::FilePath& target_exe, 1168 DCHECK(path);
1168 bool delete_folder) { 1169 DCHECK_GE(base::win::GetVersion(), base::win::VERSION_WIN8);
1169 base::FilePath target_path; 1170
1170 if (!base::win::ResolveShortcut(shortcut_path, &target_path, NULL)) 1171 base::FilePath folder;
1172 if (!PathService::Get(base::DIR_APP_SHORTCUTS, &folder)) {
1173 LOG(ERROR) << "Could not get application shortcuts location.";
1171 return false; 1174 return false;
1172
1173 if (InstallUtil::ProgramCompare(target_exe).EvaluatePath(target_path)) {
1174 // Unpin the shortcut if it was ever pinned by the user or the installer.
1175 VLOG(1) << "Trying to unpin " << shortcut_path.value();
1176 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str())) {
1177 VLOG(1) << shortcut_path.value()
1178 << " wasn't pinned (or the unpin failed).";
1179 }
1180 if (delete_folder)
1181 return file_util::Delete(shortcut_path.DirName(), true);
1182 else
1183 return file_util::Delete(shortcut_path, false);
1184 } 1175 }
1185 1176
1186 // The shortcut at |shortcut_path| doesn't point to |target_exe|, act as if 1177 folder = folder.Append(
1187 // our shortcut had been deleted. 1178 ShellUtil::GetBrowserModelId(dist, level == ShellUtil::CURRENT_USER));
1179 if (!file_util::DirectoryExists(folder)) {
1180 VLOG(1) << "No start screen shortcuts.";
1181 return false;
1182 }
1183
1184 *path = folder;
1188 return true; 1185 return true;
1189 } 1186 }
1190 1187
1188 typedef base::Callback<bool(const base::FilePath&)> FileOperationCallback;
1189
1190 // Shortcut operations for BatchShortcutAction().
1191
1192 bool ShortcutOpUnpin(const base::FilePath& shortcut_path) {
1193 VLOG(1) << "Trying to unpin " << shortcut_path.value();
1194 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str())) {
1195 VLOG(1) << shortcut_path.value() << " wasn't pinned (or the unpin failed).";
1196 // No error, since shortcut might not be pinned.
1197 }
1198 return true;
1199 }
1200
1201 bool ShortcutOpDelete(const base::FilePath& shortcut_path) {
1202 bool ret = file_util::Delete(shortcut_path, false);
1203 LOG_IF(ERROR, !ret) << "Failed to remove " << shortcut_path.value();
1204 return ret;
1205 }
1206
1207 bool ShortcutOpUpdate(const base::win::ShortcutProperties& shortcut_properties,
1208 const base::FilePath& shortcut_path) {
1209 bool ret = base::win::CreateOrUpdateShortcutLink(
1210 shortcut_path, shortcut_properties, base::win::SHORTCUT_REPLACE_EXISTING);
gab 2013/05/13 03:48:51 Arg... my bad, this should be using SHORTCUT_UPDAT
1211 LOG_IF(ERROR, !ret) << "Failed to update " << shortcut_path.value();
1212 return ret;
1213 }
1214
1215 // {|location|, |dist|, |level|} determine |shortcut_folder|.
1216 // Applies |shortcut_operation| to each shortcut in |shortcut_folder| that
1217 // targets |target_exe|.
1218 // Returns true if all operations are successful. All intended operations are
1219 // attempted even if failures occur.
1220 bool BatchShortcutAction(const FileOperationCallback& shortcut_operation,
1221 ShellUtil::ShortcutLocation location,
1222 BrowserDistribution* dist,
1223 ShellUtil::ShellChange level,
1224 const base::FilePath& target_exe) {
1225 DCHECK(!shortcut_operation.is_null());
1226 base::FilePath shortcut_folder;
1227 if (!ShellUtil::GetShortcutPath(location, dist, level, &shortcut_folder)) {
1228 LOG(WARNING) << "Cannot find path at location " << location;
1229 return false;
1230 }
1231
1232 bool success = true;
1233 InstallUtil::ProgramCompare target_compare(target_exe);
1234 file_util::FileEnumerator enumerator(
1235 shortcut_folder, false, file_util::FileEnumerator::FILES,
1236 string16(L"*") + installer::kLnkExt);
1237 base::FilePath target_path;
1238 for (base::FilePath shortcut_path = enumerator.Next();
1239 !shortcut_path.empty();
1240 shortcut_path = enumerator.Next()) {
1241 if (base::win::ResolveShortcut(shortcut_path, &target_path, NULL)) {
1242 if (target_compare.EvaluatePath(target_path) &&
1243 !shortcut_operation.Run(shortcut_path)) {
1244 success = false;
1245 }
1246 } else {
1247 LOG(ERROR) << "Cannot resolve shortcut at " << shortcut_path.value();
1248 success = false;
1249 }
1250 }
1251 return success;
1252 }
1253
1254 // Removes folder spsecified by {|location|, |dist|, |level|}.
1255 bool RemoveShortcutFolder(ShellUtil::ShortcutLocation location,
1256 BrowserDistribution* dist,
1257 ShellUtil::ShellChange level) {
1258
1259 // Explicitly whitelist locations, since accidental calls can be very harmful.
1260 if (location != ShellUtil::SHORTCUT_LOCATION_START_MENU &&
1261 location != ShellUtil::SHORTCUT_LOCATION_APP_SHORTCUTS) {
1262 NOTREACHED();
1263 return false;
1264 }
1265
1266 base::FilePath shortcut_folder;
1267 if (!ShellUtil::GetShortcutPath(location, dist, level, &shortcut_folder)) {
1268 LOG(WARNING) << "Cannot find path at location " << location;
1269 return false;
1270 }
1271 if (!file_util::Delete(shortcut_folder, true)) {
1272 LOG(ERROR) << "Cannot remove folder " << shortcut_folder.value();
1273 return false;
1274 }
1275 return true;
1276 }
1277
1191 } // namespace 1278 } // namespace
1192 1279
1193 const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon"; 1280 const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon";
1194 const wchar_t* ShellUtil::kRegShellPath = L"\\shell"; 1281 const wchar_t* ShellUtil::kRegShellPath = L"\\shell";
1195 const wchar_t* ShellUtil::kRegShellOpen = L"\\shell\\open\\command"; 1282 const wchar_t* ShellUtil::kRegShellOpen = L"\\shell\\open\\command";
1196 const wchar_t* ShellUtil::kRegStartMenuInternet = 1283 const wchar_t* ShellUtil::kRegStartMenuInternet =
1197 L"Software\\Clients\\StartMenuInternet"; 1284 L"Software\\Clients\\StartMenuInternet";
1198 const wchar_t* ShellUtil::kRegClasses = L"Software\\Classes"; 1285 const wchar_t* ShellUtil::kRegClasses = L"Software\\Classes";
1199 const wchar_t* ShellUtil::kRegRegisteredApplications = 1286 const wchar_t* ShellUtil::kRegRegisteredApplications =
1200 L"Software\\RegisteredApplications"; 1287 L"Software\\RegisteredApplications";
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 const wchar_t* ShellUtil::kRegDelegateExecute = L"DelegateExecute"; 1332 const wchar_t* ShellUtil::kRegDelegateExecute = L"DelegateExecute";
1246 const wchar_t* ShellUtil::kRegOpenWithProgids = L"OpenWithProgids"; 1333 const wchar_t* ShellUtil::kRegOpenWithProgids = L"OpenWithProgids";
1247 1334
1248 bool ShellUtil::QuickIsChromeRegisteredInHKLM(BrowserDistribution* dist, 1335 bool ShellUtil::QuickIsChromeRegisteredInHKLM(BrowserDistribution* dist,
1249 const string16& chrome_exe, 1336 const string16& chrome_exe,
1250 const string16& suffix) { 1337 const string16& suffix) {
1251 return QuickIsChromeRegistered(dist, chrome_exe, suffix, 1338 return QuickIsChromeRegistered(dist, chrome_exe, suffix,
1252 CONFIRM_SHELL_REGISTRATION_IN_HKLM); 1339 CONFIRM_SHELL_REGISTRATION_IN_HKLM);
1253 } 1340 }
1254 1341
1342 bool ShellUtil::ShortcutLocationIsSupported(
1343 ShellUtil::ShortcutLocation location) {
1344 switch (location) {
1345 case SHORTCUT_LOCATION_DESKTOP:
1346 return true;
1347 case SHORTCUT_LOCATION_QUICK_LAUNCH:
1348 return true;
1349 case SHORTCUT_LOCATION_START_MENU:
1350 return true;
1351 case SHORTCUT_LOCATION_TASKBAR_PINS:
1352 return base::win::GetVersion() >= base::win::VERSION_WIN7;
1353 case SHORTCUT_LOCATION_APP_SHORTCUTS:
1354 return base::win::GetVersion() >= base::win::VERSION_WIN8;
1355 default:
1356 NOTREACHED();
1357 return false;
1358 }
1359 }
1360
1255 bool ShellUtil::GetShortcutPath(ShellUtil::ShortcutLocation location, 1361 bool ShellUtil::GetShortcutPath(ShellUtil::ShortcutLocation location,
1256 BrowserDistribution* dist, 1362 BrowserDistribution* dist,
1257 ShellChange level, 1363 ShellChange level,
1258 base::FilePath* path) { 1364 base::FilePath* path) {
1365 DCHECK(path);
1259 int dir_key = -1; 1366 int dir_key = -1;
1260 bool add_folder_for_dist = false; 1367 bool add_folder_for_dist = false;
1261 switch (location) { 1368 switch (location) {
1262 case SHORTCUT_LOCATION_DESKTOP: 1369 case SHORTCUT_LOCATION_DESKTOP:
1263 dir_key = (level == CURRENT_USER) ? base::DIR_USER_DESKTOP : 1370 dir_key = (level == CURRENT_USER) ? base::DIR_USER_DESKTOP :
1264 base::DIR_COMMON_DESKTOP; 1371 base::DIR_COMMON_DESKTOP;
1265 break; 1372 break;
1266 case SHORTCUT_LOCATION_QUICK_LAUNCH: 1373 case SHORTCUT_LOCATION_QUICK_LAUNCH:
1267 dir_key = (level == CURRENT_USER) ? base::DIR_USER_QUICK_LAUNCH : 1374 dir_key = (level == CURRENT_USER) ? base::DIR_USER_QUICK_LAUNCH :
1268 base::DIR_DEFAULT_USER_QUICK_LAUNCH; 1375 base::DIR_DEFAULT_USER_QUICK_LAUNCH;
1269 break; 1376 break;
1270 case SHORTCUT_LOCATION_START_MENU: 1377 case SHORTCUT_LOCATION_START_MENU:
1271 dir_key = (level == CURRENT_USER) ? base::DIR_START_MENU : 1378 dir_key = (level == CURRENT_USER) ? base::DIR_START_MENU :
1272 base::DIR_COMMON_START_MENU; 1379 base::DIR_COMMON_START_MENU;
1273 add_folder_for_dist = true; 1380 add_folder_for_dist = true;
1274 break; 1381 break;
1382 case SHORTCUT_LOCATION_TASKBAR_PINS:
1383 dir_key = base::DIR_TASKBAR_PINS;
1384 break;
1385 case SHORTCUT_LOCATION_APP_SHORTCUTS:
1386 // TODO(huangs): Move GetAppShortcutsFolder() logic into base_paths_win.
1387 return GetAppShortcutsFolder(dist, level, path);
1388
1275 default: 1389 default:
1276 NOTREACHED(); 1390 NOTREACHED();
1277 return false; 1391 return false;
1278 } 1392 }
1279 1393
1280 if (!PathService::Get(dir_key, path) || path->empty()) { 1394 if (!PathService::Get(dir_key, path) || path->empty()) {
1281 NOTREACHED() << dir_key; 1395 NOTREACHED() << dir_key;
1282 return false; 1396 return false;
1283 } 1397 }
1284 1398
1285 if (add_folder_for_dist) 1399 if (add_folder_for_dist)
1286 *path = path->Append(dist->GetAppShortCutName()); 1400 *path = path->Append(dist->GetAppShortCutName());
1287 1401
1288 return true; 1402 return true;
1289 } 1403 }
1290 1404
1291 bool ShellUtil::CreateOrUpdateShortcut( 1405 bool ShellUtil::CreateOrUpdateShortcut(
1292 ShellUtil::ShortcutLocation location, 1406 ShellUtil::ShortcutLocation location,
1293 BrowserDistribution* dist, 1407 BrowserDistribution* dist,
1294 const ShellUtil::ShortcutProperties& properties, 1408 const ShellUtil::ShortcutProperties& properties,
1295 ShellUtil::ShortcutOperation operation) { 1409 ShellUtil::ShortcutOperation operation) {
1410 // Explicitly whitelist locations to which this is applicable.
1411 if (location != SHORTCUT_LOCATION_DESKTOP &&
1412 location != SHORTCUT_LOCATION_QUICK_LAUNCH &&
1413 location != SHORTCUT_LOCATION_START_MENU) {
1414 NOTREACHED();
1415 return false;
1416 }
1417
1296 DCHECK(dist); 1418 DCHECK(dist);
1297 // |pin_to_taskbar| is only acknowledged when first creating the shortcut. 1419 // |pin_to_taskbar| is only acknowledged when first creating the shortcut.
1298 DCHECK(!properties.pin_to_taskbar || 1420 DCHECK(!properties.pin_to_taskbar ||
1299 operation == SHELL_SHORTCUT_CREATE_ALWAYS || 1421 operation == SHELL_SHORTCUT_CREATE_ALWAYS ||
1300 operation == SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL); 1422 operation == SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL);
1301 1423
1302 base::FilePath user_shortcut_path; 1424 base::FilePath user_shortcut_path;
1303 base::FilePath system_shortcut_path; 1425 base::FilePath system_shortcut_path;
1304 if (!GetShortcutPath(location, dist, SYSTEM_LEVEL, &system_shortcut_path) || 1426 if (!GetShortcutPath(location, dist, SYSTEM_LEVEL, &system_shortcut_path)) {
1305 system_shortcut_path.empty()) {
1306 NOTREACHED(); 1427 NOTREACHED();
1307 return false; 1428 return false;
1308 } 1429 }
1309 1430
1310 string16 shortcut_name(ExtractShortcutNameFromProperties(dist, properties)); 1431 string16 shortcut_name(ExtractShortcutNameFromProperties(dist, properties));
1311 system_shortcut_path = system_shortcut_path.Append(shortcut_name); 1432 system_shortcut_path = system_shortcut_path.Append(shortcut_name);
1312 1433
1313 base::FilePath* chosen_path; 1434 base::FilePath* chosen_path;
1314 bool should_install_shortcut = true; 1435 bool should_install_shortcut = true;
1315 if (properties.level == SYSTEM_LEVEL) { 1436 if (properties.level == SYSTEM_LEVEL) {
1316 // Install the system-level shortcut if requested. 1437 // Install the system-level shortcut if requested.
1317 chosen_path = &system_shortcut_path; 1438 chosen_path = &system_shortcut_path;
1318 } else if (operation != SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL || 1439 } else if (operation != SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL ||
1319 !file_util::PathExists(system_shortcut_path)) { 1440 !file_util::PathExists(system_shortcut_path)) {
1320 // Otherwise install the user-level shortcut, unless the system-level 1441 // Otherwise install the user-level shortcut, unless the system-level
1321 // variant of this shortcut is present on the machine and |operation| states 1442 // variant of this shortcut is present on the machine and |operation| states
1322 // not to create a user-level shortcut in that case. 1443 // not to create a user-level shortcut in that case.
1323 if (!GetShortcutPath(location, dist, CURRENT_USER, &user_shortcut_path) || 1444 if (!GetShortcutPath(location, dist, CURRENT_USER, &user_shortcut_path)) {
1324 user_shortcut_path.empty()) {
1325 NOTREACHED(); 1445 NOTREACHED();
1326 return false; 1446 return false;
1327 } 1447 }
1328 user_shortcut_path = user_shortcut_path.Append(shortcut_name); 1448 user_shortcut_path = user_shortcut_path.Append(shortcut_name);
1329 chosen_path = &user_shortcut_path; 1449 chosen_path = &user_shortcut_path;
1330 } else { 1450 } else {
1331 // Do not install any shortcut if we are told to install a user-level 1451 // Do not install any shortcut if we are told to install a user-level
1332 // shortcut, but the system-level variant of that shortcut is present. 1452 // shortcut, but the system-level variant of that shortcut is present.
1333 // Other actions (e.g., pinning) can still happen with respect to the 1453 // Other actions (e.g., pinning) can still happen with respect to the
1334 // existing system-level shortcut however. 1454 // existing system-level shortcut however.
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 } else if (elevate_if_not_admin && 1974 } else if (elevate_if_not_admin &&
1855 base::win::GetVersion() >= base::win::VERSION_VISTA) { 1975 base::win::GetVersion() >= base::win::VERSION_VISTA) {
1856 // Elevate to do the whole job 1976 // Elevate to do the whole job
1857 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); 1977 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol);
1858 } else { 1978 } else {
1859 // Admin rights are required to register capabilities before Windows 8. 1979 // Admin rights are required to register capabilities before Windows 8.
1860 return false; 1980 return false;
1861 } 1981 }
1862 } 1982 }
1863 1983
1864 bool ShellUtil::RemoveShortcut(ShellUtil::ShortcutLocation location, 1984 // static
1865 BrowserDistribution* dist, 1985 bool ShellUtil::RemoveShortcuts(ShellUtil::ShortcutLocation location,
1866 const base::FilePath& target_exe, 1986 BrowserDistribution* dist,
1867 ShellChange level, 1987 ShellChange level,
1868 const string16* shortcut_name) { 1988 const base::FilePath& target_exe) {
1869 const bool delete_folder = (location == SHORTCUT_LOCATION_START_MENU); 1989 if (!ShellUtil::ShortcutLocationIsSupported(location))
1990 return true; // Vacuous success.
1870 1991
1871 base::FilePath shortcut_folder; 1992 switch (location) {
1872 if (!GetShortcutPath(location, dist, level, &shortcut_folder) || 1993 case SHORTCUT_LOCATION_START_MENU: // Falls through.
1873 shortcut_folder.empty()) { 1994 case SHORTCUT_LOCATION_APP_SHORTCUTS:
1874 NOTREACHED(); 1995 return RemoveShortcutFolder(location, dist, level);
1875 return false;
1876 }
1877 1996
1878 if (!delete_folder && !shortcut_name) { 1997 case SHORTCUT_LOCATION_TASKBAR_PINS:
1879 file_util::FileEnumerator enumerator(shortcut_folder, false, 1998 return BatchShortcutAction(base::Bind(&ShortcutOpUnpin), location, dist,
1880 file_util::FileEnumerator::FILES); 1999 level, target_exe);
1881 bool had_failures = false;
1882 for (base::FilePath path = enumerator.Next(); !path.empty();
1883 path = enumerator.Next()) {
1884 if (path.Extension() != installer::kLnkExt)
1885 continue;
1886 2000
1887 if (!MaybeRemoveShortcutAtPath(path, target_exe, delete_folder)) 2001 default:
1888 had_failures = true; 2002 return BatchShortcutAction(base::Bind(&ShortcutOpDelete), location, dist,
1889 } 2003 level, target_exe);
1890 return !had_failures;
1891 }
1892
1893 const string16 shortcut_base_name(
1894 (shortcut_name ? *shortcut_name : dist->GetAppShortCutName()) +
1895 installer::kLnkExt);
1896 const base::FilePath shortcut_path(
1897 shortcut_folder.Append(shortcut_base_name));
1898 if (!file_util::PathExists(shortcut_path))
1899 return true;
1900
1901 return MaybeRemoveShortcutAtPath(shortcut_path, target_exe, delete_folder);
1902 }
1903
1904 void ShellUtil::RemoveTaskbarShortcuts(const string16& target_exe) {
1905 if (base::win::GetVersion() < base::win::VERSION_WIN7)
1906 return;
1907
1908 base::FilePath taskbar_pins_path;
1909 if (!PathService::Get(base::DIR_TASKBAR_PINS, &taskbar_pins_path) ||
1910 !file_util::PathExists(taskbar_pins_path)) {
1911 LOG(ERROR) << "Couldn't find path to taskbar pins.";
1912 return;
1913 }
1914
1915 file_util::FileEnumerator shortcuts_enum(
1916 taskbar_pins_path, false,
1917 file_util::FileEnumerator::FILES, FILE_PATH_LITERAL("*.lnk"));
1918
1919 base::FilePath target_path(target_exe);
1920 InstallUtil::ProgramCompare target_compare(target_path);
1921 for (base::FilePath shortcut_path = shortcuts_enum.Next();
1922 !shortcut_path.empty();
1923 shortcut_path = shortcuts_enum.Next()) {
1924 base::FilePath read_target;
1925 if (!base::win::ResolveShortcut(shortcut_path, &read_target, NULL)) {
1926 LOG(ERROR) << "Couldn't resolve shortcut at " << shortcut_path.value();
1927 continue;
1928 }
1929 if (target_compare.EvaluatePath(read_target)) {
1930 // Unpin this shortcut if it points to |target_exe|.
1931 base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str());
1932 }
1933 } 2004 }
1934 } 2005 }
1935 2006
1936 void ShellUtil::RemoveStartScreenShortcuts(BrowserDistribution* dist, 2007 // static
1937 const string16& target_exe) { 2008 bool ShellUtil::UpdateShortcuts(
1938 if (base::win::GetVersion() < base::win::VERSION_WIN8) 2009 ShellUtil::ShortcutLocation location,
1939 return; 2010 BrowserDistribution* dist,
2011 ShellChange level,
2012 const base::FilePath& target_exe,
2013 const ShellUtil::ShortcutProperties& properties) {
2014 if (!ShellUtil::ShortcutLocationIsSupported(location))
2015 return true; // Vacuous success.
1940 2016
1941 base::FilePath app_shortcuts_path; 2017 base::win::ShortcutProperties shortcut_properties(
1942 if (!PathService::Get(base::DIR_APP_SHORTCUTS, &app_shortcuts_path)) { 2018 TranslateShortcutProperties(properties));
1943 LOG(ERROR) << "Could not get application shortcuts location to delete" 2019 return BatchShortcutAction(base::Bind(&ShortcutOpUpdate, shortcut_properties),
1944 << " start screen shortcuts."; 2020 location, dist, level, target_exe);
1945 return;
1946 }
1947
1948 app_shortcuts_path = app_shortcuts_path.Append(
1949 GetBrowserModelId(dist,
1950 InstallUtil::IsPerUserInstall(target_exe.c_str())));
1951 if (!file_util::DirectoryExists(app_shortcuts_path)) {
1952 VLOG(1) << "No start screen shortcuts to delete.";
1953 return;
1954 }
1955
1956 VLOG(1) << "Removing start screen shortcuts from "
1957 << app_shortcuts_path.value();
1958 if (!file_util::Delete(app_shortcuts_path, true)) {
1959 LOG(ERROR) << "Failed to remove start screen shortcuts from "
1960 << app_shortcuts_path.value();
1961 }
1962 } 2021 }
1963 2022
1964 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) { 2023 bool ShellUtil::GetUserSpecificRegistrySuffix(string16* suffix) {
1965 // Use a thread-safe cache for the user's suffix. 2024 // Use a thread-safe cache for the user's suffix.
1966 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance = 2025 static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance =
1967 LAZY_INSTANCE_INITIALIZER; 2026 LAZY_INSTANCE_INITIALIZER;
1968 return suffix_instance.Get().GetSuffix(suffix); 2027 return suffix_instance.Get().GetSuffix(suffix);
1969 } 2028 }
1970 2029
1971 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) { 2030 bool ShellUtil::GetOldUserSpecificRegistrySuffix(string16* suffix) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 // are any left...). 2080 // are any left...).
2022 if (free_bits >= 8 && next_byte_index < size) { 2081 if (free_bits >= 8 && next_byte_index < size) {
2023 free_bits -= 8; 2082 free_bits -= 8;
2024 bit_stream += bytes[next_byte_index++] << free_bits; 2083 bit_stream += bytes[next_byte_index++] << free_bits;
2025 } 2084 }
2026 } 2085 }
2027 2086
2028 DCHECK_EQ(ret.length(), encoded_length); 2087 DCHECK_EQ(ret.length(), encoded_length);
2029 return ret; 2088 return ret;
2030 } 2089 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698