OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/bho.h" | 5 #include "chrome_frame/bho.h" |
6 | 6 |
7 #include <shlguid.h> | 7 #include <shlguid.h> |
8 #include <shobjidl.h> | 8 #include <shobjidl.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/registry.h" | 11 #include "base/registry.h" |
12 #include "base/scoped_bstr_win.h" | 12 #include "base/scoped_bstr_win.h" |
13 #include "base/scoped_comptr_win.h" | 13 #include "base/scoped_comptr_win.h" |
14 #include "base/scoped_variant_win.h" | 14 #include "base/scoped_variant_win.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "chrome_tab.h" // NOLINT | 16 #include "chrome_tab.h" // NOLINT |
17 #include "chrome_frame/protocol_sink_wrap.h" | 17 #include "chrome_frame/protocol_sink_wrap.h" |
18 #include "chrome_frame/utils.h" | 18 #include "chrome_frame/utils.h" |
19 #include "chrome_frame/vtable_patch_manager.h" | 19 #include "chrome_frame/vtable_patch_manager.h" |
| 20 #include "net/http/http_util.h" |
20 | 21 |
21 const wchar_t kPatchProtocols[] = L"PatchProtocols"; | 22 const wchar_t kPatchProtocols[] = L"PatchProtocols"; |
22 static const int kIBrowserServiceOnHttpEquivIndex = 30; | 23 static const int kIBrowserServiceOnHttpEquivIndex = 30; |
23 | 24 |
| 25 base::LazyInstance<base::ThreadLocalPointer<Bho> > |
| 26 Bho::bho_current_thread_instance_(base::LINKER_INITIALIZED); |
| 27 |
24 PatchHelper g_patch_helper; | 28 PatchHelper g_patch_helper; |
25 | 29 |
26 BEGIN_VTABLE_PATCHES(IBrowserService) | 30 BEGIN_VTABLE_PATCHES(IBrowserService) |
27 VTABLE_PATCH_ENTRY(kIBrowserServiceOnHttpEquivIndex, Bho::OnHttpEquiv) | 31 VTABLE_PATCH_ENTRY(kIBrowserServiceOnHttpEquivIndex, Bho::OnHttpEquiv) |
28 END_VTABLE_PATCHES() | 32 END_VTABLE_PATCHES() |
29 | 33 |
30 _ATL_FUNC_INFO Bho::kBeforeNavigate2Info = { | 34 _ATL_FUNC_INFO Bho::kBeforeNavigate2Info = { |
31 CC_STDCALL, VT_EMPTY, 7, { | 35 CC_STDCALL, VT_EMPTY, 7, { |
32 VT_DISPATCH, | 36 VT_DISPATCH, |
33 VT_VARIANT | VT_BYREF, | 37 VT_VARIANT | VT_BYREF, |
(...skipping 22 matching lines...) Expand all Loading... |
56 ScopedComPtr<IBrowserService> browser_service; | 60 ScopedComPtr<IBrowserService> browser_service; |
57 hr = DoQueryService(SID_SShellBrowser, site, browser_service.Receive()); | 61 hr = DoQueryService(SID_SShellBrowser, site, browser_service.Receive()); |
58 DCHECK(browser_service) << "DoQueryService - SID_SShellBrowser failed." | 62 DCHECK(browser_service) << "DoQueryService - SID_SShellBrowser failed." |
59 << " Site: " << site << " Error: " << hr; | 63 << " Site: " << site << " Error: " << hr; |
60 if (browser_service) { | 64 if (browser_service) { |
61 g_patch_helper.PatchBrowserService(browser_service); | 65 g_patch_helper.PatchBrowserService(browser_service); |
62 DCHECK(SUCCEEDED(hr)) << "vtable_patch::PatchInterfaceMethods failed." | 66 DCHECK(SUCCEEDED(hr)) << "vtable_patch::PatchInterfaceMethods failed." |
63 << " Site: " << site << " Error: " << hr; | 67 << " Site: " << site << " Error: " << hr; |
64 } | 68 } |
65 } | 69 } |
| 70 // Save away our BHO instance in TLS which enables it to be referenced by |
| 71 // our active document/activex instances to query referrer and other |
| 72 // information for a URL. |
| 73 AddRef(); |
| 74 bho_current_thread_instance_.Pointer()->Set(this); |
| 75 } else { |
| 76 bho_current_thread_instance_.Pointer()->Set(NULL); |
| 77 Release(); |
66 } | 78 } |
67 | 79 |
68 return IObjectWithSiteImpl<Bho>::SetSite(site); | 80 return IObjectWithSiteImpl<Bho>::SetSite(site); |
69 } | 81 } |
70 | 82 |
71 STDMETHODIMP Bho::BeforeNavigate2(IDispatch* dispatch, VARIANT* url, | 83 STDMETHODIMP Bho::BeforeNavigate2(IDispatch* dispatch, VARIANT* url, |
72 VARIANT* flags, VARIANT* target_frame_name, VARIANT* post_data, | 84 VARIANT* flags, VARIANT* target_frame_name, VARIANT* post_data, |
73 VARIANT* headers, VARIANT_BOOL* cancel) { | 85 VARIANT* headers, VARIANT_BOOL* cancel) { |
74 ScopedComPtr<IWebBrowser2> web_browser2; | 86 ScopedComPtr<IWebBrowser2> web_browser2; |
75 if (dispatch) | 87 if (dispatch) |
(...skipping 29 matching lines...) Expand all Loading... |
105 target_frame_name, post_data, | 117 target_frame_name, post_data, |
106 headers); | 118 headers); |
107 DCHECK(SUCCEEDED(hr)) << "web_browser2->Navigate2 failed. Error: " << hr | 119 DCHECK(SUCCEEDED(hr)) << "web_browser2->Navigate2 failed. Error: " << hr |
108 << std::endl << "Url: " << current_url | 120 << std::endl << "Url: " << current_url |
109 << std::endl << "flags: " << flags | 121 << std::endl << "flags: " << flags |
110 << std::endl << "post data: " << post_data | 122 << std::endl << "post data: " << post_data |
111 << std::endl << "headers: " << headers; | 123 << std::endl << "headers: " << headers; |
112 } | 124 } |
113 } | 125 } |
114 } | 126 } |
| 127 |
| 128 referrer_.clear(); |
| 129 |
| 130 // Save away the referrer in case our active document needs it to initiate |
| 131 // navigation in chrome. |
| 132 if (headers && V_VT(headers) == VT_BSTR && headers->bstrVal != NULL) { |
| 133 std::string raw_headers_utf8 = WideToUTF8(headers->bstrVal); |
| 134 std::string http_headers = |
| 135 net::HttpUtil::AssembleRawHeaders(raw_headers_utf8.c_str(), |
| 136 raw_headers_utf8.length()); |
| 137 net::HttpUtil::HeadersIterator it(http_headers.begin(), http_headers.end(), |
| 138 "\r\n"); |
| 139 while (it.GetNext()) { |
| 140 if (LowerCaseEqualsASCII(it.name(), "referer")) { |
| 141 referrer_ = it.values(); |
| 142 break; |
| 143 } |
| 144 } |
| 145 } |
115 return S_OK; | 146 return S_OK; |
116 } | 147 } |
117 | 148 |
118 HRESULT Bho::FinalConstruct() { | 149 HRESULT Bho::FinalConstruct() { |
119 return S_OK; | 150 return S_OK; |
120 } | 151 } |
121 | 152 |
122 void Bho::FinalRelease() { | 153 void Bho::FinalRelease() { |
123 } | 154 } |
124 | 155 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 ScopedVariant url_var(url.c_str()); | 234 ScopedVariant url_var(url.c_str()); |
204 hr = web_browser2->Navigate2(url_var.AsInput(), &flags, &empty, &empty, | 235 hr = web_browser2->Navigate2(url_var.AsInput(), &flags, &empty, &empty, |
205 &empty); | 236 &empty); |
206 DCHECK(SUCCEEDED(hr)) << "web_browser2->Navigate2 failed. Error: " << hr | 237 DCHECK(SUCCEEDED(hr)) << "web_browser2->Navigate2 failed. Error: " << hr |
207 << std::endl << "Url: " << url; | 238 << std::endl << "Url: " << url; |
208 } | 239 } |
209 | 240 |
210 return S_OK; | 241 return S_OK; |
211 } | 242 } |
212 | 243 |
| 244 Bho* Bho::GetCurrentThreadBhoInstance() { |
| 245 DCHECK(bho_current_thread_instance_.Pointer()->Get() != NULL); |
| 246 return bho_current_thread_instance_.Pointer()->Get(); |
| 247 } |
| 248 |
213 void PatchHelper::InitializeAndPatchProtocolsIfNeeded() { | 249 void PatchHelper::InitializeAndPatchProtocolsIfNeeded() { |
214 if (state_ != UNKNOWN) | 250 if (state_ != UNKNOWN) |
215 return; | 251 return; |
216 | 252 |
217 bool patch_protocol = GetConfigBool(true, kPatchProtocols); | 253 bool patch_protocol = GetConfigBool(true, kPatchProtocols); |
218 if (patch_protocol) { | 254 if (patch_protocol) { |
219 ProtocolSinkWrap::PatchProtocolHandlers(); | 255 ProtocolSinkWrap::PatchProtocolHandlers(); |
220 state_ = PATCH_PROTOCOL; | 256 state_ = PATCH_PROTOCOL; |
221 } else { | 257 } else { |
222 state_ = PATCH_IBROWSER; | 258 state_ = PATCH_IBROWSER; |
(...skipping 10 matching lines...) Expand all Loading... |
233 void PatchHelper::UnpatchIfNeeded() { | 269 void PatchHelper::UnpatchIfNeeded() { |
234 if (state_ == PATCH_PROTOCOL) { | 270 if (state_ == PATCH_PROTOCOL) { |
235 ProtocolSinkWrap::UnpatchProtocolHandlers(); | 271 ProtocolSinkWrap::UnpatchProtocolHandlers(); |
236 } else if (state_ == PATCH_IBROWSER_OK) { | 272 } else if (state_ == PATCH_IBROWSER_OK) { |
237 vtable_patch::UnpatchInterfaceMethods(IBrowserService_PatchInfo); | 273 vtable_patch::UnpatchInterfaceMethods(IBrowserService_PatchInfo); |
238 } | 274 } |
239 | 275 |
240 state_ = UNKNOWN; | 276 state_ = UNKNOWN; |
241 } | 277 } |
242 | 278 |
OLD | NEW |