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.
4 
5 #include "base/win/wrapped_window_proc.h"
6 
7 #include "base/atomicops.h"
8 #include "base/check.h"
9 #include "base/notreached.h"
10 #include "base/strings/string_util.h"
11 
12 namespace {
13 
14 base::win::WinProcExceptionFilter s_exception_filter = nullptr;
15 
GetModuleFromWndProc(WNDPROC window_proc)16 HMODULE GetModuleFromWndProc(WNDPROC window_proc) {
17   HMODULE instance = nullptr;
18   // Converting a pointer-to-function to a void* is undefined behavior, but
19   // Windows (and POSIX) APIs require it to work.
20   void* address = reinterpret_cast<void*>(window_proc);
21   if (!::GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
22                                 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
23                             static_cast<char*>(address), &instance)) {
24     NOTREACHED();
25   }
26   return instance;
27 }
28 
29 }  // namespace.
30 
31 namespace base {
32 namespace win {
33 
SetWinProcExceptionFilter(WinProcExceptionFilter filter)34 WinProcExceptionFilter SetWinProcExceptionFilter(
35     WinProcExceptionFilter filter) {
36   subtle::AtomicWord rv = subtle::NoBarrier_AtomicExchange(
37       reinterpret_cast<subtle::AtomicWord*>(&s_exception_filter),
38       reinterpret_cast<subtle::AtomicWord>(filter));
39   return reinterpret_cast<WinProcExceptionFilter>(rv);
40 }
41 
CallExceptionFilter(EXCEPTION_POINTERS * info)42 int CallExceptionFilter(EXCEPTION_POINTERS* info) {
43   return s_exception_filter ? s_exception_filter(info)
44                             : EXCEPTION_CONTINUE_SEARCH;
45 }
46 
InitializeWindowClass(const wchar_t * class_name,WNDPROC window_proc,UINT style,int class_extra,int window_extra,HCURSOR cursor,HBRUSH background,const wchar_t * menu_name,HICON large_icon,HICON small_icon,WNDCLASSEX * class_out)47 BASE_EXPORT void InitializeWindowClass(const wchar_t* class_name,
48                                        WNDPROC window_proc,
49                                        UINT style,
50                                        int class_extra,
51                                        int window_extra,
52                                        HCURSOR cursor,
53                                        HBRUSH background,
54                                        const wchar_t* menu_name,
55                                        HICON large_icon,
56                                        HICON small_icon,
57                                        WNDCLASSEX* class_out) {
58   class_out->cbSize = sizeof(WNDCLASSEX);
59   class_out->style = style;
60   class_out->lpfnWndProc = window_proc;
61   class_out->cbClsExtra = class_extra;
62   class_out->cbWndExtra = window_extra;
63   // RegisterClassEx uses a handle of the module containing the window procedure
64   // to distinguish identically named classes registered in different modules.
65   class_out->hInstance = GetModuleFromWndProc(window_proc);
66   class_out->hIcon = large_icon;
67   class_out->hCursor = cursor;
68   class_out->hbrBackground = background;
69   class_out->lpszMenuName = menu_name;
70   class_out->lpszClassName = class_name;
71   class_out->hIconSm = small_icon;
72 
73   // Check if |window_proc| is valid.
74   DCHECK(class_out->hInstance != nullptr);
75 }
76 
77 }  // namespace win
78 }  // namespace base
79