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 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |