| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2015 Eyeo GmbH | 3  * Copyright (C) 2006-2015 Eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 12  * GNU General Public License for more details. | 12  * GNU General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU General Public License | 14  * You should have received a copy of the GNU General Public License | 
| 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 16  */ | 16  */ | 
| 17 | 17 | 
| 18 #include "PluginStdAfx.h" | 18 #include "PluginStdAfx.h" | 
| 19 | 19 | 
| 20 #include "PluginClient.h" | 20 #include "PluginClient.h" | 
| 21 #include "PluginSettings.h" | 21 #include "PluginSettings.h" | 
| 22 #include "AdblockPlusDomTraverser.h" | 22 #include "AdblockPlusDomTraverser.h" | 
| 23 #include "PluginClass.h" | 23 #include "PluginClass.h" | 
| 24 #include "PluginTabBase.h" | 24 #include "PluginTabBase.h" | 
| 25 #include "PluginUtil.h" | 25 #include "PluginUtil.h" | 
| 26 #include "../shared/IE_version.h" | 26 #include "../shared/IE_version.h" | 
| 27 #include <dispex.h> | 27 #include <dispex.h> | 
| 28 #include <Mshtmhst.h> | 28 #include <Mshtmhst.h> | 
|  | 29 #include "../shared/Utils.h" | 
| 29 | 30 | 
| 30 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) | 31 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) | 
| 31   : m_plugin(plugin) | 32   : m_plugin(plugin) | 
| 32   , m_isActivated(false) | 33   , m_isActivated(false) | 
| 33   , m_continueThreadRunning(true) | 34   , m_continueThreadRunning(true) | 
| 34 { | 35 { | 
| 35   m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); | 36   m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); | 
| 36   m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL); | 37   m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL); | 
| 37 | 38 | 
| 38   CPluginClient* client = CPluginClient::GetInstance(); | 39   CPluginClient* client = CPluginClient::GetInstance(); | 
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 131   } | 132   } | 
| 132   DEBUG_GENERAL(L"Going to inject"); | 133   DEBUG_GENERAL(L"Going to inject"); | 
| 133   CComPtr<IDispatch> pDocDispatch; | 134   CComPtr<IDispatch> pDocDispatch; | 
| 134   browser->get_Document(&pDocDispatch); | 135   browser->get_Document(&pDocDispatch); | 
| 135   CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch; | 136   CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch; | 
| 136   if (!pDoc2) | 137   if (!pDoc2) | 
| 137   { | 138   { | 
| 138     DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE
     ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume
     nt"); | 139     DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE
     ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume
     nt"); | 
| 139     return; | 140     return; | 
| 140   } | 141   } | 
|  | 142 | 
| 141   CComPtr<IHTMLWindow2> pWnd2; | 143   CComPtr<IHTMLWindow2> pWnd2; | 
| 142   pDoc2->get_parentWindow(&pWnd2); | 144   pDoc2->get_parentWindow(&pWnd2); | 
| 143   if (!pWnd2) | 145   if (!pWnd2) | 
| 144   { | 146   { | 
| 145     DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE
     ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren
     t window"); | 147     DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE
     ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren
     t window"); | 
| 146     return; | 148     return; | 
| 147   } | 149   } | 
| 148   CComQIPtr<IDispatchEx> pWndEx = pWnd2; | 150   CComQIPtr<IDispatchEx> pWndEx = pWnd2; | 
| 149   if (!pWndEx) | 151   if (!pWndEx) | 
| 150   { | 152   { | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 170   params.rgvarg = &var; | 172   params.rgvarg = &var; | 
| 171   params.rgdispidNamedArgs = 0; | 173   params.rgdispidNamedArgs = 0; | 
| 172   hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU
     T | DISPATCH_PROPERTYPUTREF, ¶ms, 0, 0, 0); | 174   hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU
     T | DISPATCH_PROPERTYPUTREF, ¶ms, 0, 0, 0); | 
| 173   DEBUG_GENERAL("Invoke"); | 175   DEBUG_GENERAL("Invoke"); | 
| 174   if (FAILED(hr)) | 176   if (FAILED(hr)) | 
| 175   { | 177   { | 
| 176     DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR
     EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to create S
     ettings in JavaScript"); | 178     DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR
     EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to create S
     ettings in JavaScript"); | 
| 177   } | 179   } | 
| 178 } | 180 } | 
| 179 | 181 | 
|  | 182 bool CPluginTabBase::IsTraverserEnabled() | 
|  | 183 { | 
|  | 184   return !IsCSSInjectionEnabled(); | 
|  | 185 } | 
|  | 186 | 
|  | 187 bool CPluginTabBase::IsCSSInjectionEnabled() | 
|  | 188 { | 
|  | 189   return IsWindowsVistaOrLater() && AdblockPlus::IE::InstalledMajorVersion() >= 
     10; | 
|  | 190 } | 
|  | 191 | 
|  | 192 namespace | 
|  | 193 { | 
|  | 194   void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstrin
     g>& hideFilters) | 
|  | 195   { | 
|  | 196     // pseudocode: styleHtmlElement = htmlDocument2.createElement("style"); | 
|  | 197     ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement; | 
|  | 198     { | 
|  | 199       ATL::CComPtr<IHTMLElement> stylePureHtmlElement; | 
|  | 200       if (FAILED(htmlDocument2.createElement(ATL::CComBSTR(L"style"), &stylePure
     HtmlElement))) | 
|  | 201       { | 
|  | 202         DEBUG_GENERAL(L"Cannot create style element"); | 
|  | 203         return; | 
|  | 204       } | 
|  | 205       if (!(styleHtmlElement = stylePureHtmlElement)) | 
|  | 206       { | 
|  | 207         DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement from IHTMLElement"); | 
|  | 208         return; | 
|  | 209       } | 
|  | 210     } | 
|  | 211     // pseudocode: styleHtmlElement.type = "text/css"; | 
|  | 212     if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css")))) | 
|  | 213     { | 
|  | 214       DEBUG_GENERAL(L"Cannot set type text/css"); | 
|  | 215       return; | 
|  | 216     } | 
|  | 217     // pseudocode: styleSheet4 = styleHtmlElement.sheet; | 
|  | 218     ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4; | 
|  | 219     { | 
|  | 220       // IHTMLStyleElement2 is availabe starting from IE9, Vista | 
|  | 221       ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement; | 
|  | 222       if (!styleHtmlElement2) | 
|  | 223       { | 
|  | 224         DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement"
     ); | 
|  | 225         return; | 
|  | 226       } | 
|  | 227       ATL::CComQIPtr<IHTMLStyleSheet> styleSheet; | 
|  | 228       if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet) | 
|  | 229       { | 
|  | 230         DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet"); | 
|  | 231         return; | 
|  | 232       } | 
|  | 233       // IHTMLStyleSheet4 is availabe starting from IE9, Vista | 
|  | 234       styleSheet4 = styleSheet; | 
|  | 235       if (!styleSheet4) | 
|  | 236       { | 
|  | 237         DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4"); | 
|  | 238         return; | 
|  | 239       } | 
|  | 240     } | 
|  | 241     // pseudocode: for (auto i = 0; i < hideFilters.length; ++i) { | 
|  | 242     // pseudocode:   i = styleSheet4.insertRule(hideFilters + cssValue, i); | 
|  | 243     // pseudocode: } | 
|  | 244     long newIndex = 0; | 
|  | 245     std::wstring cssValue = L"{ display: none !important; }"; | 
|  | 246     for (const auto& selector : hideFilters) | 
|  | 247     { | 
|  | 248       auto cssRule = selector + cssValue; | 
|  | 249       ATL::CComBSTR selector(cssRule.size(), cssRule.c_str()); | 
|  | 250       if (SUCCEEDED(styleSheet4->insertRule(selector, newIndex, &newIndex))) | 
|  | 251       { | 
|  | 252         ++newIndex; | 
|  | 253       } | 
|  | 254       else | 
|  | 255       { | 
|  | 256         DEBUG_GENERAL(L"Cannot add rule for selector " + cssRule); | 
|  | 257       } | 
|  | 258     } | 
|  | 259 | 
|  | 260     // pseudocode: htmlDocument2.head.appendChild(styleHtmlElement); | 
|  | 261     { | 
|  | 262       // IHTMLDocument7 is availabe starting from IE9, Vista | 
|  | 263       ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2; | 
|  | 264       if (!htmlDocument7) | 
|  | 265       { | 
|  | 266         DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2"); | 
|  | 267         return; | 
|  | 268       } | 
|  | 269       ATL::CComPtr<IHTMLElement> headHtmlElement; | 
|  | 270       if (FAILED(htmlDocument7->get_head(&headHtmlElement))) | 
|  | 271       { | 
|  | 272         DEBUG_GENERAL(L"Cannot obtain head from pDoc7"); | 
|  | 273         return; | 
|  | 274       } | 
|  | 275       ATL::CComQIPtr<IHTMLDOMNode> headNode = headHtmlElement; | 
|  | 276       if (!headNode) | 
|  | 277       { | 
|  | 278         DEBUG_GENERAL(L"Cannot obtain headNode from headHtmlElement"); | 
|  | 279         return; | 
|  | 280       } | 
|  | 281       ATL::CComQIPtr<IHTMLDOMNode> styleNode = styleHtmlElement; | 
|  | 282       if (!styleNode) | 
|  | 283       { | 
|  | 284         DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement"); | 
|  | 285         return; | 
|  | 286       } | 
|  | 287       if (FAILED(headNode->appendChild(styleNode, nullptr))) | 
|  | 288       { | 
|  | 289         DEBUG_GENERAL(L"Cannot append blocking style"); | 
|  | 290       } | 
|  | 291     } | 
|  | 292   } | 
|  | 293 } | 
|  | 294 | 
| 180 namespace | 295 namespace | 
| 181 { | 296 { | 
| 182   ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) | 297   ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) | 
| 183   { | 298   { | 
| 184     ATL::CComPtr<IDispatch> browserParentDispatch; | 299     ATL::CComPtr<IDispatch> browserParentDispatch; | 
| 185     if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp
     atch) | 300     if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp
     atch) | 
| 186     { | 301     { | 
| 187       return nullptr; | 302       return nullptr; | 
| 188     } | 303     } | 
| 189     // The InternetExplorer application always returns a pointer to itself. | 304     // The InternetExplorer application always returns a pointer to itself. | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 217       frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); | 332       frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); | 
| 218     } | 333     } | 
| 219     CPluginClient* client = CPluginClient::GetInstance(); | 334     CPluginClient* client = CPluginClient::GetInstance(); | 
| 220     return client->IsWhitelistedUrl(url, frameHierarchy) | 335     return client->IsWhitelistedUrl(url, frameHierarchy) | 
| 221         || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); | 336         || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); | 
| 222   } | 337   } | 
| 223 } | 338 } | 
| 224 | 339 | 
| 225 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) | 340 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) | 
| 226 { | 341 { | 
| 227   CPluginClient* client = CPluginClient::GetInstance(); | 342   if (IsTraverserEnabled()) | 
| 228   std::wstring url = GetDocumentUrl(); |  | 
| 229   if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u
     rl)) |  | 
| 230   { | 343   { | 
| 231     m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl()
     ); | 344     CPluginClient* client = CPluginClient::GetInstance(); | 
|  | 345     std::wstring url = GetDocumentUrl(); | 
|  | 346     if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain
     (url)) | 
|  | 347     { | 
|  | 348       m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl
     ()); | 
|  | 349     } | 
| 232   } | 350   } | 
| 233   InjectABP(browser); | 351   InjectABP(browser); | 
| 234 } | 352 } | 
| 235 | 353 | 
| 236 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin
     g& url, bool isDocumentBrowser) | 354 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin
     g& url, bool isDocumentBrowser) | 
| 237 { | 355 { | 
| 238   std::wstring documentUrl = GetDocumentUrl(); | 356   std::wstring documentUrl = GetDocumentUrl(); | 
| 239 | 357 | 
| 240   if (isDocumentBrowser) | 358   if (isDocumentBrowser) | 
| 241   { | 359   { | 
| 242     if (url != documentUrl) | 360     if (url != documentUrl) | 
| 243     { | 361     { | 
| 244       SetDocumentUrl(url); | 362       SetDocumentUrl(url); | 
| 245     } | 363     } | 
| 246     InjectABP(browser); | 364     InjectABP(browser); | 
| 247   } | 365   } | 
| 248   CString urlLegacy = ToCString(url); | 366   CString urlLegacy = ToCString(url); | 
| 249   if (urlLegacy.Left(6) != "res://") | 367   if (urlLegacy.Left(6) == "res://") | 
| 250   { | 368   { | 
| 251     // Get document | 369     return; | 
| 252     CComPtr<IDispatch> pDocDispatch; | 370   } | 
| 253     HRESULT hr = browser->get_Document(&pDocDispatch); | 371   // Get document | 
| 254     if (FAILED(hr) || !pDocDispatch) | 372   CComPtr<IDispatch> pDocDispatch; | 
|  | 373   HRESULT hr = browser->get_Document(&pDocDispatch); | 
|  | 374   if (FAILED(hr) || !pDocDispatch) | 
|  | 375   { | 
|  | 376     return; | 
|  | 377   } | 
|  | 378 | 
|  | 379   CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; | 
|  | 380   if (!pDoc) | 
|  | 381   { | 
|  | 382     return; | 
|  | 383   } | 
|  | 384 | 
|  | 385   if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable
     d()) | 
|  | 386   { | 
|  | 387     if (!IsFrameWhiteListed(browser)) | 
| 255     { | 388     { | 
| 256       return; | 389       DEBUG_GENERAL(L"Inject CSS into " + url); | 
|  | 390       InjectABPCSS(*pDoc, m_filter->GetHideFilters()); | 
| 257     } | 391     } | 
|  | 392   } | 
| 258 | 393 | 
| 259     CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; | 394   CComPtr<IOleObject> pOleObj; | 
| 260     if (!pDoc) | 395   pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); | 
|  | 396 | 
|  | 397   CComPtr<IOleClientSite> pClientSite; | 
|  | 398   pOleObj->GetClientSite(&pClientSite); | 
|  | 399   if (pClientSite != NULL) | 
|  | 400   { | 
|  | 401     CComPtr<IDocHostUIHandler> docHostUIHandler; | 
|  | 402     pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler
     ); | 
|  | 403     if (docHostUIHandler != NULL) | 
| 261     { | 404     { | 
| 262       return; | 405       docHostUIHandler->UpdateUI(); | 
| 263     } |  | 
| 264     CComPtr<IOleObject> pOleObj; |  | 
| 265 |  | 
| 266     pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); |  | 
| 267 |  | 
| 268 |  | 
| 269     CComPtr<IOleClientSite> pClientSite; |  | 
| 270     pOleObj->GetClientSite(&pClientSite); |  | 
| 271     if (pClientSite != NULL) |  | 
| 272     { |  | 
| 273       CComPtr<IDocHostUIHandler> docHostUIHandler; |  | 
| 274       pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandl
     er); |  | 
| 275       if (docHostUIHandler != NULL) |  | 
| 276       { |  | 
| 277         docHostUIHandler->UpdateUI(); |  | 
| 278       } |  | 
| 279     } | 406     } | 
| 280   } | 407   } | 
| 281 } | 408 } | 
| 282 | 409 | 
| 283 std::wstring CPluginTabBase::GetDocumentDomain() | 410 std::wstring CPluginTabBase::GetDocumentDomain() | 
| 284 { | 411 { | 
| 285   std::wstring domain; | 412   std::wstring domain; | 
| 286 | 413 | 
| 287   m_criticalSection.Lock(); | 414   m_criticalSection.Lock(); | 
| 288   { | 415   { | 
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 404           LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr
     rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p
     luginError.GetProcessId(), pluginError.GetThreadId()); | 531           LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr
     rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p
     luginError.GetProcessId(), pluginError.GetThreadId()); | 
| 405         } | 532         } | 
| 406 | 533 | 
| 407         // Non-hanging sleep | 534         // Non-hanging sleep | 
| 408         Sleep(50); | 535         Sleep(50); | 
| 409       } | 536       } | 
| 410 | 537 | 
| 411       tabLoopIteration++; | 538       tabLoopIteration++; | 
| 412   } | 539   } | 
| 413 } | 540 } | 
| OLD | NEW | 
|---|