| 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 |