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 |