Left: | ||
Right: |
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::RemoveAndCheck(::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"); | |
sergei
2016/02/08 13:35:37
I would also like to have asserts here and for Rem
Eric
2016/02/08 18:45:31
No. We have error handling already. Doubling it up
Oleksandr
2016/02/10 10:58:48
I don't think we need asserts here as well.
| |
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::GetTabCurrentThread() |
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 = GetTabCurrentThread(); |
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 = GetTabCurrentThread(); |
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 |