| 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/urlmon_moniker.h" | 5 #include "chrome_frame/urlmon_moniker.h" |
| 6 | 6 |
| 7 #include <shlguid.h> | 7 #include <shlguid.h> |
| 8 | 8 |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 12 #include "chrome_frame/bho.h" | 12 #include "chrome_frame/bho.h" |
| 13 #include "chrome_frame/bind_context_info.h" | 13 #include "chrome_frame/bind_context_info.h" |
| 14 #include "chrome_frame/chrome_active_document.h" |
| 14 #include "chrome_frame/exception_barrier.h" | 15 #include "chrome_frame/exception_barrier.h" |
| 15 #include "chrome_frame/chrome_active_document.h" | |
| 16 #include "chrome_frame/urlmon_bind_status_callback.h" | 16 #include "chrome_frame/urlmon_bind_status_callback.h" |
| 17 #include "chrome_frame/utils.h" | 17 #include "chrome_frame/utils.h" |
| 18 #include "chrome_frame/vtable_patch_manager.h" | 18 #include "chrome_frame/vtable_patch_manager.h" |
| 19 #include "net/http/http_util.h" | 19 #include "net/http/http_util.h" |
| 20 | 20 |
| 21 static const int kMonikerBindToObject = 8; | 21 static const int kMonikerBindToObject = 8; |
| 22 static const int kMonikerBindToStorage = kMonikerBindToObject + 1; | 22 static const int kMonikerBindToStorage = kMonikerBindToObject + 1; |
| 23 | 23 |
| 24 base::LazyInstance<base::ThreadLocalPointer<NavigationManager> > | 24 base::LazyInstance<base::ThreadLocalPointer<NavigationManager> > |
| 25 NavigationManager::thread_singleton_(base::LINKER_INITIALIZED); | 25 NavigationManager::thread_singleton_(base::LINKER_INITIALIZED); |
| 26 | 26 |
| 27 BEGIN_VTABLE_PATCHES(IMoniker) | 27 BEGIN_VTABLE_PATCHES(IMoniker) |
| 28 VTABLE_PATCH_ENTRY(kMonikerBindToObject, MonikerPatch::BindToObject) | 28 VTABLE_PATCH_ENTRY(kMonikerBindToObject, MonikerPatch::BindToObject) |
| 29 VTABLE_PATCH_ENTRY(kMonikerBindToStorage, MonikerPatch::BindToStorage) | 29 VTABLE_PATCH_ENTRY(kMonikerBindToStorage, MonikerPatch::BindToStorage) |
| 30 END_VTABLE_PATCHES() | 30 END_VTABLE_PATCHES() |
| 31 | 31 |
| 32 //////////////////////////// | 32 //////////////////////////// |
| 33 | 33 |
| 34 HRESULT NavigationManager::NavigateToCurrentUrlInCF(IBrowserService* browser) { | 34 HRESULT NavigationManager::NavigateToCurrentUrlInCF(IBrowserService* browser) { |
| 35 DCHECK(browser); | 35 DCHECK(browser); |
| 36 DVLOG(1) << __FUNCTION__ << " " << url(); | 36 DVLOG(1) << __FUNCTION__ << " " << url(); |
| 37 | 37 |
| 38 MarkBrowserOnThreadForCFNavigation(browser); | 38 MarkBrowserOnThreadForCFNavigation(browser); |
| 39 | 39 |
| 40 HRESULT hr = S_OK; | 40 HRESULT hr = S_OK; |
| 41 ScopedComPtr<IShellBrowser> shell_browser; | 41 base::win::ScopedComPtr<IShellBrowser> shell_browser; |
| 42 ScopedComPtr<IBindCtx> bind_context; | 42 base::win::ScopedComPtr<IBindCtx> bind_context; |
| 43 hr = ::CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, bind_context.Receive(), 0); | 43 hr = ::CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, bind_context.Receive(), 0); |
| 44 | 44 |
| 45 ScopedComPtr<IMoniker> moniker; | 45 base::win::ScopedComPtr<IMoniker> moniker; |
| 46 DCHECK(bind_context); | 46 DCHECK(bind_context); |
| 47 if (SUCCEEDED(hr) && | 47 if (SUCCEEDED(hr) && |
| 48 SUCCEEDED(hr = ::CreateURLMonikerEx(NULL, url_.c_str(), moniker.Receive(), | 48 SUCCEEDED(hr = ::CreateURLMonikerEx(NULL, url_.c_str(), moniker.Receive(), |
| 49 URL_MK_UNIFORM))) { | 49 URL_MK_UNIFORM))) { |
| 50 if (SUCCEEDED(hr)) { | 50 if (SUCCEEDED(hr)) { |
| 51 // If there's a referrer, preserve it. | 51 // If there's a referrer, preserve it. |
| 52 std::wstring headers; | 52 std::wstring headers; |
| 53 if (!referrer_.empty()) { | 53 if (!referrer_.empty()) { |
| 54 headers = base::StringPrintf(L"Referer: %ls\r\n\r\n", | 54 headers = base::StringPrintf(L"Referer: %ls\r\n\r\n", |
| 55 ASCIIToWide(referrer_).c_str()); | 55 ASCIIToWide(referrer_).c_str()); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 | 93 |
| 94 ///////////////////////////////////////// | 94 ///////////////////////////////////////// |
| 95 | 95 |
| 96 // static | 96 // static |
| 97 bool MonikerPatch::Initialize() { | 97 bool MonikerPatch::Initialize() { |
| 98 if (IS_PATCHED(IMoniker)) { | 98 if (IS_PATCHED(IMoniker)) { |
| 99 DLOG(WARNING) << __FUNCTION__ << " called more than once."; | 99 DLOG(WARNING) << __FUNCTION__ << " called more than once."; |
| 100 return true; | 100 return true; |
| 101 } | 101 } |
| 102 | 102 |
| 103 ScopedComPtr<IMoniker> moniker; | 103 base::win::ScopedComPtr<IMoniker> moniker; |
| 104 HRESULT hr = ::CreateURLMoniker(NULL, L"http://localhost/", | 104 HRESULT hr = ::CreateURLMoniker(NULL, L"http://localhost/", |
| 105 moniker.Receive()); | 105 moniker.Receive()); |
| 106 DCHECK(SUCCEEDED(hr)); | 106 DCHECK(SUCCEEDED(hr)); |
| 107 if (SUCCEEDED(hr)) { | 107 if (SUCCEEDED(hr)) { |
| 108 hr = vtable_patch::PatchInterfaceMethods(moniker, IMoniker_PatchInfo); | 108 hr = vtable_patch::PatchInterfaceMethods(moniker, IMoniker_PatchInfo); |
| 109 DLOG_IF(ERROR, FAILED(hr)) << base::StringPrintf( | 109 DLOG_IF(ERROR, FAILED(hr)) << base::StringPrintf( |
| 110 "patch failed 0x%08X", hr); | 110 "patch failed 0x%08X", hr); |
| 111 } | 111 } |
| 112 | 112 |
| 113 return SUCCEEDED(hr); | 113 return SUCCEEDED(hr); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 126 << base::StringPrintf(" GetDisplayName failed. Error: 0x%x", hr); | 126 << base::StringPrintf(" GetDisplayName failed. Error: 0x%x", hr); |
| 127 return false; | 127 return false; |
| 128 } | 128 } |
| 129 | 129 |
| 130 if (!IsEqualIID(IID_IStream, iid)) { | 130 if (!IsEqualIID(IID_IStream, iid)) { |
| 131 DVLOG(1) << __FUNCTION__ << " Url: " << url | 131 DVLOG(1) << __FUNCTION__ << " Url: " << url |
| 132 << " Not wrapping: IID is not IStream."; | 132 << " Not wrapping: IID is not IStream."; |
| 133 return false; | 133 return false; |
| 134 } | 134 } |
| 135 | 135 |
| 136 ScopedComPtr<BindContextInfo> info; | 136 base::win::ScopedComPtr<BindContextInfo> info; |
| 137 BindContextInfo::FromBindContext(bind_context, info.Receive()); | 137 BindContextInfo::FromBindContext(bind_context, info.Receive()); |
| 138 DCHECK(info); | 138 DCHECK(info); |
| 139 if (info && info->chrome_request()) { | 139 if (info && info->chrome_request()) { |
| 140 DVLOG(1) << __FUNCTION__ << " Url: " << url | 140 DVLOG(1) << __FUNCTION__ << " Url: " << url |
| 141 << " Not wrapping: request from chrome frame."; | 141 << " Not wrapping: request from chrome frame."; |
| 142 return false; | 142 return false; |
| 143 } | 143 } |
| 144 | 144 |
| 145 NavigationManager* mgr = NavigationManager::GetThreadInstance(); | 145 NavigationManager* mgr = NavigationManager::GetThreadInstance(); |
| 146 if (!mgr) { | 146 if (!mgr) { |
| 147 DVLOG(1) << __FUNCTION__ << " Url: " << url | 147 DVLOG(1) << __FUNCTION__ << " Url: " << url |
| 148 << " No navigation manager to wrap"; | 148 << " No navigation manager to wrap"; |
| 149 return false; | 149 return false; |
| 150 } | 150 } |
| 151 | 151 |
| 152 // Check whether request comes from MSHTML by checking for IInternetBindInfo. | 152 // Check whether request comes from MSHTML by checking for IInternetBindInfo. |
| 153 // We prefer to avoid wrapping if BindToStorage is called from AcroPDF.dll | 153 // We prefer to avoid wrapping if BindToStorage is called from AcroPDF.dll |
| 154 // (as a result of OnObjectAvailable) | 154 // (as a result of OnObjectAvailable) |
| 155 ScopedComPtr<IUnknown> bscb_holder; | 155 base::win::ScopedComPtr<IUnknown> bscb_holder; |
| 156 if (S_OK == bind_context->GetObjectParam(L"_BSCB_Holder_", | 156 if (S_OK == bind_context->GetObjectParam(L"_BSCB_Holder_", |
| 157 bscb_holder.Receive())) { | 157 bscb_holder.Receive())) { |
| 158 ScopedComPtr<IBindStatusCallback> bscb; | 158 base::win::ScopedComPtr<IBindStatusCallback> bscb; |
| 159 if (S_OK != DoQueryService(IID_IBindStatusCallback, bscb_holder, | 159 if (S_OK != DoQueryService(IID_IBindStatusCallback, bscb_holder, |
| 160 bscb.Receive())) | 160 bscb.Receive())) |
| 161 return false; | 161 return false; |
| 162 | 162 |
| 163 if (!bscb.get()) | 163 if (!bscb.get()) |
| 164 return false; | 164 return false; |
| 165 | 165 |
| 166 ScopedComPtr<IInternetBindInfo> bind_info; | 166 base::win::ScopedComPtr<IInternetBindInfo> bind_info; |
| 167 if (S_OK != bind_info.QueryFrom(bscb)) | 167 if (S_OK != bind_info.QueryFrom(bscb)) |
| 168 return false; | 168 return false; |
| 169 } | 169 } |
| 170 | 170 |
| 171 // TODO(ananta) | 171 // TODO(ananta) |
| 172 // Use the IsSubFrameRequest function to determine if a request is a top | 172 // Use the IsSubFrameRequest function to determine if a request is a top |
| 173 // level request. Something like this. | 173 // level request. Something like this. |
| 174 // ScopedComPtr<IUnknown> bscb_holder; | 174 // base::win::ScopedComPtr<IUnknown> bscb_holder; |
| 175 // bind_context->GetObjectParam(L"_BSCB_Holder_", bscb_holder.Receive()); | 175 // bind_context->GetObjectParam(L"_BSCB_Holder_", bscb_holder.Receive()); |
| 176 // if (bscb_holder) { | 176 // if (bscb_holder) { |
| 177 // ScopedComPtr<IHttpNegotiate> http_negotiate; | 177 // base::win::ScopedComPtr<IHttpNegotiate> http_negotiate; |
| 178 // http_negotiate.QueryFrom(bscb_holder); | 178 // http_negotiate.QueryFrom(bscb_holder); |
| 179 // if (http_negotiate && !IsSubFrameRequest(http_negotiate)) | 179 // if (http_negotiate && !IsSubFrameRequest(http_negotiate)) |
| 180 // return true; | 180 // return true; |
| 181 // } | 181 // } |
| 182 // There are some cases where the IsSubFrameRequest function can return | 182 // There are some cases where the IsSubFrameRequest function can return |
| 183 // incorrect results. | 183 // incorrect results. |
| 184 bool should_wrap = mgr->IsTopLevelUrl(url); | 184 bool should_wrap = mgr->IsTopLevelUrl(url); |
| 185 if (!should_wrap) { | 185 if (!should_wrap) { |
| 186 DVLOG(1) << __FUNCTION__ << " Url: " << url | 186 DVLOG(1) << __FUNCTION__ << " Url: " << url |
| 187 << " Not wrapping: Not top level url."; | 187 << " Not wrapping: Not top level url."; |
| 188 } | 188 } |
| 189 return should_wrap; | 189 return should_wrap; |
| 190 } | 190 } |
| 191 | 191 |
| 192 // static | 192 // static |
| 193 HRESULT MonikerPatch::BindToObject(IMoniker_BindToObject_Fn original, | 193 HRESULT MonikerPatch::BindToObject(IMoniker_BindToObject_Fn original, |
| 194 IMoniker* me, IBindCtx* bind_ctx, | 194 IMoniker* me, IBindCtx* bind_ctx, |
| 195 IMoniker* to_left, REFIID iid, void** obj) { | 195 IMoniker* to_left, REFIID iid, void** obj) { |
| 196 DVLOG(1) << __FUNCTION__; | 196 DVLOG(1) << __FUNCTION__; |
| 197 DCHECK(to_left == NULL); | 197 DCHECK(to_left == NULL); |
| 198 | 198 |
| 199 ExceptionBarrierReportOnlyModule barrier; | 199 ExceptionBarrierReportOnlyModule barrier; |
| 200 | 200 |
| 201 HRESULT hr = S_OK; | 201 HRESULT hr = S_OK; |
| 202 // Bind context is marked for switch when we sniff data in BSCBStorageBind | 202 // Bind context is marked for switch when we sniff data in BSCBStorageBind |
| 203 // and determine that the renderer to be used is Chrome. | 203 // and determine that the renderer to be used is Chrome. |
| 204 ScopedComPtr<BindContextInfo> info; | 204 base::win::ScopedComPtr<BindContextInfo> info; |
| 205 BindContextInfo::FromBindContext(bind_ctx, info.Receive()); | 205 BindContextInfo::FromBindContext(bind_ctx, info.Receive()); |
| 206 DCHECK(info); | 206 DCHECK(info); |
| 207 if (info) { | 207 if (info) { |
| 208 if (info->is_switching()) { | 208 if (info->is_switching()) { |
| 209 // We could implement the BindToObject ourselves here but instead we | 209 // We could implement the BindToObject ourselves here but instead we |
| 210 // simply register Chrome Frame ActiveDoc as a handler for 'text/html' | 210 // simply register Chrome Frame ActiveDoc as a handler for 'text/html' |
| 211 // in this bind context. This makes urlmon instantiate CF Active doc | 211 // in this bind context. This makes urlmon instantiate CF Active doc |
| 212 // instead of mshtml. | 212 // instead of mshtml. |
| 213 const char* media_types[] = { "text/html" }; | 213 const char* media_types[] = { "text/html" }; |
| 214 CLSID classes[] = { CLSID_ChromeActiveDocument }; | 214 CLSID classes[] = { CLSID_ChromeActiveDocument }; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 | 249 |
| 250 // If the binding terminates before the data could be played back | 250 // If the binding terminates before the data could be played back |
| 251 // now is the chance. Sometimes OnStopBinding happens after this returns | 251 // now is the chance. Sometimes OnStopBinding happens after this returns |
| 252 // and then it's too late. | 252 // and then it's too late. |
| 253 if ((S_OK == hr) && callback) | 253 if ((S_OK == hr) && callback) |
| 254 callback->MayPlayBack(BSCF_LASTDATANOTIFICATION); | 254 callback->MayPlayBack(BSCF_LASTDATANOTIFICATION); |
| 255 | 255 |
| 256 return hr; | 256 return hr; |
| 257 } | 257 } |
| 258 | 258 |
| OLD | NEW |