| LEFT | RIGHT |
| 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-2016 Eyeo GmbH | 3 * Copyright (C) 2006-2016 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 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "PluginSystem.h" | 22 #include "PluginSystem.h" |
| 23 #include "PluginFilter.h" | 23 #include "PluginFilter.h" |
| 24 #include "PluginMimeFilterClient.h" | 24 #include "PluginMimeFilterClient.h" |
| 25 #include "AdblockPlusClient.h" | 25 #include "AdblockPlusClient.h" |
| 26 #include "PluginClientFactory.h" | 26 #include "PluginClientFactory.h" |
| 27 #include "PluginUtil.h" | 27 #include "PluginUtil.h" |
| 28 #include "../shared/Utils.h" | 28 #include "../shared/Utils.h" |
| 29 #include "../shared/Dictionary.h" | 29 #include "../shared/Dictionary.h" |
| 30 #include "IeVersion.h" | 30 #include "IeVersion.h" |
| 31 #include "../shared/Version.h" | 31 #include "../shared/Version.h" |
| 32 #include "Instances.h" |
| 32 #include <thread> | 33 #include <thread> |
| 33 #include <array> | 34 #include <array> |
| 34 | 35 |
| 35 #ifdef DEBUG_HIDE_EL | 36 #ifdef DEBUG_HIDE_EL |
| 36 DWORD profileTime = 0; | 37 DWORD profileTime = 0; |
| 37 #endif | 38 #endif |
| 38 | 39 |
| 39 extern CComModule _Module; | 40 extern CComModule _Module; |
| 40 | 41 |
| 41 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); | 42 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); |
| 42 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR
ECT); | 43 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR
ECT); |
| 43 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); | 44 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); |
| 44 | 45 |
| 45 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; | 46 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; |
| 46 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL
ED, IDI_ICON_DEACTIVATED }; | 47 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL
ED, IDI_ICON_DEACTIVATED }; |
| 47 uint32_t iconHeight = 32; | 48 uint32_t iconHeight = 32; |
| 48 uint32_t iconWidth = 32; | 49 uint32_t iconWidth = 32; |
| 49 | 50 |
| 50 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; | 51 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; |
| 51 | 52 |
| 52 CLOSETHEMEDATA pfnClose = NULL; | 53 CLOSETHEMEDATA pfnClose = NULL; |
| 53 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; | 54 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; |
| 54 OPENTHEMEDATA pfnOpenThemeData = NULL; | 55 OPENTHEMEDATA pfnOpenThemeData = NULL; |
| 55 | 56 |
| 56 ATOM CPluginClass::s_atomPaneClass = NULL; | 57 ATOM CPluginClass::s_atomPaneClass = NULL; |
| 57 HINSTANCE CPluginClass::s_hUxtheme = NULL; | 58 HINSTANCE CPluginClass::s_hUxtheme = NULL; |
| 58 std::set<CPluginClass*> CPluginClass::s_instances; | 59 std::set<CPluginClass*> CPluginClass::s_instances; |
| 59 std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances; | |
| 60 | 60 |
| 61 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; | 61 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; |
| 62 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; | 62 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; |
| 63 | 63 |
| 64 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; | 64 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; |
| 65 |
| 66 namespace |
| 67 { |
| 68 /** |
| 69 * A synchronized map whose key is always the current thread ID. |
| 70 */ |
| 71 class CurrentThreadMap |
| 72 : public SyncMap<DWORD, CPluginClass*, nullptr> |
| 73 { |
| 74 typedef SyncMap<DWORD, CPluginClass*, nullptr> Base; |
| 75 |
| 76 public: |
| 77 bool AddIfAbsent(CPluginClass* p) |
| 78 { |
| 79 return Base::AddIfAbsent(::GetCurrentThreadId(), p); |
| 80 } |
| 81 |
| 82 bool RemoveAndCheck() |
| 83 { |
| 84 return Base::RemoveIfPresent(::GetCurrentThreadId()); |
| 85 } |
| 86 |
| 87 CPluginClass* Locate() |
| 88 { |
| 89 return Base::Locate(::GetCurrentThreadId()); |
| 90 } |
| 91 }; |
| 92 |
| 93 /** |
| 94 * Map from thread ID's to CPluginClass instances |
| 95 */ |
| 96 CurrentThreadMap threadMap; |
| 97 } |
| 65 | 98 |
| 66 /* | 99 /* |
| 67 * Without namespace declaration, the identifier "Rectangle" is ambiguous | 100 * Without namespace declaration, the identifier "Rectangle" is ambiguous |
| 68 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85)
.aspx | 101 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85)
.aspx |
| 69 */ | 102 */ |
| 70 namespace AdblockPlus | 103 namespace AdblockPlus |
| 71 { | 104 { |
| 72 /** | 105 /** |
| 73 * Replacement for ATL type CRect. | 106 * Replacement for ATL type CRect. |
| 74 */ | 107 */ |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 // _CrtDumpMemoryLeaks(); | 143 // _CrtDumpMemoryLeaks(); |
| 111 | 144 |
| 112 m_isAdvised = false; | 145 m_isAdvised = false; |
| 113 m_hTabWnd = NULL; | 146 m_hTabWnd = NULL; |
| 114 m_hStatusBarWnd = NULL; | 147 m_hStatusBarWnd = NULL; |
| 115 m_hPaneWnd = NULL; | 148 m_hPaneWnd = NULL; |
| 116 m_nPaneWidth = 0; | 149 m_nPaneWidth = 0; |
| 117 m_pWndProcStatus = NULL; | 150 m_pWndProcStatus = NULL; |
| 118 m_hTheme = NULL; | 151 m_hTheme = NULL; |
| 119 m_isInitializedOk = false; | 152 m_isInitializedOk = false; |
| 120 | |
| 121 | |
| 122 m_tab = new CPluginTab(); | 153 m_tab = new CPluginTab(); |
| 123 | |
| 124 Dictionary::Create(GetBrowserLanguage()); | 154 Dictionary::Create(GetBrowserLanguage()); |
| 125 } | 155 } |
| 126 | 156 |
| 127 CPluginClass::~CPluginClass() | 157 CPluginClass::~CPluginClass() |
| 128 { | 158 { |
| 129 DEBUG_GENERAL([this]() -> std::wstring | 159 DEBUG_GENERAL([this]() -> std::wstring |
| 130 { | 160 { |
| 131 std::wstring s = L"CPluginClass::<destructor>, this = "; | 161 std::wstring s = L"CPluginClass::<destructor>, this = "; |
| 132 s += ToHexLiteral(this); | 162 s += ToHexLiteral(this); |
| 133 return s; | 163 return s; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p
ointer to IWebBrowser2*"); | 268 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p
ointer to IWebBrowser2*"); |
| 239 } | 269 } |
| 240 DEBUG_GENERAL([this]() -> std::wstring | 270 DEBUG_GENERAL([this]() -> std::wstring |
| 241 { | 271 { |
| 242 std::wstringstream ss; | 272 std::wstringstream ss; |
| 243 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this); | 273 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this); |
| 244 ss << L", browser = " << ToHexLiteral(m_webBrowser2); | 274 ss << L", browser = " << ToHexLiteral(m_webBrowser2); |
| 245 return ss.str(); | 275 return ss.str(); |
| 246 }()); | 276 }()); |
| 247 | 277 |
| 278 /* |
| 279 * Add ourselves to the thread map. |
| 280 */ |
| 281 if (!threadMap.AddIfAbsent(this)) |
| 282 { |
| 283 throw std::logic_error("CPluginClass::SetSite - May not overwrite existi
ng entry in thread map"); |
| 284 } |
| 285 |
| 248 //register the mimefilter | 286 //register the mimefilter |
| 249 //and only mimefilter | 287 //and only mimefilter |
| 250 //on some few computers the mimefilter does not get properly registered wh
en it is done on another thread | 288 //on some few computers the mimefilter does not get properly registered wh
en it is done on another thread |
| 251 s_criticalSectionLocal.Lock(); | 289 s_criticalSectionLocal.Lock(); |
| 252 { | 290 { |
| 253 // Always register on startup, then check if we need to unregister in a
separate thread | 291 // Always register on startup, then check if we need to unregister in a
separate thread |
| 254 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); | 292 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
| 255 s_asyncWebBrowser2 = unknownSite; | 293 s_asyncWebBrowser2 = unknownSite; |
| 256 s_instances.insert(this); | 294 s_instances.insert(this); |
| 257 } | 295 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 m_hPaneWnd = NULL; | 349 m_hPaneWnd = NULL; |
| 312 } | 350 } |
| 313 | 351 |
| 314 m_hTabWnd = NULL; | 352 m_hTabWnd = NULL; |
| 315 m_hStatusBarWnd = NULL; | 353 m_hStatusBarWnd = NULL; |
| 316 | 354 |
| 317 // Remove instance from the list, shutdown threads | 355 // Remove instance from the list, shutdown threads |
| 318 HANDLE hMainThread = NULL; | 356 HANDLE hMainThread = NULL; |
| 319 HANDLE hTabThread = NULL; | 357 HANDLE hTabThread = NULL; |
| 320 | 358 |
| 359 if (!threadMap.RemoveAndCheck()) |
| 360 { |
| 361 throw std::logic_error("CPluginClass::SetSite - Missing entry in thread
map"); |
| 362 } |
| 363 |
| 321 s_criticalSectionLocal.Lock(); | 364 s_criticalSectionLocal.Lock(); |
| 322 { | 365 { |
| 323 s_instances.erase(this); | 366 s_instances.erase(this); |
| 324 | |
| 325 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge
tCurrentThreadId()); | |
| 326 if (it != s_threadInstances.end()) | |
| 327 { | |
| 328 s_threadInstances.erase(it); | |
| 329 } | |
| 330 if (s_instances.empty()) | 367 if (s_instances.empty()) |
| 331 { | 368 { |
| 332 // TODO: Explicitly releasing a resource when a container becomes empt
y looks like a job better suited for shared_ptr | 369 // TODO: Explicitly releasing a resource when a container becomes empt
y looks like a job better suited for shared_ptr |
| 333 CPluginClientFactory::ReleaseMimeFilterClientInstance(); | 370 CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
| 334 } | 371 } |
| 335 } | 372 } |
| 336 s_criticalSectionLocal.Unlock(); | 373 s_criticalSectionLocal.Unlock(); |
| 337 | 374 |
| 338 m_webBrowser2 = nullptr; | 375 m_webBrowser2 = nullptr; |
| 339 | 376 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 // Entry point | 593 // Entry point |
| 557 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u
nsigned long validFlagsMask) | 594 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u
nsigned long validFlagsMask) |
| 558 { | 595 { |
| 559 try | 596 try |
| 560 { | 597 { |
| 561 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); | 598 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); |
| 562 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL
ECMDIDF_WINDOWSTATE_ENABLED) | 599 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL
ECMDIDF_WINDOWSTATE_ENABLED) |
| 563 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA
BLED); | 600 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA
BLED); |
| 564 if (newtabshown) | 601 if (newtabshown) |
| 565 { | 602 { |
| 566 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(
GetCurrentThreadId()); | 603 if (!m_isInitializedOk) |
| 567 if (it == s_threadInstances.end()) | 604 { |
| 568 { | 605 m_isInitializedOk = true; |
| 569 s_threadInstances[::GetCurrentThreadId()] = this; | 606 InitObject(); |
| 570 if (!m_isInitializedOk) | 607 UpdateStatusBar(); |
| 571 { | |
| 572 m_isInitializedOk = true; | |
| 573 InitObject(); | |
| 574 UpdateStatusBar(); | |
| 575 } | |
| 576 } | 608 } |
| 577 } | 609 } |
| 578 notificationMessage.Hide(); | 610 notificationMessage.Hide(); |
| 579 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); | 611 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); |
| 580 } | 612 } |
| 581 catch (...) | 613 catch (...) |
| 582 { | 614 { |
| 583 } | 615 } |
| 584 } | 616 } |
| 585 | 617 |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 s_criticalSectionLocal.Unlock(); | 1016 s_criticalSectionLocal.Unlock(); |
| 985 | 1017 |
| 986 return result; | 1018 return result; |
| 987 } | 1019 } |
| 988 | 1020 |
| 989 CPluginTab* CPluginClass::GetTab() | 1021 CPluginTab* CPluginClass::GetTab() |
| 990 { | 1022 { |
| 991 return m_tab; | 1023 return m_tab; |
| 992 } | 1024 } |
| 993 | 1025 |
| 994 CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) | 1026 CPluginTab* CPluginClass::GetTabForCurrentThread() |
| 995 { | 1027 { |
| 996 CPluginTab* tab = NULL; | 1028 auto p = threadMap.Locate(); |
| 997 | 1029 return p ? p->m_tab : nullptr; |
| 998 s_criticalSectionLocal.Lock(); | |
| 999 { | |
| 1000 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dw
ThreadId); | |
| 1001 if (it != s_threadInstances.end()) | |
| 1002 { | |
| 1003 tab = it->second->m_tab; | |
| 1004 } | |
| 1005 } | |
| 1006 s_criticalSectionLocal.Unlock(); | |
| 1007 | |
| 1008 return tab; | |
| 1009 } | 1030 } |
| 1010 | 1031 |
| 1011 // Entry point | 1032 // Entry point |
| 1012 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O
LECMD prgCmds[], OLECMDTEXT* pCmdText) | 1033 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O
LECMD prgCmds[], OLECMDTEXT* pCmdText) |
| 1013 { | 1034 { |
| 1014 try | 1035 try |
| 1015 { | 1036 { |
| 1016 if (cCmds == 0) return E_INVALIDARG; | 1037 if (cCmds == 0) return E_INVALIDARG; |
| 1017 if (prgCmds == 0) return E_POINTER; | 1038 if (prgCmds == 0) return E_POINTER; |
| 1018 | 1039 |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 } | 1430 } |
| 1410 return ::CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lPara
m); | 1431 return ::CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lPara
m); |
| 1411 } | 1432 } |
| 1412 | 1433 |
| 1413 | 1434 |
| 1414 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) | 1435 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) |
| 1415 { | 1436 { |
| 1416 // use the disable icon as defualt, if the client doesn't exists | 1437 // use the disable icon as defualt, if the client doesn't exists |
| 1417 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); | 1438 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
| 1418 | 1439 |
| 1419 CPluginTab* tab = GetTab(::GetCurrentThreadId()); | 1440 CPluginTab* tab = GetTabForCurrentThread(); |
| 1420 if (tab) | 1441 if (tab) |
| 1421 { | 1442 { |
| 1422 CPluginClient* client = CPluginClient::GetInstance(); | 1443 CPluginClient* client = CPluginClient::GetInstance(); |
| 1423 if (CPluginSettings::GetInstance()->IsPluginEnabled()) | 1444 if (CPluginSettings::GetInstance()->IsPluginEnabled()) |
| 1424 { | 1445 { |
| 1425 if (client->IsWhitelistedUrl(url)) | 1446 if (client->IsWhitelistedUrl(url)) |
| 1426 { | 1447 { |
| 1427 hIcon = GetIcon(ICON_PLUGIN_DISABLED); | 1448 hIcon = GetIcon(ICON_PLUGIN_DISABLED); |
| 1428 } | 1449 } |
| 1429 else | 1450 else |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1573 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN | TPM_BOTTOMALIGN
); | 1594 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN | TPM_BOTTOMALIGN
); |
| 1574 break; | 1595 break; |
| 1575 } | 1596 } |
| 1576 case WM_DESTROY: | 1597 case WM_DESTROY: |
| 1577 break; | 1598 break; |
| 1578 case SC_CLOSE: | 1599 case SC_CLOSE: |
| 1579 break; | 1600 break; |
| 1580 | 1601 |
| 1581 case WM_UPDATEUISTATE: | 1602 case WM_UPDATEUISTATE: |
| 1582 { | 1603 { |
| 1583 CPluginTab* tab = GetTab(::GetCurrentThreadId()); | 1604 CPluginTab* tab = GetTabForCurrentThread(); |
| 1584 if (tab) | 1605 if (tab) |
| 1585 { | 1606 { |
| 1586 tab->OnActivate(); | 1607 tab->OnActivate(); |
| 1587 RECT rect; | 1608 RECT rect; |
| 1588 GetWindowRect(pClass->m_hPaneWnd, &rect); | 1609 GetWindowRect(pClass->m_hPaneWnd, &rect); |
| 1589 pClass->notificationMessage.MoveToCenter(rect); | 1610 pClass->notificationMessage.MoveToCenter(rect); |
| 1590 } | 1611 } |
| 1591 if (LOWORD(wParam) == UIS_CLEAR) | 1612 if (LOWORD(wParam) == UIS_CLEAR) |
| 1592 { | 1613 { |
| 1593 pClass->notificationMessage.Hide(); | 1614 pClass->notificationMessage.Hide(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1706 s_criticalSectionLocal.Unlock(); | 1727 s_criticalSectionLocal.Unlock(); |
| 1707 | 1728 |
| 1708 return icon; | 1729 return icon; |
| 1709 } | 1730 } |
| 1710 | 1731 |
| 1711 ATOM CPluginClass::GetAtomPaneClass() | 1732 ATOM CPluginClass::GetAtomPaneClass() |
| 1712 { | 1733 { |
| 1713 return s_atomPaneClass; | 1734 return s_atomPaneClass; |
| 1714 } | 1735 } |
| 1715 | 1736 |
| LEFT | RIGHT |