| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "base/win/wrapped_window_proc.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 |  | 
 | namespace { | 
 |  | 
 | DWORD kExceptionCode = 12345; | 
 | WPARAM kCrashMsg = 98765; | 
 |  | 
 | // A trivial WindowProc that generates an exception. | 
 | LRESULT CALLBACK TestWindowProc(HWND hwnd, UINT message, | 
 |                                 WPARAM wparam, LPARAM lparam) { | 
 |   if (message == kCrashMsg) | 
 |     RaiseException(kExceptionCode, 0, 0, NULL); | 
 |   return DefWindowProc(hwnd, message, wparam, lparam); | 
 | } | 
 |  | 
 | // This class implements an exception filter that can be queried about a past | 
 | // exception. | 
 | class TestWrappedExceptionFiter { | 
 |  public: | 
 |   TestWrappedExceptionFiter() : called_(false) { | 
 |     EXPECT_FALSE(s_filter_); | 
 |     s_filter_ = this; | 
 |   } | 
 |  | 
 |   ~TestWrappedExceptionFiter() { | 
 |     EXPECT_EQ(s_filter_, this); | 
 |     s_filter_ = NULL; | 
 |   } | 
 |  | 
 |   bool called() { | 
 |     return called_; | 
 |   } | 
 |  | 
 |   // The actual exception filter just records the exception. | 
 |   static int Filter(EXCEPTION_POINTERS* info) { | 
 |     EXPECT_FALSE(s_filter_->called_); | 
 |     if (info->ExceptionRecord->ExceptionCode == kExceptionCode) | 
 |       s_filter_->called_ = true; | 
 |     return EXCEPTION_EXECUTE_HANDLER; | 
 |   } | 
 |  | 
 |  private: | 
 |   bool called_; | 
 |   static TestWrappedExceptionFiter* s_filter_; | 
 | }; | 
 | TestWrappedExceptionFiter* TestWrappedExceptionFiter::s_filter_ = NULL; | 
 |  | 
 | }  // namespace. | 
 |  | 
 | TEST(WrappedWindowProc, CatchesExceptions) { | 
 |   HINSTANCE hinst = GetModuleHandle(NULL); | 
 |   std::wstring class_name(L"TestClass"); | 
 |  | 
 |   WNDCLASS wc = {0}; | 
 |   wc.lpfnWndProc = base::win::WrappedWindowProc<TestWindowProc>; | 
 |   wc.hInstance = hinst; | 
 |   wc.lpszClassName = class_name.c_str(); | 
 |   RegisterClass(&wc); | 
 |  | 
 |   HWND window = CreateWindow(class_name.c_str(), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, | 
 |                              0, hinst, 0); | 
 |   ASSERT_TRUE(window); | 
 |  | 
 |   // Before generating the exception we make sure that the filter will see it. | 
 |   TestWrappedExceptionFiter wrapper; | 
 |   base::win::WinProcExceptionFilter old_filter = | 
 |       base::win::SetWinProcExceptionFilter(TestWrappedExceptionFiter::Filter); | 
 |  | 
 |   SendMessage(window, kCrashMsg, 0, 0); | 
 |   EXPECT_TRUE(wrapper.called()); | 
 |  | 
 |   base::win::SetWinProcExceptionFilter(old_filter); | 
 | } |