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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". | 120 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". |
| 121 static string16 GetCapabilitiesKey(BrowserDistribution* dist, | 121 static string16 GetCapabilitiesKey(BrowserDistribution* dist, |
| 122 const string16& suffix) { | 122 const string16& suffix) { |
| 123 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities"); | 123 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities"); |
| 124 } | 124 } |
| 125 | 125 |
| 126 // This method returns a list of all the registry entries that | 126 // This method returns a list of all the registry entries that |
| 127 // are needed to register Chromium ProgIds. | 127 // are needed to register Chromium ProgIds. |
| 128 // These entries should be registered in HKCU for user-level installs and in | 128 // These entries should be registered in HKCU for user-level installs and in |
| 129 // HKLM for system-level installs. | 129 // HKLM for system-level installs. |
| 130 // TODO (gab): Extract the Windows 8 only registrations out of this function. | |
|
grt (UTC plus 2)
2012/06/20 19:42:12
has it been a long time since you rebased?
motek.
2012/06/20 22:02:29
Not really. This is some git accident, gab@ says l
| |
| 130 static bool GetProgIdEntries(BrowserDistribution* dist, | 131 static bool GetProgIdEntries(BrowserDistribution* dist, |
| 131 const string16& chrome_exe, | 132 const string16& chrome_exe, |
| 132 const string16& suffix, | 133 const string16& suffix, |
| 133 std::list<RegistryEntry*>* entries) { | 134 std::list<RegistryEntry*>* entries) { |
| 134 string16 icon_path(ShellUtil::GetChromeIcon(dist, chrome_exe)); | 135 string16 icon_path(ShellUtil::GetChromeIcon(dist, chrome_exe)); |
| 135 string16 open_cmd(ShellUtil::GetChromeShellOpenCmd(chrome_exe)); | 136 string16 open_cmd(ShellUtil::GetChromeShellOpenCmd(chrome_exe)); |
| 136 string16 delegate_command(ShellUtil::GetChromeDelegateCommand(chrome_exe)); | 137 string16 delegate_command(ShellUtil::GetChromeDelegateCommand(chrome_exe)); |
| 137 // For user-level installs: entries for the app id and DelegateExecute verb | 138 // For user-level installs: entries for the app id and DelegateExecute verb |
| 138 // handler will be in HKCU; thus we do not need a suffix on those entries. | 139 // handler will be in HKCU; thus we do not need a suffix on those entries. |
| 139 string16 app_id(ShellUtil::GetBrowserModelId(dist, chrome_exe)); | 140 string16 app_id(ShellUtil::GetBrowserModelId(dist, chrome_exe)); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 chrome_html_prog_id + ShellUtil::kRegDefaultIcon, icon_path)); | 192 chrome_html_prog_id + ShellUtil::kRegDefaultIcon, icon_path)); |
| 192 entries->push_front(new RegistryEntry( | 193 entries->push_front(new RegistryEntry( |
| 193 chrome_html_prog_id + ShellUtil::kRegShellOpen, open_cmd)); | 194 chrome_html_prog_id + ShellUtil::kRegShellOpen, open_cmd)); |
| 194 if (set_delegate_execute) { | 195 if (set_delegate_execute) { |
| 195 entries->push_front(new RegistryEntry( | 196 entries->push_front(new RegistryEntry( |
| 196 chrome_html_prog_id + ShellUtil::kRegShellOpen, | 197 chrome_html_prog_id + ShellUtil::kRegShellOpen, |
| 197 ShellUtil::kRegDelegateExecute, delegate_guid)); | 198 ShellUtil::kRegDelegateExecute, delegate_guid)); |
| 198 } | 199 } |
| 199 | 200 |
| 200 // The following entries are required as of Windows 8, but do not | 201 // The following entries are required as of Windows 8, but do not |
| 201 // depend on the DelegateExecute verb handler being set. | 202 // depend on the DelegateExecute. |
| 202 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | 203 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { |
| 203 entries->push_front(new RegistryEntry( | 204 entries->push_front(new RegistryEntry( |
| 204 chrome_html_prog_id, ShellUtil::kRegAppUserModelId, app_id)); | 205 chrome_html_prog_id, ShellUtil::kRegAppUserModelId, app_id)); |
| 205 | 206 |
| 206 // Add \Software\Classes\ChromeHTML\Application entries | 207 // Add \Software\Classes\ChromeHTML\Application entries |
| 207 string16 chrome_application(chrome_html_prog_id + | 208 string16 chrome_application(chrome_html_prog_id + |
| 208 ShellUtil::kRegApplication); | 209 ShellUtil::kRegApplication); |
| 209 entries->push_front(new RegistryEntry( | 210 entries->push_front(new RegistryEntry( |
| 210 chrome_application, ShellUtil::kRegAppUserModelId, app_id)); | 211 chrome_application, ShellUtil::kRegAppUserModelId, app_id)); |
| 211 entries->push_front(new RegistryEntry( | 212 entries->push_front(new RegistryEntry( |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 // This method registers Chrome on Vista by launching an elevated setup.exe. | 546 // This method registers Chrome on Vista by launching an elevated setup.exe. |
| 546 // That will show the user the standard Vista elevation prompt. If the user | 547 // That will show the user the standard Vista elevation prompt. If the user |
| 547 // accepts it the new process will make the necessary changes and return SUCCESS | 548 // accepts it the new process will make the necessary changes and return SUCCESS |
| 548 // that we capture and return. | 549 // that we capture and return. |
| 549 // If protocol is non-empty we will also register Chrome as being capable of | 550 // If protocol is non-empty we will also register Chrome as being capable of |
| 550 // handling the protocol. | 551 // handling the protocol. |
| 551 bool ElevateAndRegisterChrome(BrowserDistribution* dist, | 552 bool ElevateAndRegisterChrome(BrowserDistribution* dist, |
| 552 const string16& chrome_exe, | 553 const string16& chrome_exe, |
| 553 const string16& suffix, | 554 const string16& suffix, |
| 554 const string16& protocol) { | 555 const string16& protocol) { |
| 555 // Only user-level installs prior to Windows 8 should need to elevate to | |
| 556 // register. | |
| 557 DCHECK(InstallUtil::IsPerUserInstall(chrome_exe.c_str())); | |
| 558 DCHECK_LT(base::win::GetVersion(), base::win::VERSION_WIN8); | |
| 559 FilePath exe_path = | 556 FilePath exe_path = |
| 560 FilePath::FromWStringHack(chrome_exe).DirName() | 557 FilePath::FromWStringHack(chrome_exe).DirName() |
| 561 .Append(installer::kSetupExe); | 558 .Append(installer::kSetupExe); |
| 562 if (!file_util::PathExists(exe_path)) { | 559 if (!file_util::PathExists(exe_path)) { |
| 563 HKEY reg_root = InstallUtil::IsPerUserInstall(chrome_exe.c_str()) ? | 560 HKEY reg_root = InstallUtil::IsPerUserInstall(chrome_exe.c_str()) ? |
| 564 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 561 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
| 565 RegKey key(reg_root, dist->GetUninstallRegPath().c_str(), KEY_READ); | 562 RegKey key(reg_root, dist->GetUninstallRegPath().c_str(), KEY_READ); |
| 566 string16 uninstall_string; | 563 string16 uninstall_string; |
| 567 key.ReadValue(installer::kUninstallStringField, &uninstall_string); | 564 key.ReadValue(installer::kUninstallStringField, &uninstall_string); |
| 568 CommandLine command_line = CommandLine::FromString(uninstall_string); | 565 CommandLine command_line = CommandLine::FromString(uninstall_string); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 // It is required that Chrome be already *registered* for the given protocol. | 600 // It is required that Chrome be already *registered* for the given protocol. |
| 604 bool LaunchSelectDefaultProtocolHandlerDialog(const wchar_t* protocol) { | 601 bool LaunchSelectDefaultProtocolHandlerDialog(const wchar_t* protocol) { |
| 605 DCHECK(protocol); | 602 DCHECK(protocol); |
| 606 OPENASINFO open_as_info = {}; | 603 OPENASINFO open_as_info = {}; |
| 607 open_as_info.pcszFile = protocol; | 604 open_as_info.pcszFile = protocol; |
| 608 open_as_info.oaifInFlags = | 605 open_as_info.oaifInFlags = |
| 609 OAIF_URL_PROTOCOL | OAIF_FORCE_REGISTRATION | OAIF_REGISTER_EXT; | 606 OAIF_URL_PROTOCOL | OAIF_FORCE_REGISTRATION | OAIF_REGISTER_EXT; |
| 610 HRESULT hr = SHOpenWithDialog(NULL, &open_as_info); | 607 HRESULT hr = SHOpenWithDialog(NULL, &open_as_info); |
| 611 DLOG_IF(WARNING, FAILED(hr)) << "Failed to set as default " << protocol | 608 DLOG_IF(WARNING, FAILED(hr)) << "Failed to set as default " << protocol |
| 612 << " handler; hr=0x" << std::hex << hr; | 609 << " handler; hr=0x" << std::hex << hr; |
| 610 | |
| 613 if (FAILED(hr)) | 611 if (FAILED(hr)) |
| 614 return false; | 612 return false; |
| 615 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); | 613 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); |
| 616 return true; | 614 return SUCCEEDED(hr); |
| 617 } | 615 } |
| 618 | 616 |
| 619 // Launches the Windows 7 and Windows 8 application association dialog, which | 617 // Launches the Windows 7 and Windows 8 application association dialog, which |
| 620 // is the only documented way to make a browser the default browser on | 618 // is the only documented way to make a browser the default browser on |
| 621 // Windows 8. | 619 // Windows 8. |
| 622 bool LaunchApplicationAssociationDialog(const string16& app_id) { | 620 bool LaunchApplicationAssociationDialog(const string16& app_id) { |
| 623 base::win::ScopedComPtr<IApplicationAssociationRegistrationUI> aarui; | 621 base::win::ScopedComPtr<IApplicationAssociationRegistrationUI> aarui; |
| 624 HRESULT hr = aarui.CreateInstance(CLSID_ApplicationAssociationRegistrationUI); | 622 HRESULT hr = aarui.CreateInstance(CLSID_ApplicationAssociationRegistrationUI); |
| 625 if (FAILED(hr)) | 623 if (FAILED(hr)) |
| 626 return false; | 624 return false; |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1135 | 1133 |
| 1136 // static | 1134 // static |
| 1137 bool ShellUtil::CanMakeChromeDefaultUnattended() { | 1135 bool ShellUtil::CanMakeChromeDefaultUnattended() { |
| 1138 return base::win::GetVersion() < base::win::VERSION_WIN8; | 1136 return base::win::GetVersion() < base::win::VERSION_WIN8; |
| 1139 } | 1137 } |
| 1140 | 1138 |
| 1141 bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, | 1139 bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, |
| 1142 int shell_change, | 1140 int shell_change, |
| 1143 const string16& chrome_exe, | 1141 const string16& chrome_exe, |
| 1144 bool elevate_if_not_admin) { | 1142 bool elevate_if_not_admin) { |
| 1145 DCHECK(!(shell_change & ShellUtil::SYSTEM_LEVEL) || IsUserAnAdmin()); | |
| 1146 | |
| 1147 if (!dist->CanSetAsDefault()) | 1143 if (!dist->CanSetAsDefault()) |
| 1148 return false; | 1144 return false; |
| 1149 | 1145 |
| 1150 // Windows 8 does not permit making a browser default just like that. | 1146 // Windows 8 does not permit making a browser default just like that. |
| 1151 // This process needs to be routed through the system's UI. Use | 1147 // This process needs to be routed through the system's UI. Use |
| 1152 // ShowMakeChromeDefaultSystemUI instead (below). | 1148 // ShowMakeChromeDefaultSystemUI instead (below). |
| 1153 if (!CanMakeChromeDefaultUnattended()) { | 1149 if (!CanMakeChromeDefaultUnattended()) { |
| 1154 NOTREACHED(); | 1150 NOTREACHED(); |
| 1155 return false; | 1151 return false; |
| 1156 } | 1152 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1234 | 1230 |
| 1235 if (!RegisterChromeBrowser(dist, chrome_exe, string16(), true)) | 1231 if (!RegisterChromeBrowser(dist, chrome_exe, string16(), true)) |
| 1236 return false; | 1232 return false; |
| 1237 | 1233 |
| 1238 // On Windows 8, you can't set yourself as the default handler | 1234 // On Windows 8, you can't set yourself as the default handler |
| 1239 // programatically. In other words IApplicationAssociationRegistration | 1235 // programatically. In other words IApplicationAssociationRegistration |
| 1240 // has been rendered useless. What you can do is to launch | 1236 // has been rendered useless. What you can do is to launch |
| 1241 // "Set Program Associations" section of the "Default Programs" | 1237 // "Set Program Associations" section of the "Default Programs" |
| 1242 // control panel, which is a mess, or pop the concise "How you want to open | 1238 // control panel, which is a mess, or pop the concise "How you want to open |
| 1243 // webpages?" dialog. We choose the latter. | 1239 // webpages?" dialog. We choose the latter. |
| 1240 // Return true only when the user took an action and there was no error. | |
| 1244 return LaunchSelectDefaultProtocolHandlerDialog(L"http"); | 1241 return LaunchSelectDefaultProtocolHandlerDialog(L"http"); |
| 1245 } | 1242 } |
| 1246 | 1243 |
| 1247 bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist, | 1244 bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist, |
| 1248 const string16& chrome_exe, | 1245 const string16& chrome_exe, |
| 1249 const string16& protocol) { | 1246 const string16& protocol) { |
| 1250 if (!dist->CanSetAsDefault()) | 1247 if (!dist->CanSetAsDefault()) |
| 1251 return false; | 1248 return false; |
| 1252 | 1249 |
| 1253 ShellUtil::RegisterChromeForProtocol(dist, chrome_exe, L"", protocol, true); | 1250 ShellUtil::RegisterChromeForProtocol(dist, chrome_exe, L"", protocol, true); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1326 STLElementDeleter<std::list<RegistryEntry*> > shell_deleter(&shell_entries); | 1323 STLElementDeleter<std::list<RegistryEntry*> > shell_deleter(&shell_entries); |
| 1327 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &progids); | 1324 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &progids); |
| 1328 RegistryEntry::GetShellIntegrationEntries( | 1325 RegistryEntry::GetShellIntegrationEntries( |
| 1329 dist, chrome_exe, suffix, &shell_entries); | 1326 dist, chrome_exe, suffix, &shell_entries); |
| 1330 return AddRegistryEntries(user_level ? HKEY_CURRENT_USER : | 1327 return AddRegistryEntries(user_level ? HKEY_CURRENT_USER : |
| 1331 HKEY_LOCAL_MACHINE, | 1328 HKEY_LOCAL_MACHINE, |
| 1332 progids) && | 1329 progids) && |
| 1333 AddRegistryEntries(root, shell_entries); | 1330 AddRegistryEntries(root, shell_entries); |
| 1334 } | 1331 } |
| 1335 | 1332 |
| 1336 // If the user is not an admin and OS is between Vista and Windows 7 | 1333 // If user is not an admin and OS is Vista, try to elevate and register. |
| 1337 // inclusively, try to elevate and register. This is only intended for | |
| 1338 // user-level installs as system-level installs should always be run with | |
| 1339 // admin rights. | |
| 1340 if (elevate_if_not_admin && | 1334 if (elevate_if_not_admin && |
| 1341 base::win::GetVersion() >= base::win::VERSION_VISTA && | 1335 base::win::GetVersion() >= base::win::VERSION_VISTA && |
| 1342 ElevateAndRegisterChrome(dist, chrome_exe, suffix, L"")) | 1336 ElevateAndRegisterChrome(dist, chrome_exe, suffix, L"")) |
| 1343 return true; | 1337 return true; |
| 1344 | 1338 |
| 1345 // If we got to this point then all we can do is create ProgIds under HKCU. | 1339 // If we got to this point then all we can do is create ProgIds under HKCU |
| 1340 // on XP as well as Vista. | |
| 1346 std::list<RegistryEntry*> entries; | 1341 std::list<RegistryEntry*> entries; |
| 1347 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); | 1342 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); |
| 1348 RegistryEntry::GetProgIdEntries(dist, chrome_exe, L"", &entries); | 1343 RegistryEntry::GetProgIdEntries(dist, chrome_exe, L"", &entries); |
| 1349 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered with | 1344 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered with |
| 1350 // no suffix (as per the old registration style): in which case some other | 1345 // no suffix (as per the old registration style): in which case some other |
| 1351 // registry entries could refer to them and since we were not able to set our | 1346 // registry entries could refer to them and since we were not able to set our |
| 1352 // HKLM entries above, we are better off not altering these here. | 1347 // HKLM entries above, we are better off not altering these here. |
| 1353 if (!AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU)) { | 1348 if (!AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU)) { |
| 1354 if (!suffix.empty()) { | 1349 if (!suffix.empty()) { |
| 1355 STLDeleteElements(&entries); | 1350 STLDeleteElements(&entries); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1386 // We can do this operation directly. | 1381 // We can do this operation directly. |
| 1387 // First, make sure Chrome is fully registered on this machine. | 1382 // First, make sure Chrome is fully registered on this machine. |
| 1388 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) | 1383 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) |
| 1389 return false; | 1384 return false; |
| 1390 | 1385 |
| 1391 // Write in the capabillity for the protocol. | 1386 // Write in the capabillity for the protocol. |
| 1392 std::list<RegistryEntry*> entries; | 1387 std::list<RegistryEntry*> entries; |
| 1393 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); | 1388 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); |
| 1394 RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, | 1389 RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, |
| 1395 &entries); | 1390 &entries); |
| 1396 return AddRegistryEntries(root, entries); | 1391 return AddRegistryEntries(HKEY_LOCAL_MACHINE, entries); |
| 1397 } else if (elevate_if_not_admin && | 1392 } else if (elevate_if_not_admin && |
| 1398 base::win::GetVersion() >= base::win::VERSION_VISTA) { | 1393 base::win::GetVersion() >= base::win::VERSION_VISTA) { |
| 1399 // Elevate to do the whole job | 1394 // Elevate to do the whole job |
| 1400 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); | 1395 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); |
| 1401 } else { | 1396 } else { |
| 1402 // Admin rights are required to register capabilities before Windows 8. | 1397 // we need admin rights to register our capability. If we don't |
| 1398 // have them and can't elevate, give up. | |
| 1403 return false; | 1399 return false; |
| 1404 } | 1400 } |
| 1405 } | 1401 } |
| 1406 | 1402 |
| 1407 bool ShellUtil::RemoveChromeDesktopShortcut(BrowserDistribution* dist, | 1403 bool ShellUtil::RemoveChromeDesktopShortcut(BrowserDistribution* dist, |
| 1408 int shell_change, uint32 options) { | 1404 int shell_change, uint32 options) { |
| 1409 // Only SHORTCUT_ALTERNATE is a valid option for this function. | 1405 // Only SHORTCUT_ALTERNATE is a valid option for this function. |
| 1410 DCHECK(!options || options == ShellUtil::SHORTCUT_ALTERNATE); | 1406 DCHECK(!options || options == ShellUtil::SHORTCUT_ALTERNATE); |
| 1411 | 1407 |
| 1412 string16 shortcut_name; | 1408 string16 shortcut_name; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1511 chrome_exe.c_str(), | 1507 chrome_exe.c_str(), |
| 1512 shortcut.c_str(), | 1508 shortcut.c_str(), |
| 1513 chrome_path.value().c_str(), | 1509 chrome_path.value().c_str(), |
| 1514 arguments.c_str(), | 1510 arguments.c_str(), |
| 1515 description.c_str(), | 1511 description.c_str(), |
| 1516 icon_path.c_str(), | 1512 icon_path.c_str(), |
| 1517 icon_index, | 1513 icon_index, |
| 1518 app_id.c_str(), | 1514 app_id.c_str(), |
| 1519 ConvertShellUtilShortcutOptionsToFileUtil(options)); | 1515 ConvertShellUtilShortcutOptionsToFileUtil(options)); |
| 1520 } | 1516 } |
| OLD | NEW |