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 |