| 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 #include <WinInet.h> | 
| 13 #include "wtypes.h" | 13 #include "wtypes.h" | 
| 14 | 14 | 
| 15 EXTERN_C IMAGE_DOS_HEADER __ImageBase; |  | 
| 16 |  | 
| 17 namespace | 15 namespace | 
| 18 { | 16 { | 
| 19   std::string g_myPageBlocked = "<!DOCTYPE html>" | 17   std::string g_blockedByABPPage = "<!DOCTYPE html>" | 
| 20     "<html>" | 18     "<html>" | 
| 21         "<body>" | 19         "<body>" | 
| 22           "<!-- blocked by AdblockPlus -->" | 20           "<!-- blocked by AdblockPlus -->" | 
| 23         "</body>" | 21         "</body>" | 
| 24     "</html>"; | 22     "</html>"; | 
| 25 } | 23 } | 
| 26 | 24 | 
| 27 int WBPassthruSink::GetContentTypeFromMimeType(CString mimeType) | 25 WBPassthruSink::WBPassthruSink() | 
|  | 26   : m_currentPositionOfSentPage(0) | 
|  | 27   , m_contentType(CFilter::EContentType::contentTypeAny) | 
|  | 28   , m_blockedInTransaction(false) | 
|  | 29 { | 
|  | 30 } | 
|  | 31 | 
|  | 32 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) | 
| 28 { | 33 { | 
| 29   if (mimeType.Find(L"image/") >= 0) | 34   if (mimeType.Find(L"image/") >= 0) | 
| 30   { | 35   { | 
| 31     return CFilter::contentTypeImage; | 36     return CFilter::contentTypeImage; | 
| 32   } | 37   } | 
| 33   if (mimeType.Find(L"text/css") >= 0) | 38   if (mimeType.Find(L"text/css") >= 0) | 
| 34   { | 39   { | 
| 35     return CFilter::contentTypeStyleSheet; | 40     return CFilter::contentTypeStyleSheet; | 
| 36   } | 41   } | 
| 37   if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic
     ation/json") >= 0)) | 42   if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic
     ation/json") >= 0)) | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 48   } | 53   } | 
| 49   // It is important to have this check last, since it is rather generic, and mi
     ght overlay text/html, for example | 54   // It is important to have this check last, since it is rather generic, and mi
     ght overlay text/html, for example | 
| 50   if (mimeType.Find(L"xml") >= 0) | 55   if (mimeType.Find(L"xml") >= 0) | 
| 51   { | 56   { | 
| 52     return CFilter::contentTypeXmlHttpRequest; | 57     return CFilter::contentTypeXmlHttpRequest; | 
| 53   } | 58   } | 
| 54 | 59 | 
| 55   return CFilter::contentTypeAny; | 60   return CFilter::contentTypeAny; | 
| 56 } | 61 } | 
| 57 | 62 | 
| 58 int WBPassthruSink::GetContentTypeFromURL(CString src) | 63 int WBPassthruSink::GetContentTypeFromURL(const CString& src) | 
| 59 { | 64 { | 
| 60   CString srcExt = src; | 65   CString srcExt = src; | 
| 61 | 66 | 
| 62   int pos = 0; | 67   int pos = 0; | 
| 63   if ((pos = src.Find('?')) > 0) | 68   if ((pos = src.Find('?')) > 0) | 
| 64   { | 69   { | 
| 65     srcExt = src.Left(pos); | 70     srcExt = src.Left(pos); | 
| 66   } | 71   } | 
| 67 | 72 | 
| 68   int lastDotIndex = srcExt.ReverseFind('.'); | 73   int lastDotIndex = srcExt.ReverseFind('.'); | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 86     return CFilter::contentTypeXmlHttpRequest; | 91     return CFilter::contentTypeXmlHttpRequest; | 
| 87   } | 92   } | 
| 88   else if (ext == L".swf") | 93   else if (ext == L".swf") | 
| 89   { | 94   { | 
| 90     return CFilter::contentTypeObject; | 95     return CFilter::contentTypeObject; | 
| 91   } | 96   } | 
| 92   else if (ext == L".jsp" || ext == L".php" || ext == L".html") | 97   else if (ext == L".jsp" || ext == L".php" || ext == L".html") | 
| 93   { | 98   { | 
| 94     return CFilter::contentTypeSubdocument; | 99     return CFilter::contentTypeSubdocument; | 
| 95   } | 100   } | 
| 96   else | 101   return CFilter::contentTypeAny; | 
| 97   { |  | 
| 98     return CFilter::contentTypeAny & ~CFilter::contentTypeSubdocument; |  | 
| 99   } |  | 
| 100 |  | 
| 101 } | 102 } | 
| 102 | 103 | 
| 103 int WBPassthruSink::GetContentType(CString mimeType, CString domain, CString src
     ) | 104 int WBPassthruSink::GetContentType(const CString& mimeType, const CString& domai
     n, const CString& src) | 
| 104 { | 105 { | 
| 105   // No referer or mime type | 106   // No referer or mime type | 
| 106   // BINDSTRING_XDR_ORIGIN works only for IE v8+ | 107   // BINDSTRING_XDR_ORIGIN works only for IE v8+ | 
| 107   if (mimeType.IsEmpty() && domain.IsEmpty() && CPluginClient::GetInstance()->Ge
     tIEVersion() >= 8) | 108   if (mimeType.IsEmpty() && domain.IsEmpty() && CPluginClient::GetInstance()->Ge
     tIEVersion() >= 8) | 
| 108   { | 109   { | 
| 109     return CFilter::contentTypeXmlHttpRequest; | 110     return CFilter::contentTypeXmlHttpRequest; | 
| 110   } | 111   } | 
| 111   int contentType = GetContentTypeFromMimeType(mimeType); | 112   int contentType = GetContentTypeFromMimeType(mimeType); | 
| 112   if (contentType == CFilter::contentTypeAny) | 113   if (contentType == CFilter::contentTypeAny) | 
| 113   { | 114   { | 
| 114     contentType = GetContentTypeFromURL(src); | 115     contentType = GetContentTypeFromURL(src); | 
| 115   } | 116   } | 
| 116   return contentType; | 117   return contentType; | 
| 117 } | 118 } | 
| 118 | 119 | 
| 119 ////////////////////////////////////////////////////////////////////////////////
     //////// | 120 ////////////////////////////////////////////////////////////////////////////////
     //////// | 
| 120 //WBPassthruSink | 121 //WBPassthruSink | 
| 121 //Monitor and/or cancel every request and responde | 122 //Monitor and/or cancel every request and responde | 
| 122 //WB makes, including images, sounds, scripts, etc | 123 //WB makes, including images, sounds, scripts, etc | 
| 123 ////////////////////////////////////////////////////////////////////////////////
     //////// | 124 ////////////////////////////////////////////////////////////////////////////////
     //////// | 
| 124 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin
     k, | 125 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin
     k, | 
| 125                                 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN
     DLE_PTR dwReserved, | 126                                 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN
     DLE_PTR dwReserved, | 
| 126                                 IInternetProtocol* pTargetProtocol, bool& handle
     d) | 127                                 IInternetProtocol* pTargetProtocol, bool& handle
     d) | 
| 127 { | 128 { | 
| 128   m_pTargetProtocol = pTargetProtocol; | 129   m_pTargetProtocol = pTargetProtocol; | 
| 129   bool isBlocked = false; | 130   bool isBlocked = false; | 
| 130   m_currentPositionOfSentPage = 0; | 131   CString src = szUrl; | 
| 131   CString src; |  | 
| 132   src.Append(szUrl); |  | 
| 133   DEBUG_GENERAL(src); | 132   DEBUG_GENERAL(src); | 
| 134   CPluginClient::UnescapeUrl(src); | 133   CPluginClient::UnescapeUrl(src); | 
| 135 | 134 | 
| 136   CString boundDomain; | 135   // call the impl of the base class as soon as possible because it initializes 
     the base class | 
|  | 136   // members, used by this method. It queries for the required interfaces. | 
|  | 137   HRESULT hr = BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwRese
     rved, pTargetProtocol); | 
|  | 138   if (FAILED(hr)) | 
|  | 139   { | 
|  | 140     return hr; | 
|  | 141   } | 
|  | 142 | 
| 137   CString mimeType; | 143   CString mimeType; | 
| 138   LPOLESTR mime[10]; |  | 
| 139   if (pOIBindInfo) | 144   if (pOIBindInfo) | 
| 140   { | 145   { | 
| 141     ULONG resLen = 0; | 146     ULONG resLen = 0; | 
| 142 | 147 | 
| 143     // Apparently IE will report random mime type if there's more then 1 in the 
     list. | 148     // Apparently IE will report random mime type if there's more then 1 in the 
     list. | 
| 144     // So we get the whole list and just use the first one (top priority one) | 149     // So we get the whole list and just use the first one (top priority one) | 
|  | 150     LPOLESTR mime[10]; | 
| 145     pOIBindInfo->GetBindString(BINDSTRING_ACCEPT_MIMES, mime, 10, &resLen); | 151     pOIBindInfo->GetBindString(BINDSTRING_ACCEPT_MIMES, mime, 10, &resLen); | 
| 146     if (mime && resLen > 0) | 152     if (mime && resLen > 0) | 
| 147     { | 153     { | 
| 148       mimeType.SetString(mime[0]); | 154       mimeType.SetString(mime[0]); | 
| 149     } | 155     } | 
| 150     LPOLESTR bindToObject = 0; | 156     LPOLESTR bindString = nullptr; | 
| 151     pOIBindInfo->GetBindString(BINDSTRING_FLAG_BIND_TO_OBJECT, &bindToObject, 1,
      &resLen); | 157     pOIBindInfo->GetBindString(BINDSTRING_FLAG_BIND_TO_OBJECT, &bindString, 1, &
     resLen); | 
| 152     LPOLESTR domainRetrieved = 0; | 158     LPOLESTR domainRetrieved = nullptr; | 
| 153     if (resLen == 0 || wcscmp(bindToObject, L"FALSE") == 0) | 159     if (resLen == 0 || wcscmp(bindString, L"FALSE") == 0) | 
| 154     { | 160     { | 
| 155       HRESULT hr = pOIBindInfo->GetBindString(BINDSTRING_XDR_ORIGIN, &domainRetr
     ieved, 1, &resLen); | 161       HRESULT hr = pOIBindInfo->GetBindString(BINDSTRING_XDR_ORIGIN, &domainRetr
     ieved, 1, &resLen); | 
| 156 |  | 
| 157       if ((hr == S_OK) && domainRetrieved && (resLen > 0)) | 162       if ((hr == S_OK) && domainRetrieved && (resLen > 0)) | 
| 158       { | 163       { | 
| 159         boundDomain.SetString(domainRetrieved); | 164         m_boundDomain = domainRetrieved; | 
| 160       } | 165       } | 
| 161     } | 166     } | 
|  | 167     // We can obtain IBindCtx* here, but IEnumString obtained via IBindCtx::Enum
     ObjectParam | 
|  | 168     // does not return any parameter, so it's useless. | 
| 162   } | 169   } | 
| 163 | 170 | 
| 164   CString cookie; | 171   CString cookie; | 
| 165   ULONG len1 = 2048; | 172   ULONG len1 = 2048; | 
| 166   ULONG len2 = 2048; | 173   ULONG len2 = 2048; | 
| 167 | 174 | 
| 168 #ifdef SUPPORT_FILTER | 175 #ifdef SUPPORT_FILTER | 
| 169   int contentType = CFilter::contentTypeAny; |  | 
| 170 |  | 
| 171   CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); | 176   CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); | 
| 172   CPluginClient* client = CPluginClient::GetInstance(); | 177   CPluginClient* client = CPluginClient::GetInstance(); | 
| 173 | 178 | 
| 174 |  | 
| 175   if (tab && client) | 179   if (tab && client) | 
| 176   { | 180   { | 
| 177     CString documentUrl = tab->GetDocumentUrl(); | 181     CString documentUrl = tab->GetDocumentUrl(); | 
| 178     // Page is identical to document => don't block | 182     // Page is identical to document => don't block | 
| 179     if (documentUrl == src) | 183     if (documentUrl == src) | 
| 180     { | 184     { | 
| 181       // fall through | 185       // fall through | 
| 182     } | 186     } | 
| 183     else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi
     telistedUrl(std::wstring(documentUrl))) | 187     else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi
     telistedUrl(std::wstring(documentUrl))) | 
| 184     { | 188     { | 
| 185       boundDomain = tab->GetDocumentUrl(); | 189       m_boundDomain = tab->GetDocumentUrl(); | 
| 186 | 190       m_contentType = CFilter::contentTypeAny; | 
| 187       contentType = CFilter::contentTypeAny; |  | 
| 188 |  | 
| 189 #ifdef SUPPORT_FRAME_CACHING | 191 #ifdef SUPPORT_FRAME_CACHING | 
| 190       if ((tab != 0) && (tab->IsFrameCached(src))) | 192       if (tab != nullptr && tab->IsFrameCached(src)) | 
| 191       { | 193       { | 
| 192         contentType = CFilter::contentTypeSubdocument; | 194         m_contentType = CFilter::contentTypeSubdocument; | 
| 193       } | 195       } | 
| 194       else | 196       else | 
| 195 #endif // SUPPORT_FRAME_CACHING | 197 #endif // SUPPORT_FRAME_CACHING | 
| 196       contentType = GetContentType(mimeType, boundDomain, src); |  | 
| 197       if (client->ShouldBlock(src, contentType, boundDomain, true)) |  | 
| 198       { | 198       { | 
| 199         isBlocked = true; | 199         m_contentType = GetContentType(mimeType, m_boundDomain, src); | 
| 200 |  | 
| 201         DEBUG_BLOCKER("Blocker::Blocking Http-request:" + src); |  | 
| 202       } | 200       } | 
| 203     } | 201     } | 
| 204     if (!isBlocked) |  | 
| 205     { |  | 
| 206       DEBUG_BLOCKER("Blocker::Ignoring Http-request:" + src) |  | 
| 207     } |  | 
| 208   } | 202   } | 
| 209 | 203 | 
|  | 204   if (tab == nullptr) | 
|  | 205   { | 
|  | 206     m_contentType = GetContentType(mimeType, m_boundDomain, src); | 
|  | 207   } | 
| 210 | 208 | 
| 211   if (tab == NULL) |  | 
| 212   { | 209   { | 
| 213     contentType = GetContentType(mimeType, boundDomain, src); | 210     // Here is the heuristic which detects the requests issued by Flash.ocx. | 
| 214     if (client->ShouldBlock(src, contentType, boundDomain, true)) | 211     // It turned out that the implementation from ''Flash.ocx'' (tested version 
     is 15.0.0.152) | 
|  | 212     // returns quite minimal configuration in comparison with the implementation
      from Microsofts' | 
|  | 213     // libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often i
     ncludes something | 
|  | 214     // else. | 
|  | 215     ATL::CComPtr<IBindStatusCallback> bscb; | 
|  | 216     if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb) | 
| 215     { | 217     { | 
| 216       isBlocked = true; | 218       DWORD grfBINDF = 0; | 
|  | 219       BINDINFO bindInfo = {}; | 
|  | 220       bindInfo.cbSize = sizeof(bindInfo); | 
|  | 221       if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo)) | 
|  | 222         && (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF | 
|  | 223         && (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == 
     bindInfo.dwOptions | 
|  | 224         ) | 
|  | 225       { | 
|  | 226         m_contentType = CFilter::EContentType::contentTypeObjectSubrequest; | 
|  | 227       } | 
| 217     } | 228     } | 
| 218   } | 229   } | 
| 219 | 230 | 
| 220 #ifdef _DEBUG | 231   // The descision about EContentType::contentTypeAny is made later in | 
| 221   CString type; | 232   // WBPassthruSink::BeginningTransaction. Sometimes here we cannot detect the r
     equest type, but | 
|  | 233   // in WBPassthruSink::BeginningTransaction the header Accept is available whic
     h allows to | 
|  | 234   // obtain the "request type" in our terminology. | 
|  | 235   if (nullptr != client | 
|  | 236     && CFilter::EContentType::contentTypeAny != m_contentType | 
|  | 237     && client->ShouldBlock(src, m_contentType, m_boundDomain, true)) | 
|  | 238   { | 
|  | 239     isBlocked = true; | 
|  | 240   } | 
| 222 | 241 | 
| 223   if (contentType == CFilter::contentTypeDocument) type = "DOCUMENT"; | 242   // For IE6 and earlier there is iframe back button issue, so avoid it. | 
| 224   else if (contentType == CFilter::contentTypeObject) type = "OBJECT"; | 243   if (isBlocked && client->GetIEVersion() > 6) | 
| 225   else if (contentType == CFilter::contentTypeImage) type = "IMAGE"; |  | 
| 226   else if (contentType == CFilter::contentTypeScript) type = "SCRIPT"; |  | 
| 227   else if (contentType == CFilter::contentTypeOther) type = "OTHER"; |  | 
| 228   else if (contentType == CFilter::contentTypeUnknown) type = "OTHER"; |  | 
| 229   else if (contentType == CFilter::contentTypeSubdocument) type = "SUBDOCUMENT"; |  | 
| 230   else if (contentType == CFilter::contentTypeStyleSheet) type = "STYLESHEET"; |  | 
| 231   else type = "OTHER"; |  | 
| 232 |  | 
| 233   if (isBlocked) |  | 
| 234   { | 244   { | 
| 235     CPluginDebug::DebugResultBlocking(type, src, boundDomain); | 245     handled = true; | 
| 236   } | 246     if (CFilter::EContentType::contentTypeImage == m_contentType) | 
| 237   else |  | 
| 238   { |  | 
| 239     CPluginDebug::DebugResultIgnoring(type, src, boundDomain); |  | 
| 240   } |  | 
| 241 #endif |  | 
| 242 |  | 
| 243   //Fixes the iframe back button issue |  | 
| 244   if (client->GetIEVersion() > 6) |  | 
| 245   { |  | 
| 246     if (contentType == CFilter::contentTypeImage && isBlocked) |  | 
| 247     { | 247     { | 
| 248       BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
     rgetProtocol); |  | 
| 249       handled = true; |  | 
| 250       // IE shows a cross that img is not loaded | 248       // IE shows a cross that img is not loaded | 
| 251       return INET_E_REDIRECT_FAILED; | 249       return INET_E_REDIRECT_FAILED; | 
| 252     } | 250     } | 
| 253     if (contentType == CFilter::contentTypeSubdocument && isBlocked) | 251     if (CFilter::EContentType::contentTypeSubdocument == m_contentType) | 
| 254     { | 252     { | 
| 255       PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt
     ocol(this)->m_shouldSupplyCustomContent = true; | 253       PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt
     ocol(this)->m_shouldSupplyCustomContent = true; | 
| 256       BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
     rgetProtocol); |  | 
| 257 |  | 
| 258       m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t
     ext/html"); | 254       m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t
     ext/html"); | 
| 259       m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, static
     _cast<ULONG>(g_myPageBlocked.size())); | 255       m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, static
     _cast<ULONG>(g_blockedByABPPage.size())); | 
| 260       handled = true; |  | 
| 261       return S_OK; | 256       return S_OK; | 
| 262     } | 257     } | 
| 263     if (contentType == CFilter::contentTypeScript && isBlocked) | 258     if (CFilter::EContentType::contentTypeScript == m_contentType) | 
| 264     { | 259     { | 
| 265       BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
     rgetProtocol); |  | 
| 266       m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t
     ext/javascript"); | 260       m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t
     ext/javascript"); | 
| 267       m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); | 261       m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); | 
| 268       handled = true; |  | 
| 269       return INET_E_REDIRECT_FAILED; | 262       return INET_E_REDIRECT_FAILED; | 
| 270     } | 263     } | 
| 271     if (contentType == CFilter::contentTypeXmlHttpRequest && isBlocked) | 264     if (CFilter::EContentType::contentTypeXmlHttpRequest == m_contentType) | 
| 272     { | 265     { | 
| 273       BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
     rgetProtocol); |  | 
| 274       m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); | 266       m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); | 
| 275       handled = true; |  | 
| 276       return INET_E_REDIRECT_FAILED; | 267       return INET_E_REDIRECT_FAILED; | 
| 277     } | 268     } | 
| 278     if (isBlocked) | 269     if (CFilter::EContentType::contentTypeAny != m_contentType) | 
| 279     { | 270     { | 
| 280       BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa
     rgetProtocol); | 271       m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); | 
| 281       m_spInternetProtocolSink->ReportResult(S_FALSE, 0, L""); |  | 
| 282       handled = true; |  | 
| 283       return INET_E_REDIRECT_FAILED; | 272       return INET_E_REDIRECT_FAILED; | 
| 284     } | 273     } | 
| 285   } | 274   } | 
| 286 #endif // SUPPORT_FILTER | 275 #endif // SUPPORT_FILTER | 
| 287 | 276 | 
| 288   return isBlocked ? S_FALSE : BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInf
     o, grfPI, dwReserved, pTargetProtocol); | 277   return isBlocked ? S_FALSE : hr; | 
| 289 } | 278 } | 
| 290 | 279 | 
| 291 |  | 
| 292 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) | 280 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) | 
| 293 { | 281 { | 
| 294   if (nullptr == pv) | 282   if (pv == nullptr) | 
| 295   { | 283   { | 
| 296     return E_POINTER; | 284     return E_POINTER; | 
| 297   } | 285   } | 
| 298   if (nullptr == pcbRead) | 286   if (pcbRead == nullptr) | 
| 299   { | 287   { | 
| 300     return E_POINTER; | 288     return E_POINTER; | 
| 301   } | 289   } | 
| 302   *pcbRead = 0; | 290   *pcbRead = 0; | 
| 303 | 291 | 
| 304   if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt
     ocol(this)->m_shouldSupplyCustomContent) | 292   if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt
     ocol(this)->m_shouldSupplyCustomContent) | 
| 305   { | 293   { | 
| 306     ULONG myPageSize = static_cast<ULONG>(g_myPageBlocked.size()); | 294     ULONG blockedByABPPageSize = static_cast<ULONG>(g_blockedByABPPage.size()); | 
| 307     auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(g_myPageBlocked.s
     ize() - m_currentPositionOfSentPage)); | 295     auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(blockedByABPPageS
     ize - m_currentPositionOfSentPage)); | 
| 308     if (0 == positionGrow) { | 296     if (positionGrow == 0) { | 
| 309       return S_FALSE; | 297       return S_FALSE; | 
| 310     } | 298     } | 
| 311     std::copy(g_myPageBlocked.begin(), g_myPageBlocked.begin() + positionGrow, | 299     std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG
     row, | 
| 312       stdext::make_checked_array_iterator(static_cast<char*>(pv), cb)); | 300       stdext::make_checked_array_iterator(static_cast<char*>(pv), cb)); | 
| 313     *pcbRead = positionGrow; | 301     *pcbRead = positionGrow; | 
| 314     m_currentPositionOfSentPage += positionGrow; | 302     m_currentPositionOfSentPage += positionGrow; | 
| 315 | 303 | 
| 316     if (m_spInternetProtocolSink) | 304     if (m_spInternetProtocolSink) | 
| 317     { | 305     { | 
| 318       m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, | 306       m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, | 
| 319         static_cast<ULONG>(m_currentPositionOfSentPage), myPageSize); | 307         static_cast<ULONG>(m_currentPositionOfSentPage), blockedByABPPageSize); | 
| 320     } | 308     } | 
| 321     if (myPageSize == m_currentPositionOfSentPage && m_spInternetProtocolSink) | 309     if (blockedByABPPageSize == m_currentPositionOfSentPage && m_spInternetProto
     colSink) | 
| 322     { | 310     { | 
| 323       m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, myPageSize, 
     myPageSize); | 311       m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, blockedByABP
     PageSize, blockedByABPPageSize); | 
| 324       m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr); | 312       m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr); | 
| 325     } | 313     } | 
| 326     return S_OK; | 314     return S_OK; | 
| 327   } | 315   } | 
| 328   return m_pTargetProtocol->Read(pv, cb, pcbRead); | 316   return m_pTargetProtocol->Read(pv, cb, pcbRead); | 
| 329 } | 317 } | 
| 330 STDMETHODIMP WBPassthruSink::Switch( | 318 STDMETHODIMP WBPassthruSink::Switch( | 
| 331   /* [in] */ PROTOCOLDATA *pProtocolData) | 319   /* [in] */ PROTOCOLDATA *pProtocolData) | 
| 332 { | 320 { | 
| 333   ATLASSERT(m_spInternetProtocolSink != 0); | 321   ATLASSERT(m_spInternetProtocolSink != 0); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 347   PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call | 335   PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call | 
| 348   IInternetProtocol::Continue on the main thread. | 336   IInternetProtocol::Continue on the main thread. | 
| 349 | 337 | 
| 350   Or, if you happen to have a window handy that was created on the main | 338   Or, if you happen to have a window handy that was created on the main | 
| 351   thread, you can post yourself a message. | 339   thread, you can post yourself a message. | 
| 352   " | 340   " | 
| 353   */ | 341   */ | 
| 354   return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa
     ta) : E_UNEXPECTED; | 342   return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa
     ta) : E_UNEXPECTED; | 
| 355 } | 343 } | 
| 356 | 344 | 
| 357 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade
     rs, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) | 345 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade
     rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders) | 
| 358 { | 346 { | 
| 359   if (pszAdditionalHeaders) | 347   if (pszAdditionalHeaders) | 
| 360   { | 348   { | 
| 361     *pszAdditionalHeaders = 0; | 349     *pszAdditionalHeaders = nullptr; | 
| 362   } | 350   } | 
| 363 | 351 | 
|  | 352   CPluginClient* client = nullptr; | 
|  | 353   if (CFilter::EContentType::contentTypeAny == m_contentType && (client = CPlugi
     nClient::GetInstance())) | 
|  | 354   { | 
|  | 355     auto acceptHeader = [&]() -> std::string | 
|  | 356     { | 
|  | 357       // Despite there is HTTP_QUERY_ACCEPT and other query info flags, they don
     't work here, | 
|  | 358       // only HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS does
      dork. | 
|  | 359       ATL::CComPtr<IWinInetHttpInfo> winInetHttpInfo; | 
|  | 360       HRESULT hr = m_spTargetProtocol->QueryInterface(&winInetHttpInfo); | 
|  | 361       if(FAILED(hr)) | 
|  | 362       { | 
|  | 363         return ""; | 
|  | 364       } | 
|  | 365       DWORD size = 0; | 
|  | 366       DWORD flags = 0; | 
|  | 367       hr = winInetHttpInfo->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_F
     LAG_REQUEST_HEADERS, | 
|  | 368           /*buffer*/nullptr, /* get size */&size, &flags, /*reserved*/ 0); | 
|  | 369       if(FAILED(hr)) | 
|  | 370       { | 
|  | 371         return ""; | 
|  | 372       } | 
|  | 373       std::string buf(size, '\0'); | 
|  | 374       hr = winInetHttpInfo->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_F
     LAG_REQUEST_HEADERS, | 
|  | 375         &buf[0], &size, &flags, 0); | 
|  | 376       if(FAILED(hr)) | 
|  | 377       { | 
|  | 378         return ""; | 
|  | 379       } | 
|  | 380       char acceptHeader[] = "Accept:"; | 
|  | 381       auto acceptHeaderBeginsAt = buf.find(acceptHeader); | 
|  | 382       if (std::string::npos == acceptHeaderBeginsAt) | 
|  | 383       { | 
|  | 384         return ""; | 
|  | 385       } | 
|  | 386       acceptHeaderBeginsAt += sizeof(acceptHeader); | 
|  | 387       auto acceptHeaderEndsAt = buf.find("\n", acceptHeaderBeginsAt); | 
|  | 388       if (std::string::npos == acceptHeaderEndsAt) | 
|  | 389       { | 
|  | 390         return ""; | 
|  | 391       } | 
|  | 392       return buf.substr(acceptHeaderBeginsAt, acceptHeaderEndsAt - acceptHeaderB
     eginsAt); | 
|  | 393     }(); | 
|  | 394     m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str()
     )); | 
|  | 395     bool isBlocked = client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*
     debug flag but must be set*/true); | 
|  | 396     if (isBlocked) | 
|  | 397     { | 
|  | 398       m_blockedInTransaction = true; | 
|  | 399       return E_ABORT; | 
|  | 400     } | 
|  | 401   } | 
| 364   CComPtr<IHttpNegotiate> spHttpNegotiate; | 402   CComPtr<IHttpNegotiate> spHttpNegotiate; | 
| 365   QueryServiceFromClient(&spHttpNegotiate); | 403   QueryServiceFromClient(&spHttpNegotiate); | 
| 366   return spHttpNegotiate ? spHttpNegotiate->BeginningTransaction(szURL, szHeader
     s,dwReserved, pszAdditionalHeaders) : S_OK; | 404   return spHttpNegotiate ? spHttpNegotiate->BeginningTransaction(szURL, szHeader
     s,dwReserved, pszAdditionalHeaders) : S_OK; | 
| 367 } | 405 } | 
| 368 | 406 | 
| 369 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse
     Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) | 407 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse
     Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) | 
| 370 { | 408 { | 
| 371   if (pszAdditionalRequestHeaders) | 409   if (pszAdditionalRequestHeaders) | 
| 372   { | 410   { | 
| 373     *pszAdditionalRequestHeaders = 0; | 411     *pszAdditionalRequestHeaders = 0; | 
| 374   } | 412   } | 
| 375 | 413 | 
| 376   CComPtr<IHttpNegotiate> spHttpNegotiate; | 414   CComPtr<IHttpNegotiate> spHttpNegotiate; | 
| 377   QueryServiceFromClient(&spHttpNegotiate); | 415   QueryServiceFromClient(&spHttpNegotiate); | 
| 378 | 416 | 
| 379   return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons
     eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK; | 417   return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons
     eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK; | 
| 380 } | 418 } | 
| 381 | 419 | 
| 382 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus
     Text) | 420 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus
     Text) | 
| 383 { | 421 { | 
| 384   return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS
     tatusCode, szStatusText) : S_OK; | 422   return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS
     tatusCode, szStatusText) : S_OK; | 
| 385 } | 423 } | 
| 386 | 424 | 
|  | 425 STDMETHODIMP WBPassthruSink::ReportResult(/* [in] */ HRESULT hrResult, /* [in] *
     / DWORD dwError, /* [in] */ LPCWSTR szResult) | 
|  | 426 { | 
|  | 427   if (m_blockedInTransaction) | 
|  | 428   { | 
|  | 429     // Don't notify the client about aborting of the operation, thus don't call 
     BaseClass::ReportResult. | 
|  | 430     // Current method is called by the original protocol implementation and we a
     re intercepting the | 
|  | 431     // call here and eating it, we will call the proper ReportResult later by ou
     rself. | 
|  | 432     return S_OK; | 
|  | 433   } | 
|  | 434   return BaseClass::ReportResult(hrResult, dwError, szResult); | 
|  | 435 } | 
|  | 436 | 
|  | 437 | 
| 387 WBPassthru::WBPassthru() | 438 WBPassthru::WBPassthru() | 
| 388   : m_shouldSupplyCustomContent(false) | 439   : m_shouldSupplyCustomContent(false) | 
|  | 440   , m_hasOriginalStartCalled(false) | 
| 389 { | 441 { | 
| 390 } | 442 } | 
| 391 | 443 | 
| 392 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink
     , | 444 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink
     , | 
| 393     IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) | 445     IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) | 
| 394 { | 446 { | 
| 395   ATLASSERT(m_spInternetProtocol != 0); | 447   ATLASSERT(m_spInternetProtocol != 0); | 
| 396   if (!m_spInternetProtocol) | 448   if (!m_spInternetProtocol) | 
| 397   { | 449   { | 
| 398     return E_UNEXPECTED; | 450     return E_UNEXPECTED; | 
| 399   } | 451   } | 
| 400 | 452 | 
| 401   return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne
     tProtocol); | 453   return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne
     tProtocol); | 
| 402 } | 454 } | 
| 403 | 455 | 
| 404 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o
     ut] */ ULONG *pcbRead) | 456 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o
     ut] */ ULONG *pcbRead) | 
| 405 { | 457 { | 
| 406   WBPassthruSink* pSink = GetSink(); | 458   WBPassthruSink* pSink = GetSink(); | 
| 407   return pSink->OnRead(pv, cb, pcbRead); | 459   return pSink->OnRead(pv, cb, pcbRead); | 
| 408 } | 460 } | 
| 409 | 461 | 
| 410 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options) | 462 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options) | 
| 411 { | 463 { | 
| 412   if (m_shouldSupplyCustomContent) | 464   if (!m_hasOriginalStartCalled) | 
| 413   { | 465   { | 
| 414     return S_OK; | 466     return S_OK; | 
| 415   } | 467   } | 
| 416   return PassthroughAPP::CInternetProtocol<WBStartPolicy>::LockRequest(options); | 468   return BaseClass::LockRequest(options); | 
| 417 } | 469 } | 
| 418 | 470 | 
| 419 STDMETHODIMP WBPassthru::UnlockRequest() | 471 STDMETHODIMP WBPassthru::UnlockRequest() | 
| 420 { | 472 { | 
| 421   if (m_shouldSupplyCustomContent) | 473   if (!m_hasOriginalStartCalled) | 
| 422   { | 474   { | 
| 423     return S_OK; | 475     return S_OK; | 
| 424   } | 476   } | 
| 425   return PassthroughAPP::CInternetProtocol<WBStartPolicy>::UnlockRequest(); | 477   return BaseClass::UnlockRequest(); | 
| 426 } | 478 } | 
| OLD | NEW | 
|---|