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 |