Index: chrome_frame/urlmon_moniker.cc |
diff --git a/chrome_frame/urlmon_moniker.cc b/chrome_frame/urlmon_moniker.cc |
deleted file mode 100644 |
index 0bf3469cdafb78fa87d38bffeb8d5aa2c07cc75f..0000000000000000000000000000000000000000 |
--- a/chrome_frame/urlmon_moniker.cc |
+++ /dev/null |
@@ -1,263 +0,0 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome_frame/urlmon_moniker.h" |
- |
-#include <exdisp.h> |
-#include <shlguid.h> |
- |
-#include "base/strings/string_util.h" |
-#include "base/strings/stringprintf.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "chrome_frame/bho.h" |
-#include "chrome_frame/bind_context_info.h" |
-#include "chrome_frame/chrome_active_document.h" |
-#include "chrome_frame/exception_barrier.h" |
-#include "chrome_frame/urlmon_bind_status_callback.h" |
-#include "chrome_frame/utils.h" |
-#include "chrome_frame/vtable_patch_manager.h" |
-#include "net/http/http_util.h" |
- |
-static const int kMonikerBindToObject = 8; |
-static const int kMonikerBindToStorage = kMonikerBindToObject + 1; |
- |
-base::LazyInstance<base::ThreadLocalPointer<NavigationManager> > |
- NavigationManager::thread_singleton_ = LAZY_INSTANCE_INITIALIZER; |
- |
-BEGIN_VTABLE_PATCHES(IMoniker) |
- VTABLE_PATCH_ENTRY(kMonikerBindToObject, MonikerPatch::BindToObject) |
- VTABLE_PATCH_ENTRY(kMonikerBindToStorage, MonikerPatch::BindToStorage) |
-END_VTABLE_PATCHES() |
- |
-//////////////////////////// |
- |
-HRESULT NavigationManager::NavigateToCurrentUrlInCF(IBrowserService* browser) { |
- DCHECK(browser); |
- DVLOG(1) << __FUNCTION__ << " " << url(); |
- |
- MarkBrowserOnThreadForCFNavigation(browser); |
- |
- HRESULT hr = S_OK; |
- base::win::ScopedComPtr<IShellBrowser> shell_browser; |
- base::win::ScopedComPtr<IBindCtx> bind_context; |
- hr = ::CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, bind_context.Receive(), 0); |
- |
- base::win::ScopedComPtr<IMoniker> moniker; |
- DCHECK(bind_context); |
- if (SUCCEEDED(hr) && |
- SUCCEEDED(hr = ::CreateURLMonikerEx(NULL, url_.c_str(), moniker.Receive(), |
- URL_MK_UNIFORM))) { |
- if (SUCCEEDED(hr)) { |
- // If there's a referrer, preserve it. |
- std::wstring headers; |
- if (!referrer_.empty()) { |
- headers = base::StringPrintf(L"Referer: %ls\r\n\r\n", |
- base::ASCIIToWide(referrer_).c_str()); |
- } |
- |
- // Pass in URL fragments if applicable. |
- std::wstring fragment; |
- GURL parsed_moniker_url(url_); |
- if (parsed_moniker_url.has_ref()) { |
- fragment = base::UTF8ToWide(parsed_moniker_url.ref()); |
- } |
- |
- VARIANT flags = { VT_I4 }; |
- V_VT(&flags) = navNoHistory | navOpenInNewWindow; |
- |
- hr = NavigateBrowserToMoniker(browser, moniker, headers.c_str(), |
- bind_context, fragment.c_str(), NULL, &flags); |
- DVLOG(1) << base::StringPrintf("NavigateBrowserToMoniker: 0x%08X", hr); |
- } |
- } |
- |
- return hr; |
-} |
- |
-bool NavigationManager::IsTopLevelUrl(const wchar_t* url) { |
- return CompareUrlsWithoutFragment(url_.c_str(), url); |
-} |
- |
-///////////////////////////////////////// |
- |
-NavigationManager* NavigationManager::GetThreadInstance() { |
- return thread_singleton_.Pointer()->Get(); |
-} |
- |
-void NavigationManager::RegisterThreadInstance() { |
- DCHECK(GetThreadInstance() == NULL); |
- thread_singleton_.Pointer()->Set(this); |
-} |
- |
-void NavigationManager::UnregisterThreadInstance() { |
- DCHECK(GetThreadInstance() == this); |
- thread_singleton_.Pointer()->Set(NULL); |
-} |
- |
-///////////////////////////////////////// |
- |
-// static |
-bool MonikerPatch::Initialize() { |
- if (IS_PATCHED(IMoniker)) { |
- DLOG(WARNING) << __FUNCTION__ << " called more than once."; |
- return true; |
- } |
- |
- base::win::ScopedComPtr<IMoniker> moniker; |
- HRESULT hr = ::CreateURLMoniker(NULL, L"http://localhost/", |
- moniker.Receive()); |
- DCHECK(SUCCEEDED(hr)); |
- if (SUCCEEDED(hr)) { |
- hr = vtable_patch::PatchInterfaceMethods(moniker, IMoniker_PatchInfo); |
- DLOG_IF(ERROR, FAILED(hr)) << base::StringPrintf( |
- "patch failed 0x%08X", hr); |
- } |
- |
- return SUCCEEDED(hr); |
-} |
- |
-// static |
-void MonikerPatch::Uninitialize() { |
- vtable_patch::UnpatchInterfaceMethods(IMoniker_PatchInfo); |
-} |
- |
-bool ShouldWrapCallback(IMoniker* moniker, REFIID iid, IBindCtx* bind_context) { |
- CComHeapPtr<WCHAR> url; |
- HRESULT hr = moniker->GetDisplayName(bind_context, NULL, &url); |
- if (!url) { |
- DVLOG(1) << __FUNCTION__ |
- << base::StringPrintf(" GetDisplayName failed. Error: 0x%x", hr); |
- return false; |
- } |
- |
- if (!IsEqualIID(IID_IStream, iid)) { |
- DVLOG(1) << __FUNCTION__ << " Url: " << url |
- << " Not wrapping: IID is not IStream."; |
- return false; |
- } |
- |
- base::win::ScopedComPtr<BindContextInfo> info; |
- BindContextInfo::FromBindContext(bind_context, info.Receive()); |
- DCHECK(info); |
- if (info && info->chrome_request()) { |
- DVLOG(1) << __FUNCTION__ << " Url: " << url |
- << " Not wrapping: request from chrome frame."; |
- return false; |
- } |
- |
- NavigationManager* mgr = NavigationManager::GetThreadInstance(); |
- if (!mgr) { |
- DVLOG(1) << __FUNCTION__ << " Url: " << url |
- << " No navigation manager to wrap"; |
- return false; |
- } |
- |
- // Check whether request comes from MSHTML by checking for IInternetBindInfo. |
- // We prefer to avoid wrapping if BindToStorage is called from AcroPDF.dll |
- // (as a result of OnObjectAvailable) |
- base::win::ScopedComPtr<IUnknown> bscb_holder; |
- if (S_OK == bind_context->GetObjectParam(L"_BSCB_Holder_", |
- bscb_holder.Receive())) { |
- base::win::ScopedComPtr<IBindStatusCallback> bscb; |
- if (S_OK != DoQueryService(IID_IBindStatusCallback, bscb_holder, |
- bscb.Receive())) |
- return false; |
- |
- if (!bscb.get()) |
- return false; |
- |
- base::win::ScopedComPtr<IInternetBindInfo> bind_info; |
- if (S_OK != bind_info.QueryFrom(bscb)) |
- return false; |
- } |
- |
- // TODO(ananta) |
- // Use the IsSubFrameRequest function to determine if a request is a top |
- // level request. Something like this. |
- // base::win::ScopedComPtr<IUnknown> bscb_holder; |
- // bind_context->GetObjectParam(L"_BSCB_Holder_", bscb_holder.Receive()); |
- // if (bscb_holder) { |
- // base::win::ScopedComPtr<IHttpNegotiate> http_negotiate; |
- // http_negotiate.QueryFrom(bscb_holder); |
- // if (http_negotiate && !IsSubFrameRequest(http_negotiate)) |
- // return true; |
- // } |
- // There are some cases where the IsSubFrameRequest function can return |
- // incorrect results. |
- bool should_wrap = mgr->IsTopLevelUrl(url); |
- if (!should_wrap) { |
- DVLOG(1) << __FUNCTION__ << " Url: " << url |
- << " Not wrapping: Not top level url."; |
- } |
- return should_wrap; |
-} |
- |
-// static |
-HRESULT MonikerPatch::BindToObject(IMoniker_BindToObject_Fn original, |
- IMoniker* me, IBindCtx* bind_ctx, |
- IMoniker* to_left, REFIID iid, void** obj) { |
- DVLOG(1) << __FUNCTION__; |
- DCHECK(to_left == NULL); |
- |
- ExceptionBarrierReportOnlyModule barrier; |
- |
- HRESULT hr = S_OK; |
- // Bind context is marked for switch when we sniff data in BSCBStorageBind |
- // and determine that the renderer to be used is Chrome. |
- base::win::ScopedComPtr<BindContextInfo> info; |
- BindContextInfo::FromBindContext(bind_ctx, info.Receive()); |
- DCHECK(info); |
- if (info) { |
- if (info->is_switching()) { |
- // We could implement the BindToObject ourselves here but instead we |
- // simply register Chrome Frame ActiveDoc as a handler for 'text/html' |
- // in this bind context. This makes urlmon instantiate CF Active doc |
- // instead of mshtml. |
- const char* media_types[] = { "text/html" }; |
- CLSID classes[] = { CLSID_ChromeActiveDocument }; |
- hr = RegisterMediaTypeClass(bind_ctx, arraysize(media_types), media_types, |
- classes, 0); |
- } else { |
- // In case the binding begins with BindToObject we do not need |
- // to cache the data in the sniffing code. |
- info->set_no_cache(true); |
- } |
- } |
- |
- hr = original(me, bind_ctx, to_left, iid, obj); |
- return hr; |
-} |
- |
-// static |
-HRESULT MonikerPatch::BindToStorage(IMoniker_BindToStorage_Fn original, |
- IMoniker* me, IBindCtx* bind_ctx, |
- IMoniker* to_left, REFIID iid, void** obj) { |
- DCHECK(to_left == NULL); |
- |
- // Report a crash if the crash is in our own module. |
- ExceptionBarrierReportOnlyModule barrier; |
- |
- HRESULT hr = S_OK; |
- scoped_refptr<BSCBStorageBind> auto_release_callback; |
- CComObject<BSCBStorageBind>* callback = NULL; |
- if (ShouldWrapCallback(me, iid, bind_ctx)) { |
- hr = CComObject<BSCBStorageBind>::CreateInstance(&callback); |
- DCHECK(SUCCEEDED(hr)); |
- auto_release_callback = callback; |
- DCHECK_EQ(callback->m_dwRef, 1); |
- hr = callback->Initialize(me, bind_ctx); |
- DCHECK(SUCCEEDED(hr)); |
- } |
- |
- hr = original(me, bind_ctx, to_left, iid, obj); |
- |
- // If the binding terminates before the data could be played back |
- // now is the chance. Sometimes OnStopBinding happens after this returns |
- // and then it's too late. |
- if ((S_OK == hr) && callback) |
- callback->MayPlayBack(BSCF_LASTDATANOTIFICATION); |
- |
- return hr; |
-} |
- |