| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome_frame/test/chrome_frame_test_utils.h" | 5 #include "chrome_frame/test/chrome_frame_test_utils.h" |
| 6 | 6 |
| 7 #include <atlapp.h> | 7 #include <atlapp.h> |
| 8 #include <atlmisc.h> | 8 #include <atlmisc.h> |
| 9 #include <iepmapi.h> | 9 #include <iepmapi.h> |
| 10 #include <sddl.h> | 10 #include <sddl.h> |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 int& count = *reinterpret_cast<int*>(param); | 63 int& count = *reinterpret_cast<int*>(param); |
| 64 if (IsWindowVisible(hwnd)) { | 64 if (IsWindowVisible(hwnd)) { |
| 65 if (IsWindowEnabled(hwnd)) { | 65 if (IsWindowEnabled(hwnd)) { |
| 66 DWORD results = 0; | 66 DWORD results = 0; |
| 67 if (!::SendMessageTimeout(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0, SMTO_BLOCK, | 67 if (!::SendMessageTimeout(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0, SMTO_BLOCK, |
| 68 10000, &results)) { | 68 10000, &results)) { |
| 69 LOG(WARNING) << "Window hung: " << base::StringPrintf(L"%08X", hwnd); | 69 LOG(WARNING) << "Window hung: " << base::StringPrintf(L"%08X", hwnd); |
| 70 } | 70 } |
| 71 count++; | 71 count++; |
| 72 } else { | 72 } else { |
| 73 DLOG(WARNING) << "Skipping disabled window: " | 73 LOG(WARNING) << "Skipping disabled window: " |
| 74 << base::StringPrintf(L"%08X", hwnd); | 74 << base::StringPrintf(L"%08X", hwnd); |
| 75 } | 75 } |
| 76 } | 76 } |
| 77 return TRUE; // continue enumeration | 77 return TRUE; // continue enumeration |
| 78 } | 78 } |
| 79 | 79 |
| 80 // Attempts to close all non-child, visible windows on the given thread. | 80 // Attempts to close all non-child, visible windows on the given thread. |
| 81 // The return value is the number of visible windows a close request was | 81 // The return value is the number of visible windows a close request was |
| 82 // sent to. | 82 // sent to. |
| 83 int CloseVisibleTopLevelWindowsOnThread(DWORD thread_id) { | 83 int CloseVisibleTopLevelWindowsOnThread(DWORD thread_id) { |
| 84 int window_close_attempts = 0; | 84 int window_close_attempts = 0; |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 return ok; | 290 return ok; |
| 291 } | 291 } |
| 292 | 292 |
| 293 BOOL LowIntegrityToken::Impersonate() { | 293 BOOL LowIntegrityToken::Impersonate() { |
| 294 DCHECK(!impersonated_); | 294 DCHECK(!impersonated_); |
| 295 DCHECK(!IsImpersonated()); | 295 DCHECK(!IsImpersonated()); |
| 296 HANDLE process_token_handle = NULL; | 296 HANDLE process_token_handle = NULL; |
| 297 BOOL ok = ::OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, | 297 BOOL ok = ::OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, |
| 298 &process_token_handle); | 298 &process_token_handle); |
| 299 if (!ok) { | 299 if (!ok) { |
| 300 DLOG(ERROR) << "::OpenProcessToken failed: " << GetLastError(); | 300 LOG(ERROR) << "::OpenProcessToken failed: " << GetLastError(); |
| 301 return ok; | 301 return ok; |
| 302 } | 302 } |
| 303 | 303 |
| 304 base::win::ScopedHandle process_token(process_token_handle); | 304 base::win::ScopedHandle process_token(process_token_handle); |
| 305 // Create impersonation low integrity token. | 305 // Create impersonation low integrity token. |
| 306 HANDLE impersonation_token_handle = NULL; | 306 HANDLE impersonation_token_handle = NULL; |
| 307 ok = ::DuplicateTokenEx(process_token, | 307 ok = ::DuplicateTokenEx(process_token, |
| 308 TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, NULL, | 308 TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, NULL, |
| 309 SecurityImpersonation, TokenImpersonation, &impersonation_token_handle); | 309 SecurityImpersonation, TokenImpersonation, &impersonation_token_handle); |
| 310 if (!ok) { | 310 if (!ok) { |
| 311 DLOG(ERROR) << "::DuplicateTokenEx failed: " << GetLastError(); | 311 LOG(ERROR) << "::DuplicateTokenEx failed: " << GetLastError(); |
| 312 return ok; | 312 return ok; |
| 313 } | 313 } |
| 314 | 314 |
| 315 // TODO(stoyan): sandbox/src/restricted_token_utils.cc has | 315 // TODO(stoyan): sandbox/src/restricted_token_utils.cc has |
| 316 // SetTokenIntegrityLevel function already. | 316 // SetTokenIntegrityLevel function already. |
| 317 base::win::ScopedHandle impersonation_token(impersonation_token_handle); | 317 base::win::ScopedHandle impersonation_token(impersonation_token_handle); |
| 318 PSID integrity_sid = NULL; | 318 PSID integrity_sid = NULL; |
| 319 TOKEN_MANDATORY_LABEL tml = {0}; | 319 TOKEN_MANDATORY_LABEL tml = {0}; |
| 320 ok = ::ConvertStringSidToSid(SDDL_ML_LOW, &integrity_sid); | 320 ok = ::ConvertStringSidToSid(SDDL_ML_LOW, &integrity_sid); |
| 321 if (!ok) { | 321 if (!ok) { |
| 322 DLOG(ERROR) << "::ConvertStringSidToSid failed: " << GetLastError(); | 322 LOG(ERROR) << "::ConvertStringSidToSid failed: " << GetLastError(); |
| 323 return ok; | 323 return ok; |
| 324 } | 324 } |
| 325 | 325 |
| 326 tml.Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED; | 326 tml.Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED; |
| 327 tml.Label.Sid = integrity_sid; | 327 tml.Label.Sid = integrity_sid; |
| 328 ok = ::SetTokenInformation(impersonation_token, TokenIntegrityLevel, | 328 ok = ::SetTokenInformation(impersonation_token, TokenIntegrityLevel, |
| 329 &tml, sizeof(tml) + ::GetLengthSid(integrity_sid)); | 329 &tml, sizeof(tml) + ::GetLengthSid(integrity_sid)); |
| 330 ::LocalFree(integrity_sid); | 330 ::LocalFree(integrity_sid); |
| 331 if (!ok) { | 331 if (!ok) { |
| 332 DLOG(ERROR) << "::SetTokenInformation failed: " << GetLastError(); | 332 LOG(ERROR) << "::SetTokenInformation failed: " << GetLastError(); |
| 333 return ok; | 333 return ok; |
| 334 } | 334 } |
| 335 | 335 |
| 336 // Switch current thread to low integrity. | 336 // Switch current thread to low integrity. |
| 337 ok = ::ImpersonateLoggedOnUser(impersonation_token); | 337 ok = ::ImpersonateLoggedOnUser(impersonation_token); |
| 338 if (ok) { | 338 if (ok) { |
| 339 impersonated_ = true; | 339 impersonated_ = true; |
| 340 } else { | 340 } else { |
| 341 DLOG(ERROR) << "::ImpersonateLoggedOnUser failed: " << GetLastError(); | 341 LOG(ERROR) << "::ImpersonateLoggedOnUser failed: " << GetLastError(); |
| 342 } | 342 } |
| 343 | 343 |
| 344 return ok; | 344 return ok; |
| 345 } | 345 } |
| 346 | 346 |
| 347 bool LowIntegrityToken::IsImpersonated() { | 347 bool LowIntegrityToken::IsImpersonated() { |
| 348 HANDLE token = NULL; | 348 HANDLE token = NULL; |
| 349 if (!::OpenThreadToken(::GetCurrentThread(), 0, false, &token) && | 349 if (!::OpenThreadToken(::GetCurrentThread(), 0, false, &token) && |
| 350 ::GetLastError() != ERROR_NO_TOKEN) { | 350 ::GetLastError() != ERROR_NO_TOKEN) { |
| 351 return true; | 351 return true; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 } | 514 } |
| 515 std::string lower = StringToLowerASCII(*html_data); | 515 std::string lower = StringToLowerASCII(*html_data); |
| 516 size_t head = lower.find("<head>"); | 516 size_t head = lower.find("<head>"); |
| 517 if (head == std::string::npos) { | 517 if (head == std::string::npos) { |
| 518 // Add missing head section. | 518 // Add missing head section. |
| 519 size_t html = lower.find("<html>"); | 519 size_t html = lower.find("<html>"); |
| 520 if (html != std::string::npos) { | 520 if (html != std::string::npos) { |
| 521 head = html + strlen("<html>"); | 521 head = html + strlen("<html>"); |
| 522 html_data->insert(head, "<head></head>"); | 522 html_data->insert(head, "<head></head>"); |
| 523 } else { | 523 } else { |
| 524 DLOG(ERROR) << "Meta tag will not be injected " | 524 LOG(ERROR) << "Meta tag will not be injected " |
| 525 << "because the html tag could not be found"; | 525 << "because the html tag could not be found"; |
| 526 } | 526 } |
| 527 } | 527 } |
| 528 if (head != std::string::npos) { | 528 if (head != std::string::npos) { |
| 529 html_data->insert( | 529 html_data->insert( |
| 530 head + strlen("<head>"), | 530 head + strlen("<head>"), |
| 531 "<meta http-equiv=\"x-ua-compatible\" content=\"chrome=1\" />"); | 531 "<meta http-equiv=\"x-ua-compatible\" content=\"chrome=1\" />"); |
| 532 } | 532 } |
| 533 return head != std::string::npos; | 533 return head != std::string::npos; |
| 534 } | 534 } |
| 535 | 535 |
| 536 CloseIeAtEndOfScope::~CloseIeAtEndOfScope() { | 536 CloseIeAtEndOfScope::~CloseIeAtEndOfScope() { |
| 537 int closed = CloseAllIEWindows(); | 537 int closed = CloseAllIEWindows(); |
| 538 DLOG_IF(ERROR, closed != 0) << "Closed " << closed << " windows forcefully"; | 538 LOG_IF(ERROR, closed != 0) << "Closed " << closed << " windows forcefully"; |
| 539 } | 539 } |
| 540 | 540 |
| 541 // Attempt to connect to a running crash_service instance. Success occurs if we | 541 // Attempt to connect to a running crash_service instance. Success occurs if we |
| 542 // can actually connect to the service's pipe or we receive ERROR_PIPE_BUSY. | 542 // can actually connect to the service's pipe or we receive ERROR_PIPE_BUSY. |
| 543 // Waits up to |timeout_ms| for success. |timeout_ms| may be 0, meaning only try | 543 // Waits up to |timeout_ms| for success. |timeout_ms| may be 0, meaning only try |
| 544 // once, or negative, meaning wait forever. | 544 // once, or negative, meaning wait forever. |
| 545 bool DetectRunningCrashService(int timeout_ms) { | 545 bool DetectRunningCrashService(int timeout_ms) { |
| 546 // Wait for the crash_service.exe to be ready for clients. | 546 // Wait for the crash_service.exe to be ready for clients. |
| 547 base::Time start = base::Time::Now(); | 547 base::Time start = base::Time::Now(); |
| 548 base::win::ScopedHandle new_pipe; | 548 base::win::ScopedHandle new_pipe; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 return false; | 583 return false; |
| 584 } | 584 } |
| 585 } | 585 } |
| 586 | 586 |
| 587 Sleep(10); | 587 Sleep(10); |
| 588 } | 588 } |
| 589 } | 589 } |
| 590 | 590 |
| 591 base::ProcessHandle StartCrashService() { | 591 base::ProcessHandle StartCrashService() { |
| 592 if (DetectRunningCrashService(kCrashServiceStartupTimeoutMs)) { | 592 if (DetectRunningCrashService(kCrashServiceStartupTimeoutMs)) { |
| 593 DVLOG(1) << "crash_service.exe is already running. We will use the " | 593 VLOG(1) << "crash_service.exe is already running. We will use the " |
| 594 "existing process and leave it running after tests complete."; | 594 "existing process and leave it running after tests complete."; |
| 595 return NULL; | 595 return NULL; |
| 596 } | 596 } |
| 597 | 597 |
| 598 FilePath exe_dir; | 598 FilePath exe_dir; |
| 599 if (!PathService::Get(base::DIR_EXE, &exe_dir)) { | 599 if (!PathService::Get(base::DIR_EXE, &exe_dir)) { |
| 600 DCHECK(false); | 600 DCHECK(false); |
| 601 return NULL; | 601 return NULL; |
| 602 } | 602 } |
| 603 | 603 |
| 604 base::ProcessHandle crash_service = NULL; | 604 base::ProcessHandle crash_service = NULL; |
| 605 | 605 |
| 606 DVLOG(1) << "Starting crash_service.exe so you know if a test crashes!"; | 606 VLOG(1) << "Starting crash_service.exe so you know if a test crashes!"; |
| 607 | 607 |
| 608 FilePath crash_service_path = exe_dir.AppendASCII("crash_service.exe"); | 608 FilePath crash_service_path = exe_dir.AppendASCII("crash_service.exe"); |
| 609 if (!base::LaunchProcess(crash_service_path.value(), base::LaunchOptions(), | 609 if (!base::LaunchProcess(crash_service_path.value(), base::LaunchOptions(), |
| 610 &crash_service)) { | 610 &crash_service)) { |
| 611 DLOG(ERROR) << "Couldn't start crash_service.exe"; | 611 LOG(ERROR) << "Couldn't start crash_service.exe"; |
| 612 return NULL; | 612 return NULL; |
| 613 } | 613 } |
| 614 | 614 |
| 615 base::Time start = base::Time::Now(); | 615 base::Time start = base::Time::Now(); |
| 616 | 616 |
| 617 if (DetectRunningCrashService(kCrashServiceStartupTimeoutMs)) { | 617 if (DetectRunningCrashService(kCrashServiceStartupTimeoutMs)) { |
| 618 DVLOG(1) << "crash_service.exe is ready for clients in " | 618 VLOG(1) << "crash_service.exe is ready for clients in " |
| 619 << (base::Time::Now() - start).InMilliseconds() << " ms."; | 619 << (base::Time::Now() - start).InMilliseconds() << " ms."; |
| 620 return crash_service; | 620 return crash_service; |
| 621 } else { | 621 } else { |
| 622 DLOG(ERROR) << "crash_service.exe failed to accept client connections " | 622 LOG(ERROR) << "crash_service.exe failed to accept client connections " |
| 623 "within " << kCrashServiceStartupTimeoutMs << " ms. " | 623 "within " << kCrashServiceStartupTimeoutMs << " ms. " |
| 624 "Terminating it now."; | 624 "Terminating it now."; |
| 625 | 625 |
| 626 // First check to see if it's even still running just to minimize the | 626 // First check to see if it's even still running just to minimize the |
| 627 // likelihood of spurious error messages from KillProcess. | 627 // likelihood of spurious error messages from KillProcess. |
| 628 if (WAIT_OBJECT_0 != ::WaitForSingleObject(crash_service, 0)) { | 628 if (WAIT_OBJECT_0 != ::WaitForSingleObject(crash_service, 0)) { |
| 629 base::KillProcess(crash_service, 0, false); | 629 base::KillProcess(crash_service, 0, false); |
| 630 } | 630 } |
| 631 return NULL; | 631 return NULL; |
| 632 } | 632 } |
| 633 } | 633 } |
| 634 | 634 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &session_history_path)) | 667 if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &session_history_path)) |
| 668 return; | 668 return; |
| 669 | 669 |
| 670 session_history_path = session_history_path.AppendASCII("Microsoft"); | 670 session_history_path = session_history_path.AppendASCII("Microsoft"); |
| 671 session_history_path = session_history_path.AppendASCII("Internet Explorer"); | 671 session_history_path = session_history_path.AppendASCII("Internet Explorer"); |
| 672 session_history_path = session_history_path.AppendASCII("Recovery"); | 672 session_history_path = session_history_path.AppendASCII("Recovery"); |
| 673 file_util::Delete(session_history_path, true); | 673 file_util::Delete(session_history_path, true); |
| 674 } | 674 } |
| 675 | 675 |
| 676 } // namespace chrome_frame_test | 676 } // namespace chrome_frame_test |
| OLD | NEW |