OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/buggy_bho_handling.h" | 5 #include "chrome_frame/buggy_bho_handling.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/scoped_comptr_win.h" | 8 #include "base/win/scoped_comptr.h" |
9 | 9 |
10 #include "chrome_frame/exception_barrier.h" | 10 #include "chrome_frame/exception_barrier.h" |
11 #include "chrome_frame/function_stub.h" | 11 #include "chrome_frame/function_stub.h" |
12 #include "chrome_frame/utils.h" | 12 #include "chrome_frame/utils.h" |
13 #include "chrome_frame/vtable_patch_manager.h" | 13 #include "chrome_frame/vtable_patch_manager.h" |
14 | 14 |
15 namespace buggy_bho { | 15 namespace buggy_bho { |
16 | 16 |
17 base::ThreadLocalPointer<BuggyBhoTls> BuggyBhoTls::s_bad_object_tls_; | 17 base::ThreadLocalPointer<BuggyBhoTls> BuggyBhoTls::s_bad_object_tls_; |
18 | 18 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 HRESULT BuggyBhoTls::PatchBuggyBHOs(IWebBrowser2* browser) { | 121 HRESULT BuggyBhoTls::PatchBuggyBHOs(IWebBrowser2* browser) { |
122 if (patched_) | 122 if (patched_) |
123 return S_FALSE; | 123 return S_FALSE; |
124 | 124 |
125 DCHECK(browser); | 125 DCHECK(browser); |
126 DCHECK(web_browser2_ == NULL); | 126 DCHECK(web_browser2_ == NULL); |
127 | 127 |
128 ScopedComPtr<IConnectionPointContainer> cpc; | 128 base::win::ScopedComPtr<IConnectionPointContainer> cpc; |
129 HRESULT hr = cpc.QueryFrom(browser); | 129 HRESULT hr = cpc.QueryFrom(browser); |
130 if (SUCCEEDED(hr)) { | 130 if (SUCCEEDED(hr)) { |
131 const GUID sinks[] = { DIID_DWebBrowserEvents2, DIID_DWebBrowserEvents }; | 131 const GUID sinks[] = { DIID_DWebBrowserEvents2, DIID_DWebBrowserEvents }; |
132 for (size_t i = 0; i < arraysize(sinks); ++i) { | 132 for (size_t i = 0; i < arraysize(sinks); ++i) { |
133 ScopedComPtr<IConnectionPoint> cp; | 133 base::win::ScopedComPtr<IConnectionPoint> cp; |
134 cpc->FindConnectionPoint(sinks[i], cp.Receive()); | 134 cpc->FindConnectionPoint(sinks[i], cp.Receive()); |
135 if (cp) { | 135 if (cp) { |
136 ScopedComPtr<IEnumConnections> connections; | 136 base::win::ScopedComPtr<IEnumConnections> connections; |
137 cp->EnumConnections(connections.Receive()); | 137 cp->EnumConnections(connections.Receive()); |
138 if (connections) { | 138 if (connections) { |
139 CONNECTDATA cd = {0}; | 139 CONNECTDATA cd = {0}; |
140 DWORD fetched = 0; | 140 DWORD fetched = 0; |
141 while (connections->Next(1, &cd, &fetched) == S_OK && fetched) { | 141 while (connections->Next(1, &cd, &fetched) == S_OK && fetched) { |
142 PatchIfBuggy(cd.pUnk, sinks[i]); | 142 PatchIfBuggy(cd.pUnk, sinks[i]); |
143 cd.pUnk->Release(); | 143 cd.pUnk->Release(); |
144 fetched = 0; | 144 fetched = 0; |
145 } | 145 } |
146 } | 146 } |
147 } | 147 } |
148 } | 148 } |
149 } | 149 } |
150 patched_ = true; | 150 patched_ = true; |
151 web_browser2_ = browser; | 151 web_browser2_ = browser; |
152 return hr; | 152 return hr; |
153 } | 153 } |
154 | 154 |
155 bool BuggyBhoTls::PatchIfBuggy(IUnknown* unk, const IID& diid) { | 155 bool BuggyBhoTls::PatchIfBuggy(IUnknown* unk, const IID& diid) { |
156 DCHECK(unk); | 156 DCHECK(unk); |
157 PROC* methods = *reinterpret_cast<PROC**>(unk); | 157 PROC* methods = *reinterpret_cast<PROC**>(unk); |
158 HMODULE mod = GetModuleFromAddress(methods[0]); | 158 HMODULE mod = GetModuleFromAddress(methods[0]); |
159 if (!IsBuggyBho(mod)) | 159 if (!IsBuggyBho(mod)) |
160 return false; | 160 return false; |
161 | 161 |
162 ScopedComPtr<IDispatch> disp; | 162 base::win::ScopedComPtr<IDispatch> disp; |
163 HRESULT hr = unk->QueryInterface(diid, | 163 HRESULT hr = unk->QueryInterface(diid, |
164 reinterpret_cast<void**>(disp.Receive())); | 164 reinterpret_cast<void**>(disp.Receive())); |
165 if (FAILED(hr)) // Sometimes only IDispatch QI is supported | 165 if (FAILED(hr)) // Sometimes only IDispatch QI is supported |
166 hr = disp.QueryFrom(unk); | 166 hr = disp.QueryFrom(unk); |
167 DCHECK(SUCCEEDED(hr)); | 167 DCHECK(SUCCEEDED(hr)); |
168 | 168 |
169 if (SUCCEEDED(hr)) { | 169 if (SUCCEEDED(hr)) { |
170 const int kInvokeIndex = 6; | 170 const int kInvokeIndex = 6; |
171 DCHECK(static_cast<IUnknown*>(disp) == unk); | 171 DCHECK(static_cast<IUnknown*>(disp) == unk); |
172 if (SUCCEEDED(PatchInvokeMethod(&methods[kInvokeIndex]))) { | 172 if (SUCCEEDED(PatchInvokeMethod(&methods[kInvokeIndex]))) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 } else { | 225 } else { |
226 PinModule(); // No backing out now. | 226 PinModule(); // No backing out now. |
227 ::FlushInstructionCache(::GetCurrentProcess(), invoke, sizeof(PROC)); | 227 ::FlushInstructionCache(::GetCurrentProcess(), invoke, sizeof(PROC)); |
228 } | 228 } |
229 } | 229 } |
230 ::VirtualProtect(invoke, sizeof(PROC), flags, &flags); | 230 ::VirtualProtect(invoke, sizeof(PROC), flags, &flags); |
231 return hr; | 231 return hr; |
232 } | 232 } |
233 | 233 |
234 } // end namespace buggy_bho | 234 } // end namespace buggy_bho |
OLD | NEW |