| Index: chrome_frame/test/chrome_frame_test_utils.cc
|
| diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc
|
| deleted file mode 100644
|
| index ec589a620456975491f5ef2b232754101dad4ca7..0000000000000000000000000000000000000000
|
| --- a/chrome_frame/test/chrome_frame_test_utils.cc
|
| +++ /dev/null
|
| @@ -1,746 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome_frame/test/chrome_frame_test_utils.h"
|
| -
|
| -#include <atlapp.h>
|
| -#include <atlmisc.h>
|
| -#include <iepmapi.h>
|
| -#include <sddl.h>
|
| -#include <shlobj.h>
|
| -#include <TlHelp32.h>
|
| -#include <winsock2.h>
|
| -
|
| -#include "base/command_line.h"
|
| -#include "base/file_util.h"
|
| -#include "base/file_version_info.h"
|
| -#include "base/files/file_path.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/path_service.h"
|
| -#include "base/process/kill.h"
|
| -#include "base/process/launch.h"
|
| -#include "base/process/process.h"
|
| -#include "base/process/process_iterator.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_piece.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/win/registry.h"
|
| -#include "base/win/scoped_handle.h"
|
| -#include "base/win/windows_version.h"
|
| -#include "chrome/common/chrome_paths.h"
|
| -#include "chrome/common/chrome_paths_internal.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/test/base/ui_test_utils.h"
|
| -#include "chrome_frame/utils.h"
|
| -#include "net/base/net_util.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "ui/base/clipboard/clipboard.h"
|
| -#include "ui/base/clipboard/scoped_clipboard_writer.h"
|
| -
|
| -namespace chrome_frame_test {
|
| -
|
| -const wchar_t kCrashServicePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
|
| -
|
| -const DWORD kCrashServicePipeDesiredAccess = FILE_READ_DATA |
|
| - FILE_WRITE_DATA |
|
| - FILE_WRITE_ATTRIBUTES;
|
| -
|
| -const DWORD kCrashServicePipeFlagsAndAttributes = SECURITY_IDENTIFICATION |
|
| - SECURITY_SQOS_PRESENT;
|
| -const int kCrashServiceDetectTimeoutMs = 500;
|
| -const int kCrashServiceStartupTimeoutMs = 1000;
|
| -
|
| -const wchar_t kIEImageName[] = L"iexplore.exe";
|
| -const wchar_t kIEBrokerImageName[] = L"ieuser.exe";
|
| -const char kChromeImageName[] = "chrome.exe";
|
| -const wchar_t kIEProfileName[] = L"iexplore";
|
| -const wchar_t kChromeLauncher[] = L"chrome_launcher.exe";
|
| -
|
| -#ifndef NDEBUG
|
| -const base::TimeDelta kChromeFrameLongNavigationTimeout =
|
| - base::TimeDelta::FromSeconds(30);
|
| -const base::TimeDelta kChromeFrameVeryLongNavigationTimeout =
|
| - base::TimeDelta::FromSeconds(90);
|
| -#else
|
| -const base::TimeDelta kChromeFrameLongNavigationTimeout =
|
| - base::TimeDelta::FromSeconds(10);
|
| -const base::TimeDelta kChromeFrameVeryLongNavigationTimeout =
|
| - base::TimeDelta::FromSeconds(30);
|
| -#endif
|
| -
|
| -// Callback function for EnumThreadWindows.
|
| -BOOL CALLBACK CloseWindowsThreadCallback(HWND hwnd, LPARAM param) {
|
| - int& count = *reinterpret_cast<int*>(param);
|
| - if (IsWindowVisible(hwnd)) {
|
| - if (IsWindowEnabled(hwnd)) {
|
| - DWORD results = 0;
|
| - if (!::SendMessageTimeout(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0, SMTO_BLOCK,
|
| - 10000, &results)) {
|
| - LOG(WARNING) << "Window hung: " << base::StringPrintf(L"%08X", hwnd);
|
| - }
|
| - count++;
|
| - } else {
|
| - LOG(WARNING) << "Skipping disabled window: "
|
| - << base::StringPrintf(L"%08X", hwnd);
|
| - }
|
| - }
|
| - return TRUE; // continue enumeration
|
| -}
|
| -
|
| -// Attempts to close all non-child, visible windows on the given thread.
|
| -// The return value is the number of visible windows a close request was
|
| -// sent to.
|
| -int CloseVisibleTopLevelWindowsOnThread(DWORD thread_id) {
|
| - int window_close_attempts = 0;
|
| - EnumThreadWindows(thread_id, CloseWindowsThreadCallback,
|
| - reinterpret_cast<LPARAM>(&window_close_attempts));
|
| - return window_close_attempts;
|
| -}
|
| -
|
| -// Enumerates the threads of a process and attempts to close visible non-child
|
| -// windows on all threads of the process.
|
| -// The return value is the number of visible windows a close request was
|
| -// sent to.
|
| -int CloseVisibleWindowsOnAllThreads(HANDLE process) {
|
| - DWORD process_id = ::GetProcessId(process);
|
| - if (process_id == 0) {
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| -
|
| - base::win::ScopedHandle snapshot(
|
| - CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0));
|
| - if (!snapshot.IsValid()) {
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| -
|
| - int window_close_attempts = 0;
|
| - THREADENTRY32 te = { sizeof(THREADENTRY32) };
|
| - if (Thread32First(snapshot, &te)) {
|
| - do {
|
| - if (RTL_CONTAINS_FIELD(&te, te.dwSize, th32OwnerProcessID) &&
|
| - te.th32OwnerProcessID == process_id) {
|
| - window_close_attempts +=
|
| - CloseVisibleTopLevelWindowsOnThread(te.th32ThreadID);
|
| - }
|
| - te.dwSize = sizeof(te);
|
| - } while (Thread32Next(snapshot, &te));
|
| - }
|
| -
|
| - return window_close_attempts;
|
| -}
|
| -
|
| -std::wstring GetExecutableAppPath(const std::wstring& file) {
|
| - std::wstring kAppPathsKey =
|
| - L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";
|
| -
|
| - std::wstring app_path;
|
| - base::win::RegKey key(HKEY_LOCAL_MACHINE, (kAppPathsKey + file).c_str(),
|
| - KEY_READ);
|
| - if (key.Handle()) {
|
| - key.ReadValue(NULL, &app_path);
|
| - }
|
| -
|
| - return app_path;
|
| -}
|
| -
|
| -std::wstring FormatCommandForApp(const std::wstring& exe_name,
|
| - const std::wstring& argument) {
|
| - std::wstring reg_path(
|
| - base::StringPrintf(L"Applications\\%ls\\shell\\open\\command",
|
| - exe_name.c_str()));
|
| - base::win::RegKey key(HKEY_CLASSES_ROOT, reg_path.c_str(), KEY_READ);
|
| -
|
| - std::wstring command;
|
| - if (key.Handle()) {
|
| - key.ReadValue(NULL, &command);
|
| - int found = command.find(L"%1");
|
| - if (found >= 0) {
|
| - command.replace(found, 2, argument);
|
| - }
|
| - }
|
| - return command;
|
| -}
|
| -
|
| -base::ProcessHandle LaunchExecutable(const std::wstring& executable,
|
| - const std::wstring& argument) {
|
| - base::ProcessHandle process = NULL;
|
| - std::wstring path = GetExecutableAppPath(executable);
|
| - if (path.empty()) {
|
| - path = FormatCommandForApp(executable, argument);
|
| - if (path.empty()) {
|
| - LOG(ERROR) << "Failed to find executable: " << executable;
|
| - } else {
|
| - CommandLine cmdline = CommandLine::FromString(path);
|
| - if (!base::LaunchProcess(cmdline, base::LaunchOptions(), &process)) {
|
| - LOG(ERROR) << "LaunchProcess failed: " << ::GetLastError();
|
| - }
|
| - }
|
| - } else {
|
| - CommandLine cmdline((base::FilePath(path)));
|
| - cmdline.AppendArgNative(argument);
|
| - if (!base::LaunchProcess(cmdline, base::LaunchOptions(), &process)) {
|
| - LOG(ERROR) << "LaunchProcess failed: " << ::GetLastError();
|
| - }
|
| - }
|
| - return process;
|
| -}
|
| -
|
| -base::ProcessHandle LaunchChrome(const std::wstring& url,
|
| - const base::FilePath& user_data_dir) {
|
| - base::FilePath path;
|
| - PathService::Get(base::DIR_MODULE, &path);
|
| - path = path.AppendASCII(kChromeImageName);
|
| -
|
| - CommandLine cmd(path);
|
| - cmd.AppendSwitch(switches::kNoFirstRun);
|
| - if (!user_data_dir.empty())
|
| - cmd.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
|
| - cmd.AppendArgNative(url);
|
| -
|
| - base::ProcessHandle process = NULL;
|
| - base::LaunchProcess(cmd, base::LaunchOptions(), &process);
|
| - return process;
|
| -}
|
| -
|
| -base::ProcessHandle LaunchIEOnVista(const std::wstring& url) {
|
| - typedef HRESULT (WINAPI* IELaunchURLPtr)(const wchar_t* url,
|
| - PROCESS_INFORMATION* pi,
|
| - VOID* info);
|
| -
|
| - IELaunchURLPtr launch;
|
| - PROCESS_INFORMATION pi = {0};
|
| - IELAUNCHURLINFO info = {sizeof info, 0};
|
| - HMODULE h = LoadLibrary(L"ieframe.dll");
|
| - if (!h) {
|
| - LOG(ERROR) << "Failed to load ieframe.dll: " << ::GetLastError();
|
| - return NULL;
|
| - }
|
| - launch = reinterpret_cast<IELaunchURLPtr>(GetProcAddress(h, "IELaunchURL"));
|
| - CHECK(launch);
|
| - HRESULT hr = launch(url.c_str(), &pi, &info);
|
| - FreeLibrary(h);
|
| - if (SUCCEEDED(hr)) {
|
| - CloseHandle(pi.hThread);
|
| - } else {
|
| - LOG(ERROR) << base::StringPrintf("IELaunchURL failed: 0x%08X", hr);
|
| - }
|
| - return pi.hProcess;
|
| -}
|
| -
|
| -base::ProcessHandle LaunchIE(const std::wstring& url) {
|
| - if (GetInstalledIEVersion() >= IE_8) {
|
| - chrome_frame_test::ClearIESessionHistory();
|
| - }
|
| -
|
| - if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
|
| - return LaunchIEOnVista(url);
|
| - }
|
| - return LaunchExecutable(kIEImageName, url);
|
| -}
|
| -
|
| -bool TakeSnapshotAndLog() {
|
| - testing::UnitTest* unit_test = testing::UnitTest::GetInstance();
|
| - const testing::TestInfo* test_info = unit_test->current_test_info();
|
| - std::string name;
|
| - if (test_info != NULL) {
|
| - name.append(test_info->test_case_name())
|
| - .append(1, '.')
|
| - .append(test_info->name());
|
| - } else {
|
| - name = "unknown test";
|
| - }
|
| -
|
| - base::FilePath snapshot;
|
| - if (!ui_test_utils::SaveScreenSnapshotToDesktop(&snapshot)) {
|
| - LOG(ERROR) << "Failed saving screen snapshot for " << name;
|
| - return false;
|
| - }
|
| -
|
| - LOG(ERROR) << "Saved screen snapshot for " << name << " to "
|
| - << snapshot.value();
|
| - return true;
|
| -}
|
| -
|
| -int CloseAllIEWindows() {
|
| - int ret = 0;
|
| -
|
| - base::win::ScopedComPtr<IShellWindows> windows;
|
| - HRESULT hr = ::CoCreateInstance(__uuidof(ShellWindows), NULL, CLSCTX_ALL,
|
| - IID_IShellWindows, reinterpret_cast<void**>(windows.Receive()));
|
| - DCHECK(SUCCEEDED(hr));
|
| -
|
| - if (SUCCEEDED(hr)) {
|
| - long count = 0; // NOLINT
|
| - windows->get_Count(&count);
|
| - VARIANT i = { VT_I4 };
|
| - for (i.lVal = 0; i.lVal < count; ++i.lVal) {
|
| - base::win::ScopedComPtr<IDispatch> folder;
|
| - windows->Item(i, folder.Receive());
|
| - if (folder != NULL) {
|
| - base::win::ScopedComPtr<IWebBrowser2> browser;
|
| - if (SUCCEEDED(browser.QueryFrom(folder))) {
|
| - bool is_ie = true;
|
| - HWND window = NULL;
|
| - // Check the class of the browser window to make sure we only close
|
| - // IE windows.
|
| - if (browser->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&window))) {
|
| - wchar_t class_name[MAX_PATH];
|
| - if (::GetClassName(window, class_name, arraysize(class_name))) {
|
| - is_ie = _wcsicmp(class_name, L"IEFrame") == 0;
|
| - }
|
| - }
|
| - if (is_ie) {
|
| - browser->Quit();
|
| - ++ret;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -
|
| -LowIntegrityToken::LowIntegrityToken() : impersonated_(false) {
|
| -}
|
| -
|
| -LowIntegrityToken::~LowIntegrityToken() {
|
| - RevertToSelf();
|
| -}
|
| -
|
| -BOOL LowIntegrityToken::RevertToSelf() {
|
| - BOOL ok = TRUE;
|
| - if (impersonated_) {
|
| - DCHECK(IsImpersonated());
|
| - ok = ::RevertToSelf();
|
| - if (ok)
|
| - impersonated_ = false;
|
| - }
|
| -
|
| - return ok;
|
| -}
|
| -
|
| -BOOL LowIntegrityToken::Impersonate() {
|
| - DCHECK(!impersonated_);
|
| - DCHECK(!IsImpersonated());
|
| - HANDLE process_token_handle = NULL;
|
| - BOOL ok = ::OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE,
|
| - &process_token_handle);
|
| - if (!ok) {
|
| - LOG(ERROR) << "::OpenProcessToken failed: " << GetLastError();
|
| - return ok;
|
| - }
|
| -
|
| - base::win::ScopedHandle process_token(process_token_handle);
|
| - // Create impersonation low integrity token.
|
| - HANDLE impersonation_token_handle = NULL;
|
| - ok = ::DuplicateTokenEx(process_token,
|
| - TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, NULL,
|
| - SecurityImpersonation, TokenImpersonation, &impersonation_token_handle);
|
| - if (!ok) {
|
| - LOG(ERROR) << "::DuplicateTokenEx failed: " << GetLastError();
|
| - return ok;
|
| - }
|
| -
|
| - // TODO(stoyan): sandbox/win/src/restricted_token_utils.cc has
|
| - // SetTokenIntegrityLevel function already.
|
| - base::win::ScopedHandle impersonation_token(impersonation_token_handle);
|
| - PSID integrity_sid = NULL;
|
| - TOKEN_MANDATORY_LABEL tml = {0};
|
| - ok = ::ConvertStringSidToSid(SDDL_ML_LOW, &integrity_sid);
|
| - if (!ok) {
|
| - LOG(ERROR) << "::ConvertStringSidToSid failed: " << GetLastError();
|
| - return ok;
|
| - }
|
| -
|
| - tml.Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
|
| - tml.Label.Sid = integrity_sid;
|
| - ok = ::SetTokenInformation(impersonation_token, TokenIntegrityLevel,
|
| - &tml, sizeof(tml) + ::GetLengthSid(integrity_sid));
|
| - ::LocalFree(integrity_sid);
|
| - if (!ok) {
|
| - LOG(ERROR) << "::SetTokenInformation failed: " << GetLastError();
|
| - return ok;
|
| - }
|
| -
|
| - // Switch current thread to low integrity.
|
| - ok = ::ImpersonateLoggedOnUser(impersonation_token);
|
| - if (ok) {
|
| - impersonated_ = true;
|
| - } else {
|
| - LOG(ERROR) << "::ImpersonateLoggedOnUser failed: " << GetLastError();
|
| - }
|
| -
|
| - return ok;
|
| -}
|
| -
|
| -bool LowIntegrityToken::IsImpersonated() {
|
| - HANDLE token = NULL;
|
| - if (!::OpenThreadToken(::GetCurrentThread(), 0, false, &token) &&
|
| - ::GetLastError() != ERROR_NO_TOKEN) {
|
| - return true;
|
| - }
|
| -
|
| - if (token)
|
| - ::CloseHandle(token);
|
| -
|
| - return false;
|
| -}
|
| -
|
| -HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) {
|
| - if (!web_browser)
|
| - return E_INVALIDARG;
|
| -
|
| - if (GetInstalledIEVersion() >= IE_8) {
|
| - chrome_frame_test::ClearIESessionHistory();
|
| - }
|
| -
|
| - AllowSetForegroundWindow(ASFW_ANY);
|
| -
|
| - HRESULT hr = S_OK;
|
| - DWORD cocreate_flags = CLSCTX_LOCAL_SERVER;
|
| - chrome_frame_test::LowIntegrityToken token;
|
| - base::IntegrityLevel integrity_level = base::INTEGRITY_UNKNOWN;
|
| - // Vista has a bug which manifests itself when a medium integrity process
|
| - // launches a COM server like IE which runs in protected mode due to UAC.
|
| - // This causes the IWebBrowser2 interface which is returned to be useless,
|
| - // i.e it does not receive any events, etc. Our workaround for this is
|
| - // to impersonate a low integrity token and then launch IE. Skip this if the
|
| - // tests are running at high integrity, since the workaround results in the
|
| - // medium-integrity broker exiting, and the low-integrity IE is therefore
|
| - // unable to get chrome_launcher running at medium integrity.
|
| - if (base::win::GetVersion() == base::win::VERSION_VISTA &&
|
| - GetInstalledIEVersion() == IE_7 &&
|
| - base::GetProcessIntegrityLevel(base::Process::Current().handle(),
|
| - &integrity_level) &&
|
| - integrity_level != base::HIGH_INTEGRITY) {
|
| - // Create medium integrity browser that will launch IE broker.
|
| - base::win::ScopedComPtr<IWebBrowser2> medium_integrity_browser;
|
| - hr = medium_integrity_browser.CreateInstance(CLSID_InternetExplorer, NULL,
|
| - CLSCTX_LOCAL_SERVER);
|
| - if (FAILED(hr))
|
| - return hr;
|
| - medium_integrity_browser->Quit();
|
| - // Broker remains alive.
|
| - if (!token.Impersonate()) {
|
| - hr = HRESULT_FROM_WIN32(GetLastError());
|
| - return hr;
|
| - }
|
| -
|
| - cocreate_flags |= CLSCTX_ENABLE_CLOAKING;
|
| - }
|
| -
|
| - hr = ::CoCreateInstance(CLSID_InternetExplorer, NULL,
|
| - cocreate_flags, IID_IWebBrowser2,
|
| - reinterpret_cast<void**>(web_browser));
|
| - // ~LowIntegrityToken() will switch integrity back to medium.
|
| - return hr;
|
| -}
|
| -
|
| -std::wstring GetExeVersion(const std::wstring& exe_path) {
|
| - scoped_ptr<FileVersionInfo> ie_version_info(
|
| - FileVersionInfo::CreateFileVersionInfo(base::FilePath(exe_path)));
|
| - return ie_version_info->product_version();
|
| -}
|
| -
|
| -IEVersion GetInstalledIEVersion() {
|
| - std::wstring path(chrome_frame_test::GetExecutableAppPath(kIEImageName));
|
| - std::wstring version(GetExeVersion(path));
|
| - size_t first_dot = version.find(L'.');
|
| - int major_version = 0;
|
| - if (!base::StringToInt(base::StringPiece16(
|
| - version.data(),
|
| - first_dot == std::wstring::npos ? version.size() : first_dot),
|
| - &major_version)) {
|
| - return IE_UNSUPPORTED;
|
| - }
|
| -
|
| - switch (major_version) {
|
| - case 6:
|
| - return IE_6;
|
| - case 7:
|
| - return IE_7;
|
| - case 8:
|
| - return IE_8;
|
| - case 9:
|
| - return IE_9;
|
| - case 10:
|
| - return IE_10;
|
| - default:
|
| - break;
|
| - }
|
| -
|
| - return IE_UNSUPPORTED;
|
| -}
|
| -
|
| -base::FilePath GetProfilePathForIE() {
|
| - base::FilePath profile_path;
|
| - // Browsers without IDeleteBrowsingHistory in non-priv mode
|
| - // have their profiles moved into "Temporary Internet Files".
|
| - // The code below basically retrieves the version of IE and computes
|
| - // the profile directory accordingly.
|
| - if (GetInstalledIEVersion() <= IE_7) {
|
| - profile_path = GetIETemporaryFilesFolder();
|
| - profile_path = profile_path.Append(L"Google Chrome Frame");
|
| - } else {
|
| - GetChromeFrameProfilePath(kIEProfileName, &profile_path);
|
| - }
|
| - return profile_path;
|
| -}
|
| -
|
| -base::FilePath GetTestDataFolder() {
|
| - base::FilePath test_dir;
|
| - PathService::Get(base::DIR_SOURCE_ROOT, &test_dir);
|
| - test_dir = test_dir.Append(FILE_PATH_LITERAL("chrome_frame"))
|
| - .Append(FILE_PATH_LITERAL("test"))
|
| - .Append(FILE_PATH_LITERAL("data"));
|
| - return test_dir;
|
| -}
|
| -
|
| -base::FilePath GetSeleniumTestFolder() {
|
| - base::FilePath test_dir;
|
| - PathService::Get(base::DIR_SOURCE_ROOT, &test_dir);
|
| - test_dir = test_dir.Append(FILE_PATH_LITERAL("data"))
|
| - .Append(FILE_PATH_LITERAL("selenium_core"));
|
| - return test_dir;
|
| -}
|
| -
|
| -std::wstring GetPathFromUrl(const std::wstring& url) {
|
| - base::string16 url16 = base::WideToUTF16(url);
|
| - GURL gurl = GURL(url16);
|
| - if (gurl.has_query()) {
|
| - GURL::Replacements replacements;
|
| - replacements.ClearQuery();
|
| - gurl = gurl.ReplaceComponents(replacements);
|
| - }
|
| - return base::UTF8ToWide(gurl.PathForRequest());
|
| -}
|
| -
|
| -std::wstring GetPathAndQueryFromUrl(const std::wstring& url) {
|
| - base::string16 url16 = base::WideToUTF16(url);
|
| - GURL gurl = GURL(url16);
|
| - return base::UTF8ToWide(gurl.PathForRequest());
|
| -}
|
| -
|
| -std::wstring GetClipboardText() {
|
| - base::string16 text16;
|
| - ui::Clipboard::GetForCurrentThread()->ReadText(
|
| - ui::CLIPBOARD_TYPE_COPY_PASTE, &text16);
|
| - return base::UTF16ToWide(text16);
|
| -}
|
| -
|
| -void DestroyClipboard() {
|
| - ui::Clipboard::DestroyClipboardForCurrentThread();
|
| -}
|
| -
|
| -void SetClipboardText(const std::wstring& text) {
|
| - ui::ScopedClipboardWriter clipboard_writer(
|
| - ui::Clipboard::GetForCurrentThread(),
|
| - ui::CLIPBOARD_TYPE_COPY_PASTE);
|
| - clipboard_writer.WriteText(base::WideToUTF16(text));
|
| -}
|
| -
|
| -bool AddCFMetaTag(std::string* html_data) {
|
| - if (!html_data) {
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| - std::string lower = StringToLowerASCII(*html_data);
|
| - size_t head = lower.find("<head>");
|
| - if (head == std::string::npos) {
|
| - // Add missing head section.
|
| - size_t html = lower.find("<html>");
|
| - if (html != std::string::npos) {
|
| - head = html + strlen("<html>");
|
| - html_data->insert(head, "<head></head>");
|
| - } else {
|
| - LOG(ERROR) << "Meta tag will not be injected "
|
| - << "because the html tag could not be found";
|
| - }
|
| - }
|
| - if (head != std::string::npos) {
|
| - html_data->insert(
|
| - head + strlen("<head>"),
|
| - "<meta http-equiv=\"x-ua-compatible\" content=\"chrome=1\" />");
|
| - }
|
| - return head != std::string::npos;
|
| -}
|
| -
|
| -CloseIeAtEndOfScope::~CloseIeAtEndOfScope() {
|
| - int closed = CloseAllIEWindows();
|
| - LOG_IF(ERROR, closed != 0) << "Closed " << closed << " windows forcefully";
|
| -}
|
| -
|
| -// Attempt to connect to a running crash_service instance. Success occurs if we
|
| -// can actually connect to the service's pipe or we receive ERROR_PIPE_BUSY.
|
| -// Waits up to |timeout_ms| for success. |timeout_ms| may be 0, meaning only try
|
| -// once, or negative, meaning wait forever.
|
| -bool DetectRunningCrashService(int timeout_ms) {
|
| - // Wait for the crash_service.exe to be ready for clients.
|
| - base::Time start = base::Time::Now();
|
| - base::win::ScopedHandle new_pipe;
|
| -
|
| - while (true) {
|
| - new_pipe.Set(::CreateFile(kCrashServicePipeName,
|
| - kCrashServicePipeDesiredAccess,
|
| - 0, // dwShareMode
|
| - NULL, // lpSecurityAttributes
|
| - OPEN_EXISTING,
|
| - kCrashServicePipeFlagsAndAttributes,
|
| - NULL)); // hTemplateFile
|
| -
|
| - if (new_pipe.IsValid()) {
|
| - return true;
|
| - }
|
| -
|
| - switch (::GetLastError()) {
|
| - case ERROR_PIPE_BUSY:
|
| - // OK, it exists, let's assume that clients will eventually be able to
|
| - // connect to it.
|
| - return true;
|
| - case ERROR_FILE_NOT_FOUND:
|
| - // Wait a bit longer
|
| - break;
|
| - default:
|
| - DPLOG(WARNING) << "Unexpected error while checking crash_service.exe's "
|
| - << "pipe.";
|
| - // Go ahead and wait in case it clears up.
|
| - break;
|
| - }
|
| -
|
| - if (timeout_ms == 0) {
|
| - return false;
|
| - } else if (timeout_ms > 0) {
|
| - base::TimeDelta duration = base::Time::Now() - start;
|
| - if (duration.InMilliseconds() > timeout_ms) {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - Sleep(10);
|
| - }
|
| -}
|
| -
|
| -base::ProcessHandle StartCrashService() {
|
| - if (DetectRunningCrashService(kCrashServiceDetectTimeoutMs)) {
|
| - VLOG(1) << "crash_service.exe is already running. We will use the "
|
| - "existing process and leave it running after tests complete.";
|
| - return NULL;
|
| - }
|
| -
|
| - base::FilePath exe_dir;
|
| - if (!PathService::Get(base::DIR_EXE, &exe_dir)) {
|
| - DCHECK(false);
|
| - return NULL;
|
| - }
|
| -
|
| - base::win::ScopedHandle crash_service;
|
| -
|
| - VLOG(1) << "Starting crash_service.exe so you know if a test crashes!";
|
| -
|
| - base::FilePath crash_service_path = exe_dir.AppendASCII("crash_service.exe");
|
| - if (!base::LaunchProcess(crash_service_path.value(), base::LaunchOptions(),
|
| - &crash_service)) {
|
| - LOG(ERROR) << "Couldn't start crash_service.exe";
|
| - return NULL;
|
| - }
|
| -
|
| - base::Time start = base::Time::Now();
|
| -
|
| - if (DetectRunningCrashService(kCrashServiceStartupTimeoutMs)) {
|
| - VLOG(1) << "crash_service.exe is ready for clients in "
|
| - << (base::Time::Now() - start).InMilliseconds() << " ms.";
|
| - return crash_service.Take();
|
| - } else {
|
| - LOG(ERROR) << "crash_service.exe failed to accept client connections "
|
| - "within " << kCrashServiceStartupTimeoutMs << " ms. "
|
| - "Terminating it now.";
|
| -
|
| - // First check to see if it's even still running just to minimize the
|
| - // likelihood of spurious error messages from KillProcess.
|
| - if (WAIT_OBJECT_0 != ::WaitForSingleObject(crash_service.Get(), 0)) {
|
| - base::KillProcess(crash_service.Get(), 0, false);
|
| - }
|
| - return NULL;
|
| - }
|
| -}
|
| -
|
| -ScopedVirtualizeHklmAndHkcu::ScopedVirtualizeHklmAndHkcu() {
|
| - override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE, L"hklm_fake");
|
| - override_manager_.OverrideRegistry(HKEY_CURRENT_USER, L"hkcu_fake");
|
| -}
|
| -
|
| -ScopedVirtualizeHklmAndHkcu::~ScopedVirtualizeHklmAndHkcu() {
|
| -}
|
| -
|
| -bool KillProcesses(const std::wstring& executable_name, int exit_code,
|
| - bool wait) {
|
| - bool result = true;
|
| - base::NamedProcessIterator iter(executable_name, NULL);
|
| - while (const base::ProcessEntry* entry = iter.NextProcessEntry()) {
|
| - result &= base::KillProcessById(entry->pid(), exit_code, wait);
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -ScopedChromeFrameRegistrar::RegistrationType GetTestBedType() {
|
| - if (GetConfigBool(false, L"PerUserTestBed")) {
|
| - return ScopedChromeFrameRegistrar::PER_USER;
|
| - } else {
|
| - return ScopedChromeFrameRegistrar::SYSTEM_LEVEL;
|
| - }
|
| -}
|
| -
|
| -void ClearIESessionHistory() {
|
| - base::FilePath session_history_path;
|
| - if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &session_history_path))
|
| - return;
|
| -
|
| - session_history_path = session_history_path.AppendASCII("Microsoft");
|
| - session_history_path = session_history_path.AppendASCII("Internet Explorer");
|
| - session_history_path = session_history_path.AppendASCII("Recovery");
|
| - base::DeleteFile(session_history_path, true);
|
| -}
|
| -
|
| -std::string GetLocalIPv4Address() {
|
| - std::string address;
|
| - net::NetworkInterfaceList nic_list;
|
| -
|
| - if (!net::GetNetworkList(&nic_list,
|
| - net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)) {
|
| - LOG(ERROR) << "GetNetworkList failed to look up non-loopback adapters. "
|
| - << "Tests will be run over the loopback adapter, which may "
|
| - << "result in hangs.";
|
| - } else {
|
| - // GetNetworkList only returns 'Up' non-loopback adapters. Select the first
|
| - // IPv4 address found - we should be able to bind/connect over it.
|
| - for (size_t i = 0; i < nic_list.size(); ++i) {
|
| - if (nic_list[i].address.size() != net::kIPv4AddressSize)
|
| - continue;
|
| - char* address_string =
|
| - inet_ntoa(*reinterpret_cast<in_addr*>(&nic_list[i].address[0]));
|
| - DCHECK(address_string != NULL);
|
| - if (address_string != NULL) {
|
| - LOG(INFO) << "HTTP tests will run over " << address_string << ".";
|
| - address.assign(address_string);
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (address.empty()) {
|
| - LOG(ERROR) << "Failed to find a non-loopback IP_V4 address. Tests will be "
|
| - << "run over the loopback adapter, which may result in hangs.";
|
| - address.assign("127.0.0.1");
|
| - }
|
| -
|
| - return address;
|
| -}
|
| -
|
| -} // namespace chrome_frame_test
|
|
|