| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "base/win/wrapped_window_proc.h" | 
 |  | 
 | #include "base/atomicops.h" | 
 | #include "base/logging.h" | 
 |  | 
 | namespace { | 
 |  | 
 | base::win::WinProcExceptionFilter s_exception_filter = NULL; | 
 |  | 
 | HMODULE GetModuleFromWndProc(WNDPROC window_proc) { | 
 |   HMODULE instance = NULL; | 
 |   // Converting a pointer-to-function to a void* is undefined behavior, but | 
 |   // Windows (and POSIX) APIs require it to work. | 
 |   void* address = reinterpret_cast<void*>(window_proc); | 
 |   if (!::GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | | 
 |                             GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, | 
 |                             static_cast<char*>(address), | 
 |                             &instance)) { | 
 |     NOTREACHED(); | 
 |   } | 
 |   return instance; | 
 | } | 
 |  | 
 | }  // namespace. | 
 |  | 
 | namespace base { | 
 | namespace win { | 
 |  | 
 | WinProcExceptionFilter SetWinProcExceptionFilter( | 
 |     WinProcExceptionFilter filter) { | 
 |   subtle::AtomicWord rv = subtle::NoBarrier_AtomicExchange( | 
 |       reinterpret_cast<subtle::AtomicWord*>(&s_exception_filter), | 
 |       reinterpret_cast<subtle::AtomicWord>(filter)); | 
 |   return reinterpret_cast<WinProcExceptionFilter>(rv); | 
 | } | 
 |  | 
 | int CallExceptionFilter(EXCEPTION_POINTERS* info) { | 
 |   return s_exception_filter ? s_exception_filter(info) : | 
 |                               EXCEPTION_CONTINUE_SEARCH; | 
 | } | 
 |  | 
 | BASE_EXPORT void InitializeWindowClass( | 
 |     const char16* class_name, | 
 |     WNDPROC window_proc, | 
 |     UINT style, | 
 |     int class_extra, | 
 |     int window_extra, | 
 |     HCURSOR cursor, | 
 |     HBRUSH background, | 
 |     const char16* menu_name, | 
 |     HICON large_icon, | 
 |     HICON small_icon, | 
 |     WNDCLASSEX* class_out) { | 
 |   class_out->cbSize = sizeof(WNDCLASSEX); | 
 |   class_out->style = style; | 
 |   class_out->lpfnWndProc = window_proc; | 
 |   class_out->cbClsExtra = class_extra; | 
 |   class_out->cbWndExtra = window_extra; | 
 |   // RegisterClassEx uses a handle of the module containing the window procedure | 
 |   // to distinguish identically named classes registered in different modules. | 
 |   class_out->hInstance = GetModuleFromWndProc(window_proc); | 
 |   class_out->hIcon = large_icon; | 
 |   class_out->hCursor = cursor; | 
 |   class_out->hbrBackground = background; | 
 |   class_out->lpszMenuName = menu_name; | 
 |   class_out->lpszClassName = class_name; | 
 |   class_out->hIconSm = small_icon; | 
 |  | 
 |   // Check if |window_proc| is valid. | 
 |   DCHECK(class_out->hInstance != NULL); | 
 | } | 
 |  | 
 | }  // namespace win | 
 | }  // namespace base |