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

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

Issue 11743022: Windows: Remove desktop profile shortcuts (and any others pointing to the exe) on uninstall. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « chrome/installer/util/shell_util.h ('k') | chrome/installer/util/shell_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 const base::win::Version windows_version = base::win::GetVersion(); 1147 const base::win::Version windows_version = base::win::GetVersion();
1148 1148
1149 if (windows_version >= base::win::VERSION_WIN8) 1149 if (windows_version >= base::win::VERSION_WIN8)
1150 return ProbeCurrentDefaultHandlers(protocols, num_protocols); 1150 return ProbeCurrentDefaultHandlers(protocols, num_protocols);
1151 else if (windows_version >= base::win::VERSION_VISTA) 1151 else if (windows_version >= base::win::VERSION_VISTA)
1152 return ProbeAppIsDefaultHandlers(protocols, num_protocols); 1152 return ProbeAppIsDefaultHandlers(protocols, num_protocols);
1153 1153
1154 return ProbeOpenCommandHandlers(protocols, num_protocols); 1154 return ProbeOpenCommandHandlers(protocols, num_protocols);
1155 } 1155 }
1156 1156
1157 // Removes shortcut at |shortcut_path| if it is a shortcut that points to
1158 // |target_exe|. If |delete_folder| is true, deletes the parent folder of
1159 // the shortcut completely. Returns true if either the shortcut was deleted
1160 // successfully or if the shortcut did not point to |target_exe|.
1161 bool MaybeRemoveShortcutAtPath(const FilePath& shortcut_path,
1162 const FilePath& target_exe,
1163 bool delete_folder) {
1164 FilePath target_path;
1165 if (!base::win::ResolveShortcut(shortcut_path, &target_path, NULL))
1166 return false;
1167
1168 if (InstallUtil::ProgramCompare(target_exe).EvaluatePath(target_path)) {
1169 // Unpin the shortcut if it was ever pinned by the user or the installer.
1170 VLOG(1) << "Trying to unpin " << shortcut_path.value();
1171 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str())) {
1172 VLOG(1) << shortcut_path.value()
1173 << " wasn't pinned (or the unpin failed).";
1174 }
1175 if (delete_folder)
1176 return file_util::Delete(shortcut_path.DirName(), true);
1177 else
1178 return file_util::Delete(shortcut_path, false);
1179 }
1180
1181 // The shortcut at |shortcut_path| doesn't point to |target_exe|, act as if
1182 // our shortcut had been deleted.
1183 return true;
1184 }
1185
1157 } // namespace 1186 } // namespace
1158 1187
1159 const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon"; 1188 const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon";
1160 const wchar_t* ShellUtil::kRegShellPath = L"\\shell"; 1189 const wchar_t* ShellUtil::kRegShellPath = L"\\shell";
1161 const wchar_t* ShellUtil::kRegShellOpen = L"\\shell\\open\\command"; 1190 const wchar_t* ShellUtil::kRegShellOpen = L"\\shell\\open\\command";
1162 const wchar_t* ShellUtil::kRegStartMenuInternet = 1191 const wchar_t* ShellUtil::kRegStartMenuInternet =
1163 L"Software\\Clients\\StartMenuInternet"; 1192 L"Software\\Clients\\StartMenuInternet";
1164 const wchar_t* ShellUtil::kRegClasses = L"Software\\Classes"; 1193 const wchar_t* ShellUtil::kRegClasses = L"Software\\Classes";
1165 const wchar_t* ShellUtil::kRegRegisteredApplications = 1194 const wchar_t* ShellUtil::kRegRegisteredApplications =
1166 L"Software\\RegisteredApplications"; 1195 L"Software\\RegisteredApplications";
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 user_shortcut_path.empty() || 1299 user_shortcut_path.empty() ||
1271 system_shortcut_path.empty()) { 1300 system_shortcut_path.empty()) {
1272 NOTREACHED(); 1301 NOTREACHED();
1273 return false; 1302 return false;
1274 } 1303 }
1275 1304
1276 string16 shortcut_name(ExtractShortcutNameFromProperties(dist, properties)); 1305 string16 shortcut_name(ExtractShortcutNameFromProperties(dist, properties));
1277 user_shortcut_path = user_shortcut_path.Append(shortcut_name); 1306 user_shortcut_path = user_shortcut_path.Append(shortcut_name);
1278 system_shortcut_path = system_shortcut_path.Append(shortcut_name); 1307 system_shortcut_path = system_shortcut_path.Append(shortcut_name);
1279 1308
1280 FilePath *chosen_path; 1309 FilePath* chosen_path;
1281 bool should_install_shortcut = true; 1310 bool should_install_shortcut = true;
1282 if (properties.level == SYSTEM_LEVEL) { 1311 if (properties.level == SYSTEM_LEVEL) {
1283 // Install the system-level shortcut if requested. 1312 // Install the system-level shortcut if requested.
1284 chosen_path = &system_shortcut_path; 1313 chosen_path = &system_shortcut_path;
1285 } else if (operation != SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL || 1314 } else if (operation != SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL ||
1286 !file_util::PathExists(system_shortcut_path)){ 1315 !file_util::PathExists(system_shortcut_path)) {
1287 // Otherwise install the user-level shortcut, unless the system-level 1316 // Otherwise install the user-level shortcut, unless the system-level
1288 // variant of this shortcut is present on the machine and |operation| states 1317 // variant of this shortcut is present on the machine and |operation| states
1289 // not to create a user-level shortcut in that case. 1318 // not to create a user-level shortcut in that case.
1290 chosen_path = &user_shortcut_path; 1319 chosen_path = &user_shortcut_path;
1291 } else { 1320 } else {
1292 // Do not install any shortcut if we are told to install a user-level 1321 // Do not install any shortcut if we are told to install a user-level
1293 // shortcut, but the system-level variant of that shortcut is present. 1322 // shortcut, but the system-level variant of that shortcut is present.
1294 // Other actions (e.g., pinning) can still happen with respect to the 1323 // Other actions (e.g., pinning) can still happen with respect to the
1295 // existing system-level shortcut however. 1324 // existing system-level shortcut however.
1296 chosen_path = &system_shortcut_path; 1325 chosen_path = &system_shortcut_path;
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 // Elevate to do the whole job 1817 // Elevate to do the whole job
1789 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); 1818 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol);
1790 } else { 1819 } else {
1791 // Admin rights are required to register capabilities before Windows 8. 1820 // Admin rights are required to register capabilities before Windows 8.
1792 return false; 1821 return false;
1793 } 1822 }
1794 } 1823 }
1795 1824
1796 bool ShellUtil::RemoveShortcut(ShellUtil::ShortcutLocation location, 1825 bool ShellUtil::RemoveShortcut(ShellUtil::ShortcutLocation location,
1797 BrowserDistribution* dist, 1826 BrowserDistribution* dist,
1798 const string16& target_exe, 1827 const FilePath& target_exe,
1799 ShellChange level, 1828 ShellChange level,
1800 const string16* shortcut_name) { 1829 const string16* shortcut_name) {
1801 bool delete_folder = (location == SHORTCUT_LOCATION_START_MENU); 1830 const bool delete_folder = (location == SHORTCUT_LOCATION_START_MENU);
1802 1831
1803 FilePath shortcut_folder; 1832 FilePath shortcut_folder;
1804 if (!GetShortcutPath(location, dist, level, &shortcut_folder) || 1833 if (!GetShortcutPath(location, dist, level, &shortcut_folder) ||
1805 shortcut_folder.empty()) { 1834 shortcut_folder.empty()) {
1806 NOTREACHED(); 1835 NOTREACHED();
1807 return false; 1836 return false;
1808 } 1837 }
1809 1838
1810 string16 shortcut_base_name( 1839 if (!delete_folder && !shortcut_name) {
1840 file_util::FileEnumerator enumerator(shortcut_folder, false,
1841 file_util::FileEnumerator::FILES);
1842 bool had_failures = false;
1843 for (FilePath path = enumerator.Next(); !path.empty();
1844 path = enumerator.Next()) {
1845 if (path.Extension() != installer::kLnkExt)
1846 continue;
1847
1848 if (!MaybeRemoveShortcutAtPath(path, target_exe, delete_folder))
1849 had_failures = true;
1850 }
1851 return !had_failures;
1852 }
1853
1854 const string16 shortcut_base_name(
1811 (shortcut_name ? *shortcut_name : dist->GetAppShortCutName()) + 1855 (shortcut_name ? *shortcut_name : dist->GetAppShortCutName()) +
1812 installer::kLnkExt); 1856 installer::kLnkExt);
1813 FilePath shortcut_path(shortcut_folder.Append(shortcut_base_name)); 1857 const FilePath shortcut_path(shortcut_folder.Append(shortcut_base_name));
1814
1815 if (!file_util::PathExists(shortcut_path)) 1858 if (!file_util::PathExists(shortcut_path))
1816 return true; 1859 return true;
1817 1860
1818 base::win::ScopedComPtr<IShellLink> i_shell_link; 1861 return MaybeRemoveShortcutAtPath(shortcut_path, target_exe, delete_folder);
1819 base::win::ScopedComPtr<IPersistFile> i_persist_file;
1820 wchar_t read_target[MAX_PATH] = {};
1821 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL,
1822 CLSCTX_INPROC_SERVER)) ||
1823 FAILED(i_persist_file.QueryFrom(i_shell_link)) ||
1824 FAILED(i_persist_file->Load(shortcut_path.value().c_str(), STGM_READ)) ||
1825 FAILED(i_shell_link->GetPath(read_target, MAX_PATH, NULL,
1826 SLGP_SHORTPATH))) {
1827 NOTREACHED();
1828 return false;
1829 }
1830
1831 if (InstallUtil::ProgramCompare(FilePath(target_exe)).Evaluate(read_target)) {
1832 // Unpin the shortcut if it was ever pinned by the user or the installer.
1833 VLOG(1) << "Trying to unpin " << shortcut_path.value();
1834 if (!base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str())) {
1835 VLOG(1) << shortcut_path.value()
1836 << " wasn't pinned (or the unpin failed).";
1837 }
1838 if (delete_folder)
1839 return file_util::Delete(shortcut_folder, true);
1840 else
1841 return file_util::Delete(shortcut_path, false);
1842 }
1843
1844 // The shortcut at |shortcut_path| doesn't point to |target_exe|, act as if
1845 // our shortcut had been deleted.
1846 return true;
1847 } 1862 }
1848 1863
1849 void ShellUtil::RemoveTaskbarShortcuts(const string16& target_exe) { 1864 void ShellUtil::RemoveTaskbarShortcuts(const string16& target_exe) {
1850 if (base::win::GetVersion() < base::win::VERSION_WIN7) 1865 if (base::win::GetVersion() < base::win::VERSION_WIN7)
1851 return; 1866 return;
1852 1867
1853 FilePath taskbar_pins_path; 1868 FilePath taskbar_pins_path;
1854 if (!PathService::Get(base::DIR_TASKBAR_PINS, &taskbar_pins_path) || 1869 if (!PathService::Get(base::DIR_TASKBAR_PINS, &taskbar_pins_path) ||
1855 !file_util::PathExists(taskbar_pins_path)) { 1870 !file_util::PathExists(taskbar_pins_path)) {
1856 LOG(ERROR) << "Couldn't find path to taskbar pins."; 1871 LOG(ERROR) << "Couldn't find path to taskbar pins.";
1857 return; 1872 return;
1858 } 1873 }
1859 1874
1860 file_util::FileEnumerator shortcuts_enum( 1875 file_util::FileEnumerator shortcuts_enum(
1861 taskbar_pins_path, false, 1876 taskbar_pins_path, false,
1862 file_util::FileEnumerator::FILES, FILE_PATH_LITERAL("*.lnk")); 1877 file_util::FileEnumerator::FILES, FILE_PATH_LITERAL("*.lnk"));
1863 1878
1864 FilePath target_path(target_exe); 1879 FilePath target_path(target_exe);
1865 InstallUtil::ProgramCompare target_compare(target_path); 1880 InstallUtil::ProgramCompare target_compare(target_path);
1866 for (FilePath shortcut_path = shortcuts_enum.Next(); !shortcut_path.empty(); 1881 for (FilePath shortcut_path = shortcuts_enum.Next(); !shortcut_path.empty();
1867 shortcut_path = shortcuts_enum.Next()) { 1882 shortcut_path = shortcuts_enum.Next()) {
1868 FilePath read_target; 1883 FilePath read_target;
1869 if (!base::win::ResolveShortcut(shortcut_path, &read_target, NULL)) { 1884 if (!base::win::ResolveShortcut(shortcut_path, &read_target, NULL)) {
1870 LOG(ERROR) << "Couldn't resolve shortcut at " << shortcut_path.value(); 1885 LOG(ERROR) << "Couldn't resolve shortcut at " << shortcut_path.value();
1871 continue; 1886 continue;
1872 } 1887 }
1873 if (target_compare.Evaluate(read_target.value())) { 1888 if (target_compare.EvaluatePath(read_target)) {
1874 // Unpin this shortcut if it points to |target_exe|. 1889 // Unpin this shortcut if it points to |target_exe|.
1875 base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str()); 1890 base::win::TaskbarUnpinShortcutLink(shortcut_path.value().c_str());
1876 } 1891 }
1877 } 1892 }
1878 } 1893 }
1879 1894
1880 void ShellUtil::RemoveStartScreenShortcuts(BrowserDistribution* dist, 1895 void ShellUtil::RemoveStartScreenShortcuts(BrowserDistribution* dist,
1881 const string16& target_exe) { 1896 const string16& target_exe) {
1882 if (base::win::GetVersion() < base::win::VERSION_WIN8) 1897 if (base::win::GetVersion() < base::win::VERSION_WIN8)
1883 return; 1898 return;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 // are any left...). 1980 // are any left...).
1966 if (free_bits >= 8 && next_byte_index < size) { 1981 if (free_bits >= 8 && next_byte_index < size) {
1967 free_bits -= 8; 1982 free_bits -= 8;
1968 bit_stream += bytes[next_byte_index++] << free_bits; 1983 bit_stream += bytes[next_byte_index++] << free_bits;
1969 } 1984 }
1970 } 1985 }
1971 1986
1972 DCHECK_EQ(ret.length(), encoded_length); 1987 DCHECK_EQ(ret.length(), encoded_length);
1973 return ret; 1988 return ret;
1974 } 1989 }
OLDNEW
« no previous file with comments | « chrome/installer/util/shell_util.h ('k') | chrome/installer/util/shell_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698