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 = stylePureHtmlElement = htmlDocument2.creat
eElement("style"); |
| 197 // pseudocode: stylePureHtmlElement is used later to get styleNode |
| 198 ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement; |
| 199 { |
| 200 ATL::CComPtr<IHTMLElement> stylePureHtmlElement; |
| 201 if (FAILED(htmlDocument2.createElement(ATL::CComBSTR(L"style"), &stylePure
HtmlElement))) |
| 202 { |
| 203 DEBUG_GENERAL(L"Cannot create style element"); |
| 204 return; |
| 205 } |
| 206 if (!(styleHtmlElement = stylePureHtmlElement)) |
| 207 { |
| 208 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement from IHTMLElement"); |
| 209 return; |
| 210 } |
| 211 } |
| 212 // pseudocode: styleHtmlElement.type = "text/css"; |
| 213 if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css")))) |
| 214 { |
| 215 DEBUG_GENERAL(L"Cannot set type text/css"); |
| 216 return; |
| 217 } |
| 218 // pseudocode: styleSheet4 = styleHtmlElement.sheet; |
| 219 ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4; |
| 220 { |
| 221 // IHTMLStyleElement2 is availabe starting from IE9, Vista |
| 222 ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement; |
| 223 if (!styleHtmlElement2) |
| 224 { |
| 225 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement"
); |
| 226 return; |
| 227 } |
| 228 ATL::CComQIPtr<IHTMLStyleSheet> styleSheet; |
| 229 if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet) |
| 230 { |
| 231 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet"); |
| 232 return; |
| 233 } |
| 234 // IHTMLStyleSheet4 is availabe starting from IE9, Vista |
| 235 styleSheet4 = styleSheet; |
| 236 if (!styleSheet4) |
| 237 { |
| 238 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4"); |
| 239 return; |
| 240 } |
| 241 } |
| 242 // pseudocode: for (auto i = 0; i < hideFilters.length; ++i) { |
| 243 // pseudocode: i = styleSheet4.insertRule(hideFilters + cssValue, i); |
| 244 // pseudocode: } |
| 245 long newIndex = 0; |
| 246 std::wstring cssValue = L"{ display: none !important; }"; |
| 247 for (const auto& selector : hideFilters) |
| 248 { |
| 249 auto cssRule = selector + cssValue; |
| 250 ATL::CComBSTR selector(cssRule.size(), cssRule.c_str()); |
| 251 if (SUCCEEDED(styleSheet4->insertRule(selector, newIndex, &newIndex))) |
| 252 { |
| 253 ++newIndex; |
| 254 } |
| 255 else |
| 256 { |
| 257 DEBUG_GENERAL(L"Cannot add rule for selector " + cssRule); |
| 258 } |
| 259 } |
| 260 |
| 261 // pseudocode: htmlDocument2.head.appendChild(styleHtmlElement); |
| 262 { |
| 263 // IHTMLDocument7 is availabe starting from IE9, Vista |
| 264 ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2; |
| 265 if (!htmlDocument7) |
| 266 { |
| 267 DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2"); |
| 268 return; |
| 269 } |
| 270 ATL::CComPtr<IHTMLElement> headHtmlElement; |
| 271 if (FAILED(htmlDocument7->get_head(&headHtmlElement))) |
| 272 { |
| 273 DEBUG_GENERAL(L"Cannot obtain head from pDoc7"); |
| 274 return; |
| 275 } |
| 276 ATL::CComQIPtr<IHTMLDOMNode> headNode = headHtmlElement; |
| 277 if (!headNode) |
| 278 { |
| 279 DEBUG_GENERAL(L"Cannot obtain headNode from headHtmlElement"); |
| 280 return; |
| 281 } |
| 282 ATL::CComQIPtr<IHTMLDOMNode> styleNode = styleHtmlElement; |
| 283 if (!styleNode) |
| 284 { |
| 285 DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement"); |
| 286 return; |
| 287 } |
| 288 if (FAILED(headNode->appendChild(styleNode, nullptr))) |
| 289 { |
| 290 DEBUG_GENERAL(L"Cannot append blocking style"); |
| 291 } |
| 292 } |
| 293 } |
| 294 } |
| 295 |
180 namespace | 296 namespace |
181 { | 297 { |
182 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) | 298 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) |
183 { | 299 { |
184 ATL::CComPtr<IDispatch> browserParentDispatch; | 300 ATL::CComPtr<IDispatch> browserParentDispatch; |
185 if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp
atch) | 301 if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp
atch) |
186 { | 302 { |
187 return nullptr; | 303 return nullptr; |
188 } | 304 } |
189 // The InternetExplorer application always returns a pointer to itself. | 305 // The InternetExplorer application always returns a pointer to itself. |
(...skipping 27 matching lines...) Expand all Loading... |
217 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); | 333 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); |
218 } | 334 } |
219 CPluginClient* client = CPluginClient::GetInstance(); | 335 CPluginClient* client = CPluginClient::GetInstance(); |
220 return client->IsWhitelistedUrl(url, frameHierarchy) | 336 return client->IsWhitelistedUrl(url, frameHierarchy) |
221 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); | 337 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); |
222 } | 338 } |
223 } | 339 } |
224 | 340 |
225 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) | 341 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) |
226 { | 342 { |
227 CPluginClient* client = CPluginClient::GetInstance(); | 343 if (IsTraverserEnabled()) |
228 std::wstring url = GetDocumentUrl(); | |
229 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u
rl)) | |
230 { | 344 { |
231 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl()
); | 345 CPluginClient* client = CPluginClient::GetInstance(); |
| 346 std::wstring url = GetDocumentUrl(); |
| 347 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain
(url)) |
| 348 { |
| 349 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl
()); |
| 350 } |
232 } | 351 } |
233 InjectABP(browser); | 352 InjectABP(browser); |
234 } | 353 } |
235 | 354 |
236 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin
g& url, bool isDocumentBrowser) | 355 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin
g& url, bool isDocumentBrowser) |
237 { | 356 { |
238 std::wstring documentUrl = GetDocumentUrl(); | 357 std::wstring documentUrl = GetDocumentUrl(); |
239 | 358 |
240 if (isDocumentBrowser) | 359 if (isDocumentBrowser) |
241 { | 360 { |
242 if (url != documentUrl) | 361 if (url != documentUrl) |
243 { | 362 { |
244 SetDocumentUrl(url); | 363 SetDocumentUrl(url); |
245 } | 364 } |
246 InjectABP(browser); | 365 InjectABP(browser); |
247 } | 366 } |
248 CString urlLegacy = ToCString(url); | 367 CString urlLegacy = ToCString(url); |
249 if (urlLegacy.Left(6) != "res://") | 368 if (urlLegacy.Left(6) == "res://") |
250 { | 369 { |
251 // Get document | 370 return; |
252 CComPtr<IDispatch> pDocDispatch; | 371 } |
253 HRESULT hr = browser->get_Document(&pDocDispatch); | 372 // Get document |
254 if (FAILED(hr) || !pDocDispatch) | 373 CComPtr<IDispatch> pDocDispatch; |
| 374 HRESULT hr = browser->get_Document(&pDocDispatch); |
| 375 if (FAILED(hr) || !pDocDispatch) |
| 376 { |
| 377 return; |
| 378 } |
| 379 |
| 380 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; |
| 381 if (!pDoc) |
| 382 { |
| 383 return; |
| 384 } |
| 385 |
| 386 if (IsCSSInjectionEnabled()) |
| 387 { |
| 388 if (!IsFrameWhiteListed(browser)) |
255 { | 389 { |
256 return; | 390 DEBUG_GENERAL(L"Inject CSS into " + url); |
| 391 InjectABPCSS(*pDoc, m_filter->GetHideFilters()); |
257 } | 392 } |
| 393 } |
258 | 394 |
259 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; | 395 CComPtr<IOleObject> pOleObj; |
260 if (!pDoc) | 396 pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); |
| 397 |
| 398 CComPtr<IOleClientSite> pClientSite; |
| 399 pOleObj->GetClientSite(&pClientSite); |
| 400 if (pClientSite != NULL) |
| 401 { |
| 402 CComPtr<IDocHostUIHandler> docHostUIHandler; |
| 403 pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler
); |
| 404 if (docHostUIHandler != NULL) |
261 { | 405 { |
262 return; | 406 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 } | 407 } |
280 } | 408 } |
281 } | 409 } |
282 | 410 |
283 std::wstring CPluginTabBase::GetDocumentDomain() | 411 std::wstring CPluginTabBase::GetDocumentDomain() |
284 { | 412 { |
285 std::wstring domain; | 413 std::wstring domain; |
286 | 414 |
287 m_criticalSection.Lock(); | 415 m_criticalSection.Lock(); |
288 { | 416 { |
(...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()); | 532 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr
rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p
luginError.GetProcessId(), pluginError.GetThreadId()); |
405 } | 533 } |
406 | 534 |
407 // Non-hanging sleep | 535 // Non-hanging sleep |
408 Sleep(50); | 536 Sleep(50); |
409 } | 537 } |
410 | 538 |
411 tabLoopIteration++; | 539 tabLoopIteration++; |
412 } | 540 } |
413 } | 541 } |
OLD | NEW |