| 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 #include "AdblockPlusClient.h" | 19 #include "AdblockPlusClient.h" |
| 20 #include "PluginClientBase.h" | 20 #include "PluginClientBase.h" |
| 21 #include "PluginSettings.h" | 21 #include "PluginSettings.h" |
| 22 #include "AdblockPlusDomTraverser.h" | 22 #include "AdblockPlusDomTraverser.h" |
| 23 #include "PluginTabBase.h" | 23 #include "PluginTabBase.h" |
| 24 #include "IeVersion.h" | 24 #include "IeVersion.h" |
| 25 #include "../shared/Utils.h" | 25 #include "../shared/Utils.h" |
| 26 #include <Mshtmhst.h> | 26 #include <Mshtmhst.h> |
| 27 #include "../shared/Utils.h" |
| 27 | 28 |
| 28 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) | 29 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) |
| 29 : m_plugin(plugin) | 30 : m_plugin(plugin) |
| 30 , m_isActivated(false) | 31 , m_isActivated(false) |
| 31 , m_continueThreadRunning(true) | 32 , m_continueThreadRunning(true) |
| 32 { | 33 { |
| 33 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); | 34 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); |
| 34 m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL); | 35 m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL); |
| 35 | 36 |
| 36 CPluginClient* client = CPluginClient::GetInstance(); | 37 CPluginClient* client = CPluginClient::GetInstance(); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 } | 159 } |
| 159 DEBUG_GENERAL(L"InjectABP. Injecting"); | 160 DEBUG_GENERAL(L"InjectABP. Injecting"); |
| 160 CComPtr<IDispatch> pDocDispatch; | 161 CComPtr<IDispatch> pDocDispatch; |
| 161 browser->get_Document(&pDocDispatch); | 162 browser->get_Document(&pDocDispatch); |
| 162 CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch; | 163 CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch; |
| 163 if (!pDoc2) | 164 if (!pDoc2) |
| 164 { | 165 { |
| 165 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE
ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume
nt"); | 166 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE
ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume
nt"); |
| 166 return; | 167 return; |
| 167 } | 168 } |
| 169 |
| 168 CComPtr<IHTMLWindow2> pWnd2; | 170 CComPtr<IHTMLWindow2> pWnd2; |
| 169 pDoc2->get_parentWindow(&pWnd2); | 171 pDoc2->get_parentWindow(&pWnd2); |
| 170 if (!pWnd2) | 172 if (!pWnd2) |
| 171 { | 173 { |
| 172 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE
ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren
t window"); | 174 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE
ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren
t window"); |
| 173 return; | 175 return; |
| 174 } | 176 } |
| 175 CComQIPtr<IDispatchEx> pWndEx = pWnd2; | 177 CComQIPtr<IDispatchEx> pWndEx = pWnd2; |
| 176 if (!pWndEx) | 178 if (!pWndEx) |
| 177 { | 179 { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 197 params.rgvarg = &var; | 199 params.rgvarg = &var; |
| 198 params.rgdispidNamedArgs = 0; | 200 params.rgdispidNamedArgs = 0; |
| 199 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU
T | DISPATCH_PROPERTYPUTREF, ¶ms, 0, 0, 0); | 201 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU
T | DISPATCH_PROPERTYPUTREF, ¶ms, 0, 0, 0); |
| 200 DEBUG_GENERAL("Invoke"); | 202 DEBUG_GENERAL("Invoke"); |
| 201 if (FAILED(hr)) | 203 if (FAILED(hr)) |
| 202 { | 204 { |
| 203 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"); | 205 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"); |
| 204 } | 206 } |
| 205 } | 207 } |
| 206 | 208 |
| 209 bool CPluginTabBase::IsTraverserEnabled() |
| 210 { |
| 211 return !IsCSSInjectionEnabled(); |
| 212 } |
| 213 |
| 214 bool CPluginTabBase::IsCSSInjectionEnabled() |
| 215 { |
| 216 return IsWindowsVistaOrLater() && AdblockPlus::IE::InstalledMajorVersion() >=
10; |
| 217 } |
| 218 |
| 219 namespace |
| 220 { |
| 221 void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstrin
g>& hideFilters) |
| 222 { |
| 223 // pseudocode: styleHtmlElement = htmlDocument2.createElement("style"); |
| 224 ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement; |
| 225 { |
| 226 ATL::CComPtr<IHTMLElement> stylePureHtmlElement; |
| 227 if (FAILED(htmlDocument2.createElement(ATL::CComBSTR(L"style"), &stylePure
HtmlElement))) |
| 228 { |
| 229 DEBUG_GENERAL(L"Cannot create style element"); |
| 230 return; |
| 231 } |
| 232 if (!(styleHtmlElement = stylePureHtmlElement)) |
| 233 { |
| 234 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement from IHTMLElement"); |
| 235 return; |
| 236 } |
| 237 } |
| 238 // pseudocode: styleHtmlElement.type = "text/css"; |
| 239 if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css")))) |
| 240 { |
| 241 DEBUG_GENERAL(L"Cannot set type text/css"); |
| 242 return; |
| 243 } |
| 244 // pseudocode: styleSheet4 = styleHtmlElement.sheet; |
| 245 ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4; |
| 246 { |
| 247 // IHTMLStyleElement2 is availabe starting from IE9, Vista |
| 248 ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement; |
| 249 if (!styleHtmlElement2) |
| 250 { |
| 251 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement"
); |
| 252 return; |
| 253 } |
| 254 ATL::CComQIPtr<IHTMLStyleSheet> styleSheet; |
| 255 if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet) |
| 256 { |
| 257 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet"); |
| 258 return; |
| 259 } |
| 260 // IHTMLStyleSheet4 is availabe starting from IE9, Vista |
| 261 styleSheet4 = styleSheet; |
| 262 if (!styleSheet4) |
| 263 { |
| 264 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4"); |
| 265 return; |
| 266 } |
| 267 } |
| 268 // pseudocode: for (auto i = 0; i < hideFilters.length; ++i) { |
| 269 // pseudocode: i = styleSheet4.insertRule(hideFilters + cssValue, i); |
| 270 // pseudocode: } |
| 271 long newIndex = 0; |
| 272 std::wstring cssValue = L"{ display: none !important; }"; |
| 273 for (const auto& selector : hideFilters) |
| 274 { |
| 275 auto cssRule = selector + cssValue; |
| 276 ATL::CComBSTR selector(cssRule.size(), cssRule.c_str()); |
| 277 if (SUCCEEDED(styleSheet4->insertRule(selector, newIndex, &newIndex))) |
| 278 { |
| 279 ++newIndex; |
| 280 } |
| 281 else |
| 282 { |
| 283 DEBUG_GENERAL(L"Cannot add rule for selector " + cssRule); |
| 284 } |
| 285 } |
| 286 |
| 287 // pseudocode: htmlDocument2.head.appendChild(styleHtmlElement); |
| 288 { |
| 289 // IHTMLDocument7 is availabe starting from IE9, Vista |
| 290 ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2; |
| 291 if (!htmlDocument7) |
| 292 { |
| 293 DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2"); |
| 294 return; |
| 295 } |
| 296 ATL::CComPtr<IHTMLElement> headHtmlElement; |
| 297 if (FAILED(htmlDocument7->get_head(&headHtmlElement))) |
| 298 { |
| 299 DEBUG_GENERAL(L"Cannot obtain head from pDoc7"); |
| 300 return; |
| 301 } |
| 302 ATL::CComQIPtr<IHTMLDOMNode> headNode = headHtmlElement; |
| 303 if (!headNode) |
| 304 { |
| 305 DEBUG_GENERAL(L"Cannot obtain headNode from headHtmlElement"); |
| 306 return; |
| 307 } |
| 308 ATL::CComQIPtr<IHTMLDOMNode> styleNode = styleHtmlElement; |
| 309 if (!styleNode) |
| 310 { |
| 311 DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement"); |
| 312 return; |
| 313 } |
| 314 if (FAILED(headNode->appendChild(styleNode, nullptr))) |
| 315 { |
| 316 DEBUG_GENERAL(L"Cannot append blocking style"); |
| 317 } |
| 318 } |
| 319 } |
| 320 } |
| 321 |
| 207 namespace | 322 namespace |
| 208 { | 323 { |
| 209 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) | 324 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) |
| 210 { | 325 { |
| 211 ATL::CComPtr<IDispatch> parentDispatch; | 326 ATL::CComPtr<IDispatch> parentDispatch; |
| 212 if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch) | 327 if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch) |
| 213 { | 328 { |
| 214 return nullptr; | 329 return nullptr; |
| 215 } | 330 } |
| 216 // The InternetExplorer application always returns a pointer to itself. | 331 // The InternetExplorer application always returns a pointer to itself. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 245 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); | 360 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); |
| 246 } | 361 } |
| 247 CPluginClient* client = CPluginClient::GetInstance(); | 362 CPluginClient* client = CPluginClient::GetInstance(); |
| 248 return client->IsWhitelistedUrl(url, frameHierarchy) | 363 return client->IsWhitelistedUrl(url, frameHierarchy) |
| 249 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); | 364 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); |
| 250 } | 365 } |
| 251 } | 366 } |
| 252 | 367 |
| 253 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) | 368 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) |
| 254 { | 369 { |
| 255 CPluginClient* client = CPluginClient::GetInstance(); | 370 if (IsTraverserEnabled()) |
| 256 std::wstring url = GetDocumentUrl(); | |
| 257 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u
rl)) | |
| 258 { | 371 { |
| 259 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl()
); | 372 CPluginClient* client = CPluginClient::GetInstance(); |
| 373 std::wstring url = GetDocumentUrl(); |
| 374 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain
(url)) |
| 375 { |
| 376 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl
()); |
| 377 } |
| 260 } | 378 } |
| 261 InjectABP(browser); | 379 InjectABP(browser); |
| 262 } | 380 } |
| 263 | 381 |
| 264 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin
g& url, bool isDocumentBrowser) | 382 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin
g& url, bool isDocumentBrowser) |
| 265 { | 383 { |
| 266 std::wstring documentUrl = GetDocumentUrl(); | 384 std::wstring documentUrl = GetDocumentUrl(); |
| 267 | 385 |
| 268 if (isDocumentBrowser) | 386 if (isDocumentBrowser) |
| 269 { | 387 { |
| 270 if (url != documentUrl) | 388 if (url != documentUrl) |
| 271 { | 389 { |
| 272 SetDocumentUrl(url); | 390 SetDocumentUrl(url); |
| 273 } | 391 } |
| 274 InjectABP(browser); | 392 InjectABP(browser); |
| 275 } | 393 } |
| 276 CString urlLegacy = ToCString(url); | 394 CString urlLegacy = ToCString(url); |
| 277 if (urlLegacy.Left(6) != "res://") | 395 if (urlLegacy.Left(6) == "res://") |
| 278 { | 396 { |
| 279 // Get document | 397 return; |
| 280 CComPtr<IDispatch> pDocDispatch; | 398 } |
| 281 HRESULT hr = browser->get_Document(&pDocDispatch); | 399 // Get document |
| 282 if (FAILED(hr) || !pDocDispatch) | 400 CComPtr<IDispatch> pDocDispatch; |
| 401 HRESULT hr = browser->get_Document(&pDocDispatch); |
| 402 if (FAILED(hr) || !pDocDispatch) |
| 403 { |
| 404 return; |
| 405 } |
| 406 |
| 407 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; |
| 408 if (!pDoc) |
| 409 { |
| 410 return; |
| 411 } |
| 412 |
| 413 if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable
d()) |
| 414 { |
| 415 if (!IsFrameWhiteListed(browser)) |
| 283 { | 416 { |
| 284 return; | 417 DEBUG_GENERAL(L"Inject CSS into " + url); |
| 418 InjectABPCSS(*pDoc, m_filter->GetHideFilters()); |
| 285 } | 419 } |
| 420 } |
| 286 | 421 |
| 287 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; | 422 CComPtr<IOleObject> pOleObj; |
| 288 if (!pDoc) | 423 pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); |
| 424 |
| 425 CComPtr<IOleClientSite> pClientSite; |
| 426 pOleObj->GetClientSite(&pClientSite); |
| 427 if (pClientSite != NULL) |
| 428 { |
| 429 CComPtr<IDocHostUIHandler> docHostUIHandler; |
| 430 pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler
); |
| 431 if (docHostUIHandler != NULL) |
| 289 { | 432 { |
| 290 return; | 433 docHostUIHandler->UpdateUI(); |
| 291 } | |
| 292 CComPtr<IOleObject> pOleObj; | |
| 293 | |
| 294 pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); | |
| 295 | |
| 296 | |
| 297 CComPtr<IOleClientSite> pClientSite; | |
| 298 pOleObj->GetClientSite(&pClientSite); | |
| 299 if (pClientSite != NULL) | |
| 300 { | |
| 301 CComPtr<IDocHostUIHandler> docHostUIHandler; | |
| 302 pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandl
er); | |
| 303 if (docHostUIHandler != NULL) | |
| 304 { | |
| 305 docHostUIHandler->UpdateUI(); | |
| 306 } | |
| 307 } | 434 } |
| 308 } | 435 } |
| 309 } | 436 } |
| 310 | 437 |
| 311 std::wstring CPluginTabBase::GetDocumentDomain() | 438 std::wstring CPluginTabBase::GetDocumentDomain() |
| 312 { | 439 { |
| 313 std::wstring domain; | 440 std::wstring domain; |
| 314 | 441 |
| 315 m_criticalSection.Lock(); | 442 m_criticalSection.Lock(); |
| 316 { | 443 { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr
rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p
luginError.GetProcessId(), pluginError.GetThreadId()); | 559 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr
rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p
luginError.GetProcessId(), pluginError.GetThreadId()); |
| 433 } | 560 } |
| 434 | 561 |
| 435 // Non-hanging sleep | 562 // Non-hanging sleep |
| 436 Sleep(50); | 563 Sleep(50); |
| 437 } | 564 } |
| 438 | 565 |
| 439 tabLoopIteration++; | 566 tabLoopIteration++; |
| 440 } | 567 } |
| 441 } | 568 } |
| OLD | NEW |