| Index: chrome/installer/util/shell_util.cc
|
| diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
|
| index 7353f64760b221be565277f79522cf1a35256bea..96f73cfa0a7160529c69e9566b0e6916a8089f77 100644
|
| --- a/chrome/installer/util/shell_util.cc
|
| +++ b/chrome/installer/util/shell_util.cc
|
| @@ -13,6 +13,7 @@
|
|
|
| #include "chrome/installer/util/shell_util.h"
|
|
|
| +#include "base/command_line.h"
|
| #include "base/file_path.h"
|
| #include "base/file_util.h"
|
| #include "base/logging.h"
|
| @@ -219,35 +220,13 @@ bool IsChromeRegistered(const std::wstring& chrome_exe) {
|
| return registered;
|
| }
|
|
|
| -bool CreateChromeRegKeysForXP(HKEY root_key, const std::wstring& chrome_exe) {
|
| +bool BindChromeAssociations(HKEY root_key, const std::wstring& chrome_exe) {
|
| // Create a list of registry entries to create so that we can rollback
|
| // in case of problem.
|
| scoped_ptr<WorkItemList> items(WorkItem::CreateWorkItemList());
|
| - std::wstring classes_path(ShellUtil::kRegClasses);
|
| -
|
| - std::wstring exe_name = file_util::GetFilenameFromPath(chrome_exe);
|
| - std::wstring chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
|
| - std::wstring chrome_icon(chrome_exe);
|
| - ShellUtil::GetChromeIcon(chrome_icon);
|
| -
|
| - // Create Software\Classes\ChromeHTML
|
| - std::wstring html_prog_id = classes_path + L"\\" +
|
| - ShellUtil::kChromeHTMLProgId;
|
| - items->AddCreateRegKeyWorkItem(root_key, html_prog_id);
|
| - items->AddSetRegValueWorkItem(root_key, html_prog_id,
|
| - L"", ShellUtil::kChromeHTMLProgIdDesc, true);
|
| - items->AddSetRegValueWorkItem(root_key, html_prog_id,
|
| - ShellUtil::kRegUrlProtocol, L"", true);
|
| - std::wstring default_icon = html_prog_id + ShellUtil::kRegDefaultIcon;
|
| - items->AddCreateRegKeyWorkItem(root_key, default_icon);
|
| - items->AddSetRegValueWorkItem(root_key, default_icon, L"",
|
| - chrome_icon, true);
|
| - std::wstring open_cmd = html_prog_id + ShellUtil::kRegShellOpen;
|
| - items->AddCreateRegKeyWorkItem(root_key, open_cmd);
|
| - items->AddSetRegValueWorkItem(root_key, open_cmd, L"",
|
| - chrome_open, true);
|
|
|
| // file extension associations
|
| + std::wstring classes_path(ShellUtil::kRegClasses);
|
| for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
|
| std::wstring key_path = classes_path + L"\\" +
|
| ShellUtil::kFileAssociations[i];
|
| @@ -257,6 +236,9 @@ bool CreateChromeRegKeysForXP(HKEY root_key, const std::wstring& chrome_exe) {
|
| }
|
|
|
| // protocols associations
|
| + std::wstring chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
|
| + std::wstring chrome_icon(chrome_exe);
|
| + ShellUtil::GetChromeIcon(chrome_icon);
|
| for (int i = 0; ShellUtil::kProtocolAssociations[i] != NULL; i++) {
|
| std::wstring key_path = classes_path + L"\\" +
|
| ShellUtil::kProtocolAssociations[i];
|
| @@ -281,6 +263,7 @@ bool CreateChromeRegKeysForXP(HKEY root_key, const std::wstring& chrome_exe) {
|
| }
|
|
|
| // start->Internet shortcut.
|
| + std::wstring exe_name = file_util::GetFilenameFromPath(chrome_exe);
|
| std::wstring start_internet(ShellUtil::kRegStartMenuInternet);
|
| items->AddCreateRegKeyWorkItem(root_key, start_internet);
|
| items->AddSetRegValueWorkItem(root_key, start_internet, L"",
|
| @@ -295,6 +278,25 @@ bool CreateChromeRegKeysForXP(HKEY root_key, const std::wstring& chrome_exe) {
|
| return true;
|
| }
|
|
|
| +// Populate work_item_list with WorkItem entries that will add chrome.exe to
|
| +// the set of App Paths registry keys so that ShellExecute can find it. Note
|
| +// that this is done in HKLM, regardless of whether this is a single-user
|
| +// install or not. For non-admin users, this will fail.
|
| +// chrome_exe: full path to chrome.exe
|
| +// work_item_list: pointer to the WorkItemList that will be populated
|
| +void AddChromeAppPathWorkItems(const std::wstring& chrome_exe,
|
| + WorkItemList* item_list) {
|
| + FilePath chrome_path(chrome_exe);
|
| + std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey);
|
| + file_util::AppendToPath(&app_path_key, chrome_path.BaseName().value());
|
| + item_list->AddCreateRegKeyWorkItem(HKEY_LOCAL_MACHINE, app_path_key);
|
| + item_list->AddSetRegValueWorkItem(HKEY_LOCAL_MACHINE, app_path_key, L"",
|
| + chrome_exe, true);
|
| + item_list->AddSetRegValueWorkItem(HKEY_LOCAL_MACHINE, app_path_key,
|
| + ShellUtil::kAppPathsRegistryPathName,
|
| + chrome_path.DirName().value(), true);
|
| +}
|
| +
|
| // This method creates the registry entries required for Add/Remove Programs->
|
| // Set Program Access and Defaults, Start->Default Programs on Windows Vista
|
| // and Chrome ProgIds for file extension and protocol handler. root_key is
|
| @@ -316,7 +318,7 @@ bool SetAccessDefaultRegEntries(HKEY root_key,
|
| // Append the App Paths registry entries. Do this only if we are an admin,
|
| // since they are always written to HKLM.
|
| if (IsUserAnAdmin())
|
| - ShellUtil::AddChromeAppPathWorkItems(chrome_exe, items.get());
|
| + AddChromeAppPathWorkItems(chrome_exe, items.get());
|
|
|
| // Apply all the registry changes and if there is a problem, rollback.
|
| if (!items->Do()) {
|
| @@ -347,8 +349,9 @@ ShellUtil::RegisterStatus RegisterOnVista(const std::wstring& chrome_exe,
|
| BrowserDistribution* dist = BrowserDistribution::GetDistribution();
|
| RegKey key(HKEY_CURRENT_USER, dist->GetUninstallRegPath().c_str());
|
| key.ReadValue(installer_util::kUninstallStringField, &exe_path);
|
| - exe_path = exe_path.substr(0, exe_path.find_first_of(L" --"));
|
| - TrimString(exe_path, L" \"", &exe_path);
|
| + CommandLine command_line(L"");
|
| + command_line.ParseFromString(exe_path);
|
| + exe_path = command_line.program();
|
| }
|
| if (file_util::PathExists(exe_path)) {
|
| std::wstring params(L"--");
|
| @@ -376,6 +379,9 @@ const wchar_t* ShellUtil::kRegRegisteredApplications =
|
| L"Software\\RegisteredApplications";
|
| const wchar_t* ShellUtil::kRegVistaUrlPrefs =
|
| L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice";
|
| +const wchar_t* ShellUtil::kAppPathsRegistryKey =
|
| + L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths";
|
| +const wchar_t* ShellUtil::kAppPathsRegistryPathName = L"Path";
|
|
|
| const wchar_t* ShellUtil::kChromeHTMLProgId = L"ChromeHTML";
|
| const wchar_t* ShellUtil::kChromeHTMLProgIdDesc = L"Chrome HTML";
|
| @@ -471,29 +477,6 @@ bool ShellUtil::GetQuickLaunchPath(bool system_level, std::wstring* path) {
|
| return true;
|
| }
|
|
|
| -void ShellUtil::AddChromeAppPathWorkItems(
|
| - const std::wstring& chrome_exe, WorkItemList* item_list) {
|
| - WorkItem* create_work_item = WorkItem::CreateCreateRegKeyWorkItem(
|
| - HKEY_LOCAL_MACHINE, installer_util::kAppPathsRegistryKey);
|
| -
|
| - item_list->AddWorkItem(create_work_item);
|
| -
|
| - WorkItem* set_default_value_work_item =
|
| - WorkItem::CreateSetRegValueWorkItem(HKEY_LOCAL_MACHINE,
|
| - installer_util::kAppPathsRegistryKey,
|
| - installer_util::kAppPathsRegistryDefaultName,
|
| - chrome_exe, true);
|
| - item_list->AddWorkItem(set_default_value_work_item);
|
| -
|
| - FilePath chrome_path(chrome_exe);
|
| - WorkItem* set_path_value_work_item =
|
| - WorkItem::CreateSetRegValueWorkItem(HKEY_LOCAL_MACHINE,
|
| - installer_util::kAppPathsRegistryKey,
|
| - installer_util::kAppPathsRegistryPathName,
|
| - chrome_path.DirName().value(), true);
|
| - item_list->AddWorkItem(set_path_value_work_item);
|
| -}
|
| -
|
| bool ShellUtil::CreateChromeDesktopShortcut(const std::wstring& chrome_exe,
|
| int shell_change,
|
| bool create_new) {
|
| @@ -566,6 +549,8 @@ bool ShellUtil::CreateChromeQuickLaunchShortcut(const std::wstring& chrome_exe,
|
| bool ShellUtil::MakeChromeDefault(int shell_change,
|
| const std::wstring chrome_exe) {
|
| bool ret = true;
|
| + // First use the new "recommended" way on Vista to make Chrome default
|
| + // browser.
|
| if (win_util::GetWinVersion() == win_util::WINVERSION_VISTA) {
|
| LOG(INFO) << "Registering Chrome as default browser on Vista.";
|
| IApplicationAssociationRegistration* pAAR;
|
| @@ -581,18 +566,22 @@ bool ShellUtil::MakeChromeDefault(int shell_change,
|
| ret = false;
|
| LOG(ERROR) << "Could not make Chrome default browser.";
|
| }
|
| - } else {
|
| - // Change the default browser for current user.
|
| - if ((shell_change & ShellUtil::CURRENT_USER) &&
|
| - !CreateChromeRegKeysForXP(HKEY_CURRENT_USER, chrome_exe))
|
| - ret = false;
|
| -
|
| - // Chrome as default browser at system level.
|
| - if ((shell_change & ShellUtil::SYSTEM_LEVEL) &&
|
| - !CreateChromeRegKeysForXP(HKEY_LOCAL_MACHINE, chrome_exe))
|
| - ret = false;
|
| }
|
|
|
| + // Now use the old way to associate Chrome with supported protocols and file
|
| + // associations. This should not be required on Vista but since some
|
| + // applications still read Software\Classes\http key directly, we have to do
|
| + // this on Vista also.
|
| + // Change the default browser for current user.
|
| + if ((shell_change & ShellUtil::CURRENT_USER) &&
|
| + !BindChromeAssociations(HKEY_CURRENT_USER, chrome_exe))
|
| + ret = false;
|
| +
|
| + // Chrome as default browser at system level.
|
| + if ((shell_change & ShellUtil::SYSTEM_LEVEL) &&
|
| + !BindChromeAssociations(HKEY_LOCAL_MACHINE, chrome_exe))
|
| + ret = false;
|
| +
|
| // Send Windows notification event so that it can update icons for
|
| // file associations.
|
| SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
|
|