| OLD | NEW |
| 1 // Copyright (c) 2011 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/bho.h" | 5 #include "chrome_frame/bho.h" |
| 6 | 6 |
| 7 #include <shlguid.h> | 7 #include <shlguid.h> |
| 8 | 8 |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 void ReadyModeDelegateImpl::DisableChromeFrame() { | 87 void ReadyModeDelegateImpl::DisableChromeFrame() { |
| 88 HttpNegotiatePatch::set_modify_user_agent(false); | 88 HttpNegotiatePatch::set_modify_user_agent(false); |
| 89 ProtocolSinkWrap::set_ignore_xua(true); | 89 ProtocolSinkWrap::set_ignore_xua(true); |
| 90 } | 90 } |
| 91 | 91 |
| 92 } // namespace | 92 } // namespace |
| 93 | 93 |
| 94 STDMETHODIMP Bho::SetSite(IUnknown* site) { | 94 STDMETHODIMP Bho::SetSite(IUnknown* site) { |
| 95 HRESULT hr = S_OK; | 95 HRESULT hr = S_OK; |
| 96 if (site) { | 96 if (site) { |
| 97 ScopedComPtr<IWebBrowser2> web_browser2; | 97 base::win::ScopedComPtr<IWebBrowser2> web_browser2; |
| 98 web_browser2.QueryFrom(site); | 98 web_browser2.QueryFrom(site); |
| 99 if (web_browser2) { | 99 if (web_browser2) { |
| 100 hr = DispEventAdvise(web_browser2, &DIID_DWebBrowserEvents2); | 100 hr = DispEventAdvise(web_browser2, &DIID_DWebBrowserEvents2); |
| 101 DCHECK(SUCCEEDED(hr)) << "DispEventAdvise failed. Error: " << hr; | 101 DCHECK(SUCCEEDED(hr)) << "DispEventAdvise failed. Error: " << hr; |
| 102 | 102 |
| 103 ready_mode::Configure(new ReadyModeDelegateImpl(), web_browser2); | 103 ready_mode::Configure(new ReadyModeDelegateImpl(), web_browser2); |
| 104 } | 104 } |
| 105 | 105 |
| 106 if (g_patch_helper.state() == PatchHelper::PATCH_IBROWSER) { | 106 if (g_patch_helper.state() == PatchHelper::PATCH_IBROWSER) { |
| 107 ScopedComPtr<IBrowserService> browser_service; | 107 base::win::ScopedComPtr<IBrowserService> browser_service; |
| 108 hr = DoQueryService(SID_SShellBrowser, site, browser_service.Receive()); | 108 hr = DoQueryService(SID_SShellBrowser, site, browser_service.Receive()); |
| 109 DCHECK(browser_service) << "DoQueryService - SID_SShellBrowser failed." | 109 DCHECK(browser_service) << "DoQueryService - SID_SShellBrowser failed." |
| 110 << " Site: " << site << " Error: " << hr; | 110 << " Site: " << site << " Error: " << hr; |
| 111 if (browser_service) { | 111 if (browser_service) { |
| 112 g_patch_helper.PatchBrowserService(browser_service); | 112 g_patch_helper.PatchBrowserService(browser_service); |
| 113 DCHECK(SUCCEEDED(hr)) << "vtable_patch::PatchInterfaceMethods failed." | 113 DCHECK(SUCCEEDED(hr)) << "vtable_patch::PatchInterfaceMethods failed." |
| 114 << " Site: " << site << " Error: " << hr; | 114 << " Site: " << site << " Error: " << hr; |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 // Save away our BHO instance in TLS which enables it to be referenced by | 117 // Save away our BHO instance in TLS which enables it to be referenced by |
| 118 // our active document/activex instances to query referrer and other | 118 // our active document/activex instances to query referrer and other |
| 119 // information for a URL. | 119 // information for a URL. |
| 120 AddRef(); | 120 AddRef(); |
| 121 RegisterThreadInstance(); | 121 RegisterThreadInstance(); |
| 122 MetricsService::Start(); | 122 MetricsService::Start(); |
| 123 | 123 |
| 124 if (!IncreaseWinInetConnections(kMaxHttpConnections)) { | 124 if (!IncreaseWinInetConnections(kMaxHttpConnections)) { |
| 125 DLOG(WARNING) << "Failed to bump up HTTP connections. Error:" | 125 DLOG(WARNING) << "Failed to bump up HTTP connections. Error:" |
| 126 << ::GetLastError(); | 126 << ::GetLastError(); |
| 127 } | 127 } |
| 128 } else { | 128 } else { |
| 129 UnregisterThreadInstance(); | 129 UnregisterThreadInstance(); |
| 130 buggy_bho::BuggyBhoTls::DestroyInstance(); | 130 buggy_bho::BuggyBhoTls::DestroyInstance(); |
| 131 ScopedComPtr<IWebBrowser2> web_browser2; | 131 base::win::ScopedComPtr<IWebBrowser2> web_browser2; |
| 132 web_browser2.QueryFrom(m_spUnkSite); | 132 web_browser2.QueryFrom(m_spUnkSite); |
| 133 DispEventUnadvise(web_browser2, &DIID_DWebBrowserEvents2); | 133 DispEventUnadvise(web_browser2, &DIID_DWebBrowserEvents2); |
| 134 Release(); | 134 Release(); |
| 135 } | 135 } |
| 136 | 136 |
| 137 return IObjectWithSiteImpl<Bho>::SetSite(site); | 137 return IObjectWithSiteImpl<Bho>::SetSite(site); |
| 138 } | 138 } |
| 139 | 139 |
| 140 STDMETHODIMP Bho::BeforeNavigate2(IDispatch* dispatch, VARIANT* url, | 140 STDMETHODIMP Bho::BeforeNavigate2(IDispatch* dispatch, VARIANT* url, |
| 141 VARIANT* flags, VARIANT* target_frame_name, VARIANT* post_data, | 141 VARIANT* flags, VARIANT* target_frame_name, VARIANT* post_data, |
| 142 VARIANT* headers, VARIANT_BOOL* cancel) { | 142 VARIANT* headers, VARIANT_BOOL* cancel) { |
| 143 if (!url || url->vt != VT_BSTR || url->bstrVal == NULL) { | 143 if (!url || url->vt != VT_BSTR || url->bstrVal == NULL) { |
| 144 DLOG(WARNING) << "Invalid URL passed in"; | 144 DLOG(WARNING) << "Invalid URL passed in"; |
| 145 return S_OK; | 145 return S_OK; |
| 146 } | 146 } |
| 147 | 147 |
| 148 ScopedComPtr<IWebBrowser2> web_browser2; | 148 base::win::ScopedComPtr<IWebBrowser2> web_browser2; |
| 149 if (dispatch) | 149 if (dispatch) |
| 150 web_browser2.QueryFrom(dispatch); | 150 web_browser2.QueryFrom(dispatch); |
| 151 | 151 |
| 152 if (!web_browser2) { | 152 if (!web_browser2) { |
| 153 NOTREACHED() << "Can't find WebBrowser2 with given dispatch"; | 153 NOTREACHED() << "Can't find WebBrowser2 with given dispatch"; |
| 154 return S_OK; | 154 return S_OK; |
| 155 } | 155 } |
| 156 | 156 |
| 157 DVLOG(1) << "BeforeNavigate2: " << url->bstrVal; | 157 DVLOG(1) << "BeforeNavigate2: " << url->bstrVal; |
| 158 | 158 |
| 159 ScopedComPtr<IBrowserService> browser_service; | 159 base::win::ScopedComPtr<IBrowserService> browser_service; |
| 160 DoQueryService(SID_SShellBrowser, web_browser2, browser_service.Receive()); | 160 DoQueryService(SID_SShellBrowser, web_browser2, browser_service.Receive()); |
| 161 if (!browser_service || !CheckForCFNavigation(browser_service, false)) { | 161 if (!browser_service || !CheckForCFNavigation(browser_service, false)) { |
| 162 // TODO(tommi): Remove? Isn't this done below by calling set_referrer("")? | 162 // TODO(tommi): Remove? Isn't this done below by calling set_referrer("")? |
| 163 referrer_.clear(); | 163 referrer_.clear(); |
| 164 } | 164 } |
| 165 | 165 |
| 166 VARIANT_BOOL is_top_level = VARIANT_FALSE; | 166 VARIANT_BOOL is_top_level = VARIANT_FALSE; |
| 167 web_browser2->get_TopLevelContainer(&is_top_level); | 167 web_browser2->get_TopLevelContainer(&is_top_level); |
| 168 if (is_top_level) { | 168 if (is_top_level) { |
| 169 set_url(url->bstrVal); | 169 set_url(url->bstrVal); |
| 170 set_referrer(""); | 170 set_referrer(""); |
| 171 set_post_data(post_data); | 171 set_post_data(post_data); |
| 172 set_headers(headers); | 172 set_headers(headers); |
| 173 } | 173 } |
| 174 return S_OK; | 174 return S_OK; |
| 175 } | 175 } |
| 176 | 176 |
| 177 STDMETHODIMP_(void) Bho::NavigateComplete2(IDispatch* dispatch, VARIANT* url) { | 177 STDMETHODIMP_(void) Bho::NavigateComplete2(IDispatch* dispatch, VARIANT* url) { |
| 178 DVLOG(1) << __FUNCTION__; | 178 DVLOG(1) << __FUNCTION__; |
| 179 } | 179 } |
| 180 | 180 |
| 181 STDMETHODIMP_(void) Bho::DocumentComplete(IDispatch* dispatch, VARIANT* url) { | 181 STDMETHODIMP_(void) Bho::DocumentComplete(IDispatch* dispatch, VARIANT* url) { |
| 182 DVLOG(1) << __FUNCTION__; | 182 DVLOG(1) << __FUNCTION__; |
| 183 | 183 |
| 184 ScopedComPtr<IWebBrowser2> web_browser2; | 184 base::win::ScopedComPtr<IWebBrowser2> web_browser2; |
| 185 if (dispatch) | 185 if (dispatch) |
| 186 web_browser2.QueryFrom(dispatch); | 186 web_browser2.QueryFrom(dispatch); |
| 187 | 187 |
| 188 if (web_browser2) { | 188 if (web_browser2) { |
| 189 VARIANT_BOOL is_top_level = VARIANT_FALSE; | 189 VARIANT_BOOL is_top_level = VARIANT_FALSE; |
| 190 web_browser2->get_TopLevelContainer(&is_top_level); | 190 web_browser2->get_TopLevelContainer(&is_top_level); |
| 191 if (is_top_level) { | 191 if (is_top_level) { |
| 192 CrashMetricsReporter::GetInstance()->IncrementMetric( | 192 CrashMetricsReporter::GetInstance()->IncrementMetric( |
| 193 CrashMetricsReporter::NAVIGATION_COUNT); | 193 CrashMetricsReporter::NAVIGATION_COUNT); |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 | 197 |
| 198 namespace { | 198 namespace { |
| 199 | 199 |
| 200 // See comments in Bho::OnHttpEquiv for details. | 200 // See comments in Bho::OnHttpEquiv for details. |
| 201 void ClearDocumentContents(IUnknown* browser) { | 201 void ClearDocumentContents(IUnknown* browser) { |
| 202 ScopedComPtr<IWebBrowser2> web_browser2; | 202 base::win::ScopedComPtr<IWebBrowser2> web_browser2; |
| 203 if (SUCCEEDED(DoQueryService(SID_SWebBrowserApp, browser, | 203 if (SUCCEEDED(DoQueryService(SID_SWebBrowserApp, browser, |
| 204 web_browser2.Receive()))) { | 204 web_browser2.Receive()))) { |
| 205 ScopedComPtr<IDispatch> doc_disp; | 205 base::win::ScopedComPtr<IDispatch> doc_disp; |
| 206 web_browser2->get_Document(doc_disp.Receive()); | 206 web_browser2->get_Document(doc_disp.Receive()); |
| 207 ScopedComPtr<IHTMLDocument2> doc; | 207 base::win::ScopedComPtr<IHTMLDocument2> doc; |
| 208 if (doc_disp && SUCCEEDED(doc.QueryFrom(doc_disp))) { | 208 if (doc_disp && SUCCEEDED(doc.QueryFrom(doc_disp))) { |
| 209 SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 0); | 209 SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 0); |
| 210 doc->write(sa); | 210 doc->write(sa); |
| 211 ::SafeArrayDestroy(sa); | 211 ::SafeArrayDestroy(sa); |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 | 215 |
| 216 // Returns true if the currently loaded document in the browser has | 216 // Returns true if the currently loaded document in the browser has |
| 217 // any embedded items such as a frame or an iframe. | 217 // any embedded items such as a frame or an iframe. |
| 218 bool DocumentHasEmbeddedItems(IUnknown* browser) { | 218 bool DocumentHasEmbeddedItems(IUnknown* browser) { |
| 219 bool has_embedded_items = false; | 219 bool has_embedded_items = false; |
| 220 | 220 |
| 221 ScopedComPtr<IWebBrowser2> web_browser2; | 221 base::win::ScopedComPtr<IWebBrowser2> web_browser2; |
| 222 ScopedComPtr<IDispatch> document; | 222 base::win::ScopedComPtr<IDispatch> document; |
| 223 if (SUCCEEDED(DoQueryService(SID_SWebBrowserApp, browser, | 223 if (SUCCEEDED(DoQueryService(SID_SWebBrowserApp, browser, |
| 224 web_browser2.Receive())) && | 224 web_browser2.Receive())) && |
| 225 SUCCEEDED(web_browser2->get_Document(document.Receive()))) { | 225 SUCCEEDED(web_browser2->get_Document(document.Receive()))) { |
| 226 ScopedComPtr<IOleContainer> container; | 226 base::win::ScopedComPtr<IOleContainer> container; |
| 227 if (SUCCEEDED(container.QueryFrom(document))) { | 227 if (SUCCEEDED(container.QueryFrom(document))) { |
| 228 ScopedComPtr<IEnumUnknown> enumerator; | 228 base::win::ScopedComPtr<IEnumUnknown> enumerator; |
| 229 container->EnumObjects(OLECONTF_EMBEDDINGS, enumerator.Receive()); | 229 container->EnumObjects(OLECONTF_EMBEDDINGS, enumerator.Receive()); |
| 230 if (enumerator) { | 230 if (enumerator) { |
| 231 ScopedComPtr<IUnknown> unk; | 231 base::win::ScopedComPtr<IUnknown> unk; |
| 232 DWORD fetched = 0; | 232 DWORD fetched = 0; |
| 233 while (!has_embedded_items && | 233 while (!has_embedded_items && |
| 234 SUCCEEDED(enumerator->Next(1, unk.Receive(), &fetched)) | 234 SUCCEEDED(enumerator->Next(1, unk.Receive(), &fetched)) |
| 235 && fetched) { | 235 && fetched) { |
| 236 // If a top level document has embedded iframes then the theory is | 236 // If a top level document has embedded iframes then the theory is |
| 237 // that first the top level document finishes loading and then the | 237 // that first the top level document finishes loading and then the |
| 238 // iframes load. We should only treat an embedded element as an | 238 // iframes load. We should only treat an embedded element as an |
| 239 // iframe if it supports the IWebBrowser interface. | 239 // iframe if it supports the IWebBrowser interface. |
| 240 ScopedComPtr<IWebBrowser2> embedded_web_browser2; | 240 base::win::ScopedComPtr<IWebBrowser2> embedded_web_browser2; |
| 241 if (SUCCEEDED(embedded_web_browser2.QueryFrom(unk))) { | 241 if (SUCCEEDED(embedded_web_browser2.QueryFrom(unk))) { |
| 242 // If we initiate a top level navigation then at times MSHTML | 242 // If we initiate a top level navigation then at times MSHTML |
| 243 // creates a temporary IWebBrowser2 interface which basically shows | 243 // creates a temporary IWebBrowser2 interface which basically shows |
| 244 // up as a temporary iframe in the parent document. It is not clear | 244 // up as a temporary iframe in the parent document. It is not clear |
| 245 // as to how we can detect this. I tried the usual stuff like | 245 // as to how we can detect this. I tried the usual stuff like |
| 246 // getting to the parent IHTMLWindow2 interface. They all end up | 246 // getting to the parent IHTMLWindow2 interface. They all end up |
| 247 // pointing to dummy tear off interfaces owned by MSHTML. | 247 // pointing to dummy tear off interfaces owned by MSHTML. |
| 248 // As a temporary workaround, we found that the location url in | 248 // As a temporary workaround, we found that the location url in |
| 249 // this case is about:blank. We now check for the same and don't | 249 // this case is about:blank. We now check for the same and don't |
| 250 // treat it as an iframe. This should be fine in most cases as we | 250 // treat it as an iframe. This should be fine in most cases as we |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 VARIANT_BOOL is_top_level = VARIANT_FALSE; | 333 VARIANT_BOOL is_top_level = VARIANT_FALSE; |
| 334 browser->get_TopLevelContainer(&is_top_level); | 334 browser->get_TopLevelContainer(&is_top_level); |
| 335 DCHECK(is_top_level); | 335 DCHECK(is_top_level); |
| 336 #endif | 336 #endif |
| 337 | 337 |
| 338 std::wstring current_url(url, SysStringLen(url)); | 338 std::wstring current_url(url, SysStringLen(url)); |
| 339 if (IsValidUrlScheme(GURL(current_url), false)) { | 339 if (IsValidUrlScheme(GURL(current_url), false)) { |
| 340 bool cf_protocol = StartsWith(current_url, kChromeProtocolPrefix, false); | 340 bool cf_protocol = StartsWith(current_url, kChromeProtocolPrefix, false); |
| 341 if (!cf_protocol && IsChrome(RendererTypeForUrl(current_url))) { | 341 if (!cf_protocol && IsChrome(RendererTypeForUrl(current_url))) { |
| 342 DVLOG(1) << "Opt-in URL. Switching to cf."; | 342 DVLOG(1) << "Opt-in URL. Switching to cf."; |
| 343 ScopedComPtr<IBrowserService> browser_service; | 343 base::win::ScopedComPtr<IBrowserService> browser_service; |
| 344 DoQueryService(SID_SShellBrowser, browser, browser_service.Receive()); | 344 DoQueryService(SID_SShellBrowser, browser, browser_service.Receive()); |
| 345 DCHECK(browser_service) << "DoQueryService - SID_SShellBrowser failed."; | 345 DCHECK(browser_service) << "DoQueryService - SID_SShellBrowser failed."; |
| 346 MarkBrowserOnThreadForCFNavigation(browser_service); | 346 MarkBrowserOnThreadForCFNavigation(browser_service); |
| 347 } | 347 } |
| 348 } | 348 } |
| 349 } | 349 } |
| 350 | 350 |
| 351 bool PatchHelper::InitializeAndPatchProtocolsIfNeeded() { | 351 bool PatchHelper::InitializeAndPatchProtocolsIfNeeded() { |
| 352 bool ret = false; | 352 bool ret = false; |
| 353 | 353 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 373 } | 373 } |
| 374 } | 374 } |
| 375 | 375 |
| 376 void PatchHelper::UnpatchIfNeeded() { | 376 void PatchHelper::UnpatchIfNeeded() { |
| 377 if (state_ == PATCH_PROTOCOL) { | 377 if (state_ == PATCH_PROTOCOL) { |
| 378 g_trans_hooks.RevertHooks(); | 378 g_trans_hooks.RevertHooks(); |
| 379 HttpNegotiatePatch::Uninitialize(); | 379 HttpNegotiatePatch::Uninitialize(); |
| 380 } | 380 } |
| 381 state_ = UNKNOWN; | 381 state_ = UNKNOWN; |
| 382 } | 382 } |
| OLD | NEW |