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