Index: base/browser_utils.cc |
diff --git a/base/browser_utils.cc b/base/browser_utils.cc |
deleted file mode 100644 |
index c21c30e36e4e682e4857f7ccdd22535037062423..0000000000000000000000000000000000000000 |
--- a/base/browser_utils.cc |
+++ /dev/null |
@@ -1,727 +0,0 @@ |
-// Copyright 2006 Google Inc. |
-// |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
-// you may not use this file except in compliance with the License. |
-// You may obtain a copy of the License at |
-// |
-// http://www.apache.org/licenses/LICENSE-2.0 |
-// |
-// Unless required by applicable law or agreed to in writing, software |
-// distributed under the License is distributed on an "AS IS" BASIS, |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-// See the License for the specific language governing permissions and |
-// limitations under the License. |
-// ======================================================================== |
- |
-#include <exdisp.h> |
-#include "omaha/base/browser_utils.h" |
-#include "base/basictypes.h" |
-#include "omaha/base/commands.h" |
-#include "omaha/base/const_utils.h" |
-#include "omaha/base/debug.h" |
-#include "omaha/base/error.h" |
-#include "omaha/base/file.h" |
-#include "omaha/base/logging.h" |
-#include "omaha/base/path.h" |
-#include "omaha/base/process.h" |
-#include "omaha/base/proc_utils.h" |
-#include "omaha/base/reg_key.h" |
-#include "omaha/base/scope_guard.h" |
-#include "omaha/base/scoped_ptr_address.h" |
-#include "omaha/base/shell.h" |
-#include "omaha/base/string.h" |
-#include "omaha/base/system.h" |
-#include "omaha/base/utils.h" |
-#include "omaha/base/thread.h" |
-#include "omaha/base/vistautil.h" |
-#include "omaha/base/vista_utils.h" |
- |
-namespace omaha { |
- |
-namespace { |
- |
-// Attempts to force instances of IE to quit gracefully using shell APIs. |
-HRESULT CloseIeUsingShell(const CString& sid) { |
- CComPtr<IShellWindows> shell_windows; |
- HRESULT hr = shell_windows.CoCreateInstance(CLSID_ShellWindows); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- long num_windows = 0; // NOLINT |
- hr = shell_windows->get_Count(&num_windows); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- for (int32 i = 0; i < num_windows; ++i) { |
- CComVariant index(i); |
- |
- CComPtr<IDispatch> disp; |
- hr = shell_windows->Item(index, &disp); |
- if (FAILED(hr)) { |
- UTIL_LOG(L3, (_T("[CloseIeUsingShell][Item failed][0x%08x]"), hr)); |
- return hr; |
- } |
- if (!disp) { |
- // Skip - this shell window was registered with a NULL IDispatch |
- continue; |
- } |
- |
- CComPtr<IWebBrowser2> browser; |
- hr = disp.QueryInterface(&browser); |
- if (FAILED(hr)) { |
- // Skip - this shell window doesn't implement IWebBrowser2 |
- continue; |
- } |
- |
- // Okay, this window implements IWebBrowser2, so it's potentially an |
- // IE session. Identify the owning process. |
- long hwnd = 0; // NOLINT |
- hr = browser->get_HWND(&hwnd); |
- if (FAILED(hr)) { |
- UTIL_LOG(L3, (_T("[CloseIeUsingShell][get_HWND failed][0x%08x]"), hr)); |
- continue; |
- } |
- |
- DWORD process_id = 0; |
- ::GetWindowThreadProcessId(reinterpret_cast<HWND>(hwnd), &process_id); |
- if (0 == process_id) { |
- UTIL_LOG(L3, (_T("[CloseIeUsingShell][invalid process id]"))); |
- continue; |
- } |
- |
- // If a SID was passed in, check that the SID owns this process. (If we |
- // can't query the process owner, play it safe and skip it.) |
- if (!sid.IsEmpty()) { |
- CString process_sid; |
- hr = Process::GetProcessOwner(process_id, &process_sid); |
- if (FAILED(hr)) { |
- UTIL_LOG(L3, (_T("[CloseIeUsingShell][GetProcessOwner][0x%08x]"), hr)); |
- continue; |
- } |
- |
- if (0 != sid.CompareNoCase(process_sid)) { |
- // Skip - process is not owned by us |
- continue; |
- } |
- } |
- |
- // Verify that the process executable is iexplore.exe, as this list may |
- // also contain embedded shdocvw sessions in explorer.exe. (If we can't |
- // fetch the process executable, play it safe and skip it.) |
- CString process_module; |
- hr = Process::GetExecutablePath(process_id, &process_module); |
- if (FAILED(hr)) { |
- UTIL_LOG(L3, (_T("[CloseIeUsingShell][GetExecutablePath][0x%08x]"), hr)); |
- continue; |
- } |
- |
- if (0 != GetFileFromPath(process_module).CompareNoCase(kIeExeName)) { |
- // Skip - it's not an iexplore.exe |
- continue; |
- } |
- |
- // Okay, this is an IWebBrowser2 hosted by an iexplore.exe that is running |
- // under the requested SID. Ask it to quit. (Note: It may not necessarily |
- // honor this request. We can follow it up with WM_CLOSE messages or a |
- // process termination if absolutely necessary.) |
- UTIL_LOG(L3, (_T("[CloseIeUsingShell][Closing IE session][pid %d]"), |
- process_id)); |
- |
- hr = browser->Quit(); |
- if (FAILED(hr)) { |
- UTIL_LOG(L3, (_T("[CloseIeUsingShell][Quit failed][0x%08x]"), hr)); |
- continue; |
- } |
- } |
- |
- return S_OK; |
-} |
- |
-class CloseIeUsingShellRunnable : public Runnable { |
- public: |
- explicit CloseIeUsingShellRunnable(const CString& sid) : sid_(sid) {} |
- protected: |
- virtual ~CloseIeUsingShellRunnable() {} |
- |
- virtual void Run() { |
- UTIL_LOG(L3, (_T("[CloseIeUsingShellRunnable][%s]"), sid_)); |
- |
- scoped_co_init co_init(COINIT_MULTITHREADED); |
- VERIFY1(SUCCEEDED(co_init.hresult())); |
- |
- CloseIeUsingShell(sid_); |
- delete this; |
- } |
- |
- private: |
- CString sid_; |
-}; |
- |
-} // end namespace |
- |
-HRESULT GetLegacyDefaultBrowserInfo(CString* name, CString* path) { |
- UTIL_LOG(L3, (_T("[GetLegacyDefaultBrowserInfo]"))); |
- ASSERT1(name); |
- ASSERT1(path); |
- name->Empty(); |
- path->Empty(); |
- |
- CString browser_command_line; |
- HRESULT hr = RegKey::GetValue(kRegKeyLegacyDefaultBrowserCommand, |
- NULL, |
- &browser_command_line); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[Read failed][%s]"), kRegKeyLegacyDefaultBrowserCommand)); |
- return hr; |
- } |
- |
- UTIL_LOG(L5, (_T("[browser_command_line][%s]"), browser_command_line)); |
- browser_command_line.Trim(_T(" ")); |
- if (browser_command_line.IsEmpty()) { |
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); |
- } |
- |
- CString browser_path; |
- if (File::Exists(browser_command_line)) { |
- if (File::IsDirectory(browser_command_line)) { |
- UTIL_LOG(LE, (_T("[Unexpected. Command line should not be directory]"))); |
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); |
- } |
- |
- browser_path = browser_command_line; |
- } else { |
- hr = GetExePathFromCommandLine(browser_command_line, &browser_path); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- if (!File::Exists(browser_path) || |
- File::IsDirectory(browser_path)) { |
- UTIL_LOG(LE, (_T("[browser_path invalid][%s]"), browser_path)); |
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); |
- } |
- } |
- |
- CString browser_name = ::PathFindFileName(browser_path); |
- if (browser_name.IsEmpty() || |
- !String_EndsWith(browser_name, _T(".exe"), true)) { |
- UTIL_LOG(LE, (_T("[browser name invalid][%s]"), browser_name)); |
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); |
- } |
- |
- *path = browser_path; |
- *name = browser_name; |
- return S_OK; |
-} |
- |
-HRESULT GetDefaultBrowserName(CString* name) { |
- ASSERT1(name); |
- name->Empty(); |
- |
- // Get the default browser name from current user registry. |
- HKEY user_root_key = NULL; |
- VERIFY1(::RegOpenCurrentUser(KEY_READ, &user_root_key) == ERROR_SUCCESS); |
- RegKey user_default_browser; |
- HRESULT hr = user_default_browser.Open( |
- user_root_key ? user_root_key : HKEY_CURRENT_USER, |
- kRegKeyDefaultBrowser, |
- KEY_READ); |
- if (SUCCEEDED(hr)) { |
- hr = user_default_browser.GetValue(NULL, name); |
- } |
- if (user_root_key) { |
- LONG error(::RegCloseKey(user_root_key)); |
- |
- // See bug http://b/1231862 for details when RegCloseKey can |
- // return ERROR_INVALID_HANDLE. |
- ASSERT1(error == ERROR_SUCCESS || |
- error == ERROR_INVALID_HANDLE); |
- } |
- |
- if (SUCCEEDED(hr) && !name->IsEmpty()) { |
- UTIL_LOG(L3, (_T("[Default browser for the user is %s]"), *name)); |
- return S_OK; |
- } |
- |
- // Try to get from local machine registry. |
- hr = RegKey::GetValue(kRegKeyMachineDefaultBrowser, NULL, name); |
- if (SUCCEEDED(hr) && !name->IsEmpty()) { |
- UTIL_LOG(L3, (_T("[Default browser for the machine is %s]"), *name)); |
- return S_OK; |
- } |
- |
- // Try to get from legacy default browser location. |
- CString browser_path; |
- hr = GetLegacyDefaultBrowserInfo(name, &browser_path); |
- if (SUCCEEDED(hr) && !name->IsEmpty()) { |
- UTIL_LOG(L3, (_T("[Legacy default browser is %s]"), *name)); |
- return S_OK; |
- } |
- |
- // If still failed, we don't want to break in this case so we default to |
- // IEXPLORE.EXE. A scenario where this can happen is when the user installs |
- // a browser that configures itself to be default. Then the user uninstalls |
- // or somehow removes that browser and the registry is not updated correctly. |
- *name = kIeExeName; |
- return S_OK; |
-} |
- |
-HRESULT GetDefaultBrowserType(BrowserType* type) { |
- ASSERT1(type); |
- |
- CString name; |
- HRESULT hr = GetDefaultBrowserName(&name); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- if (name.CompareNoCase(kIeExeName) == 0) { |
- *type = BROWSER_IE; |
- } else if (name.CompareNoCase(kFirefoxExeName) == 0) { |
- *type = BROWSER_FIREFOX; |
- } else if (name.CompareNoCase(kChromeExeName) == 0 || |
- name.CompareNoCase(kChromeBrowserName) == 0) { |
- *type = BROWSER_CHROME; |
- } else { |
- *type = BROWSER_UNKNOWN; |
- } |
- |
- return S_OK; |
-} |
- |
-// Returns a path that is always unenclosed. The method could return a short or |
-// long form path. |
-HRESULT GetDefaultBrowserPath(CString* path) { |
- ASSERT1(path); |
- path->Empty(); |
- ON_SCOPE_EXIT(UnenclosePath, path); |
- |
- // Get the default browser name. |
- CString name; |
- if (FAILED(GetDefaultBrowserName(&name))) { |
- // Try getting IE's path through COM registration and app path entries. |
- return GetBrowserImagePath(BROWSER_IE, path); |
- } |
- |
- CString shell_open_path(_T("\\")); |
- shell_open_path += name; |
- shell_open_path += kRegKeyShellOpenCommand; |
- |
- // Read the path corresponding to it from current user registry. |
- CString browser_key(kRegKeyUserDefaultBrowser); |
- browser_key += shell_open_path; |
- HRESULT hr = RegKey::GetValue(browser_key, NULL, path); |
- |
- CString cmd_line(*path); |
- CString args; |
- if (SUCCEEDED(hr) && |
- !path->IsEmpty() && |
- SUCCEEDED(CommandParsingSimple::SplitExeAndArgsGuess(cmd_line, |
- path, |
- &args))) { |
- return S_OK; |
- } |
- |
- // If failed, try to get from local machine registry. |
- browser_key = kRegKeyMachineDefaultBrowser; |
- browser_key += shell_open_path; |
- hr = RegKey::GetValue(browser_key, NULL, path); |
- |
- cmd_line = *path; |
- args.Empty(); |
- if (SUCCEEDED(hr) && |
- !path->IsEmpty() && |
- SUCCEEDED(CommandParsingSimple::SplitExeAndArgsGuess(cmd_line, |
- path, |
- &args))) { |
- return S_OK; |
- } |
- |
- // Try to get from legacy default browser location. |
- hr = GetLegacyDefaultBrowserInfo(&name, path); |
- if (SUCCEEDED(hr) && !path->IsEmpty()) { |
- return S_OK; |
- } |
- |
- // If failed and the default browser is not IE, try IE once again. |
- if (name.CompareNoCase(kIeExeName) != 0) { |
- browser_key = kRegKeyMachineDefaultBrowser |
- _T("\\") kIeExeName kRegKeyShellOpenCommand; |
- hr = RegKey::GetValue(browser_key, NULL, path); |
- |
- cmd_line = *path; |
- args.Empty(); |
- if (SUCCEEDED(hr) && |
- !path->IsEmpty() && |
- SUCCEEDED(CommandParsingSimple::SplitExeAndArgsGuess(cmd_line, |
- path, |
- &args))) { |
- return S_OK; |
- } |
- } |
- |
- // Try getting the default browser's path through COM registration and app |
- // path entries. |
- BrowserType default_type = BROWSER_UNKNOWN; |
- hr = GetDefaultBrowserType(&default_type); |
- if (FAILED(hr) || |
- default_type == BROWSER_UNKNOWN || |
- default_type == BROWSER_DEFAULT) { |
- default_type = BROWSER_IE; |
- } |
- |
- return GetBrowserImagePath(default_type, path); |
-} |
- |
-HRESULT GetFirefoxDefaultProfile(CString* name, CString* path) { |
- ASSERT1(name); |
- ASSERT1(path); |
- |
- const TCHAR kFirefoxAppDataPath[] = _T("\\Mozilla\\Firefox\\"); |
- const TCHAR kFirefoxProfileIni[] = _T("profiles.ini"); |
- const TCHAR kFirefoxDefaultProfileSecName[] = _T("Profile0"); |
- const TCHAR kFirefoxProfileIniNameKey[] = _T("Name"); |
- const TCHAR kFirefoxProfileIniIsRelativeKey[] = _T("IsRelative"); |
- const TCHAR kFirefoxProfileIniPathKey[] = _T("Path"); |
- const TCHAR kFirefoxProfileIniDefaultKey[] = _T("Default"); |
- |
- name->Empty(); |
- path->Empty(); |
- |
- // Get appdata path for storing Firefox settings. |
- CString appdata_path; |
- RET_IF_FAILED(Shell::GetSpecialFolder(CSIDL_APPDATA, false, &appdata_path)); |
- appdata_path += kFirefoxAppDataPath; |
- |
- // Get profile.ini. |
- CString profile_ini = appdata_path + kFirefoxProfileIni; |
- UTIL_LOG(L3, (_T("[FireFox profile.ini][%s]"), profile_ini)); |
- |
- if (!File::Exists(profile_ini)) { |
- UTIL_LOG(LE, (_T("[File does not exist][%s]"), profile_ini)); |
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); |
- } |
- |
- // Read all section names in profile.ini. |
- // The buffer is filled with one or more null-terminated strings; the last |
- // string is followed by a second null character. |
- const int kMaxProfileSecNamesLength = 2048; |
- CString profile_sec_names; |
- DWORD char_returned = ::GetPrivateProfileSectionNames( |
- profile_sec_names.GetBufferSetLength(kMaxProfileSecNamesLength), |
- kMaxProfileSecNamesLength, |
- profile_ini); |
- if (char_returned == kMaxProfileSecNamesLength - 2) { |
- UTIL_LOG(LW, (_T("[FireFox profile.ini contains too many sections]"))); |
- } |
- profile_sec_names.ReleaseBuffer(char_returned); |
- |
- // Iterate through all the sections to find the default profile. |
- const TCHAR* default_profile_sec = NULL; |
- const TCHAR* ptr = profile_sec_names.GetString(); |
- const TCHAR* end = ptr + char_returned; |
- while (ptr < end && *ptr) { |
- if (::GetPrivateProfileInt(ptr, |
- kFirefoxProfileIniDefaultKey, |
- 0, |
- profile_ini)) { |
- default_profile_sec = ptr; |
- break; |
- } |
- |
- for (; ptr < end && *ptr; ++ptr) { |
- } |
- ++ptr; |
- } |
- |
- if (!default_profile_sec) { |
- default_profile_sec = kFirefoxDefaultProfileSecName; |
- } |
- |
- DWORD name_len = ::GetPrivateProfileString(default_profile_sec, |
- kFirefoxProfileIniNameKey, _T(""), |
- name->GetBufferSetLength(256), |
- 256, |
- profile_ini); |
- name->ReleaseBuffer(name_len); |
- |
- DWORD path_len = ::GetPrivateProfileString(default_profile_sec, |
- kFirefoxProfileIniPathKey, |
- _T(""), |
- path->GetBufferSetLength(1024), |
- 1024, |
- profile_ini); |
- path->ReleaseBuffer(path_len); |
- path->Replace(_T('/'), _T('\\')); |
- |
- bool is_relative = ::GetPrivateProfileInt(default_profile_sec, |
- kFirefoxProfileIniIsRelativeKey, |
- 0, |
- profile_ini) != 0; |
- |
- if (is_relative && !path->IsEmpty()) { |
- path->Insert(0, appdata_path); |
- } |
- |
- return S_OK; |
-} |
- |
-HRESULT BrowserTypeToProcessName(BrowserType type, CString* exe_name) { |
- ASSERT1(exe_name); |
- ASSERT1(type < BROWSER_MAX); |
- |
- switch (type) { |
- case BROWSER_IE: |
- *exe_name = kIeExeName; |
- break; |
- case BROWSER_FIREFOX: |
- *exe_name = kFirefoxExeName; |
- break; |
- case BROWSER_CHROME: |
- *exe_name = kChromeExeName; |
- break; |
- case BROWSER_DEFAULT: |
- return GetDefaultBrowserName(exe_name); |
- case BROWSER_UNKNOWN: |
- // Fall through. |
- case BROWSER_MAX: |
- // Fall through. |
- default: |
- return E_FAIL; |
- } |
- |
- return S_OK; |
-} |
- |
-// Returns a path that is always unenclosed. The method could return a short or |
-// long form path. |
-HRESULT GetBrowserImagePath(BrowserType type, CString* path) { |
- ASSERT1(path); |
- ASSERT1(type < BROWSER_MAX); |
- |
- HRESULT hr = E_FAIL; |
- switch (type) { |
- case BROWSER_IE: { |
- hr = RegKey::GetValue(kRegKeyIeClass, kRegValueIeClass, path); |
- break; |
- } |
- case BROWSER_FIREFOX: { |
- hr = RegKey::GetValue(kRegKeyFirefox, kRegValueFirefox, path); |
- if (SUCCEEDED(hr) && !path->IsEmpty()) { |
- // The Firefox registry key contains a -url %1 value. Remove this |
- // because we only want to return the path. |
- ReplaceCString(*path, _T("-url \"%1\""), _T("")); |
- } |
- break; |
- } |
- case BROWSER_CHROME: { |
- hr = RegKey::GetValue(kRegKeyChrome, kRegValueChrome, path); |
- if (SUCCEEDED(hr) && !path->IsEmpty()) { |
- // The Chrome registry key contains a -- "%1" value. Remove this because |
- // we only want to return the path. |
- ReplaceCString(*path, _T("-- \"%1\""), _T("")); |
- } |
- break; |
- } |
- case BROWSER_DEFAULT: { |
- hr = GetDefaultBrowserPath(path); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[GetDefaultBrowserPath failed.][0x%08x]"), hr)); |
- } |
- path->Trim(); |
- UnenclosePath(path); |
- return hr; |
- } |
- case BROWSER_UNKNOWN: |
- // Fall through. |
- case BROWSER_MAX: |
- // Fall through. |
- default: |
- return E_FAIL; |
- } |
- |
- CString cmd_line(*path); |
- CString args; |
- if (SUCCEEDED(hr) && |
- !path->IsEmpty() && |
- SUCCEEDED(CommandParsingSimple::SplitExeAndArgsGuess(cmd_line, |
- path, |
- &args))) { |
- return S_OK; |
- } |
- |
- // If the above did not work, then we try to read the value from |
- // "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths". |
- CString browser_exe_name; |
- hr = BrowserTypeToProcessName(type, &browser_exe_name); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[BrowserTypeToProcessName failed][0x%08x]"), hr)); |
- return hr; |
- } |
- |
- CString exe_path; |
- hr = Shell::GetApplicationExecutablePath(browser_exe_name, &exe_path); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[GetApplicationExecutablePath failed][0x%08x]"), hr)); |
- return hr; |
- } |
- |
- *path = ConcatenatePath(exe_path, browser_exe_name); |
- ASSERT1(!path->IsEmpty()); |
- |
- path->Trim(); |
- UnenclosePath(path); |
- return S_OK; |
-} |
- |
-HRESULT TerminateBrowserProcess(BrowserType type, |
- const CString& sid, |
- int timeout_msec, |
- bool* found) { |
- UTIL_LOG(L3, (_T("[TerminateBrowserProcess][%d]"), type)); |
- ASSERT1(found); |
- ASSERT1(type < BROWSER_MAX); |
- |
- *found = false; |
- if (type == BROWSER_UNKNOWN || type >= BROWSER_MAX) { |
- return E_FAIL; |
- } |
- |
- if (type == BROWSER_IE) { |
- Thread close_ie_thread; |
- |
- close_ie_thread.Start(new CloseIeUsingShellRunnable(sid)); |
- close_ie_thread.WaitTillExit(timeout_msec); |
- |
- // Fall through after attempting to close IE via automation - if it |
- // succeeded, we'll find no processes, but if it failed we still want |
- // to attempt a conventional WM_CLOSE quit. (This also applies to |
- // third-party hosts of IE that may not respect IWebBrowser2::Quit.) |
- } |
- |
- CString browser_exe_name; |
- HRESULT hr = BrowserTypeToProcessName(type, &browser_exe_name); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[BrowserTypeToProcessName failed][0x%08x]"), hr)); |
- return hr; |
- } |
- |
- DWORD current_session = System::GetCurrentSessionId(); |
- uint32 method_mask = ProcessTerminator::KILL_METHOD_1_WINDOW_MESSAGE; |
- ProcessTerminator process(browser_exe_name, sid, current_session); |
- hr = process.KillTheProcess(timeout_msec, found, method_mask, true); |
- if (FAILED(hr)) { |
- UTIL_LOG(LEVEL_WARNING, (_T("[KillTheProcess failed][0x%08x]"), hr)); |
- return hr; |
- } |
- |
- return S_OK; |
-} |
- |
-HRESULT WaitForBrowserToDie(BrowserType type, |
- const CString& sid, |
- int timeout_msec) { |
- UTIL_LOG(L3, (_T("[WaitForBrowserToDie][%d]"), type)); |
- ASSERT1(type < BROWSER_MAX); |
- |
- if (type == BROWSER_UNKNOWN || type >= BROWSER_MAX) { |
- return E_FAIL; |
- } |
- |
- CString browser_exe_name; |
- HRESULT hr = BrowserTypeToProcessName(type, &browser_exe_name); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[BrowserTypeToProcessName failed][0x%08x]"), hr)); |
- return hr; |
- } |
- |
- DWORD current_session = System::GetCurrentSessionId(); |
- ProcessTerminator process(browser_exe_name, sid, current_session); |
- hr = process.WaitForAllToDie(timeout_msec); |
- if (FAILED(hr)) { |
- UTIL_LOG(LEVEL_WARNING, (_T("[WaitForAllToDie failed][0x%08x]"), hr)); |
- return hr; |
- } |
- |
- return S_OK; |
-} |
- |
-HRESULT RunBrowser(BrowserType type, const CString& url) { |
- UTIL_LOG(L3, (_T("[RunBrowser][%d][%s]"), type, url)); |
- ASSERT1(type < BROWSER_MAX); |
- |
- if (type == BROWSER_UNKNOWN || type >= BROWSER_MAX) { |
- return E_FAIL; |
- } |
- |
- CString path; |
- HRESULT hr = GetBrowserImagePath(type, &path); |
- if (FAILED(hr)) { |
- UTIL_LOG(LW, (_T("[GetBrowserImagePath failed][0x%08x]"), hr)); |
- // ShellExecute the url directly as a last resort. |
- return Shell::Execute(url); |
- } |
- EnclosePath(&path); |
- |
- UTIL_LOG(L3, (_T("[Execute browser][%s][%s]"), path, url)); |
- |
- // http://b/1219313: For Vista, in some cases, using ShellExecuteEx does not |
- // re-launch the process. So, using CreateProcess instead. |
- // http://b/1223658: For Vista, especially in the impersonated case, need to |
- // create a fresh environment block. Otherwise, the environment is tainted. |
- hr = vista::RunAsCurrentUser(path + _T(' ') + url); |
- |
- if (FAILED(hr)) { |
- UTIL_LOG(LW, (_T("[RunAsCurrentUser failed][0x%x]"), hr)); |
- // ShellExecute the url directly as a last resort. |
- return Shell::Execute(url); |
- } |
- |
- return S_OK; |
-} |
- |
-// Gets the font size of IE. This is the value that corresponds to what IE |
-// displays in "Page/Text Size" menu option. There are 5 values and the default |
-// is "Medium", for which the numeric value is 2. The "IEFontSize" is only |
-// present after the user has modified the default text size in IE, therefore |
-// the absence of the value indicates "Medium" text size. |
-HRESULT GetIeFontSize(uint32* font_size) { |
- ASSERT1(font_size); |
- |
- const TCHAR ie_scripts_key[] = |
- _T("HKCU\\Software\\Microsoft\\Internet Explorer\\International\\Scripts\\3"); // NOLINT |
- const TCHAR ie_font_size[] = _T("IEFontSize"); |
- const uint32 kDefaultFontSize = 2; |
- |
- // We expect the scripts key to be there in all cases. The "IEFontSize" value |
- // is optional but we want to fail if the key is not there. |
- if (!RegKey::HasKey(ie_scripts_key)) { |
- return E_UNEXPECTED; |
- } |
- |
- scoped_array<byte> buf; // The font size is a binary registry value. |
- DWORD buf_size(0); |
- if (FAILED(RegKey::GetValue(ie_scripts_key, ie_font_size, |
- address(buf), &buf_size))) { |
- *font_size = kDefaultFontSize; |
- return S_OK; |
- } |
- |
- ASSERT1(buf_size == sizeof(uint32)); // NOLINT |
- if (buf_size != sizeof(uint32)) { // NOLINT |
- return E_UNEXPECTED; |
- } |
- |
- uint32 val = *reinterpret_cast<uint32*>(buf.get()); |
- ASSERT1(val <= 4); |
- if (val > 4) { |
- return E_UNEXPECTED; |
- } |
- |
- *font_size = val; |
- return S_OK; |
-} |
- |
-} // namespace omaha |