Bluetooth: clean up Bluetooth classes
[chromium-blink-merge.git] / chrome_frame / test / chrome_frame_test_utils.cc
blob7e14bca49bb520fb4490db29ba68cc877e907c6c
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome_frame/test/chrome_frame_test_utils.h"
7 #include <atlapp.h>
8 #include <atlmisc.h>
9 #include <iepmapi.h>
10 #include <sddl.h>
11 #include <shlobj.h>
12 #include <winsock2.h>
14 #include "base/command_line.h"
15 #include "base/file_util.h"
16 #include "base/file_version_info.h"
17 #include "base/files/file_path.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/path_service.h"
20 #include "base/process.h"
21 #include "base/process_util.h"
22 #include "base/string_number_conversions.h"
23 #include "base/string_piece.h"
24 #include "base/string_util.h"
25 #include "base/stringprintf.h"
26 #include "base/utf_string_conversions.h"
27 #include "base/win/registry.h"
28 #include "base/win/scoped_handle.h"
29 #include "base/win/windows_version.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_paths_internal.h"
32 #include "chrome/common/chrome_switches.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "chrome_frame/utils.h"
35 #include "net/base/net_util.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "ui/base/clipboard/clipboard.h"
38 #include "ui/base/clipboard/scoped_clipboard_writer.h"
40 namespace chrome_frame_test {
42 const wchar_t kCrashServicePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
44 const DWORD kCrashServicePipeDesiredAccess = FILE_READ_DATA |
45 FILE_WRITE_DATA |
46 FILE_WRITE_ATTRIBUTES;
48 const DWORD kCrashServicePipeFlagsAndAttributes = SECURITY_IDENTIFICATION |
49 SECURITY_SQOS_PRESENT;
50 const int kCrashServiceDetectTimeoutMs = 500;
51 const int kCrashServiceStartupTimeoutMs = 1000;
53 const wchar_t kIEImageName[] = L"iexplore.exe";
54 const wchar_t kIEBrokerImageName[] = L"ieuser.exe";
55 const char kChromeImageName[] = "chrome.exe";
56 const wchar_t kIEProfileName[] = L"iexplore";
57 const wchar_t kChromeLauncher[] = L"chrome_launcher.exe";
59 #ifndef NDEBUG
60 const base::TimeDelta kChromeFrameLongNavigationTimeout =
61 base::TimeDelta::FromSeconds(30);
62 const base::TimeDelta kChromeFrameVeryLongNavigationTimeout =
63 base::TimeDelta::FromSeconds(90);
64 #else
65 const base::TimeDelta kChromeFrameLongNavigationTimeout =
66 base::TimeDelta::FromSeconds(10);
67 const base::TimeDelta kChromeFrameVeryLongNavigationTimeout =
68 base::TimeDelta::FromSeconds(30);
69 #endif
71 // Callback function for EnumThreadWindows.
72 BOOL CALLBACK CloseWindowsThreadCallback(HWND hwnd, LPARAM param) {
73 int& count = *reinterpret_cast<int*>(param);
74 if (IsWindowVisible(hwnd)) {
75 if (IsWindowEnabled(hwnd)) {
76 DWORD results = 0;
77 if (!::SendMessageTimeout(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0, SMTO_BLOCK,
78 10000, &results)) {
79 LOG(WARNING) << "Window hung: " << base::StringPrintf(L"%08X", hwnd);
81 count++;
82 } else {
83 LOG(WARNING) << "Skipping disabled window: "
84 << base::StringPrintf(L"%08X", hwnd);
87 return TRUE; // continue enumeration
90 // Attempts to close all non-child, visible windows on the given thread.
91 // The return value is the number of visible windows a close request was
92 // sent to.
93 int CloseVisibleTopLevelWindowsOnThread(DWORD thread_id) {
94 int window_close_attempts = 0;
95 EnumThreadWindows(thread_id, CloseWindowsThreadCallback,
96 reinterpret_cast<LPARAM>(&window_close_attempts));
97 return window_close_attempts;
100 // Enumerates the threads of a process and attempts to close visible non-child
101 // windows on all threads of the process.
102 // The return value is the number of visible windows a close request was
103 // sent to.
104 int CloseVisibleWindowsOnAllThreads(HANDLE process) {
105 DWORD process_id = ::GetProcessId(process);
106 if (process_id == 0) {
107 NOTREACHED();
108 return 0;
111 base::win::ScopedHandle snapshot(
112 CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0));
113 if (!snapshot.IsValid()) {
114 NOTREACHED();
115 return 0;
118 int window_close_attempts = 0;
119 THREADENTRY32 te = { sizeof(THREADENTRY32) };
120 if (Thread32First(snapshot, &te)) {
121 do {
122 if (RTL_CONTAINS_FIELD(&te, te.dwSize, th32OwnerProcessID) &&
123 te.th32OwnerProcessID == process_id) {
124 window_close_attempts +=
125 CloseVisibleTopLevelWindowsOnThread(te.th32ThreadID);
127 te.dwSize = sizeof(te);
128 } while (Thread32Next(snapshot, &te));
131 return window_close_attempts;
134 std::wstring GetExecutableAppPath(const std::wstring& file) {
135 std::wstring kAppPathsKey =
136 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";
138 std::wstring app_path;
139 base::win::RegKey key(HKEY_LOCAL_MACHINE, (kAppPathsKey + file).c_str(),
140 KEY_READ);
141 if (key.Handle()) {
142 key.ReadValue(NULL, &app_path);
145 return app_path;
148 std::wstring FormatCommandForApp(const std::wstring& exe_name,
149 const std::wstring& argument) {
150 std::wstring reg_path(
151 base::StringPrintf(L"Applications\\%ls\\shell\\open\\command",
152 exe_name.c_str()));
153 base::win::RegKey key(HKEY_CLASSES_ROOT, reg_path.c_str(), KEY_READ);
155 std::wstring command;
156 if (key.Handle()) {
157 key.ReadValue(NULL, &command);
158 int found = command.find(L"%1");
159 if (found >= 0) {
160 command.replace(found, 2, argument);
163 return command;
166 base::ProcessHandle LaunchExecutable(const std::wstring& executable,
167 const std::wstring& argument) {
168 base::ProcessHandle process = NULL;
169 std::wstring path = GetExecutableAppPath(executable);
170 if (path.empty()) {
171 path = FormatCommandForApp(executable, argument);
172 if (path.empty()) {
173 LOG(ERROR) << "Failed to find executable: " << executable;
174 } else {
175 CommandLine cmdline = CommandLine::FromString(path);
176 if (!base::LaunchProcess(cmdline, base::LaunchOptions(), &process)) {
177 LOG(ERROR) << "LaunchProcess failed: " << ::GetLastError();
180 } else {
181 CommandLine cmdline((base::FilePath(path)));
182 cmdline.AppendArgNative(argument);
183 if (!base::LaunchProcess(cmdline, base::LaunchOptions(), &process)) {
184 LOG(ERROR) << "LaunchProcess failed: " << ::GetLastError();
187 return process;
190 base::ProcessHandle LaunchChrome(const std::wstring& url,
191 const base::FilePath& user_data_dir) {
192 base::FilePath path;
193 PathService::Get(base::DIR_MODULE, &path);
194 path = path.AppendASCII(kChromeImageName);
196 CommandLine cmd(path);
197 cmd.AppendSwitch(switches::kNoFirstRun);
198 if (!user_data_dir.empty())
199 cmd.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
200 cmd.AppendArgNative(url);
202 base::ProcessHandle process = NULL;
203 base::LaunchProcess(cmd, base::LaunchOptions(), &process);
204 return process;
207 base::ProcessHandle LaunchIEOnVista(const std::wstring& url) {
208 typedef HRESULT (WINAPI* IELaunchURLPtr)(const wchar_t* url,
209 PROCESS_INFORMATION* pi,
210 VOID* info);
212 IELaunchURLPtr launch;
213 PROCESS_INFORMATION pi = {0};
214 IELAUNCHURLINFO info = {sizeof info, 0};
215 HMODULE h = LoadLibrary(L"ieframe.dll");
216 if (!h) {
217 LOG(ERROR) << "Failed to load ieframe.dll: " << ::GetLastError();
218 return NULL;
220 launch = reinterpret_cast<IELaunchURLPtr>(GetProcAddress(h, "IELaunchURL"));
221 CHECK(launch);
222 HRESULT hr = launch(url.c_str(), &pi, &info);
223 FreeLibrary(h);
224 if (SUCCEEDED(hr)) {
225 CloseHandle(pi.hThread);
226 } else {
227 LOG(ERROR) << base::StringPrintf("IELaunchURL failed: 0x%08X", hr);
229 return pi.hProcess;
232 base::ProcessHandle LaunchIE(const std::wstring& url) {
233 if (GetInstalledIEVersion() >= IE_8) {
234 chrome_frame_test::ClearIESessionHistory();
237 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
238 return LaunchIEOnVista(url);
240 return LaunchExecutable(kIEImageName, url);
243 bool TakeSnapshotAndLog() {
244 testing::UnitTest* unit_test = testing::UnitTest::GetInstance();
245 const testing::TestInfo* test_info = unit_test->current_test_info();
246 std::string name;
247 if (test_info != NULL) {
248 name.append(test_info->test_case_name())
249 .append(1, '.')
250 .append(test_info->name());
251 } else {
252 name = "unknown test";
255 base::FilePath snapshot;
256 if (!ui_test_utils::SaveScreenSnapshotToDesktop(&snapshot)) {
257 LOG(ERROR) << "Failed saving screen snapshot for " << name;
258 return false;
261 LOG(ERROR) << "Saved screen snapshot for " << name << " to "
262 << snapshot.value();
263 return true;
266 int CloseAllIEWindows() {
267 int ret = 0;
269 base::win::ScopedComPtr<IShellWindows> windows;
270 HRESULT hr = ::CoCreateInstance(__uuidof(ShellWindows), NULL, CLSCTX_ALL,
271 IID_IShellWindows, reinterpret_cast<void**>(windows.Receive()));
272 DCHECK(SUCCEEDED(hr));
274 if (SUCCEEDED(hr)) {
275 long count = 0; // NOLINT
276 windows->get_Count(&count);
277 VARIANT i = { VT_I4 };
278 for (i.lVal = 0; i.lVal < count; ++i.lVal) {
279 base::win::ScopedComPtr<IDispatch> folder;
280 windows->Item(i, folder.Receive());
281 if (folder != NULL) {
282 base::win::ScopedComPtr<IWebBrowser2> browser;
283 if (SUCCEEDED(browser.QueryFrom(folder))) {
284 bool is_ie = true;
285 HWND window = NULL;
286 // Check the class of the browser window to make sure we only close
287 // IE windows.
288 if (browser->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&window))) {
289 wchar_t class_name[MAX_PATH];
290 if (::GetClassName(window, class_name, arraysize(class_name))) {
291 is_ie = _wcsicmp(class_name, L"IEFrame") == 0;
294 if (is_ie) {
295 browser->Quit();
296 ++ret;
303 return ret;
307 LowIntegrityToken::LowIntegrityToken() : impersonated_(false) {
310 LowIntegrityToken::~LowIntegrityToken() {
311 RevertToSelf();
314 BOOL LowIntegrityToken::RevertToSelf() {
315 BOOL ok = TRUE;
316 if (impersonated_) {
317 DCHECK(IsImpersonated());
318 ok = ::RevertToSelf();
319 if (ok)
320 impersonated_ = false;
323 return ok;
326 BOOL LowIntegrityToken::Impersonate() {
327 DCHECK(!impersonated_);
328 DCHECK(!IsImpersonated());
329 HANDLE process_token_handle = NULL;
330 BOOL ok = ::OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE,
331 &process_token_handle);
332 if (!ok) {
333 LOG(ERROR) << "::OpenProcessToken failed: " << GetLastError();
334 return ok;
337 base::win::ScopedHandle process_token(process_token_handle);
338 // Create impersonation low integrity token.
339 HANDLE impersonation_token_handle = NULL;
340 ok = ::DuplicateTokenEx(process_token,
341 TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, NULL,
342 SecurityImpersonation, TokenImpersonation, &impersonation_token_handle);
343 if (!ok) {
344 LOG(ERROR) << "::DuplicateTokenEx failed: " << GetLastError();
345 return ok;
348 // TODO(stoyan): sandbox/win/src/restricted_token_utils.cc has
349 // SetTokenIntegrityLevel function already.
350 base::win::ScopedHandle impersonation_token(impersonation_token_handle);
351 PSID integrity_sid = NULL;
352 TOKEN_MANDATORY_LABEL tml = {0};
353 ok = ::ConvertStringSidToSid(SDDL_ML_LOW, &integrity_sid);
354 if (!ok) {
355 LOG(ERROR) << "::ConvertStringSidToSid failed: " << GetLastError();
356 return ok;
359 tml.Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
360 tml.Label.Sid = integrity_sid;
361 ok = ::SetTokenInformation(impersonation_token, TokenIntegrityLevel,
362 &tml, sizeof(tml) + ::GetLengthSid(integrity_sid));
363 ::LocalFree(integrity_sid);
364 if (!ok) {
365 LOG(ERROR) << "::SetTokenInformation failed: " << GetLastError();
366 return ok;
369 // Switch current thread to low integrity.
370 ok = ::ImpersonateLoggedOnUser(impersonation_token);
371 if (ok) {
372 impersonated_ = true;
373 } else {
374 LOG(ERROR) << "::ImpersonateLoggedOnUser failed: " << GetLastError();
377 return ok;
380 bool LowIntegrityToken::IsImpersonated() {
381 HANDLE token = NULL;
382 if (!::OpenThreadToken(::GetCurrentThread(), 0, false, &token) &&
383 ::GetLastError() != ERROR_NO_TOKEN) {
384 return true;
387 if (token)
388 ::CloseHandle(token);
390 return false;
393 HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) {
394 if (!web_browser)
395 return E_INVALIDARG;
397 if (GetInstalledIEVersion() >= IE_8) {
398 chrome_frame_test::ClearIESessionHistory();
401 AllowSetForegroundWindow(ASFW_ANY);
403 HRESULT hr = S_OK;
404 DWORD cocreate_flags = CLSCTX_LOCAL_SERVER;
405 chrome_frame_test::LowIntegrityToken token;
406 base::IntegrityLevel integrity_level = base::INTEGRITY_UNKNOWN;
407 // Vista has a bug which manifests itself when a medium integrity process
408 // launches a COM server like IE which runs in protected mode due to UAC.
409 // This causes the IWebBrowser2 interface which is returned to be useless,
410 // i.e it does not receive any events, etc. Our workaround for this is
411 // to impersonate a low integrity token and then launch IE. Skip this if the
412 // tests are running at high integrity, since the workaround results in the
413 // medium-integrity broker exiting, and the low-integrity IE is therefore
414 // unable to get chrome_launcher running at medium integrity.
415 if (base::win::GetVersion() == base::win::VERSION_VISTA &&
416 GetInstalledIEVersion() == IE_7 &&
417 base::GetProcessIntegrityLevel(base::Process::Current().handle(),
418 &integrity_level) &&
419 integrity_level != base::HIGH_INTEGRITY) {
420 // Create medium integrity browser that will launch IE broker.
421 base::win::ScopedComPtr<IWebBrowser2> medium_integrity_browser;
422 hr = medium_integrity_browser.CreateInstance(CLSID_InternetExplorer, NULL,
423 CLSCTX_LOCAL_SERVER);
424 if (FAILED(hr))
425 return hr;
426 medium_integrity_browser->Quit();
427 // Broker remains alive.
428 if (!token.Impersonate()) {
429 hr = HRESULT_FROM_WIN32(GetLastError());
430 return hr;
433 cocreate_flags |= CLSCTX_ENABLE_CLOAKING;
436 hr = ::CoCreateInstance(CLSID_InternetExplorer, NULL,
437 cocreate_flags, IID_IWebBrowser2,
438 reinterpret_cast<void**>(web_browser));
439 // ~LowIntegrityToken() will switch integrity back to medium.
440 return hr;
443 std::wstring GetExeVersion(const std::wstring& exe_path) {
444 scoped_ptr<FileVersionInfo> ie_version_info(
445 FileVersionInfo::CreateFileVersionInfo(base::FilePath(exe_path)));
446 return ie_version_info->product_version();
449 IEVersion GetInstalledIEVersion() {
450 std::wstring path(chrome_frame_test::GetExecutableAppPath(kIEImageName));
451 std::wstring version(GetExeVersion(path));
452 size_t first_dot = version.find(L'.');
453 int major_version = 0;
454 if (!base::StringToInt(base::StringPiece16(
455 version.data(),
456 first_dot == std::wstring::npos ? version.size() : first_dot),
457 &major_version)) {
458 return IE_UNSUPPORTED;
461 switch (major_version) {
462 case 6:
463 return IE_6;
464 case 7:
465 return IE_7;
466 case 8:
467 return IE_8;
468 case 9:
469 return IE_9;
470 case 10:
471 return IE_10;
472 default:
473 break;
476 return IE_UNSUPPORTED;
479 base::FilePath GetProfilePathForIE() {
480 base::FilePath profile_path;
481 // Browsers without IDeleteBrowsingHistory in non-priv mode
482 // have their profiles moved into "Temporary Internet Files".
483 // The code below basically retrieves the version of IE and computes
484 // the profile directory accordingly.
485 if (GetInstalledIEVersion() <= IE_7) {
486 profile_path = GetIETemporaryFilesFolder();
487 profile_path = profile_path.Append(L"Google Chrome Frame");
488 } else {
489 GetChromeFrameProfilePath(kIEProfileName, &profile_path);
491 return profile_path;
494 base::FilePath GetTestDataFolder() {
495 base::FilePath test_dir;
496 PathService::Get(base::DIR_SOURCE_ROOT, &test_dir);
497 test_dir = test_dir.Append(FILE_PATH_LITERAL("chrome_frame"))
498 .Append(FILE_PATH_LITERAL("test"))
499 .Append(FILE_PATH_LITERAL("data"));
500 return test_dir;
503 base::FilePath GetSeleniumTestFolder() {
504 base::FilePath test_dir;
505 PathService::Get(base::DIR_SOURCE_ROOT, &test_dir);
506 test_dir = test_dir.Append(FILE_PATH_LITERAL("data"))
507 .Append(FILE_PATH_LITERAL("selenium_core"));
508 return test_dir;
511 std::wstring GetPathFromUrl(const std::wstring& url) {
512 string16 url16 = WideToUTF16(url);
513 GURL gurl = GURL(url16);
514 if (gurl.has_query()) {
515 GURL::Replacements replacements;
516 replacements.ClearQuery();
517 gurl = gurl.ReplaceComponents(replacements);
519 return UTF8ToWide(gurl.PathForRequest());
522 std::wstring GetPathAndQueryFromUrl(const std::wstring& url) {
523 string16 url16 = WideToUTF16(url);
524 GURL gurl = GURL(url16);
525 return UTF8ToWide(gurl.PathForRequest());
528 std::wstring GetClipboardText() {
529 string16 text16;
530 ui::Clipboard::GetForCurrentThread()->ReadText(
531 ui::Clipboard::BUFFER_STANDARD, &text16);
532 return UTF16ToWide(text16);
535 void SetClipboardText(const std::wstring& text) {
536 ui::ScopedClipboardWriter clipboard_writer(
537 ui::Clipboard::GetForCurrentThread(),
538 ui::Clipboard::BUFFER_STANDARD);
539 clipboard_writer.WriteText(WideToUTF16(text));
542 bool AddCFMetaTag(std::string* html_data) {
543 if (!html_data) {
544 NOTREACHED();
545 return false;
547 std::string lower = StringToLowerASCII(*html_data);
548 size_t head = lower.find("<head>");
549 if (head == std::string::npos) {
550 // Add missing head section.
551 size_t html = lower.find("<html>");
552 if (html != std::string::npos) {
553 head = html + strlen("<html>");
554 html_data->insert(head, "<head></head>");
555 } else {
556 LOG(ERROR) << "Meta tag will not be injected "
557 << "because the html tag could not be found";
560 if (head != std::string::npos) {
561 html_data->insert(
562 head + strlen("<head>"),
563 "<meta http-equiv=\"x-ua-compatible\" content=\"chrome=1\" />");
565 return head != std::string::npos;
568 CloseIeAtEndOfScope::~CloseIeAtEndOfScope() {
569 int closed = CloseAllIEWindows();
570 LOG_IF(ERROR, closed != 0) << "Closed " << closed << " windows forcefully";
573 // Attempt to connect to a running crash_service instance. Success occurs if we
574 // can actually connect to the service's pipe or we receive ERROR_PIPE_BUSY.
575 // Waits up to |timeout_ms| for success. |timeout_ms| may be 0, meaning only try
576 // once, or negative, meaning wait forever.
577 bool DetectRunningCrashService(int timeout_ms) {
578 // Wait for the crash_service.exe to be ready for clients.
579 base::Time start = base::Time::Now();
580 base::win::ScopedHandle new_pipe;
582 while (true) {
583 new_pipe.Set(::CreateFile(kCrashServicePipeName,
584 kCrashServicePipeDesiredAccess,
585 0, // dwShareMode
586 NULL, // lpSecurityAttributes
587 OPEN_EXISTING,
588 kCrashServicePipeFlagsAndAttributes,
589 NULL)); // hTemplateFile
591 if (new_pipe.IsValid()) {
592 return true;
595 switch (::GetLastError()) {
596 case ERROR_PIPE_BUSY:
597 // OK, it exists, let's assume that clients will eventually be able to
598 // connect to it.
599 return true;
600 case ERROR_FILE_NOT_FOUND:
601 // Wait a bit longer
602 break;
603 default:
604 DPLOG(WARNING) << "Unexpected error while checking crash_service.exe's "
605 << "pipe.";
606 // Go ahead and wait in case it clears up.
607 break;
610 if (timeout_ms == 0) {
611 return false;
612 } else if (timeout_ms > 0) {
613 base::TimeDelta duration = base::Time::Now() - start;
614 if (duration.InMilliseconds() > timeout_ms) {
615 return false;
619 Sleep(10);
623 base::ProcessHandle StartCrashService() {
624 if (DetectRunningCrashService(kCrashServiceDetectTimeoutMs)) {
625 VLOG(1) << "crash_service.exe is already running. We will use the "
626 "existing process and leave it running after tests complete.";
627 return NULL;
630 base::FilePath exe_dir;
631 if (!PathService::Get(base::DIR_EXE, &exe_dir)) {
632 DCHECK(false);
633 return NULL;
636 base::ProcessHandle crash_service = NULL;
638 VLOG(1) << "Starting crash_service.exe so you know if a test crashes!";
640 base::FilePath crash_service_path = exe_dir.AppendASCII("crash_service.exe");
641 if (!base::LaunchProcess(crash_service_path.value(), base::LaunchOptions(),
642 &crash_service)) {
643 LOG(ERROR) << "Couldn't start crash_service.exe";
644 return NULL;
647 base::Time start = base::Time::Now();
649 if (DetectRunningCrashService(kCrashServiceStartupTimeoutMs)) {
650 VLOG(1) << "crash_service.exe is ready for clients in "
651 << (base::Time::Now() - start).InMilliseconds() << " ms.";
652 return crash_service;
653 } else {
654 LOG(ERROR) << "crash_service.exe failed to accept client connections "
655 "within " << kCrashServiceStartupTimeoutMs << " ms. "
656 "Terminating it now.";
658 // First check to see if it's even still running just to minimize the
659 // likelihood of spurious error messages from KillProcess.
660 if (WAIT_OBJECT_0 != ::WaitForSingleObject(crash_service, 0)) {
661 base::KillProcess(crash_service, 0, false);
663 return NULL;
667 ScopedVirtualizeHklmAndHkcu::ScopedVirtualizeHklmAndHkcu() {
668 override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE, L"hklm_fake");
669 override_manager_.OverrideRegistry(HKEY_CURRENT_USER, L"hkcu_fake");
672 ScopedVirtualizeHklmAndHkcu::~ScopedVirtualizeHklmAndHkcu() {
675 void ScopedVirtualizeHklmAndHkcu::RemoveAllOverrides() {
676 override_manager_.RemoveAllOverrides();
679 bool KillProcesses(const std::wstring& executable_name, int exit_code,
680 bool wait) {
681 bool result = true;
682 base::NamedProcessIterator iter(executable_name, NULL);
683 while (const base::ProcessEntry* entry = iter.NextProcessEntry()) {
684 result &= base::KillProcessById(entry->pid(), exit_code, wait);
686 return result;
689 ScopedChromeFrameRegistrar::RegistrationType GetTestBedType() {
690 if (GetConfigBool(false, L"PerUserTestBed")) {
691 return ScopedChromeFrameRegistrar::PER_USER;
692 } else {
693 return ScopedChromeFrameRegistrar::SYSTEM_LEVEL;
697 void ClearIESessionHistory() {
698 base::FilePath session_history_path;
699 if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &session_history_path))
700 return;
702 session_history_path = session_history_path.AppendASCII("Microsoft");
703 session_history_path = session_history_path.AppendASCII("Internet Explorer");
704 session_history_path = session_history_path.AppendASCII("Recovery");
705 file_util::Delete(session_history_path, true);
708 std::string GetLocalIPv4Address() {
709 std::string address;
710 net::NetworkInterfaceList nic_list;
712 if (!net::GetNetworkList(&nic_list)) {
713 LOG(ERROR) << "GetNetworkList failed to look up non-loopback adapters. "
714 << "Tests will be run over the loopback adapter, which may "
715 << "result in hangs.";
716 } else {
717 // GetNetworkList only returns 'Up' non-loopback adapters. Select the first
718 // IPv4 address found - we should be able to bind/connect over it.
719 for (size_t i = 0; i < nic_list.size(); ++i) {
720 if (nic_list[i].address.size() != net::kIPv4AddressSize)
721 continue;
722 char* address_string =
723 inet_ntoa(*reinterpret_cast<in_addr*>(&nic_list[i].address[0]));
724 DCHECK(address_string != NULL);
725 if (address_string != NULL) {
726 LOG(INFO) << "HTTP tests will run over " << address_string << ".";
727 address.assign(address_string);
728 break;
733 if (address.empty()) {
734 LOG(ERROR) << "Failed to find a non-loopback IP_V4 address. Tests will be "
735 << "run over the loopback adapter, which may result in hangs.";
736 address.assign("127.0.0.1");
739 return address;
742 } // namespace chrome_frame_test