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-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 |
(...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 | |
sergei
2016/02/01 15:50:43
Why not to put it into anonymous namespace?
Eric
2016/02/03 17:17:05
OK.
| |
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::RemoveAndCheck(::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; | |
sergei
2016/02/01 15:50:43
Off topic: Still a global variable. When will we s
Eric
2016/02/03 17:17:05
The map from threads to BHO instances is inherentl
| |
97 | |
67 /* | 98 /* |
68 * Without namespace declaration, the identifier "Rectangle" is ambiguous | 99 * Without namespace declaration, the identifier "Rectangle" is ambiguous |
69 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx | 100 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx |
70 */ | 101 */ |
71 namespace AdblockPlus | 102 namespace AdblockPlus |
72 { | 103 { |
73 /** | 104 /** |
74 * Replacement for ATL type CRect. | 105 * Replacement for ATL type CRect. |
75 */ | 106 */ |
76 class Rectangle | 107 class Rectangle |
(...skipping 19 matching lines...) Expand all Loading... | |
96 // _CrtDumpMemoryLeaks(); | 127 // _CrtDumpMemoryLeaks(); |
97 | 128 |
98 m_isAdvised = false; | 129 m_isAdvised = false; |
99 m_hTabWnd = NULL; | 130 m_hTabWnd = NULL; |
100 m_hStatusBarWnd = NULL; | 131 m_hStatusBarWnd = NULL; |
101 m_hPaneWnd = NULL; | 132 m_hPaneWnd = NULL; |
102 m_nPaneWidth = 0; | 133 m_nPaneWidth = 0; |
103 m_pWndProcStatus = NULL; | 134 m_pWndProcStatus = NULL; |
104 m_hTheme = NULL; | 135 m_hTheme = NULL; |
105 m_isInitializedOk = false; | 136 m_isInitializedOk = false; |
106 | |
107 | |
108 m_tab = new CPluginTab(this); | 137 m_tab = new CPluginTab(this); |
109 | |
110 Dictionary::Create(GetBrowserLanguage()); | 138 Dictionary::Create(GetBrowserLanguage()); |
111 } | 139 } |
112 | 140 |
113 CPluginClass::~CPluginClass() | 141 CPluginClass::~CPluginClass() |
114 { | 142 { |
115 delete m_tab; | 143 delete m_tab; |
116 } | 144 } |
117 | 145 |
118 HWND CPluginClass::GetBrowserHWND() const | 146 HWND CPluginClass::GetBrowserHWND() const |
119 { | 147 { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 | 236 |
209 /* | 237 /* |
210 * We were instantiated as a BHO, so our site is always of type IWebBrowse r2. | 238 * We were instantiated as a BHO, so our site is always of type IWebBrowse r2. |
211 */ | 239 */ |
212 m_webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite); | 240 m_webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite); |
213 if (!m_webBrowser2) | 241 if (!m_webBrowser2) |
214 { | 242 { |
215 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p ointer to IWebBrowser2*"); | 243 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p ointer to IWebBrowser2*"); |
216 } | 244 } |
217 | 245 |
246 /* | |
247 * Add ourselves to the thread map. | |
248 */ | |
249 if (!threadMap.AddIfAbsent(this)) | |
250 { | |
251 throw std::logic_error("CPluginClass::SetSite - May not overwrite existi ng entry in thread map"); | |
sergei
2016/02/01 15:50:43
That looks suspicious. It can happen that two inst
Eric
2016/02/03 17:17:05
Actually, that cannot happen.
| |
252 } | |
253 | |
218 //register the mimefilter | 254 //register the mimefilter |
219 //and only mimefilter | 255 //and only mimefilter |
220 //on some few computers the mimefilter does not get properly registered wh en it is done on another thread | 256 //on some few computers the mimefilter does not get properly registered wh en it is done on another thread |
221 s_criticalSectionLocal.Lock(); | 257 s_criticalSectionLocal.Lock(); |
222 { | 258 { |
223 // Always register on startup, then check if we need to unregister in a separate thread | 259 // Always register on startup, then check if we need to unregister in a separate thread |
224 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); | 260 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
225 s_asyncWebBrowser2 = unknownSite; | 261 s_asyncWebBrowser2 = unknownSite; |
226 s_instances.insert(this); | 262 s_instances.insert(this); |
227 } | 263 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
274 m_hPaneWnd = NULL; | 310 m_hPaneWnd = NULL; |
275 } | 311 } |
276 | 312 |
277 m_hTabWnd = NULL; | 313 m_hTabWnd = NULL; |
278 m_hStatusBarWnd = NULL; | 314 m_hStatusBarWnd = NULL; |
279 | 315 |
280 // Remove instance from the list, shutdown threads | 316 // Remove instance from the list, shutdown threads |
281 HANDLE hMainThread = NULL; | 317 HANDLE hMainThread = NULL; |
282 HANDLE hTabThread = NULL; | 318 HANDLE hTabThread = NULL; |
283 | 319 |
320 if (!threadMap.RemoveAndCheck()) | |
321 { | |
322 throw std::logic_error("CPluginClass::SetSite - Missing entry in thread map"); | |
323 } | |
324 | |
284 s_criticalSectionLocal.Lock(); | 325 s_criticalSectionLocal.Lock(); |
285 { | 326 { |
286 s_instances.erase(this); | 327 s_instances.erase(this); |
287 | |
288 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge tCurrentThreadId()); | |
289 if (it != s_threadInstances.end()) | |
290 { | |
291 s_threadInstances.erase(it); | |
292 } | |
293 if (s_instances.empty()) | 328 if (s_instances.empty()) |
294 { | 329 { |
295 // TODO: Explicitly releasing a resource when a container becomes empt y looks like a job better suited for shared_ptr | 330 // TODO: Explicitly releasing a resource when a container becomes empt y looks like a job better suited for shared_ptr |
296 CPluginClientFactory::ReleaseMimeFilterClientInstance(); | 331 CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
297 } | 332 } |
298 } | 333 } |
299 s_criticalSectionLocal.Unlock(); | 334 s_criticalSectionLocal.Unlock(); |
300 | 335 |
301 m_webBrowser2 = nullptr; | 336 m_webBrowser2 = nullptr; |
302 | 337 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
519 // Entry point | 554 // Entry point |
520 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u nsigned long validFlagsMask) | 555 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u nsigned long validFlagsMask) |
521 { | 556 { |
522 try | 557 try |
523 { | 558 { |
524 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); | 559 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); |
525 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL ECMDIDF_WINDOWSTATE_ENABLED) | 560 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL ECMDIDF_WINDOWSTATE_ENABLED) |
526 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA BLED); | 561 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA BLED); |
527 if (newtabshown) | 562 if (newtabshown) |
528 { | 563 { |
529 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find( GetCurrentThreadId()); | 564 if (!m_isInitializedOk) |
530 if (it == s_threadInstances.end()) | |
531 { | 565 { |
532 s_threadInstances[::GetCurrentThreadId()] = this; | 566 m_isInitializedOk = true; |
sergei
2016/02/01 15:50:43
Pay attention that we are overriding the value of
Eric
2016/02/03 17:17:05
I don't know what you mean here.
| |
533 if (!m_isInitializedOk) | 567 InitObject(); |
534 { | 568 UpdateStatusBar(); |
535 m_isInitializedOk = true; | |
536 InitObject(); | |
537 UpdateStatusBar(); | |
538 } | |
539 } | 569 } |
540 } | 570 } |
541 notificationMessage.Hide(); | 571 notificationMessage.Hide(); |
542 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); | 572 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); |
543 } | 573 } |
544 catch (...) | 574 catch (...) |
545 { | 575 { |
546 } | 576 } |
547 } | 577 } |
548 | 578 |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 s_criticalSectionLocal.Unlock(); | 977 s_criticalSectionLocal.Unlock(); |
948 | 978 |
949 return result; | 979 return result; |
950 } | 980 } |
951 | 981 |
952 CPluginTab* CPluginClass::GetTab() | 982 CPluginTab* CPluginClass::GetTab() |
953 { | 983 { |
954 return m_tab; | 984 return m_tab; |
955 } | 985 } |
956 | 986 |
957 CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) | 987 CPluginTab* CPluginClass::GetTabCurrentThread() |
958 { | 988 { |
959 CPluginTab* tab = NULL; | 989 auto p = threadMap.Locate(); |
960 | 990 return p ? p->m_tab : nullptr; |
961 s_criticalSectionLocal.Lock(); | |
962 { | |
963 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dw ThreadId); | |
964 if (it != s_threadInstances.end()) | |
965 { | |
966 tab = it->second->m_tab; | |
967 } | |
968 } | |
969 s_criticalSectionLocal.Unlock(); | |
970 | |
971 return tab; | |
972 } | 991 } |
973 | 992 |
974 | 993 |
975 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O LECMD prgCmds[], OLECMDTEXT* pCmdText) | 994 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O LECMD prgCmds[], OLECMDTEXT* pCmdText) |
976 { | 995 { |
977 if (cCmds == 0) return E_INVALIDARG; | 996 if (cCmds == 0) return E_INVALIDARG; |
978 if (prgCmds == 0) return E_POINTER; | 997 if (prgCmds == 0) return E_POINTER; |
979 | 998 |
980 prgCmds[0].cmdf = OLECMDF_ENABLED; | 999 prgCmds[0].cmdf = OLECMDF_ENABLED; |
981 | 1000 |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1342 return result; | 1361 return result; |
1343 | 1362 |
1344 } | 1363 } |
1345 | 1364 |
1346 | 1365 |
1347 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) | 1366 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) |
1348 { | 1367 { |
1349 // use the disable icon as defualt, if the client doesn't exists | 1368 // use the disable icon as defualt, if the client doesn't exists |
1350 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); | 1369 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
1351 | 1370 |
1352 CPluginTab* tab = GetTab(::GetCurrentThreadId()); | 1371 CPluginTab* tab = GetTabCurrentThread(); |
1353 if (tab) | 1372 if (tab) |
1354 { | 1373 { |
1355 CPluginClient* client = CPluginClient::GetInstance(); | 1374 CPluginClient* client = CPluginClient::GetInstance(); |
1356 if (CPluginSettings::GetInstance()->IsPluginEnabled()) | 1375 if (CPluginSettings::GetInstance()->IsPluginEnabled()) |
1357 { | 1376 { |
1358 if (client->IsWhitelistedUrl(url)) | 1377 if (client->IsWhitelistedUrl(url)) |
1359 { | 1378 { |
1360 hIcon = GetIcon(ICON_PLUGIN_DISABLED); | 1379 hIcon = GetIcon(ICON_PLUGIN_DISABLED); |
1361 } | 1380 } |
1362 else | 1381 else |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1505 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN|TPM_BOTTOMALIGN); | 1524 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN|TPM_BOTTOMALIGN); |
1506 } | 1525 } |
1507 break; | 1526 break; |
1508 case WM_DESTROY: | 1527 case WM_DESTROY: |
1509 break; | 1528 break; |
1510 case SC_CLOSE: | 1529 case SC_CLOSE: |
1511 break; | 1530 break; |
1512 | 1531 |
1513 case WM_UPDATEUISTATE: | 1532 case WM_UPDATEUISTATE: |
1514 { | 1533 { |
1515 CPluginTab* tab = GetTab(::GetCurrentThreadId()); | 1534 CPluginTab* tab = GetTabCurrentThread(); |
1516 if (tab) | 1535 if (tab) |
1517 { | 1536 { |
1518 tab->OnActivate(); | 1537 tab->OnActivate(); |
1519 RECT rect; | 1538 RECT rect; |
1520 GetWindowRect(pClass->m_hPaneWnd, &rect); | 1539 GetWindowRect(pClass->m_hPaneWnd, &rect); |
1521 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2); | 1540 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2); |
1522 } | 1541 } |
1523 if (LOWORD(wParam) == UIS_CLEAR) | 1542 if (LOWORD(wParam) == UIS_CLEAR) |
1524 { | 1543 { |
1525 pClass->notificationMessage.Hide(); | 1544 pClass->notificationMessage.Hide(); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1633 s_criticalSectionLocal.Unlock(); | 1652 s_criticalSectionLocal.Unlock(); |
1634 | 1653 |
1635 return icon; | 1654 return icon; |
1636 } | 1655 } |
1637 | 1656 |
1638 ATOM CPluginClass::GetAtomPaneClass() | 1657 ATOM CPluginClass::GetAtomPaneClass() |
1639 { | 1658 { |
1640 return s_atomPaneClass; | 1659 return s_atomPaneClass; |
1641 } | 1660 } |
1642 | 1661 |
OLD | NEW |