chrome_frame_test_utils.cc revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/test/chrome_frame_test_utils.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlapp.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlmisc.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iepmapi.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sddl.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock2.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_version_info.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/process.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/process_util.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths_internal.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/utils.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/clipboard.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/scoped_clipboard_writer.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome_frame_test { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kCrashServicePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const DWORD kCrashServicePipeDesiredAccess = FILE_READ_DATA | 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_WRITE_DATA | 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_WRITE_ATTRIBUTES; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const DWORD kCrashServicePipeFlagsAndAttributes = SECURITY_IDENTIFICATION | 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECURITY_SQOS_PRESENT; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kCrashServiceDetectTimeoutMs = 500; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kCrashServiceStartupTimeoutMs = 1000; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kIEImageName[] = L"iexplore.exe"; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kIEBrokerImageName[] = L"ieuser.exe"; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kChromeImageName[] = "chrome.exe"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kIEProfileName[] = L"iexplore"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeLauncher[] = L"chrome_launcher.exe"; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::TimeDelta kChromeFrameLongNavigationTimeout = 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(30); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::TimeDelta kChromeFrameVeryLongNavigationTimeout = 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(90); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::TimeDelta kChromeFrameLongNavigationTimeout = 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromSeconds(10); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::TimeDelta kChromeFrameVeryLongNavigationTimeout = 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromSeconds(30); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Callback function for EnumThreadWindows. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BOOL CALLBACK CloseWindowsThreadCallback(HWND hwnd, LPARAM param) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int& count = *reinterpret_cast<int*>(param); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsWindowVisible(hwnd)) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsWindowEnabled(hwnd)) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD results = 0; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::SendMessageTimeout(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0, SMTO_BLOCK, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10000, &results)) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Window hung: " << base::StringPrintf(L"%08X", hwnd); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count++; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Skipping disabled window: " 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << base::StringPrintf(L"%08X", hwnd); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRUE; // continue enumeration 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Attempts to close all non-child, visible windows on the given thread. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The return value is the number of visible windows a close request was 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sent to. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CloseVisibleTopLevelWindowsOnThread(DWORD thread_id) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int window_close_attempts = 0; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumThreadWindows(thread_id, CloseWindowsThreadCallback, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<LPARAM>(&window_close_attempts)); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return window_close_attempts; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enumerates the threads of a process and attempts to close visible non-child 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// windows on all threads of the process. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The return value is the number of visible windows a close request was 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sent to. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CloseVisibleWindowsOnAllThreads(HANDLE process) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD process_id = ::GetProcessId(process); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process_id == 0) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedHandle snapshot( 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0)); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!snapshot.IsValid()) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int window_close_attempts = 0; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREADENTRY32 te = { sizeof(THREADENTRY32) }; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Thread32First(snapshot, &te)) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (RTL_CONTAINS_FIELD(&te, te.dwSize, th32OwnerProcessID) && 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) te.th32OwnerProcessID == process_id) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_close_attempts += 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseVisibleTopLevelWindowsOnThread(te.th32ThreadID); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) te.dwSize = sizeof(te); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (Thread32Next(snapshot, &te)); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return window_close_attempts; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GetExecutableAppPath(const std::wstring& file) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring kAppPathsKey = 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\"; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring app_path; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey key(HKEY_LOCAL_MACHINE, (kAppPathsKey + file).c_str(), 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KEY_READ); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key.Handle()) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key.ReadValue(NULL, &app_path); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_path; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring FormatCommandForApp(const std::wstring& exe_name, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::wstring& argument) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring reg_path( 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf(L"Applications\\%ls\\shell\\open\\command", 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exe_name.c_str())); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey key(HKEY_CLASSES_ROOT, reg_path.c_str(), KEY_READ); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring command; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key.Handle()) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key.ReadValue(NULL, &command); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int found = command.find(L"%1"); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found >= 0) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command.replace(found, 2, argument); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ProcessHandle LaunchExecutable(const std::wstring& executable, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::wstring& argument) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle process = NULL; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring path = GetExecutableAppPath(executable); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (path.empty()) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = FormatCommandForApp(executable, argument); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (path.empty()) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to find executable: " << executable; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine cmdline = CommandLine::FromString(path); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::LaunchProcess(cmdline, base::LaunchOptions(), &process)) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "LaunchProcess failed: " << ::GetLastError(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine cmdline((base::FilePath(path))); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmdline.AppendArgNative(argument); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::LaunchProcess(cmdline, base::LaunchOptions(), &process)) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "LaunchProcess failed: " << ::GetLastError(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return process; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ProcessHandle LaunchChrome(const std::wstring& url, 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& user_data_dir) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(base::DIR_MODULE, &path); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = path.AppendASCII(kChromeImageName); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine cmd(path); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AppendSwitch(switches::kNoFirstRun); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!user_data_dir.empty()) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AppendSwitchPath(switches::kUserDataDir, user_data_dir); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AppendArgNative(url); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle process = NULL; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::LaunchProcess(cmd, base::LaunchOptions(), &process); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return process; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ProcessHandle LaunchIEOnVista(const std::wstring& url) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef HRESULT (WINAPI* IELaunchURLPtr)(const wchar_t* url, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PROCESS_INFORMATION* pi, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VOID* info); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IELaunchURLPtr launch; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PROCESS_INFORMATION pi = {0}; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IELAUNCHURLINFO info = {sizeof info, 0}; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE h = LoadLibrary(L"ieframe.dll"); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!h) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to load ieframe.dll: " << ::GetLastError(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launch = reinterpret_cast<IELaunchURLPtr>(GetProcAddress(h, "IELaunchURL")); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(launch); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = launch(url.c_str(), &pi, &info); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreeLibrary(h); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SUCCEEDED(hr)) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(pi.hThread); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << base::StringPrintf("IELaunchURL failed: 0x%08X", hr); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pi.hProcess; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ProcessHandle LaunchIE(const std::wstring& url) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetInstalledIEVersion() >= IE_8) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_frame_test::ClearIESessionHistory(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() >= base::win::VERSION_VISTA) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LaunchIEOnVista(url); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LaunchExecutable(kIEImageName, url); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TakeSnapshotAndLog() { 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) testing::UnitTest* unit_test = testing::UnitTest::GetInstance(); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const testing::TestInfo* test_info = unit_test->current_test_info(); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string name; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (test_info != NULL) { 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name.append(test_info->test_case_name()) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .append(1, '.') 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .append(test_info->name()); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name = "unknown test"; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath snapshot; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ui_test_utils::SaveScreenSnapshotToDesktop(&snapshot)) { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed saving screen snapshot for " << name; 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Saved screen snapshot for " << name << " to " 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << snapshot.value(); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CloseAllIEWindows() { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IShellWindows> windows; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = ::CoCreateInstance(__uuidof(ShellWindows), NULL, CLSCTX_ALL, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IID_IShellWindows, reinterpret_cast<void**>(windows.Receive())); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(SUCCEEDED(hr)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SUCCEEDED(hr)) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long count = 0; // NOLINT 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windows->get_Count(&count); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VARIANT i = { VT_I4 }; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i.lVal = 0; i.lVal < count; ++i.lVal) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IDispatch> folder; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windows->Item(i, folder.Receive()); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (folder != NULL) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IWebBrowser2> browser; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SUCCEEDED(browser.QueryFrom(folder))) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_ie = true; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND window = NULL; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the class of the browser window to make sure we only close 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IE windows. 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&window))) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t class_name[MAX_PATH]; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::GetClassName(window, class_name, arraysize(class_name))) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_ie = _wcsicmp(class_name, L"IEFrame") == 0; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_ie) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->Quit(); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++ret; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LowIntegrityToken::LowIntegrityToken() : impersonated_(false) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LowIntegrityToken::~LowIntegrityToken() { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RevertToSelf(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BOOL LowIntegrityToken::RevertToSelf() { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL ok = TRUE; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (impersonated_) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsImpersonated()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = ::RevertToSelf(); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ok) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) impersonated_ = false; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ok; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BOOL LowIntegrityToken::Impersonate() { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!impersonated_); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsImpersonated()); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE process_token_handle = NULL; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL ok = ::OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &process_token_handle); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ok) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "::OpenProcessToken failed: " << GetLastError(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ok; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedHandle process_token(process_token_handle); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create impersonation low integrity token. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE impersonation_token_handle = NULL; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = ::DuplicateTokenEx(process_token, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, NULL, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecurityImpersonation, TokenImpersonation, &impersonation_token_handle); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ok) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "::DuplicateTokenEx failed: " << GetLastError(); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ok; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(stoyan): sandbox/win/src/restricted_token_utils.cc has 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SetTokenIntegrityLevel function already. 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedHandle impersonation_token(impersonation_token_handle); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PSID integrity_sid = NULL; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TOKEN_MANDATORY_LABEL tml = {0}; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = ::ConvertStringSidToSid(SDDL_ML_LOW, &integrity_sid); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ok) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "::ConvertStringSidToSid failed: " << GetLastError(); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ok; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tml.Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tml.Label.Sid = integrity_sid; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = ::SetTokenInformation(impersonation_token, TokenIntegrityLevel, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &tml, sizeof(tml) + ::GetLengthSid(integrity_sid)); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::LocalFree(integrity_sid); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ok) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "::SetTokenInformation failed: " << GetLastError(); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ok; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Switch current thread to low integrity. 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = ::ImpersonateLoggedOnUser(impersonation_token); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ok) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) impersonated_ = true; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "::ImpersonateLoggedOnUser failed: " << GetLastError(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ok; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LowIntegrityToken::IsImpersonated() { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE token = NULL; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::OpenThreadToken(::GetCurrentThread(), 0, false, &token) && 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetLastError() != ERROR_NO_TOKEN) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (token) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(token); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!web_browser) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return E_INVALIDARG; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetInstalledIEVersion() >= IE_8) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_frame_test::ClearIESessionHistory(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllowSetForegroundWindow(ASFW_ANY); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = S_OK; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD cocreate_flags = CLSCTX_LOCAL_SERVER; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_frame_test::LowIntegrityToken token; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IntegrityLevel integrity_level = base::INTEGRITY_UNKNOWN; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vista has a bug which manifests itself when a medium integrity process 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // launches a COM server like IE which runs in protected mode due to UAC. 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This causes the IWebBrowser2 interface which is returned to be useless, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // i.e it does not receive any events, etc. Our workaround for this is 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to impersonate a low integrity token and then launch IE. Skip this if the 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tests are running at high integrity, since the workaround results in the 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // medium-integrity broker exiting, and the low-integrity IE is therefore 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unable to get chrome_launcher running at medium integrity. 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() == base::win::VERSION_VISTA && 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInstalledIEVersion() == IE_7 && 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::GetProcessIntegrityLevel(base::Process::Current().handle(), 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &integrity_level) && 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) integrity_level != base::HIGH_INTEGRITY) { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create medium integrity browser that will launch IE broker. 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IWebBrowser2> medium_integrity_browser; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = medium_integrity_browser.CreateInstance(CLSID_InternetExplorer, NULL, 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLSCTX_LOCAL_SERVER); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) medium_integrity_browser->Quit(); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Broker remains alive. 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!token.Impersonate()) { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = HRESULT_FROM_WIN32(GetLastError()); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cocreate_flags |= CLSCTX_ENABLE_CLOAKING; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = ::CoCreateInstance(CLSID_InternetExplorer, NULL, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cocreate_flags, IID_IWebBrowser2, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<void**>(web_browser)); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ~LowIntegrityToken() will switch integrity back to medium. 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GetExeVersion(const std::wstring& exe_path) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<FileVersionInfo> ie_version_info( 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileVersionInfo::CreateFileVersionInfo(base::FilePath(exe_path))); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ie_version_info->product_version(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IEVersion GetInstalledIEVersion() { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring path(chrome_frame_test::GetExecutableAppPath(kIEImageName)); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring version(GetExeVersion(path)); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t first_dot = version.find(L'.'); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int major_version = 0; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt(base::StringPiece16( 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version.data(), 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_dot == std::wstring::npos ? version.size() : first_dot), 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &major_version)) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IE_UNSUPPORTED; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (major_version) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 6: 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IE_6; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 7: 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IE_7; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IE_8; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 9: 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IE_9; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 10: 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IE_10; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IE_UNSUPPORTED; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetProfilePathForIE() { 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath profile_path; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Browsers without IDeleteBrowsingHistory in non-priv mode 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have their profiles moved into "Temporary Internet Files". 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The code below basically retrieves the version of IE and computes 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the profile directory accordingly. 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetInstalledIEVersion() <= IE_7) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_path = GetIETemporaryFilesFolder(); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_path = profile_path.Append(L"Google Chrome Frame"); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetChromeFrameProfilePath(kIEProfileName, &profile_path); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return profile_path; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetTestDataFolder() { 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_dir; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(base::DIR_SOURCE_ROOT, &test_dir); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_dir = test_dir.Append(FILE_PATH_LITERAL("chrome_frame")) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Append(FILE_PATH_LITERAL("test")) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Append(FILE_PATH_LITERAL("data")); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return test_dir; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetSeleniumTestFolder() { 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_dir; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(base::DIR_SOURCE_ROOT, &test_dir); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_dir = test_dir.Append(FILE_PATH_LITERAL("data")) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Append(FILE_PATH_LITERAL("selenium_core")); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return test_dir; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GetPathFromUrl(const std::wstring& url) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 url16 = WideToUTF16(url); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL gurl = GURL(url16); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gurl.has_query()) { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL::Replacements replacements; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.ClearQuery(); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gurl = gurl.ReplaceComponents(replacements); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UTF8ToWide(gurl.PathForRequest()); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GetPathAndQueryFromUrl(const std::wstring& url) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 url16 = WideToUTF16(url); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL gurl = GURL(url16); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UTF8ToWide(gurl.PathForRequest()); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GetClipboardText() { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 text16; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Clipboard::GetForCurrentThread()->ReadText( 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Clipboard::BUFFER_STANDARD, &text16); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UTF16ToWide(text16); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetClipboardText(const std::wstring& text) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScopedClipboardWriter clipboard_writer( 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Clipboard::GetForCurrentThread(), 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Clipboard::BUFFER_STANDARD); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_writer.WriteText(WideToUTF16(text)); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AddCFMetaTag(std::string* html_data) { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!html_data) { 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string lower = StringToLowerASCII(*html_data); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t head = lower.find("<head>"); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (head == std::string::npos) { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add missing head section. 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t html = lower.find("<html>"); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (html != std::string::npos) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) head = html + strlen("<html>"); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) html_data->insert(head, "<head></head>"); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Meta tag will not be injected " 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "because the html tag could not be found"; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (head != std::string::npos) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) html_data->insert( 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) head + strlen("<head>"), 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<meta http-equiv=\"x-ua-compatible\" content=\"chrome=1\" />"); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return head != std::string::npos; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloseIeAtEndOfScope::~CloseIeAtEndOfScope() { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int closed = CloseAllIEWindows(); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(ERROR, closed != 0) << "Closed " << closed << " windows forcefully"; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Attempt to connect to a running crash_service instance. Success occurs if we 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can actually connect to the service's pipe or we receive ERROR_PIPE_BUSY. 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Waits up to |timeout_ms| for success. |timeout_ms| may be 0, meaning only try 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once, or negative, meaning wait forever. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DetectRunningCrashService(int timeout_ms) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for the crash_service.exe to be ready for clients. 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start = base::Time::Now(); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedHandle new_pipe; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_pipe.Set(::CreateFile(kCrashServicePipeName, 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCrashServicePipeDesiredAccess, 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // dwShareMode 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // lpSecurityAttributes 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPEN_EXISTING, 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCrashServicePipeFlagsAndAttributes, 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL)); // hTemplateFile 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_pipe.IsValid()) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (::GetLastError()) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERROR_PIPE_BUSY: 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OK, it exists, let's assume that clients will eventually be able to 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // connect to it. 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERROR_FILE_NOT_FOUND: 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait a bit longer 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(WARNING) << "Unexpected error while checking crash_service.exe's " 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "pipe."; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Go ahead and wait in case it clears up. 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timeout_ms == 0) { 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (timeout_ms > 0) { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta duration = base::Time::Now() - start; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (duration.InMilliseconds() > timeout_ms) { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Sleep(10); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ProcessHandle StartCrashService() { 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DetectRunningCrashService(kCrashServiceDetectTimeoutMs)) { 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "crash_service.exe is already running. We will use the " 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "existing process and leave it running after tests complete."; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath exe_dir; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PathService::Get(base::DIR_EXE, &exe_dir)) { 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(false); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle crash_service = NULL; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Starting crash_service.exe so you know if a test crashes!"; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath crash_service_path = exe_dir.AppendASCII("crash_service.exe"); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::LaunchProcess(crash_service_path.value(), base::LaunchOptions(), 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &crash_service)) { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Couldn't start crash_service.exe"; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start = base::Time::Now(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DetectRunningCrashService(kCrashServiceStartupTimeoutMs)) { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "crash_service.exe is ready for clients in " 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (base::Time::Now() - start).InMilliseconds() << " ms."; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return crash_service; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "crash_service.exe failed to accept client connections " 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "within " << kCrashServiceStartupTimeoutMs << " ms. " 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Terminating it now."; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First check to see if it's even still running just to minimize the 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // likelihood of spurious error messages from KillProcess. 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (WAIT_OBJECT_0 != ::WaitForSingleObject(crash_service, 0)) { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::KillProcess(crash_service, 0, false); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedVirtualizeHklmAndHkcu::ScopedVirtualizeHklmAndHkcu() { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE, L"hklm_fake"); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) override_manager_.OverrideRegistry(HKEY_CURRENT_USER, L"hkcu_fake"); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedVirtualizeHklmAndHkcu::~ScopedVirtualizeHklmAndHkcu() { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedVirtualizeHklmAndHkcu::RemoveAllOverrides() { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) override_manager_.RemoveAllOverrides(); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool KillProcesses(const std::wstring& executable_name, int exit_code, 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool wait) { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = true; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::NamedProcessIterator iter(executable_name, NULL); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (const base::ProcessEntry* entry = iter.NextProcessEntry()) { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result &= base::KillProcessById(entry->pid(), exit_code, wait); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedChromeFrameRegistrar::RegistrationType GetTestBedType() { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetConfigBool(false, L"PerUserTestBed")) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ScopedChromeFrameRegistrar::PER_USER; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ScopedChromeFrameRegistrar::SYSTEM_LEVEL; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClearIESessionHistory() { 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath session_history_path; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &session_history_path)) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_history_path = session_history_path.AppendASCII("Microsoft"); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_history_path = session_history_path.AppendASCII("Internet Explorer"); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_history_path = session_history_path.AppendASCII("Recovery"); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::Delete(session_history_path, true); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetLocalIPv4Address() { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string address; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkInterfaceList nic_list; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!net::GetNetworkList(&nic_list)) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "GetNetworkList failed to look up non-loopback adapters. " 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Tests will be run over the loopback adapter, which may " 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "result in hangs."; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetNetworkList only returns 'Up' non-loopback adapters. Select the first 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv4 address found - we should be able to bind/connect over it. 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < nic_list.size(); ++i) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nic_list[i].address.size() != net::kIPv4AddressSize) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* address_string = 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inet_ntoa(*reinterpret_cast<in_addr*>(&nic_list[i].address[0])); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(address_string != NULL); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address_string != NULL) { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "HTTP tests will run over " << address_string << "."; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address.assign(address_string); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address.empty()) { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to find a non-loopback IP_V4 address. Tests will be " 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "run over the loopback adapter, which may result in hangs."; 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address.assign("127.0.0.1"); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return address; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chrome_frame_test 743