Index: src/plugin/PluginClass.cpp |
diff --git a/src/plugin/PluginClass.cpp b/src/plugin/PluginClass.cpp |
index a275b06157b4be9cb2b26299d99822bbf5acb663..b08361fa07741ae10bb9e1db6a373d5c4dd95837 100644 |
--- a/src/plugin/PluginClass.cpp |
+++ b/src/plugin/PluginClass.cpp |
@@ -1,20 +1,20 @@ |
-/* |
- * This file is part of Adblock Plus <https://adblockplus.org/>, |
- * Copyright (C) 2006-2015 Eyeo GmbH |
- * |
- * Adblock Plus is free software: you can redistribute it and/or modify |
- * it under the terms of the GNU General Public License version 3 as |
- * published by the Free Software Foundation. |
- * |
- * Adblock Plus is distributed in the hope that it will be useful, |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- * GNU General Public License for more details. |
- * |
- * You should have received a copy of the GNU General Public License |
- * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
- */ |
- |
+/* |
+ * This file is part of Adblock Plus <https://adblockplus.org/>, |
+ * Copyright (C) 2006-2015 Eyeo GmbH |
+ * |
+ * Adblock Plus is free software: you can redistribute it and/or modify |
+ * it under the terms of the GNU General Public License version 3 as |
+ * published by the Free Software Foundation. |
+ * |
+ * Adblock Plus is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
+ */ |
+ |
#include "PluginStdAfx.h" |
#include "PluginClass.h" |
@@ -239,168 +239,171 @@ DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) |
// so we should handle that it is called this way several times during a session |
STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
{ |
- CPluginSettings* settings = CPluginSettings::GetInstance(); |
- |
- MULTIPLE_VERSIONS_CHECK(); |
- |
- if (unknownSite) |
+ return EntryPointWithHResult([&]()->HRESULT |
{ |
+ CPluginSettings* settings = CPluginSettings::GetInstance(); |
- DEBUG_GENERAL(L"================================================================================\nNEW TAB UI\n================================================================================") |
+ MULTIPLE_VERSIONS_CHECK(); |
- HRESULT hr = ::CoInitialize(NULL); |
- if (FAILED(hr)) |
+ if (unknownSite) |
{ |
- DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, "Class::SetSite - CoInitialize"); |
- } |
- s_criticalSectionBrowser.Lock(); |
- { |
- m_webBrowser2 = unknownSite; |
- } |
- s_criticalSectionBrowser.Unlock(); |
+ DEBUG_GENERAL(L"================================================================================\nNEW TAB UI\n================================================================================") |
- //register the mimefilter |
- //and only mimefilter |
- //on some few computers the mimefilter does not get properly registered when it is done on another thread |
+ HRESULT hr = ::CoInitialize(NULL); |
+ if (FAILED(hr)) |
+ { |
+ DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, "Class::SetSite - CoInitialize"); |
+ } |
- s_criticalSectionLocal.Lock(); |
- { |
- // Always register on startup, then check if we need to unregister in a separate thread |
- s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
- s_asyncWebBrowser2 = unknownSite; |
- s_instances.insert(this); |
- } |
- s_criticalSectionLocal.Unlock(); |
+ s_criticalSectionBrowser.Lock(); |
+ { |
+ m_webBrowser2 = unknownSite; |
+ } |
+ s_criticalSectionBrowser.Unlock(); |
- try |
- { |
- // Check if loaded as BHO |
- if (GetBrowser()) |
+ //register the mimefilter |
+ //and only mimefilter |
+ //on some few computers the mimefilter does not get properly registered when it is done on another thread |
+ |
+ s_criticalSectionLocal.Lock(); |
{ |
- DEBUG_GENERAL("Loaded as BHO"); |
- CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); |
- if (pPoint) |
+ // Always register on startup, then check if we need to unregister in a separate thread |
+ s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
+ s_asyncWebBrowser2 = unknownSite; |
+ s_instances.insert(this); |
+ } |
+ s_criticalSectionLocal.Unlock(); |
+ |
+ try |
+ { |
+ // Check if loaded as BHO |
+ if (GetBrowser()) |
{ |
- HRESULT hr = pPoint->Advise((IDispatch*)this, &m_nConnectionID); |
- if (SUCCEEDED(hr)) |
+ DEBUG_GENERAL("Loaded as BHO"); |
+ CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); |
+ if (pPoint) |
{ |
- m_isAdviced = true; |
- |
- try |
+ HRESULT hr = pPoint->Advise((IDispatch*)this, &m_nConnectionID); |
+ if (SUCCEEDED(hr)) |
{ |
- std::thread startInitObjectThread(StartInitObject, this); |
- startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr. |
+ m_isAdviced = true; |
+ |
+ try |
+ { |
+ std::thread startInitObjectThread(StartInitObject, this); |
+ startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr. |
+ } |
+ catch (const std::system_error& ex) |
+ { |
+ auto errDescription = std::string("Class::Thread - Failed to create StartInitObject thread, ") + |
+ ex.code().message() + ex.what(); |
+ DEBUG_ERROR_LOG(ex.code().value(), PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS, errDescription.c_str()); |
+ } |
} |
- catch (const std::system_error& ex) |
+ else |
{ |
- auto errDescription = std::string("Class::Thread - Failed to create StartInitObject thread, ") + |
- ex.code().message() + ex.what(); |
- DEBUG_ERROR_LOG(ex.code().value(), PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS, errDescription.c_str()); |
+ DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, "Class::SetSite - Advice"); |
} |
} |
- else |
- { |
- DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, "Class::SetSite - Advice"); |
- } |
} |
- } |
- else // Check if loaded as toolbar handler |
- { |
- DEBUG_GENERAL("Loaded as toolbar handler"); |
- CComPtr<IServiceProvider> pServiceProvider; |
- |
- HRESULT hr = unknownSite->QueryInterface(&pServiceProvider); |
- if (SUCCEEDED(hr)) |
+ else // Check if loaded as toolbar handler |
{ |
- if (pServiceProvider) |
+ DEBUG_GENERAL("Loaded as toolbar handler"); |
+ CComPtr<IServiceProvider> pServiceProvider; |
+ |
+ HRESULT hr = unknownSite->QueryInterface(&pServiceProvider); |
+ if (SUCCEEDED(hr)) |
{ |
- s_criticalSectionBrowser.Lock(); |
+ if (pServiceProvider) |
{ |
- HRESULT hr = pServiceProvider->QueryService(IID_IWebBrowserApp, &m_webBrowser2); |
- if (SUCCEEDED(hr)) |
+ s_criticalSectionBrowser.Lock(); |
{ |
- if (m_webBrowser2) |
+ HRESULT hr = pServiceProvider->QueryService(IID_IWebBrowserApp, &m_webBrowser2); |
+ if (SUCCEEDED(hr)) |
{ |
- InitObject(false); |
+ if (m_webBrowser2) |
+ { |
+ InitObject(false); |
+ } |
+ } |
+ else |
+ { |
+ DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_QUERY_BROWSER, "Class::SetSite - QueryService (IID_IWebBrowserApp)"); |
} |
} |
- else |
- { |
- DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_QUERY_BROWSER, "Class::SetSite - QueryService (IID_IWebBrowserApp)"); |
- } |
+ s_criticalSectionBrowser.Unlock(); |
} |
- s_criticalSectionBrowser.Unlock(); |
+ } |
+ else |
+ { |
+ DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_QUERY_SERVICE_PROVIDER, "Class::SetSite - QueryInterface (service provider)"); |
} |
} |
- else |
- { |
- DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_QUERY_SERVICE_PROVIDER, "Class::SetSite - QueryInterface (service provider)"); |
- } |
+ } |
+ catch (std::runtime_error e) |
+ { |
+ DEBUG_ERROR(e.what()); |
+ Unadvice(); |
} |
} |
- catch (std::runtime_error e) |
+ else |
{ |
- DEBUG_ERROR(e.what()); |
+ // Unadvice |
Unadvice(); |
- } |
- } |
- else |
- { |
- // Unadvice |
- Unadvice(); |
- |
- // Destroy window |
- if (m_pWndProcStatus) |
- { |
- ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWndProcStatus); |
- m_pWndProcStatus = NULL; |
- } |
+ // Destroy window |
+ if (m_pWndProcStatus) |
+ { |
+ ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWndProcStatus); |
- if (m_hPaneWnd) |
- { |
- DestroyWindow(m_hPaneWnd); |
- m_hPaneWnd = NULL; |
- } |
+ m_pWndProcStatus = NULL; |
+ } |
- m_hTabWnd = NULL; |
- m_hStatusBarWnd = NULL; |
+ if (m_hPaneWnd) |
+ { |
+ DestroyWindow(m_hPaneWnd); |
+ m_hPaneWnd = NULL; |
+ } |
- // Remove instance from the list, shutdown threads |
- HANDLE hMainThread = NULL; |
- HANDLE hTabThread = NULL; |
+ m_hTabWnd = NULL; |
+ m_hStatusBarWnd = NULL; |
- s_criticalSectionLocal.Lock(); |
- { |
- s_instances.erase(this); |
+ // Remove instance from the list, shutdown threads |
+ HANDLE hMainThread = NULL; |
+ HANDLE hTabThread = NULL; |
- std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetCurrentThreadId()); |
- if (it != s_threadInstances.end()) |
+ s_criticalSectionLocal.Lock(); |
{ |
- s_threadInstances.erase(it); |
+ s_instances.erase(this); |
+ |
+ std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetCurrentThreadId()); |
+ if (it != s_threadInstances.end()) |
+ { |
+ s_threadInstances.erase(it); |
+ } |
+ if (s_instances.empty()) |
+ { |
+ // TODO: Explicitly releasing a resource when a container becomes empty looks like a job better suited for shared_ptr |
+ CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
+ } |
} |
- if (s_instances.empty()) |
+ s_criticalSectionLocal.Unlock(); |
+ |
+ // Release browser interface |
+ s_criticalSectionBrowser.Lock(); |
{ |
- // TODO: Explicitly releasing a resource when a container becomes empty looks like a job better suited for shared_ptr |
- CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
+ m_webBrowser2.Release(); |
} |
- } |
- s_criticalSectionLocal.Unlock(); |
- |
- // Release browser interface |
- s_criticalSectionBrowser.Lock(); |
- { |
- m_webBrowser2.Release(); |
- } |
- s_criticalSectionBrowser.Unlock(); |
+ s_criticalSectionBrowser.Unlock(); |
- DEBUG_GENERAL("================================================================================\nNEW TAB UI - END\n================================================================================") |
+ DEBUG_GENERAL("================================================================================\nNEW TAB UI - END\n================================================================================") |
- ::CoUninitialize(); |
- } |
+ ::CoUninitialize(); |
+ } |
- return IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); |
+ return IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); |
+ }); |
} |
bool CPluginClass::IsStatusBarEnabled() |
@@ -619,11 +622,9 @@ STDMETHODIMP CPluginClass::OnTabChanged(DISPPARAMS* pDispParams, WORD wFlags) |
return S_OK; |
} |
-// This gets called whenever there's a browser event |
-// ENTRY POINT |
STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) |
{ |
- try |
+ return EntryPointWithHResult([&]()->HRESULT |
{ |
WCHAR tmp[256]; |
wsprintf(tmp, L"Invoke: %d\n", dispidMember); |
@@ -761,13 +762,7 @@ STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, W |
// do nothing |
break; |
} |
- } |
- catch(...) |
- { |
- DEBUG_GENERAL( "Caught unknown exception in CPluginClass::Invoke" ); |
- return E_FAIL; |
- } |
- return S_OK; |
+ }); |
} |
bool CPluginClass::InitObject(bool bBHO) |
@@ -1146,12 +1141,15 @@ CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) |
STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText) |
{ |
- if (cCmds == 0) return E_INVALIDARG; |
- if (prgCmds == 0) return E_POINTER; |
+ return EntryPointWithHResult([&]()->HRESULT |
+ { |
+ if (cCmds == 0) return E_INVALIDARG; |
+ if (prgCmds == 0) return E_POINTER; |
- prgCmds[0].cmdf = OLECMDF_ENABLED; |
+ prgCmds[0].cmdf = OLECMDF_ENABLED; |
- return S_OK; |
+ return S_OK; |
+ }); |
} |
HMENU CPluginClass::CreatePluginMenu(const std::wstring& url) |
@@ -1356,83 +1354,86 @@ bool CPluginClass::SetMenuBar(HMENU hMenu, const std::wstring& url) |
STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, VARIANTARG*) |
{ |
- HWND hBrowserWnd = GetBrowserHWND(); |
- if (!hBrowserWnd) |
- { |
- return E_FAIL; |
- } |
- |
- // Create menu |
- HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); |
- if (!hMenu) |
+ return EntryPointWithHResult([&]()->HRESULT |
{ |
- return E_FAIL; |
- } |
+ HWND hBrowserWnd = GetBrowserHWND(); |
+ if (!hBrowserWnd) |
+ { |
+ return E_FAIL; |
+ } |
- // Check if button in toolbar was pressed |
- int nIDCommand = -1; |
- BOOL bRightAlign = FALSE; |
+ // Create menu |
+ HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); |
+ if (!hMenu) |
+ { |
+ return E_FAIL; |
+ } |
- POINT pt; |
- GetCursorPos(&pt); |
+ // Check if button in toolbar was pressed |
+ int nIDCommand = -1; |
+ BOOL bRightAlign = FALSE; |
- HWND hWndToolBar = ::WindowFromPoint(pt); |
+ POINT pt; |
+ GetCursorPos(&pt); |
- DWORD nProcessId; |
- ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); |
+ HWND hWndToolBar = ::WindowFromPoint(pt); |
- if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) |
- { |
- ::ScreenToClient(hWndToolBar, &pt); |
- int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); |
+ DWORD nProcessId; |
+ ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); |
- if (nButton > 0) |
+ if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) |
{ |
- TBBUTTON pTBBtn = {}; |
+ ::ScreenToClient(hWndToolBar, &pt); |
+ int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); |
- if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) |
+ if (nButton > 0) |
{ |
- RECT rcButton; |
- nIDCommand = pTBBtn.idCommand; |
+ TBBUTTON pTBBtn = {}; |
- if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) |
+ if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) |
{ |
- pt.x = rcButton.left; |
- pt.y = rcButton.bottom; |
- ClientToScreen(hWndToolBar, &pt); |
+ RECT rcButton; |
+ nIDCommand = pTBBtn.idCommand; |
- RECT rcWorkArea; |
- SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0); |
- if (rcWorkArea.right - pt.x < 150) |
+ if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) |
{ |
- bRightAlign = TRUE; |
- pt.x = rcButton.right; |
+ pt.x = rcButton.left; |
pt.y = rcButton.bottom; |
ClientToScreen(hWndToolBar, &pt); |
+ |
+ RECT rcWorkArea; |
+ SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0); |
+ if (rcWorkArea.right - pt.x < 150) |
+ { |
+ bRightAlign = TRUE; |
+ pt.x = rcButton.right; |
+ pt.y = rcButton.bottom; |
+ ClientToScreen(hWndToolBar, &pt); |
+ } |
} |
} |
} |
+ else |
+ { |
+ GetCursorPos(&pt); |
+ } |
+ } |
+ |
+ // Display menu |
+ UINT nFlags = 0; |
+ if (bRightAlign) |
+ { |
+ nFlags |= TPM_RIGHTALIGN; |
} |
else |
{ |
- GetCursorPos(&pt); |
+ nFlags |= TPM_LEFTALIGN; |
} |
- } |
- // Display menu |
- UINT nFlags = 0; |
- if (bRightAlign) |
- { |
- nFlags |= TPM_RIGHTALIGN; |
- } |
- else |
- { |
- nFlags |= TPM_LEFTALIGN; |
- } |
- |
- DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); |
+ DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); |
- return S_OK; |
+ return S_OK; |
+ }); |
} |
///////////////////////////////////////////////////////////////////////////// |