| OLD | NEW |
| 1 #include "PluginStdAfx.h" | 1 #include "PluginStdAfx.h" |
| 2 | 2 |
| 3 #include "PluginWbPassThrough.h" | 3 #include "PluginWbPassThrough.h" |
| 4 #include "PluginClient.h" | 4 #include "PluginClient.h" |
| 5 #include "PluginClientFactory.h" | 5 #include "PluginClientFactory.h" |
| 6 #ifdef SUPPORT_FILTER | 6 #ifdef SUPPORT_FILTER |
| 7 #include "PluginFilter.h" | 7 #include "PluginFilter.h" |
| 8 #endif | 8 #endif |
| 9 #include "PluginSettings.h" | 9 #include "PluginSettings.h" |
| 10 #include "PluginClass.h" | 10 #include "PluginClass.h" |
| 11 #include "PluginSystem.h" | 11 #include "PluginSystem.h" |
| 12 | 12 |
| 13 #include "wtypes.h" | 13 #include "wtypes.h" |
| 14 | 14 |
| 15 EXTERN_C IMAGE_DOS_HEADER __ImageBase; | 15 EXTERN_C IMAGE_DOS_HEADER __ImageBase; |
| 16 | 16 |
| 17 | 17 namespace |
| 18 { |
| 19 std::string g_myPageBlocked = "<!DOCTYPE html>" |
| 20 "<html>" |
| 21 "<body>" |
| 22 "<!-- blocked by AdblockPlus -->" |
| 23 "</body>" |
| 24 "</html>"; |
| 25 } |
| 18 | 26 |
| 19 int WBPassthruSink::GetContentTypeFromMimeType(CString mimeType) | 27 int WBPassthruSink::GetContentTypeFromMimeType(CString mimeType) |
| 20 { | 28 { |
| 21 if (mimeType.Find(L"image/") >= 0) | 29 if (mimeType.Find(L"image/") >= 0) |
| 22 { | 30 { |
| 23 return CFilter::contentTypeImage; | 31 return CFilter::contentTypeImage; |
| 24 } | 32 } |
| 25 if (mimeType.Find(L"text/css") >= 0) | 33 if (mimeType.Find(L"text/css") >= 0) |
| 26 { | 34 { |
| 27 return CFilter::contentTypeStyleSheet; | 35 return CFilter::contentTypeStyleSheet; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 return contentType; | 116 return contentType; |
| 109 } | 117 } |
| 110 | 118 |
| 111 ////////////////////////////////////////////////////////////////////////////////
//////// | 119 ////////////////////////////////////////////////////////////////////////////////
//////// |
| 112 //WBPassthruSink | 120 //WBPassthruSink |
| 113 //Monitor and/or cancel every request and responde | 121 //Monitor and/or cancel every request and responde |
| 114 //WB makes, including images, sounds, scripts, etc | 122 //WB makes, including images, sounds, scripts, etc |
| 115 ////////////////////////////////////////////////////////////////////////////////
//////// | 123 ////////////////////////////////////////////////////////////////////////////////
//////// |
| 116 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin
k, | 124 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin
k, |
| 117 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN
DLE_PTR dwReserved, | 125 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN
DLE_PTR dwReserved, |
| 118 IInternetProtocol* pTargetProtocol) | 126 IInternetProtocol* pTargetProtocol, bool& handle
d) |
| 119 { | 127 { |
| 120 | |
| 121 m_pTargetProtocol = pTargetProtocol; | 128 m_pTargetProtocol = pTargetProtocol; |
| 122 bool isBlocked = false; | 129 bool isBlocked = false; |
| 123 m_shouldBlock = false; | 130 m_currentPositionOfSentPage = 0; |
| 124 m_lastDataReported = false; | |
| 125 CString src; | 131 CString src; |
| 126 src.Append(szUrl); | 132 src.Append(szUrl); |
| 127 DEBUG_GENERAL(src); | 133 DEBUG_GENERAL(src); |
| 128 CPluginClient::UnescapeUrl(src); | 134 CPluginClient::UnescapeUrl(src); |
| 129 | 135 |
| 130 CString boundDomain; | 136 CString boundDomain; |
| 131 CString mimeType; | 137 CString mimeType; |
| 132 LPOLESTR mime[10]; | 138 LPOLESTR mime[10]; |
| 133 if (pOIBindInfo) | 139 if (pOIBindInfo) |
| 134 { | 140 { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 } | 236 } |
| 231 else | 237 else |
| 232 { | 238 { |
| 233 CPluginDebug::DebugResultIgnoring(type, src, boundDomain); | 239 CPluginDebug::DebugResultIgnoring(type, src, boundDomain); |
| 234 } | 240 } |
| 235 #endif | 241 #endif |
| 236 | 242 |
| 237 //Fixes the iframe back button issue | 243 //Fixes the iframe back button issue |
| 238 if (client->GetIEVersion() > 6) | 244 if (client->GetIEVersion() > 6) |
| 239 { | 245 { |
| 240 if ((contentType == CFilter::contentTypeImage) && (isBlocked)) | 246 if (contentType == CFilter::contentTypeImage && isBlocked) |
| 241 { | 247 { |
| 242 m_shouldBlock = true; | |
| 243 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); | 248 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); |
| 244 | 249 handled = true; |
| 250 // IE shows a cross that img is not loaded |
| 245 return INET_E_REDIRECT_FAILED; | 251 return INET_E_REDIRECT_FAILED; |
| 246 | |
| 247 } | 252 } |
| 248 if (((contentType == CFilter::contentTypeSubdocument))&& (isBlocked)) | 253 if (contentType == CFilter::contentTypeSubdocument && isBlocked) |
| 249 { | 254 { |
| 250 m_shouldBlock = true; | 255 PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt
ocol(this)->m_shouldSupplyCustomContent = true; |
| 251 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); | 256 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); |
| 252 | 257 |
| 253 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t
ext/html"); | 258 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t
ext/html"); |
| 254 | 259 m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, static
_cast<ULONG>(g_myPageBlocked.size())); |
| 255 //Here we check if we are running on Windows 8 Consumer Preview. | 260 handled = true; |
| 256 //For some reason on that environment the next line causes IE to crash | 261 return S_OK; |
| 257 if (CPluginSettings::GetInstance()->GetWindowsBuildNumber() != 8250) | |
| 258 { | |
| 259 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECT_FAILED, 0, szUrl)
; | |
| 260 } | |
| 261 | |
| 262 return INET_E_REDIRECT_FAILED; | |
| 263 } | 262 } |
| 264 if (((contentType == CFilter::contentTypeScript)) && (isBlocked)) | 263 if (contentType == CFilter::contentTypeScript && isBlocked) |
| 265 { | 264 { |
| 266 m_shouldBlock = true; | |
| 267 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); | 265 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); |
| 268 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t
ext/javascript"); | 266 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t
ext/javascript"); |
| 269 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); | 267 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); |
| 268 handled = true; |
| 270 return INET_E_REDIRECT_FAILED; | 269 return INET_E_REDIRECT_FAILED; |
| 271 } | 270 } |
| 272 if ((contentType == CFilter::contentTypeXmlHttpRequest) && (isBlocked)) | 271 if (contentType == CFilter::contentTypeXmlHttpRequest && isBlocked) |
| 273 { | 272 { |
| 274 m_shouldBlock = true; | |
| 275 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); | 273 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); |
| 276 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); | 274 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); |
| 275 handled = true; |
| 277 return INET_E_REDIRECT_FAILED; | 276 return INET_E_REDIRECT_FAILED; |
| 278 } | 277 } |
| 279 if ((isBlocked)) | 278 if (isBlocked) |
| 280 { | 279 { |
| 281 m_shouldBlock = true; | |
| 282 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); | 280 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
rgetProtocol); |
| 283 m_spInternetProtocolSink->ReportResult(S_FALSE, 0, L""); | 281 m_spInternetProtocolSink->ReportResult(S_FALSE, 0, L""); |
| 284 | 282 handled = true; |
| 285 return INET_E_REDIRECT_FAILED; | 283 return INET_E_REDIRECT_FAILED; |
| 286 } | 284 } |
| 287 } | 285 } |
| 288 #endif // SUPPORT_FILTER | 286 #endif // SUPPORT_FILTER |
| 289 | 287 |
| 290 return isBlocked ? S_FALSE : BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInf
o, grfPI, dwReserved, pTargetProtocol); | 288 return isBlocked ? S_FALSE : BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInf
o, grfPI, dwReserved, pTargetProtocol); |
| 291 } | 289 } |
| 292 | 290 |
| 293 | 291 |
| 294 HRESULT WBPassthruSink::Read(void *pv, ULONG cb, ULONG* pcbRead) | 292 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) |
| 295 { | 293 { |
| 296 if (m_shouldBlock) | 294 if (nullptr == pv) { |
| 295 return E_POINTER; |
| 296 } |
| 297 if (nullptr == pcbRead) { |
| 298 return E_POINTER; |
| 299 } |
| 300 *pcbRead = 0; |
| 301 |
| 302 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt
ocol(this)->m_shouldSupplyCustomContent) |
| 297 { | 303 { |
| 298 *pcbRead = 0; | 304 ULONG myPageSize = static_cast<ULONG>(g_myPageBlocked.size()); |
| 299 if (!m_lastDataReported) | 305 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(g_myPageBlocked.s
ize() - m_currentPositionOfSentPage)); |
| 300 { | 306 if (0 == positionGrow) { |
| 301 if (cb <= 1) | 307 return S_FALSE; |
| 302 { | 308 } |
| 303 //IE must've gone nuts if this happened, but let's be cool about it and
report we have no more data | 309 std::copy(g_myPageBlocked.begin(), g_myPageBlocked.begin() + positionGrow, |
| 304 m_spInternetProtocolSink->ReportResult(S_FALSE, 0, NULL); | 310 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb)); |
| 305 return S_FALSE; | 311 *pcbRead = positionGrow; |
| 306 } | 312 m_currentPositionOfSentPage += positionGrow; |
| 307 *pcbRead = 1; | |
| 308 memcpy(pv, " ", 1); | |
| 309 | 313 |
| 310 if (m_spInternetProtocolSink != NULL) | 314 if (m_spInternetProtocolSink) { |
| 311 { | 315 m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, |
| 312 m_spInternetProtocolSink->ReportResult(S_OK, 0, NULL); | 316 static_cast<ULONG>(m_currentPositionOfSentPage), myPageSize); |
| 313 } | 317 } |
| 314 m_lastDataReported = true; | 318 if (myPageSize == m_currentPositionOfSentPage && m_spInternetProtocolSink) { |
| 315 m_shouldBlock = false; | 319 m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, myPageSize,
myPageSize); |
| 316 return S_OK; | 320 m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr); |
| 317 } | 321 } |
| 318 return S_OK; | 322 return S_OK; |
| 319 } | 323 } |
| 320 else | 324 return m_pTargetProtocol->Read(pv, cb, pcbRead); |
| 321 { | |
| 322 | |
| 323 return m_pTargetProtocol->Read(pv, cb, pcbRead); | |
| 324 } | |
| 325 return S_OK; | |
| 326 } | 325 } |
| 327 STDMETHODIMP WBPassthruSink::Switch( | 326 STDMETHODIMP WBPassthruSink::Switch( |
| 328 /* [in] */ PROTOCOLDATA *pProtocolData) | 327 /* [in] */ PROTOCOLDATA *pProtocolData) |
| 329 { | 328 { |
| 330 ATLASSERT(m_spInternetProtocolSink != 0); | 329 ATLASSERT(m_spInternetProtocolSink != 0); |
| 331 | 330 |
| 332 /* | 331 /* |
| 333 From Igor Tandetnik "itandetnik@mvps.org" | 332 From Igor Tandetnik "itandetnik@mvps.org" |
| 334 " | 333 " |
| 335 Beware multithreading. URLMon has this nasty habit of spinning worker | 334 Beware multithreading. URLMon has this nasty habit of spinning worker |
| 336 threads, not even bothering to initialize COM on them, and calling APP | 335 threads, not even bothering to initialize COM on them, and calling APP |
| 337 methods on those threads. If you try to raise COM events directly from | 336 methods on those threads. If you try to raise COM events directly from |
| 338 such a thread, bad things happen (random crashes, events being lost). | 337 such a thread, bad things happen (random crashes, events being lost). |
| 339 You are only guaranteed to be on the main STA thread in two cases. | 338 You are only guaranteed to be on the main STA thread in two cases. |
| 340 First, in methods of interfaces that were obtained with | 339 First, in methods of interfaces that were obtained with |
| 341 IServiceProvider, such as IHttpNegotiage::BeginningTransaction or | 340 IServiceProvider, such as IHttpNegotiage::BeginningTransaction or |
| 342 IAuthenticate::Authenticate. Second, you can call | 341 IAuthenticate::Authenticate. Second, you can call |
| 343 IInternetProtocolSink::Switch with PD_FORCE_SWITCH flag in | 342 IInternetProtocolSink::Switch with PD_FORCE_SWITCH flag in |
| 344 PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call | 343 PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call |
| 345 IInternetProtocol::Continue on the main thread. | 344 IInternetProtocol::Continue on the main thread. |
| 346 | 345 |
| 347 Or, if you happen to have a window handy that was created on the main | 346 Or, if you happen to have a window handy that was created on the main |
| 348 thread, you can post yourself a message. | 347 thread, you can post yourself a message. |
| 349 " | 348 " |
| 350 */ | 349 */ |
| 351 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa
ta) : E_UNEXPECTED; | 350 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa
ta) : E_UNEXPECTED; |
| 352 } | 351 } |
| 353 | 352 |
| 354 | |
| 355 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade
rs, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) | 353 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade
rs, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) |
| 356 { | 354 { |
| 357 if (pszAdditionalHeaders) | 355 if (pszAdditionalHeaders) |
| 358 { | 356 { |
| 359 *pszAdditionalHeaders = 0; | 357 *pszAdditionalHeaders = 0; |
| 360 } | 358 } |
| 361 | 359 |
| 362 CComPtr<IHttpNegotiate> spHttpNegotiate; | 360 CComPtr<IHttpNegotiate> spHttpNegotiate; |
| 363 QueryServiceFromClient(&spHttpNegotiate); | 361 QueryServiceFromClient(&spHttpNegotiate); |
| 364 return spHttpNegotiate ? spHttpNegotiate->BeginningTransaction(szURL, szHeader
s,dwReserved, pszAdditionalHeaders) : S_OK; | 362 return spHttpNegotiate ? spHttpNegotiate->BeginningTransaction(szURL, szHeader
s,dwReserved, pszAdditionalHeaders) : S_OK; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 375 QueryServiceFromClient(&spHttpNegotiate); | 373 QueryServiceFromClient(&spHttpNegotiate); |
| 376 | 374 |
| 377 return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons
eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK; | 375 return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons
eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK; |
| 378 } | 376 } |
| 379 | 377 |
| 380 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus
Text) | 378 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus
Text) |
| 381 { | 379 { |
| 382 return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS
tatusCode, szStatusText) : S_OK; | 380 return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS
tatusCode, szStatusText) : S_OK; |
| 383 } | 381 } |
| 384 | 382 |
| 383 WBPassthru::WBPassthru() |
| 384 : m_shouldSupplyCustomContent(false) |
| 385 { |
| 386 } |
| 385 | 387 |
| 386 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink
, | 388 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink
, |
| 387 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) | 389 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) |
| 388 { | 390 { |
| 389 ATLASSERT(m_spInternetProtocol != 0); | 391 ATLASSERT(m_spInternetProtocol != 0); |
| 390 if (!m_spInternetProtocol) | 392 if (!m_spInternetProtocol) |
| 391 { | 393 { |
| 392 return E_UNEXPECTED; | 394 return E_UNEXPECTED; |
| 393 } | 395 } |
| 394 | 396 |
| 395 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, | 397 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne
tProtocol); |
| 396 dwReserved, m_spInternetProtocol); | |
| 397 } | 398 } |
| 398 | 399 |
| 399 STDMETHODIMP WBPassthru::Read(»/* [in, out] */ void *pv,/* [in] */ ULONG cb,/*
[out] */ ULONG *pcbRead) | 400 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o
ut] */ ULONG *pcbRead) |
| 400 { | 401 { |
| 401 | 402 WBPassthruSink* pSink = GetSink(); |
| 402 WBPassthruSink* pSink = GetSink(); | 403 return pSink->OnRead(pv, cb, pcbRead); |
| 403 return pSink->Read(pv, cb, pcbRead); | 404 } |
| 404 } | 405 |
| 406 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options) |
| 407 { |
| 408 if (m_shouldSupplyCustomContent) |
| 409 { |
| 410 return S_OK; |
| 411 } |
| 412 return PassthroughAPP::CInternetProtocol<WBStartPolicy>::LockRequest(options); |
| 413 } |
| 414 |
| 415 STDMETHODIMP WBPassthru::UnlockRequest() |
| 416 { |
| 417 if (m_shouldSupplyCustomContent) |
| 418 { |
| 419 return S_OK; |
| 420 } |
| 421 return PassthroughAPP::CInternetProtocol<WBStartPolicy>::UnlockRequest(); |
| 422 } |
| OLD | NEW |