| Index: src/plugin/PluginClass.cpp |
| =================================================================== |
| --- a/src/plugin/PluginClass.cpp |
| +++ b/src/plugin/PluginClass.cpp |
| @@ -1,2222 +1,2222 @@ |
| -#include "PluginStdAfx.h" |
| - |
| -#include "PluginClass.h" |
| -#include "PluginDictionary.h" |
| -#include "PluginSettings.h" |
| -#include "PluginSystem.h" |
| -#ifdef SUPPORT_FILTER |
| -#include "PluginFilter.h" |
| -#endif |
| -#include "PluginMimeFilterClient.h" |
| -#include "PluginClient.h" |
| -#include "PluginClientFactory.h" |
| -#include "PluginHttpRequest.h" |
| -#include "PluginMutex.h" |
| -#include "DownloadSource.h" |
| -#include "sddl.h" |
| -#include "PluginUtil.h" |
| -#include "PluginUserSettings.h" |
| - |
| -#ifdef DEBUG_HIDE_EL |
| -DWORD profileTime = 0; |
| -#endif |
| - |
| -typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); |
| -typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPRECT); |
| -typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); |
| - |
| - |
| -HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; |
| -DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABLED, IDI_ICON_DEACTIVATED }; |
| - |
| -CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; |
| - |
| -CLOSETHEMEDATA pfnClose = NULL; |
| -DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; |
| -OPENTHEMEDATA pfnOpenThemeData = NULL; |
| - |
| -ATOM CPluginClass::s_atomPaneClass = NULL; |
| -HINSTANCE CPluginClass::s_hUxtheme = NULL; |
| -CSimpleArray<CPluginClass*> CPluginClass::s_instances; |
| -std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances; |
| - |
| -CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; |
| -CComAutoCriticalSection CPluginClass::s_criticalSectionBrowser; |
| -CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; |
| - |
| -CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; |
| - |
| -#ifdef SUPPORT_WHITELIST |
| -std::map<UINT,CString> CPluginClass::s_menuDomains; |
| -#endif |
| - |
| -bool CPluginClass::s_isPluginToBeUpdated = false; |
| - |
| -CPluginTab* CPluginClass::s_activeTab = NULL; |
| - |
| - |
| -CPluginClass::CPluginClass() |
| -{ |
| - //Use this line to debug memory leaks |
| - // _CrtDumpMemoryLeaks(); |
| - |
| - m_isAdviced = false; |
| - m_nConnectionID = 0; |
| - m_hTabWnd = NULL; |
| - m_hStatusBarWnd = NULL; |
| - m_hPaneWnd = NULL; |
| - m_nPaneWidth = 0; |
| - m_pWndProcStatus = NULL; |
| - m_hTheme = NULL; |
| - m_isInitializedOk = false; |
| - |
| - |
| - m_tab = new CPluginTab(this); |
| - |
| - // Load / create settings |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - |
| - CPluginSystem* system = CPluginSystem::GetInstance(); |
| - |
| - bool isMainTab = settings->IncrementTabCount(); |
| - |
| - if (isMainTab) |
| - { |
| - // Prepare settings |
| - settings->SetMainProcessId(); |
| - settings->SetMainUiThreadId(); |
| - |
| - // Ensure plugin version |
| - if (!settings->Has(SETTING_PLUGIN_VERSION)) |
| - { |
| - settings->SetString(SETTING_PLUGIN_VERSION, IEPLUGIN_VERSION); |
| - settings->SetFirstRunUpdate(); |
| - } |
| - |
| - // First run or deleted settings file (dictionary version = 1) |
| - if (settings->GetString(SETTING_DICTIONARY_VERSION, L"1").Compare(L"1") == 0) |
| - { |
| - settings->SetFirstRun(); |
| - } |
| - |
| - // Update? |
| - CString oldVersion = settings->GetString(SETTING_PLUGIN_VERSION); |
| - if (settings->IsFirstRunUpdate() || settings->GetString(SETTING_PLUGIN_UPDATE_VERSION) == IEPLUGIN_VERSION || oldVersion != IEPLUGIN_VERSION) |
| - { |
| - settings->SetString(SETTING_PLUGIN_VERSION, IEPLUGIN_VERSION); |
| - |
| - settings->Remove(SETTING_PLUGIN_UPDATE_TIME); |
| - settings->Remove(SETTING_PLUGIN_UPDATE_VERSION); |
| - settings->Remove(SETTING_PLUGIN_UPDATE_URL); |
| - |
| - settings->SetFirstRunUpdate(); |
| - } |
| - |
| - int info = settings->GetValue(SETTING_PLUGIN_INFO_PANEL, 0); |
| - |
| -#ifdef ENABLE_DEBUG_RESULT |
| - CPluginDebug::DebugResultClear(); |
| -#endif |
| - |
| -#ifdef ENABLE_DEBUG_INFO |
| - if (info == 0 || info > 2) |
| - { |
| - CPluginDebug::DebugClear(); |
| - } |
| -#endif // ENABLE_DEBUG_INFO |
| - |
| - settings->Write(false); |
| - } |
| -} |
| - |
| -CPluginClass::~CPluginClass() |
| -{ |
| - delete m_tab; |
| - |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - |
| - settings->DecrementTabCount(); |
| -} |
| - |
| - |
| -///////////////////////////////////////////////////////////////////////////// |
| -// Initialization |
| - |
| -HRESULT CPluginClass::FinalConstruct() |
| -{ |
| - return S_OK; |
| -} |
| - |
| -void CPluginClass::FinalRelease() |
| -{ |
| - s_criticalSectionBrowser.Lock(); |
| - { |
| - m_webBrowser2.Release(); |
| - } |
| - s_criticalSectionBrowser.Unlock(); |
| -} |
| - |
| - |
| -// This method tries to get a 'connection point' from the stored browser, which can be |
| -// used to attach or detach from the stream of browser events |
| -CComPtr<IConnectionPoint> CPluginClass::GetConnectionPoint() |
| -{ |
| - CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pContainer(GetBrowser()); |
| - if (!pContainer) |
| - { |
| - return NULL; |
| - } |
| - |
| - CComPtr<IConnectionPoint> pPoint; |
| - HRESULT hr = pContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &pPoint); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_FIND_CONNECTION_POINT, "Class::GetConnectionPoint - FindConnectionPoint") |
| - return NULL; |
| - } |
| - |
| - return pPoint; |
| -} |
| - |
| -// This method tries to get a 'connection point' from the stored browser, which can be |
| -// used to attach or detach from the stream of browser events |
| -CComPtr<IConnectionPoint> CPluginClass::GetConnectionPointPropSink() |
| -{ |
| - CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pContainer(GetBrowser()); |
| - if (!pContainer) |
| - { |
| - return NULL; |
| - } |
| - |
| - CComPtr<IConnectionPoint> pPoint; |
| - HRESULT hr = pContainer->FindConnectionPoint(IID_IPropertyNotifySink, &pPoint); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_FIND_CONNECTION_POINT, "Class::GetConnectionPoint - FindConnectionPoint") |
| - return NULL; |
| - } |
| - |
| - return pPoint; |
| -} |
| - |
| - |
| -HWND CPluginClass::GetBrowserHWND() const |
| -{ |
| - SHANDLE_PTR hBrowserWndHandle = NULL; |
| - |
| - CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| - if (browser) |
| - { |
| - HRESULT hr = browser->get_HWND(&hBrowserWndHandle); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_BROWSER_WINDOW, "Class::GetBrowserHWND - failed") |
| - } |
| - } |
| - |
| - return (HWND)hBrowserWndHandle; |
| -} |
| - |
| - |
| -CComQIPtr<IWebBrowser2> CPluginClass::GetBrowser() const |
| -{ |
| - CComQIPtr<IWebBrowser2> browser; |
| - |
| - s_criticalSectionBrowser.Lock(); |
| - { |
| - browser = m_webBrowser2; |
| - } |
| - s_criticalSectionBrowser.Unlock(); |
| - |
| - return browser; |
| -} |
| - |
| - |
| -CComQIPtr<IWebBrowser2> CPluginClass::GetAsyncBrowser() |
| -{ |
| - CComQIPtr<IWebBrowser2> browser; |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - browser = s_asyncWebBrowser2; |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - return browser; |
| -} |
| - |
| -CString CPluginClass::GetBrowserUrl() const |
| -{ |
| - CString url; |
| - |
| - CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| - if (browser) |
| - { |
| - CComBSTR bstrURL; |
| - |
| - if (SUCCEEDED(browser->get_LocationURL(&bstrURL))) |
| - { |
| - url = bstrURL; |
| - CPluginClient::UnescapeUrl(url); |
| - } |
| - } |
| - else |
| - { |
| - url = m_tab->GetDocumentUrl(); |
| - } |
| - |
| - return url; |
| -} |
| - |
| -void CPluginClass::LaunchUpdater(const CString& strPath) |
| -{ |
| - PROCESS_INFORMATION pi; |
| - ::ZeroMemory(&pi, sizeof(pi)); |
| - |
| - STARTUPINFO si; |
| - ::ZeroMemory(&si, sizeof(si)); |
| - si.cb = sizeof(si); |
| - si.wShowWindow = FALSE; |
| - CString cpath; |
| - if (strPath.Find(L".exe") == strPath.GetLength() - 4) |
| - { |
| - cpath = strPath; |
| - } |
| - else |
| - { |
| - cpath = _T("\"msiexec.exe\" /i \"") + strPath + _T("\" UPDATEPLUGIN=\"True\""); |
| - } |
| - |
| - if (!::CreateProcess(NULL, cpath.GetBuffer(), NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi)) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UPDATER, PLUGIN_ERROR_UPDATER_CREATE_PROCESS, "Class::Updater - Failed to start process"); |
| - return; |
| - } |
| -#ifndef AUTOMATIC_SHUTDOWN |
| - else |
| - { |
| - ::WaitForSingleObject(pi.hProcess, INFINITE); |
| - } |
| -#endif // not AUTOMATIC_SHUTDOWN |
| - |
| - ::CloseHandle(pi.hProcess); |
| - ::CloseHandle(pi.hThread); |
| -} |
| - |
| -DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) |
| -{ |
| - if (thisPtr == NULL) |
| - return 0; |
| - if (!((CPluginClass*)thisPtr)->InitObject(true)) |
| - { |
| - ((CPluginClass*)thisPtr)->Unadvice(); |
| - } |
| - |
| - if ((((CPluginClass*)thisPtr)->m_hPaneWnd == NULL) || (!((CPluginClass*)thisPtr)->IsStatusBarEnabled())) |
| - { |
| - ((CPluginClass*)thisPtr)->ShowStatusBar(); |
| - } |
| - return 0; |
| -} |
| - |
| - |
| - |
| -// This gets called when a new browser window is created (which also triggers the |
| -// creation of this object). The pointer passed in should be to a IWebBrowser2 |
| -// interface that represents the browser for the window. |
| -// it is also called when a tab is closed, this unknownSite will be null |
| -// so we should handle that it is called this way several times during a session |
| -STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
| -{ |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - CPluginSystem* system = CPluginSystem::GetInstance(); |
| - |
| - MULTIPLE_VERSIONS_CHECK(); |
| - |
| - if (unknownSite) |
| - { |
| - if (settings->IsMainProcess() && settings->IsMainUiThread()) |
| - { |
| - DEBUG_GENERAL(L"================================================================================\nMAIN TAB UI\n================================================================================") |
| - } |
| - else |
| - { |
| - DEBUG_GENERAL(L"================================================================================\nNEW TAB UI\n================================================================================") |
| - } |
| - |
| - HRESULT hr = ::CoInitialize(NULL); |
| - if (FAILED(hr)) |
| - { |
| - 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(); |
| - |
| - //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(); |
| - { |
| - if (settings->GetPluginEnabled()) |
| - { |
| - s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
| - } |
| - |
| - s_asyncWebBrowser2 = unknownSite; |
| - s_instances.Add(this); |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - try |
| - { |
| - // Check if loaded as BHO |
| - if (GetBrowser()) |
| - { |
| - CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); |
| - if (pPoint) |
| - { |
| - HRESULT hr = pPoint->Advise((IDispatch*)this, &m_nConnectionID); |
| - if (SUCCEEDED(hr)) |
| - { |
| - m_isAdviced = true; |
| - |
| - DWORD id; |
| - HANDLE handle = ::CreateThread(NULL, 0, StartInitObject, (LPVOID)this, NULL, &id); |
| - if (handle == NULL) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS, "Class::Thread - Failed to create main thread"); |
| - } |
| - |
| - } |
| - else |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, "Class::SetSite - Advice"); |
| - } |
| - } |
| - } |
| - else // Check if loaded as toolbar handler |
| - { |
| - CComPtr<IServiceProvider> pServiceProvider; |
| - |
| - HRESULT hr = unknownSite->QueryInterface(&pServiceProvider); |
| - if (SUCCEEDED(hr)) |
| - { |
| - if (pServiceProvider) |
| - { |
| - s_criticalSectionBrowser.Lock(); |
| - { |
| - HRESULT hr = pServiceProvider->QueryService(IID_IWebBrowserApp, &m_webBrowser2); |
| - if (SUCCEEDED(hr)) |
| - { |
| - 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)"); |
| - } |
| - } |
| - s_criticalSectionBrowser.Unlock(); |
| - } |
| - } |
| - 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) |
| - { |
| - Unadvice(); |
| - } |
| - } |
| - else |
| - { |
| - // Unadvice |
| - Unadvice(); |
| - |
| - // Destroy window |
| - if (m_pWndProcStatus) |
| - { |
| - ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWndProcStatus); |
| - |
| - m_pWndProcStatus = NULL; |
| - } |
| - |
| - if (m_hPaneWnd) |
| - { |
| - DestroyWindow(m_hPaneWnd); |
| - m_hPaneWnd = NULL; |
| - } |
| - |
| - m_hTabWnd = NULL; |
| - m_hStatusBarWnd = NULL; |
| - |
| - // Remove instance from the list, shutdown threads |
| - HANDLE hMainThread = NULL; |
| - HANDLE hTabThread = NULL; |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - s_instances.Remove(this); |
| - |
| - if (s_instances.GetSize() == 0) |
| - { |
| - if (settings->IsMainProcess() && settings->IsMainUiThread()) |
| - { |
| - hMainThread = s_hMainThread; |
| - s_hMainThread = NULL; |
| - } |
| - } |
| - |
| - std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetCurrentThreadId()); |
| - if (it != s_threadInstances.end()) |
| - { |
| - s_threadInstances.erase(it); |
| - } |
| - if (s_instances.GetSize() == 0) |
| - { |
| - CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - if (hMainThread != NULL) |
| - { |
| - s_isMainThreadDone = true; |
| - |
| - ::WaitForSingleObject(hMainThread, INFINITE); |
| - ::CloseHandle(hMainThread); |
| - } |
| - |
| - // Release browser interface |
| - s_criticalSectionBrowser.Lock(); |
| - { |
| - m_webBrowser2.Release(); |
| - } |
| - s_criticalSectionBrowser.Unlock(); |
| - |
| - if (settings->IsMainProcess() && settings->IsMainUiThread()) |
| - { |
| - DEBUG_GENERAL("================================================================================\nMAIN TAB UI - END\n================================================================================") |
| - } |
| - else |
| - { |
| - DEBUG_GENERAL("================================================================================\nNEW TAB UI - END\n================================================================================") |
| - } |
| - |
| - ::CoUninitialize(); |
| - } |
| - |
| - return IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); |
| -} |
| - |
| -bool CPluginClass::IsStatusBarEnabled() |
| -{ |
| - HKEY pHkey; |
| - HKEY pHkeySub; |
| - RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); |
| - DWORD trueth = 1; |
| - DWORD truethSize = sizeof(DWORD); |
| - RegOpenKey(pHkey, L"Software\\Microsoft\\Internet Explorer\\Main", &pHkeySub); |
| - LONG res = RegQueryValueEx(pHkeySub, L"StatusBarWeb", NULL, NULL, (BYTE*)&trueth, &truethSize); |
| - RegCloseKey(pHkey); |
| - if (res != ERROR_SUCCESS) |
| - { |
| - res = RegOpenKey(pHkey, L"Software\\Microsoft\\Internet Explorer\\MINIE", &pHkeySub); |
| - if (res == ERROR_SUCCESS) |
| - { |
| - LONG res = RegQueryValueEx(pHkeySub, L"ShowStatusBar", NULL, NULL, (BYTE*)&trueth, &truethSize); |
| - if (res == ERROR_SUCCESS) |
| - { |
| - RegCloseKey(pHkey); |
| - } |
| - } |
| - } |
| - return trueth == 1; |
| -} |
| - |
| -void CPluginClass::ShowStatusBar() |
| -{ |
| - VARIANT_BOOL isVisible; |
| - |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - |
| - CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); |
| - if (browser) |
| - { |
| - HRESULT hr = S_OK; |
| - hr = browser->get_StatusBar(&isVisible); |
| - if (SUCCEEDED(hr)) |
| - { |
| - if (!isVisible) |
| - { |
| - if (!settings->GetBool("statusbarasked", false)) |
| - { |
| - SHANDLE_PTR pBrowserHWnd; |
| - browser->get_HWND((SHANDLE_PTR*)&pBrowserHWnd); |
| - CPluginDictionary* dictionary = CPluginDictionary::GetInstance(false); |
| - settings->SetBool("statusbarasked", true); |
| - settings->Write(); |
| - |
| - HKEY pHkey; |
| - HKEY pHkeySub; |
| - LSTATUS regRes = 0; |
| - regRes = RegOpenCurrentUser(KEY_WRITE, &pHkey); |
| - |
| - // Do we have enough rights to enable a status bar? |
| - if (regRes != 0) |
| - { |
| - // We use the tab window here and in the next few calls, since the browser window may still not be available |
| - LRESULT res = MessageBox((HWND)m_hTabWnd, dictionary->Lookup("ERROR_CAN_NOT_ENABLE_STATUS_BAR"), |
| - dictionary->Lookup("ERROR_CAN_NOT_ENABLE_STATUS_BAR_TITLE"), MB_OK); |
| - return; |
| - } |
| - // Ask if a user wants to enable a status bar automatically |
| - LRESULT res = MessageBox((HWND)m_hTabWnd, dictionary->Lookup("ERROR_STATUS_BAR_DISABLED"), |
| - dictionary->Lookup("ERROR_STATUS_BAR_DISABLED_TITLE"), MB_YESNO); |
| - if (res == IDYES) |
| - { |
| - DWORD trueth = 1; |
| - regRes = RegOpenKey(pHkey, L"Software\\Microsoft\\Internet Explorer\\MINIE", &pHkeySub); |
| - regRes = RegSetValueEx(pHkeySub, L"ShowStatusBar", 0, REG_DWORD, (BYTE*)&trueth, sizeof(DWORD)); |
| - regRes = RegCloseKey(pHkeySub); |
| - regRes = RegOpenKey(pHkey, L"Software\\Microsoft\\Internet Explorer\\Main", &pHkeySub); |
| - regRes = RegSetValueEx(pHkeySub, L"StatusBarWeb", 0, REG_DWORD, (BYTE*)&trueth, sizeof(DWORD)); |
| - regRes = RegCloseKey(pHkeySub); |
| - hr = browser->put_StatusBar(TRUE); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_PUT_STATUSBAR, "Class::Enable statusbar"); |
| - } |
| - CreateStatusBarPane(); |
| - |
| - // We need to restart the tab now, to enable the status bar properly |
| - VARIANT vFlags; |
| - vFlags.vt = VT_I4; |
| - vFlags.intVal = navOpenInNewTab; |
| - |
| - CComBSTR curLoc; |
| - browser->get_LocationURL(&curLoc); |
| - HRESULT hr = browser->Navigate(curLoc, &vFlags, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - vFlags.intVal = navOpenInNewWindow; |
| - |
| - hr = browser->Navigate(CComBSTR(curLoc), &vFlags, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION, "Navigation::Failed") |
| - } |
| - } |
| - browser->Quit(); |
| - |
| - } |
| - } |
| - } |
| - } |
| - else |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_STATUSBAR, "Class::Get statusbar state"); |
| - } |
| - } |
| -} |
| - |
| -void CPluginClass::BeforeNavigate2(DISPPARAMS* pDispParams) |
| -{ |
| - |
| - if (pDispParams->cArgs < 7) |
| - { |
| - return; |
| - } |
| - //Register a mime filter if it's not registered yet |
| - if (s_mimeFilter == NULL) |
| - { |
| - s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
| - } |
| - |
| - // Get the IWebBrowser2 interface |
| - CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> WebBrowser2Ptr; |
| - VARTYPE vt = pDispParams->rgvarg[6].vt; |
| - if (vt == VT_DISPATCH) |
| - { |
| - WebBrowser2Ptr = pDispParams->rgvarg[6].pdispVal; |
| - } |
| - else |
| - { |
| - // Wrong type, return. |
| - return; |
| - } |
| - |
| - // Get the URL |
| - CString url; |
| - vt = pDispParams->rgvarg[5].vt; |
| - if (vt == VT_BYREF + VT_VARIANT) |
| - { |
| - url = pDispParams->rgvarg[5].pvarVal->bstrVal; |
| - |
| - CPluginClient::UnescapeUrl(url); |
| - } |
| - else |
| - { |
| - // Wrong type, return. |
| - return; |
| - } |
| - |
| - // If webbrowser2 is equal to top level browser (as set in SetSite), we are navigating new page |
| - CPluginClient* client = CPluginClient::GetInstance(); |
| - |
| - if (url.Find(L"javascript") == 0) |
| - { |
| - } |
| - else if (GetBrowser().IsEqualObject(WebBrowser2Ptr)) |
| - { |
| - m_tab->OnNavigate(url); |
| - |
| - DEBUG_GENERAL(L"================================================================================\nBegin main navigation url:" + url + "\n================================================================================") |
| - |
| -#ifdef ENABLE_DEBUG_RESULT |
| - CPluginDebug::DebugResultDomain(url); |
| -#endif |
| - |
| - UpdateStatusBar(); |
| - } |
| - else |
| - { |
| - DEBUG_NAVI(L"Navi::Begin navigation url:" + url) |
| - |
| -#ifdef SUPPORT_FRAME_CACHING |
| - m_tab->CacheFrame(url); |
| -#endif |
| - } |
| -} |
| -STDMETHODIMP CPluginClass::OnTabChanged(DISPPARAMS* pDispParams, WORD wFlags) |
| -{ |
| - bool newtabshown = pDispParams->rgvarg[1].intVal==3; |
| - if (newtabshown) |
| - { |
| - std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(GetCurrentThreadId()); |
| - if (it == s_threadInstances.end()) |
| - { |
| - s_threadInstances[::GetCurrentThreadId()] = this; |
| - |
| - |
| - if (!m_isInitializedOk) |
| - { |
| - m_isInitializedOk = true; |
| - if (!InitObject(true)) |
| - { |
| - // Unadvice(); |
| - } |
| - UpdateStatusBar(); |
| - } |
| - } |
| - } |
| - return VARIANT_TRUE; |
| -} |
| - |
| -// This gets called whenever there's a browser event |
| -STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) |
| -{ |
| - WCHAR tmp[256]; |
| - wsprintf(tmp, L"Invoke: %d\n", dispidMember); |
| - DEBUG_GENERAL(tmp); |
| - switch (dispidMember) |
| - { |
| - |
| - case DISPID_WINDOWSTATECHANGED: |
| - return OnTabChanged(pDispParams, wFlags); |
| - break; |
| - case DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREUPDATE: |
| - return VARIANT_TRUE; |
| - break; |
| - |
| - case DISPID_HTMLDOCUMENTEVENTS2_ONCLICK: |
| - return VARIANT_TRUE; |
| - break; |
| - |
| - case DISPID_EVMETH_ONLOAD: |
| - DEBUG_NAVI("Navi::OnLoad") |
| - return VARIANT_TRUE; |
| - break; |
| - |
| - case DISPID_EVMETH_ONCHANGE: |
| - return VARIANT_TRUE; |
| - |
| - case DISPID_EVMETH_ONMOUSEDOWN: |
| - return VARIANT_TRUE; |
| - |
| - case DISPID_EVMETH_ONMOUSEENTER: |
| - return VARIANT_TRUE; |
| - |
| - case DISPID_IHTMLIMGELEMENT_START: |
| - return VARIANT_TRUE; |
| - |
| - case STDDISPID_XOBJ_ERRORUPDATE: |
| - return VARIANT_TRUE; |
| - |
| - case STDDISPID_XOBJ_ONPROPERTYCHANGE: |
| - return VARIANT_TRUE; |
| - |
| - case DISPID_READYSTATECHANGE: |
| - DEBUG_NAVI("Navi::ReadyStateChange") |
| - return VARIANT_TRUE; |
| - |
| - case DISPID_BEFORENAVIGATE: |
| - DEBUG_NAVI("Navi::BeforeNavigate") |
| - return VARIANT_TRUE; |
| - case DISPID_COMMANDSTATECHANGE: |
| - if (m_hPaneWnd == NULL) |
| - { |
| - CreateStatusBarPane(); |
| - } |
| - else |
| - { |
| - RECT rect; |
| - BOOL rectRes = GetClientRect(m_hStatusBarWnd, &rect); |
| - if (rectRes == TRUE) |
| - { |
| - MoveWindow(m_hPaneWnd, rect.right - 200, 0, m_nPaneWidth, rect.bottom - rect.top, TRUE); |
| - } |
| - } |
| - break; |
| - case DISPID_STATUSTEXTCHANGE: |
| - break; |
| - |
| - case DISPID_BEFORENAVIGATE2: |
| - BeforeNavigate2(pDispParams); |
| - break; |
| - |
| - case DISPID_DOWNLOADBEGIN: |
| - { |
| - DEBUG_NAVI("Navi::Download Begin") |
| - } |
| - break; |
| - |
| - case DISPID_DOWNLOADCOMPLETE: |
| - { |
| - DEBUG_NAVI("Navi::Download Complete") |
| - |
| - CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| - if (browser) |
| - { |
| - m_tab->OnDownloadComplete(browser); |
| - } |
| - } |
| - break; |
| - |
| - case DISPID_DOCUMENTCOMPLETE: |
| - { |
| - DEBUG_NAVI("Navi::Document Complete") |
| - |
| - CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| - |
| - if (browser && pDispParams->cArgs >= 2 && pDispParams->rgvarg[1].vt == VT_DISPATCH) |
| - { |
| - CComQIPtr<IWebBrowser2> pBrowser = pDispParams->rgvarg[1].pdispVal; |
| - if (pBrowser) |
| - { |
| - CString url; |
| - CComBSTR bstrUrl; |
| - if (SUCCEEDED(pBrowser->get_LocationURL(&bstrUrl)) && ::SysStringLen(bstrUrl) > 0) |
| - { |
| - url = bstrUrl; |
| - |
| - CPluginClient::UnescapeUrl(url); |
| - |
| - m_tab->OnDocumentComplete(browser, url, browser.IsEqualObject(pBrowser)); |
| - } |
| - } |
| - } |
| - } |
| - break; |
| - |
| - case DISPID_ONQUIT: |
| - case DISPID_QUIT: |
| - { |
| - Unadvice(); |
| - } |
| - break; |
| - |
| - default: |
| - { |
| - CString did; |
| - did.Format(L"DispId:%u", dispidMember); |
| - |
| - DEBUG_NAVI(L"Navi::Default " + did) |
| - } |
| - |
| - // do nothing |
| - break; |
| - } |
| - |
| - return VARIANT_TRUE; |
| -} |
| - |
| -bool CPluginClass::InitObject(bool bBHO) |
| -{ |
| - // Load theme module |
| - |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - if (!s_hUxtheme) |
| - { |
| - s_hUxtheme = ::GetModuleHandle(_T("uxtheme.dll")); |
| - if (s_hUxtheme) |
| - { |
| - pfnClose = (CLOSETHEMEDATA)::GetProcAddress(s_hUxtheme, "CloseThemeData"); |
| - if (!pfnClose) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_CLOSE, "Class::InitObject - GetProcAddress(CloseThemeData)"); |
| - } |
| - |
| - pfnDrawThemeBackground = (DRAWTHEMEBACKGROUND)::GetProcAddress(s_hUxtheme, "DrawThemeBackground"); |
| - if (!pfnDrawThemeBackground) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_DRAW_BACKGROUND, "Class::InitObject - GetProcAddress(DrawThemeBackground)"); |
| - } |
| - |
| - pfnOpenThemeData = (OPENTHEMEDATA)::GetProcAddress(s_hUxtheme, "OpenThemeData"); |
| - if (!pfnOpenThemeData) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_OPEN, "Class::InitObject - GetProcAddress(pfnOpenThemeData)"); |
| - } |
| - } |
| - else |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME, "Class::InitObject - GetModuleHandle(uxtheme.dll)"); |
| - } |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - // Register pane class |
| - if (!GetAtomPaneClass()) |
| - { |
| - WNDCLASSEX wcex; |
| - |
| - wcex.cbSize = sizeof(WNDCLASSEX); |
| - wcex.style = 0; |
| - wcex.lpfnWndProc = (WNDPROC)PaneWindowProc; |
| - wcex.cbClsExtra = 0; |
| - wcex.cbWndExtra = 0; |
| - wcex.hInstance = _Module.m_hInst; |
| - wcex.hIcon = NULL; |
| - wcex.hCursor = NULL; |
| - wcex.hbrBackground = NULL; |
| - wcex.lpszMenuName = NULL; |
| - wcex.lpszClassName = _T(STATUSBAR_PANE_NAME); |
| - wcex.hIconSm = NULL; |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - s_atomPaneClass = ::RegisterClassEx(&wcex); |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - if (!GetAtomPaneClass()) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_REGISTER_PANE_CLASS, "Class::InitObject - RegisterClassEx"); |
| - return false; |
| - } |
| - } |
| - |
| - |
| - // Create status pane |
| - if (bBHO) |
| - { |
| - if (!CreateStatusBarPane()) |
| - { |
| - return false; |
| - } |
| - } |
| - |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - |
| - // Create main thread |
| - if (GetMainThreadHandle() == NULL && settings->IsMainProcess() && settings->IsMainUiThread()) |
| - { |
| - DWORD id; |
| - HANDLE handle = ::CreateThread(NULL, 0, MainThreadProc, (LPVOID)m_tab, CREATE_SUSPENDED, &id); |
| - if (handle == NULL) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS, "Class::Thread - Failed to create main thread"); |
| - } |
| - |
| - s_hMainThread = handle; |
| - |
| - ::ResumeThread(handle); |
| - } |
| - |
| - return true; |
| -} |
| - |
| -bool CPluginClass::CreateStatusBarPane() |
| -{ |
| - DEBUG_GENERAL(L"Getting client"); |
| - |
| - CPluginClient* client = CPluginClient::GetInstance(); |
| - |
| - DEBUG_GENERAL(L"Getting ieversion"); |
| - |
| - if (client->GetIEVersion()< 7) |
| - |
| - return true; |
| - |
| - TCHAR szClassName[MAX_PATH]; |
| - DEBUG_GENERAL(L"Getting browser wnd"); |
| - // Get browser window and url |
| - HWND hBrowserWnd = GetBrowserHWND(); |
| - if (!hBrowserWnd) |
| - { |
| - DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_BROWSER, "Class::CreateStatusBarPane - No status bar") |
| - return false; |
| - } |
| - |
| - // Looking for a TabWindowClass window in IE7 |
| - // the last one should be parent for statusbar |
| - HWND hWndStatusBar = NULL; |
| - |
| - DEBUG_GENERAL(L"Locating status bar window"); |
| - |
| - HWND hTabWnd = ::GetWindow(hBrowserWnd, GW_CHILD); |
| - UINT amoundOfNewTabs = 0; |
| - HWND uniqueNewTab = NULL; |
| - while (hTabWnd) |
| - { |
| - memset(szClassName, 0, MAX_PATH); |
| - GetClassName(hTabWnd, szClassName, MAX_PATH); |
| - |
| - if (_tcscmp(szClassName, _T("TabWindowClass")) == 0 || _tcscmp(szClassName,_T("Frame Tab")) == 0) |
| - { |
| - // IE8 support |
| - HWND hTabWnd2 = hTabWnd; |
| - if (_tcscmp(szClassName,_T("Frame Tab")) == 0) |
| - { |
| - hTabWnd2 = ::FindWindowEx(hTabWnd2, NULL, _T("TabWindowClass"), NULL); |
| - } |
| - |
| - if (hTabWnd2) |
| - { |
| - DWORD nProcessId; |
| - ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); |
| - if (::GetCurrentProcessId() == nProcessId) |
| - { |
| - bool bExistingTab = false; |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - for (int i = 0; i < s_instances.GetSize(); i++) |
| - { |
| - if (s_instances[i]->m_hTabWnd == hTabWnd2) |
| - { |
| - |
| - bExistingTab = true; |
| - break; |
| - } |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - if (!bExistingTab) |
| - { |
| - amoundOfNewTabs ++; |
| - uniqueNewTab = hTabWnd2; |
| - if (GetCurrentThreadId() == GetWindowThreadProcessId(hTabWnd2, NULL)) |
| - { |
| - hBrowserWnd = hTabWnd = hTabWnd2; |
| - break; |
| - } |
| - |
| - } |
| - } |
| - } |
| - } |
| - |
| - hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); |
| - } |
| - |
| - DEBUG_GENERAL(L"status bar window located"); |
| - |
| - HWND hWnd = ::GetWindow(hBrowserWnd, GW_CHILD); |
| - while (hWnd) |
| - { |
| - memset(szClassName, 0, MAX_PATH); |
| - ::GetClassName(hWnd, szClassName, MAX_PATH); |
| - |
| - if (_tcscmp(szClassName,_T("msctls_statusbar32")) == 0) |
| - { |
| - hWndStatusBar = hWnd; |
| - break; |
| - } |
| - |
| - hWnd = ::GetWindow(hWnd, GW_HWNDNEXT); |
| - } |
| - |
| - DEBUG_GENERAL(L"Status bar located 2"); |
| - |
| - if (!hWndStatusBar) |
| - { |
| - DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_WIN, "Class::CreateStatusBarPane - No status bar") |
| - return true; |
| - } |
| - |
| - // Calculate pane height |
| - CRect rcStatusBar; |
| - ::GetClientRect(hWndStatusBar, &rcStatusBar); |
| - |
| - if (rcStatusBar.Height() > 0) |
| - { |
| -#ifdef _DEBUG |
| - m_nPaneWidth = 70; |
| -#else |
| - m_nPaneWidth = min(rcStatusBar.Height(), 22); |
| -#endif |
| - } |
| - else |
| - { |
| -#ifdef _DEBUG |
| - m_nPaneWidth = 70; |
| -#else |
| - m_nPaneWidth = 22; |
| -#endif |
| - } |
| - // Create pane window |
| - HWND hWndNewPane = ::CreateWindowEx( |
| - NULL, |
| - MAKEINTATOM(GetAtomPaneClass()), |
| - _T(""), |
| - WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, |
| - rcStatusBar.Width() - 500,0,m_nPaneWidth,rcStatusBar.Height(), |
| - hWndStatusBar, |
| - (HMENU)3671, |
| - _Module.m_hInst, |
| - NULL); |
| - |
| - if (!hWndNewPane) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_CREATE_STATUSBAR_PANE, "Class::CreateStatusBarPane - CreateWindowEx") |
| - return false; |
| - } |
| - |
| - m_hTabWnd = hTabWnd; |
| - m_hStatusBarWnd = hWndStatusBar; |
| - m_hPaneWnd = hWndNewPane; |
| - |
| - UpdateTheme(); |
| - |
| - // Subclass status bar |
| - m_pWndProcStatus = (WNDPROC)SetWindowLongPtr(hWndStatusBar, GWLP_WNDPROC, (LPARAM)(WNDPROC)NewStatusProc); |
| - |
| - // Adjust pane |
| - UINT nPartCount = ::SendMessage(m_hStatusBarWnd, SB_GETPARTS, 0, 0); |
| - |
| - if (nPartCount > 1) |
| - { |
| - INT *pData = new INT[nPartCount]; |
| - |
| - ::SendMessage(m_hStatusBarWnd, SB_GETPARTS, nPartCount, (LPARAM)pData); |
| - ::SendMessage(m_hStatusBarWnd, SB_SETPARTS, nPartCount, (LPARAM)pData); |
| - |
| - delete[] pData; |
| - } |
| - HDC hdc = GetWindowDC(m_hStatusBarWnd); |
| - SendMessage(m_hStatusBarWnd, WM_PAINT, (WPARAM)hdc, 0); |
| - ReleaseDC(m_hStatusBarWnd, hdc); |
| - return true; |
| -}///////////////////////////////////////////////////////////////////////////// |
| -// Implementation |
| - |
| -void CPluginClass::CloseTheme() |
| -{ |
| - if (m_hTheme) |
| - { |
| - if (pfnClose) |
| - { |
| - pfnClose(m_hTheme); |
| - } |
| - |
| - m_hTheme = NULL; |
| - } |
| -} |
| - |
| -void CPluginClass::UpdateTheme() |
| -{ |
| - CloseTheme(); |
| - |
| - if (pfnOpenThemeData) |
| - { |
| - m_hTheme = pfnOpenThemeData(m_hPaneWnd, L"STATUS"); |
| - if (!m_hTheme) |
| - { |
| - } |
| - } |
| -} |
| - |
| - |
| -CPluginClass* CPluginClass::FindInstance(HWND hStatusBarWnd) |
| -{ |
| - CPluginClass* instance = NULL; |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - for (int i = 0; i < s_instances.GetSize(); i++) |
| - { |
| - if (s_instances[i]->m_hStatusBarWnd == hStatusBarWnd) |
| - { |
| - instance = s_instances[i]; |
| - break; |
| - } |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - return instance; |
| -} |
| - |
| -CPluginTab* CPluginClass::GetTab() |
| -{ |
| - return m_tab; |
| -} |
| - |
| -CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) |
| -{ |
| - CPluginTab* tab = NULL; |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dwThreadId); |
| - if (it != s_threadInstances.end()) |
| - { |
| - tab = it->second->m_tab; |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - return tab; |
| -} |
| - |
| - |
| -STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText) |
| -{ |
| - if (cCmds == 0) return E_INVALIDARG; |
| - if (prgCmds == 0) return E_POINTER; |
| - |
| - prgCmds[0].cmdf = OLECMDF_ENABLED; |
| - |
| - return S_OK; |
| -} |
| - |
| -HMENU CPluginClass::CreatePluginMenu(const CString& url) |
| -{ |
| - HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); |
| - |
| - HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); |
| - |
| - HMENU hMenuTrackPopup = GetSubMenu(hMenu, 0); |
| - |
| - SetMenuBar(hMenuTrackPopup, url); |
| - |
| - return hMenuTrackPopup; |
| -} |
| -BOOL CreateLowProcess(WCHAR* wszProcessName, WCHAR* cmdLine) |
| -{ |
| - |
| - BOOL fRet; |
| - HANDLE hToken = NULL; |
| - HANDLE hNewToken = NULL; |
| - PSID pIntegritySid = NULL; |
| - TOKEN_MANDATORY_LABEL TIL = {0}; |
| - PROCESS_INFORMATION ProcInfo = {0}; |
| - STARTUPINFO StartupInfo = {0}; |
| - |
| - |
| - |
| - // Low integrity SID |
| - WCHAR wszIntegritySid[20] = L"S-1-16-4096"; |
| - |
| - |
| - fRet = OpenProcessToken(GetCurrentProcess(), |
| - TOKEN_DUPLICATE | |
| - TOKEN_ADJUST_DEFAULT | |
| - TOKEN_QUERY | |
| - TOKEN_ASSIGN_PRIMARY, |
| - &hToken); |
| - |
| - if (!fRet) |
| - { |
| - goto CleanExit; |
| - } |
| - |
| - fRet = DuplicateTokenEx(hToken, |
| - 0, |
| - NULL, |
| - SecurityImpersonation, |
| - TokenPrimary, |
| - &hNewToken); |
| - |
| - if (!fRet) |
| - { |
| - goto CleanExit; |
| - } |
| - |
| - fRet = ConvertStringSidToSid(wszIntegritySid, &pIntegritySid); |
| - |
| - if (!fRet) |
| - { |
| - goto CleanExit; |
| - } |
| - |
| - |
| - TIL.Label.Attributes = SE_GROUP_INTEGRITY; |
| - TIL.Label.Sid = pIntegritySid; |
| - |
| - |
| - // |
| - // Set the process integrity level |
| - // |
| - |
| - fRet = SetTokenInformation(hNewToken, |
| - TokenIntegrityLevel, |
| - &TIL, |
| - sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)); |
| - |
| - if (!fRet) |
| - { |
| - goto CleanExit; |
| - } |
| - |
| - // |
| - // Create the new process at Low integrity |
| - // |
| - |
| - fRet = CreateProcessAsUser(hNewToken, |
| - wszProcessName, |
| - cmdLine, |
| - NULL, |
| - NULL, |
| - FALSE, |
| - 0, |
| - NULL, |
| - NULL, |
| - &StartupInfo, |
| - &ProcInfo); |
| - |
| - |
| -CleanExit: |
| - |
| - if (ProcInfo.hProcess != NULL) |
| - { |
| - CloseHandle(ProcInfo.hProcess); |
| - } |
| - |
| - if (ProcInfo.hThread != NULL) |
| - { |
| - CloseHandle(ProcInfo.hThread); |
| - } |
| - |
| - LocalFree(pIntegritySid); |
| - |
| - if (hNewToken != NULL) |
| - { |
| - CloseHandle(hNewToken); |
| - } |
| - |
| - if (hToken != NULL) |
| - { |
| - CloseHandle(hToken); |
| - } |
| - |
| - return fRet; |
| -} |
| - |
| -void CPluginClass::DisplayPluginMenu(HMENU hMenu, int nToolbarCmdID, POINT pt, UINT nMenuFlags) |
| -{ |
| - CPluginClient* client = CPluginClient::GetInstance(); |
| - |
| - CPluginSystem* system = CPluginSystem::GetInstance(); |
| - |
| - CString url; |
| - int navigationErrorId = 0; |
| - |
| - // Create menu parent window |
| - HWND hMenuWnd = ::CreateWindowEx( |
| - NULL, |
| - MAKEINTATOM(GetAtomPaneClass()), |
| - _T(""), |
| - 0, |
| - 0,0,0,0, |
| - NULL, |
| - NULL, |
| - _Module.m_hInst, |
| - NULL); |
| - |
| - if (!hMenuWnd) |
| - { |
| - DestroyMenu(hMenu); |
| - return; |
| - } |
| - |
| - // Display menu |
| - nMenuFlags |= TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON; |
| - |
| - int nCommand = ::TrackPopupMenu(hMenu, nMenuFlags, pt.x, pt.y, 0, hMenuWnd, 0); |
| - |
| - ::DestroyMenu(hMenu); |
| - ::DestroyWindow(hMenuWnd); |
| - |
| - switch (nCommand) |
| - { |
| - case ID_PLUGIN_UPDATE: |
| - { |
| - s_isPluginToBeUpdated = true; |
| - } |
| - break; |
| - |
| - case ID_PLUGIN_ENABLE: |
| - { |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - |
| - settings->TogglePluginEnabled(); |
| - |
| - // Enable / disable mime filter |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - if (settings->GetPluginEnabled()) |
| - { |
| - s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
| - } |
| - else |
| - { |
| - s_mimeFilter = NULL; |
| - |
| - CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| -#ifdef SUPPORT_WHITELIST |
| - client->ClearWhiteListCache(); |
| -#endif |
| - } |
| - break; |
| -#ifndef ENTERPRISE |
| - case ID_SETTINGS: |
| - { |
| - url = UserSettingsFileUrl(); |
| - } |
| - break; |
| -#endif |
| - case ID_INVITEFRIENDS: |
| - { |
| - url = CPluginHttpRequest::GetStandardUrl(USERS_SCRIPT_INVITATION); |
| - navigationErrorId = PLUGIN_ERROR_NAVIGATION_INVITATION; |
| - } |
| - break; |
| - |
| - case ID_FAQ: |
| - { |
| - url = CPluginHttpRequest::GetStandardUrl(USERS_SCRIPT_FAQ); |
| - navigationErrorId = PLUGIN_ERROR_NAVIGATION_FAQ; |
| - } |
| - break; |
| - |
| - case ID_FEEDBACK: |
| - { |
| - CPluginHttpRequest httpRequest(USERS_SCRIPT_FEEDBACK); |
| - |
| - httpRequest.AddPluginId(); |
| - httpRequest.Add("reason", 0); |
| - httpRequest.Add(L"url", m_tab->GetDocumentUrl(), false); |
| - |
| - url = httpRequest.GetUrl(); |
| - navigationErrorId = PLUGIN_ERROR_NAVIGATION_FEEDBACK; |
| - } |
| - break; |
| - |
| - case ID_ABOUT: |
| - { |
| - url = CPluginHttpRequest::GetStandardUrl(USERS_SCRIPT_ABOUT); |
| - navigationErrorId = PLUGIN_ERROR_NAVIGATION_ABOUT; |
| - } |
| - break; |
| - |
| - default: |
| - |
| - break; |
| - } |
| - |
| - // Invalidate and redraw the control |
| - UpdateStatusBar(); |
| - |
| - CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| - if (!url.IsEmpty() && browser) |
| - { |
| - VARIANT vFlags; |
| - vFlags.vt = VT_I4; |
| - vFlags.intVal = navOpenInNewTab; |
| - |
| - HRESULT hr = browser->Navigate(CComBSTR(url), &vFlags, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - vFlags.intVal = navOpenInNewWindow; |
| - |
| - hr = browser->Navigate(CComBSTR(url), &vFlags, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, navigationErrorId, "Navigation::Failed") |
| - } |
| - } |
| - } |
| -} |
| - |
| - |
| -bool CPluginClass::SetMenuBar(HMENU hMenu, const CString& url) |
| -{ |
| - CString ctext; |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| -#ifdef SUPPORT_WHITELIST |
| - s_menuDomains.clear(); |
| -#endif |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - CPluginTab* tab = GetTab(::GetCurrentThreadId()); |
| - if (!tab) |
| - { |
| - return false; |
| - } |
| - |
| - CPluginDictionary* dictionary = CPluginDictionary::GetInstance(); |
| - |
| - MENUITEMINFO fmii; |
| - memset(&fmii, 0, sizeof(MENUITEMINFO)); |
| - fmii.cbSize = sizeof(MENUITEMINFO); |
| - |
| - MENUITEMINFO miiSep; |
| - memset(&miiSep, 0, sizeof(MENUITEMINFO)); |
| - miiSep.cbSize = sizeof(MENUITEMINFO); |
| - miiSep.fMask = MIIM_TYPE | MIIM_FTYPE; |
| - miiSep.fType = MFT_SEPARATOR; |
| - |
| - CPluginClient* client = CPluginClient::GetInstance(); |
| - |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - |
| - settings->RefreshTab(); |
| - |
| - // Update settings |
| - m_tab->OnUpdateSettings(false); |
| - |
| - // Plugin update |
| - if (settings->IsPluginUpdateAvailable()) |
| - { |
| - ctext = dictionary->Lookup("MENU_UPDATE"); |
| - fmii.fMask = MIIM_STATE | MIIM_STRING; |
| - fmii.fState = MFS_ENABLED; |
| - fmii.dwTypeData = ctext.GetBuffer(); |
| - fmii.cch = ctext.GetLength(); |
| - ::SetMenuItemInfo(hMenu, ID_PLUGIN_UPDATE, FALSE, &fmii); |
| - } |
| - else |
| - { |
| - ::DeleteMenu(hMenu, ID_PLUGIN_UPDATE, FALSE); |
| - } |
| -#ifdef SUPPORT_WHITELIST |
| - { |
| - // White list domain |
| - ctext = dictionary->Lookup("MENU_DISABLE_ON"); |
| - fmii.fMask = MIIM_STRING | MIIM_STATE; |
| - fmii.fState = MFS_DISABLED; |
| - fmii.dwTypeData = ctext.GetBuffer(); |
| - fmii.cch = ctext.GetLength(); |
| - |
| - UINT index = WM_WHITELIST_DOMAIN; |
| - |
| - ::SetMenuItemInfo(hMenu, ID_WHITELISTDOMAIN, FALSE, &fmii); |
| - } |
| -#else |
| - { |
| - ::DeleteMenu(hMenu, ID_WHITELISTDOMAIN, FALSE); |
| - } |
| -#endif // SUPPORT_WHITELIST |
| - |
| - // Invite friends |
| - ctext = dictionary->Lookup("MENU_INVITE_FRIENDS"); |
| - fmii.fMask = MIIM_STATE | MIIM_STRING; |
| - fmii.fState = MFS_ENABLED; |
| - fmii.dwTypeData = ctext.GetBuffer(); |
| - fmii.cch = ctext.GetLength(); |
| - ::SetMenuItemInfo(hMenu, ID_INVITEFRIENDS, FALSE, &fmii); |
| - |
| - // FAQ |
| - ctext = dictionary->Lookup("MENU_FAQ"); |
| - fmii.fMask = MIIM_STATE | MIIM_STRING; |
| - fmii.fState = MFS_ENABLED; |
| - fmii.dwTypeData = ctext.GetBuffer(); |
| - fmii.cch = ctext.GetLength(); |
| - ::SetMenuItemInfo(hMenu, ID_FAQ, FALSE, &fmii); |
| - |
| - // About |
| - ctext = dictionary->Lookup("MENU_ABOUT"); |
| - fmii.fMask = MIIM_STATE | MIIM_STRING; |
| - fmii.fState = MFS_ENABLED; |
| - fmii.dwTypeData = ctext.GetBuffer(); |
| - fmii.cch = ctext.GetLength(); |
| - ::SetMenuItemInfo(hMenu, ID_ABOUT, FALSE, &fmii); |
| - |
| - // Feedback |
| - ctext = dictionary->Lookup("MENU_FEEDBACK"); |
| - fmii.fMask = MIIM_STATE | MIIM_STRING; |
| - fmii.fState = MFS_ENABLED; |
| - fmii.dwTypeData = ctext.GetBuffer(); |
| - fmii.cch = ctext.GetLength(); |
| - ::SetMenuItemInfo(hMenu, ID_FEEDBACK, FALSE, &fmii); |
| - |
| - // Plugin enable |
| - if (settings->GetPluginEnabled()) |
| - { |
| - ctext = dictionary->Lookup("MENU_DISABLE"); |
| - } |
| - else |
| - { |
| - ctext = dictionary->Lookup("MENU_ENABLE"); |
| - } |
| - fmii.fMask = MIIM_STATE | MIIM_STRING; |
| - fmii.fState = client ? MFS_ENABLED : MFS_DISABLED; |
| - fmii.dwTypeData = ctext.GetBuffer(); |
| - fmii.cch = ctext.GetLength(); |
| - ::SetMenuItemInfo(hMenu, ID_PLUGIN_ENABLE, FALSE, &fmii); |
| - |
| - // Settings |
| -#ifndef ENTERPRISE |
| - ctext = dictionary->Lookup("MENU_SETTINGS"); |
| - fmii.fMask = MIIM_STATE | MIIM_STRING; |
| - fmii.fState = MFS_ENABLED; |
| - fmii.dwTypeData = ctext.GetBuffer(); |
| - fmii.cch = ctext.GetLength(); |
| - ::SetMenuItemInfo(hMenu, ID_SETTINGS, FALSE, &fmii); |
| -#else |
| - RemoveMenu(hMenu, ID_SETTINGS, MF_BYCOMMAND); |
| - RemoveMenu(hMenu, 5, MF_BYPOSITION); |
| -#endif |
| - |
| - ctext.ReleaseBuffer(); |
| - |
| - return true; |
| -} |
| - |
| - |
| -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 E_FAIL; |
| - } |
| - |
| - // Check if button in toolbar was pressed |
| - int nIDCommand = -1; |
| - BOOL bRightAlign = FALSE; |
| - |
| - POINT pt; |
| - GetCursorPos(&pt); |
| - |
| - HWND hWndToolBar = ::WindowFromPoint(pt); |
| - |
| - DWORD nProcessId; |
| - ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); |
| - |
| - if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) |
| - { |
| - ::ScreenToClient(hWndToolBar, &pt); |
| - int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); |
| - |
| - if (nButton > 0) |
| - { |
| - TBBUTTON pTBBtn; |
| - memset(&pTBBtn, 0, sizeof(TBBUTTON)); |
| - |
| - if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) |
| - { |
| - RECT rcButton; |
| - nIDCommand = pTBBtn.idCommand; |
| - |
| - if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) |
| - { |
| - 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 |
| - { |
| - nFlags |= TPM_LEFTALIGN; |
| - } |
| - |
| - DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); |
| - |
| - return S_OK; |
| -} |
| - |
| -///////////////////////////////////////////////////////////////////////////// |
| -// Window procedures |
| - |
| -LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
| -{ |
| - // Find tab |
| - CPluginClass *pClass = FindInstance(hWnd); |
| - if (!pClass) |
| - { |
| - return DefWindowProc(hWnd, message, wParam, lParam); |
| - } |
| - |
| - // Process message |
| - switch (message) |
| - { |
| - case SB_SIMPLE: |
| - { |
| - ShowWindow(pClass->m_hPaneWnd, !wParam); |
| - break; |
| - } |
| - |
| - case WM_SYSCOLORCHANGE: |
| - { |
| - pClass->UpdateTheme(); |
| - break; |
| - } |
| - |
| - case SB_SETPARTS: |
| - { |
| - if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd)) |
| - { |
| - return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam); |
| - } |
| - |
| - int nParts = wParam; |
| - if (STATUSBAR_PANE_NUMBER >= nParts) |
| - { |
| - return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam); |
| - } |
| - |
| - HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts+1)); |
| - LPINT lpParts = (LPINT)LocalLock(hLocal); |
| - memcpy(lpParts, (void*)lParam, wParam*sizeof(int)); |
| - |
| - for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++) |
| - { |
| - lpParts[i] -= pClass->m_nPaneWidth; |
| - } |
| - LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, (LPARAM)lpParts); |
| - |
| - CRect rcPane; |
| - ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane); |
| - |
| - CRect rcClient; |
| - ::GetClientRect(hWnd, &rcClient); |
| - |
| - ::MoveWindow( |
| - pClass->m_hPaneWnd, |
| - lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth, |
| - 0, |
| - pClass->m_nPaneWidth, |
| - rcClient.Height(), |
| - TRUE); |
| - |
| - ::LocalFree(hLocal); |
| - |
| - |
| - return hRet; |
| - } |
| - |
| - default: |
| - break; |
| - } |
| - |
| - LRESULT result = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam); |
| - |
| - |
| - return result; |
| - |
| -} |
| - |
| - |
| -HICON CPluginClass::GetStatusBarIcon(const CString& url) |
| -{ |
| - // use the disable icon as defualt, if the client doesn't exists |
| - HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
| - |
| - CPluginTab* tab = GetTab(::GetCurrentThreadId()); |
| - if (tab) |
| - { |
| - CPluginClient* client = CPluginClient::GetInstance(); |
| - |
| -#ifdef PRODUCT_ADBLOCKPLUS |
| - if (!CPluginSettings::GetInstance()->IsPluginEnabled()) |
| - { |
| - } |
| -#ifdef SUPPORT_WHITELIST |
| - else if (client->IsUrlWhiteListed(url)) |
| - { |
| - hIcon = GetIcon(ICON_PLUGIN_DISABLED); |
| - } |
| -#endif // SUPPORT_WHITELIST |
| - else |
| - { |
| - //Deativate adblock icon if adblock limit reached |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - if (!settings->GetPluginEnabled()) { |
| - hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
| - return hIcon; |
| - } |
| - hIcon = GetIcon(ICON_PLUGIN_ENABLED); |
| - } |
| - |
| -#endif // PRODUCT_ADBLOCKPLUS |
| - } |
| - |
| - return hIcon; |
| -} |
| - |
| - |
| -LRESULT CALLBACK CPluginClass::PaneWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
| -{ |
| - // Find tab |
| - CPluginClass *pClass = FindInstance(GetParent(hWnd)); |
| - if (!pClass) |
| - { |
| - return ::DefWindowProc(hWnd, message, wParam, lParam); |
| - } |
| - |
| - CPluginSystem* system = CPluginSystem::GetInstance(); |
| - |
| - // Process message |
| - switch (message) |
| - { |
| - |
| - case WM_SETCURSOR: |
| - { |
| - ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); |
| - return TRUE; |
| - } |
| - case WM_PAINT: |
| - { |
| - PAINTSTRUCT ps; |
| - HDC hDC = ::BeginPaint(hWnd, &ps); |
| - |
| - CRect rcClient; |
| - ::GetClientRect(hWnd, &rcClient); |
| - |
| - int nDrawEdge = 0; |
| - |
| - // Old Windows background drawing |
| - if (pClass->m_hTheme == NULL) |
| - { |
| - ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); |
| - ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); |
| - |
| - nDrawEdge = 3; |
| - rcClient.left += 3; |
| - |
| - ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); |
| - } |
| - // Themed background drawing |
| - else |
| - { |
| - // Draw background |
| - if (pfnDrawThemeBackground) |
| - { |
| - CRect rc = rcClient; |
| - rc.right -= 2; |
| - pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); |
| - } |
| - |
| - // Copy separator picture to left side |
| - int nHeight = rcClient.Height(); |
| - int nWidth = rcClient.Width() - 2; |
| - |
| - for (int i = 0; i < 2; i++) |
| - { |
| - for (int j = 0; j < nHeight; j++) |
| - { |
| - COLORREF clr = ::GetPixel(hDC, i + nWidth, j); |
| - |
| - // Ignore black boxes (if source is obscured by other windows) |
| - if (clr != -1 && (GetRValue(clr) > 8 || GetGValue(clr) > 8 || GetBValue(clr) > 8)) |
| - { |
| - ::SetPixel(hDC, i, j, clr); |
| - } |
| - } |
| - } |
| - } |
| - |
| - // Draw icon |
| - if (CPluginClient::GetInstance()) |
| - { |
| - HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl()); |
| - |
| - int offx = (rcClient.Height() - 16)/2 + nDrawEdge; |
| - if (hIcon) |
| - { |
| - ::DrawIconEx(hDC, offx, (rcClient.Height() - 16)/2 + 2, hIcon, 16, 16, NULL, NULL, DI_NORMAL); |
| - offx += 22; |
| - } |
| -#ifdef _DEBUG |
| - // Display version |
| - HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT, 0, 0); |
| - HGDIOBJ hOldFont = ::SelectObject(hDC,hFont); |
| - |
| - CRect rcText = rcClient; |
| - rcText.left += offx; |
| - ::SetBkMode(hDC, TRANSPARENT); |
| - ::DrawText(hDC, _T(IEPLUGIN_VERSION), -1, &rcText, DT_WORD_ELLIPSIS|DT_LEFT|DT_SINGLELINE|DT_VCENTER); |
| - |
| - ::SelectObject(hDC, hOldFont); |
| -#endif // _DEBUG |
| - } |
| - |
| - // Done! |
| - EndPaint(hWnd, &ps); |
| - |
| - return 0; |
| - } |
| - |
| - case WM_LBUTTONUP: |
| - case WM_RBUTTONUP: |
| - { |
| - CString strURL = pClass->GetBrowserUrl(); |
| - if (strURL != pClass->GetTab()->GetDocumentUrl()) |
| - { |
| - pClass->GetTab()->SetDocumentUrl(strURL); |
| - } |
| - |
| -#ifdef SUPPORT_SHOW_PLUGIN_MENU |
| - // Create menu |
| - HMENU hMenu = pClass->CreatePluginMenu(strURL); |
| - if (!hMenu) |
| - { |
| - return 0; |
| - } |
| - |
| - // Display menu |
| - POINT pt; |
| - ::GetCursorPos(&pt); |
| - |
| - RECT rc; |
| - ::GetWindowRect(hWnd, &rc); |
| - |
| - if (rc.left >= 0 && rc.top >= 0) |
| - { |
| - pt.x = rc.left; |
| - pt.y = rc.top; |
| - } |
| - |
| - pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN|TPM_BOTTOMALIGN); |
| -#else |
| - CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); |
| - if (browser) |
| - { |
| - VARIANT vFlags; |
| - vFlags.vt = VT_I4; |
| - vFlags.intVal = navOpenInNewTab; |
| - |
| - HRESULT hr = browser->Navigate(CComBSTR(UserSettingsFileUrl()), &vFlags, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - vFlags.intVal = navOpenInNewWindow; |
| - |
| - hr = browser->Navigate(CComBSTR(UserSettingsFileUrl()), &vFlags, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_SETTINGS, "Navigation::Failed") |
| - } |
| - } |
| - } |
| -#endif |
| - } |
| - break; |
| - |
| -#ifndef ENTERPRISE |
| - |
| - case WM_LAUNCH_INFO: |
| - { |
| - // Set the status bar visible, if it isn't |
| - // Otherwise the user won't see the icon the first time |
| - |
| - if (wParam == 1) |
| - { |
| - // Redirect to welcome page |
| - VARIANT_BOOL isVisible; |
| - CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); |
| - if (browser) |
| - { |
| - HRESULT hr = S_OK; |
| - |
| - hr = browser->get_StatusBar(&isVisible); |
| - if (SUCCEEDED(hr)) |
| - { |
| - if (!isVisible) |
| - { |
| - CPluginDictionary* dictionary = CPluginDictionary::GetInstance(); |
| - |
| - LRESULT res = MessageBox(NULL, dictionary->Lookup("ERROR_STATUS_BAR_DISABLED"), dictionary->Lookup("ERROR_STATUS_BAR_DISABLED_TITLE"), MB_YESNO); |
| - if (res == IDYES) |
| - { |
| - hr = browser->put_StatusBar(TRUE); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_PUT_STATUSBAR, "Class::Enable statusbar"); |
| - } |
| - } |
| - } |
| - } |
| - else |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_STATUSBAR, "Class::Get statusbar state"); |
| - } |
| - |
| - CPluginSettings* settings = CPluginSettings::GetInstance(); |
| - |
| - CPluginHttpRequest httpRequest(USERS_SCRIPT_WELCOME); |
| - |
| - httpRequest.Add("errors", settings->GetErrorList()); |
| - |
| - |
| - hr = browser->Navigate(CComBSTR(httpRequest.GetUrl() + "&src=" + DOWNLOAD_SOURCE), NULL, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_WELCOME, "Navigation::Welcome page failed") |
| - } |
| - |
| - // Update settings server side on next IE start, as they have possibly changed |
| - settings->ForceConfigurationUpdateOnStart(); |
| - } |
| - } |
| - else |
| - { |
| - // Redirect to info page |
| - CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); |
| - if (browser) |
| - { |
| - CPluginHttpRequest httpRequest(USERS_SCRIPT_INFO); |
| - |
| - httpRequest.Add("info", wParam); |
| - |
| - VARIANT vFlags; |
| - vFlags.vt = VT_I4; |
| - vFlags.intVal = navOpenInNewTab; |
| - |
| - HRESULT hr = browser->Navigate(CComBSTR(httpRequest.GetUrl()), &vFlags, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - vFlags.intVal = navOpenInNewWindow; |
| - |
| - hr = browser->Navigate(CComBSTR(httpRequest.GetUrl()), &vFlags, NULL, NULL, NULL); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_INFO, "Navigation::Info page failed") |
| - } |
| - } |
| - } |
| - } |
| - } |
| - break; |
| -#endif |
| - |
| - case WM_DESTROY: |
| - break; |
| - case SC_CLOSE: |
| - break; |
| - |
| - case WM_UPDATEUISTATE: |
| - { |
| - CPluginTab* tab = GetTab(::GetCurrentThreadId()); |
| - if (tab) |
| - { |
| - tab->OnActivate(); |
| - } |
| - } |
| - break; |
| - } |
| - |
| - return DefWindowProc(hWnd, message, wParam, lParam); |
| -} |
| - |
| - |
| -void CPluginClass::UpdateStatusBar() |
| -{ |
| - DEBUG_GENERAL("*** Updating statusbar") |
| - |
| - if (m_hPaneWnd == NULL) |
| - { |
| - CreateStatusBarPane(); |
| - } |
| - if (m_hPaneWnd != NULL) |
| - { |
| - if (!::InvalidateRect(m_hPaneWnd, NULL, FALSE)) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_INVALIDATE_STATUSBAR, "Class::Invalidate statusbar"); |
| - } |
| - } |
| -} |
| - |
| - |
| -void CPluginClass::Unadvice() |
| -{ |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - if (m_isAdviced) |
| - { |
| - CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); |
| - if (pPoint) |
| - { |
| - HRESULT hr = pPoint->Unadvise(m_nConnectionID); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVICE, "Class::Unadvice - Unadvise"); |
| - } |
| - } |
| - |
| - m_isAdviced = false; |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| -} |
| - |
| -HICON CPluginClass::GetIcon(int type) |
| -{ |
| - HICON icon = NULL; |
| - |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - if (!s_hIcons[type]) |
| - { |
| - s_hIcons[type] = ::LoadIcon(_Module.m_hInst, MAKEINTRESOURCE(s_hIconTypes[type])); |
| - if (!s_hIcons[type]) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_LOAD_ICON, "Class::GetIcon - LoadIcon") |
| - } |
| - } |
| - |
| - icon = s_hIcons[type]; |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - return icon; |
| -} |
| - |
| -ATOM CPluginClass::GetAtomPaneClass() |
| -{ |
| - return s_atomPaneClass; |
| -} |
| - |
| -HWND CPluginClass::GetTabHWND() const |
| -{ |
| - |
| - TCHAR szClassName[MAX_PATH]; |
| - // Get browser window and url |
| - HWND hBrowserWnd = GetBrowserHWND(); |
| - if (!hBrowserWnd) |
| - { |
| - DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_BROWSER, "Class::GetTabWindow - No tab window") |
| - s_criticalSectionWindow.Unlock(); |
| - |
| - return false; |
| - } |
| - |
| - // Looking for a TabWindowClass window in IE7 |
| - |
| - HWND hTabWnd = ::GetWindow(hBrowserWnd, GW_CHILD); |
| - while (hTabWnd) |
| - { |
| - memset(szClassName, 0, MAX_PATH); |
| - GetClassName(hTabWnd, szClassName, MAX_PATH); |
| - |
| - if (_tcscmp(szClassName, _T("TabWindowClass")) == 0 || _tcscmp(szClassName,_T("Frame Tab")) == 0) |
| - { |
| - // IE8 support |
| - HWND hTabWnd2 = hTabWnd; |
| - if (_tcscmp(szClassName,_T("Frame Tab")) == 0) |
| - { |
| - hTabWnd2 = ::FindWindowEx(hTabWnd2, NULL, _T("TabWindowClass"), NULL); |
| - } |
| - |
| - if (hTabWnd2) |
| - { |
| - DWORD nProcessId; |
| - ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); |
| - if (::GetCurrentProcessId() == nProcessId) |
| - { |
| - bool bExistingTab = false; |
| - s_criticalSectionLocal.Lock(); |
| - |
| - { |
| - for (int i = 0; i < s_instances.GetSize(); i++) |
| - { |
| - if (s_instances[i]->m_hTabWnd == hTabWnd2) |
| - { |
| - bExistingTab = true; |
| - break; |
| - } |
| - } |
| - } |
| - |
| - if (!bExistingTab) |
| - { |
| - hBrowserWnd = hTabWnd2; |
| - hTabWnd = hTabWnd2; |
| - s_criticalSectionLocal.Unlock(); |
| - break; |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| - } |
| - } |
| - } |
| - |
| - hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); |
| - } |
| - |
| - return hTabWnd; |
| - |
| -} |
| +#include "PluginStdAfx.h" |
| + |
| +#include "PluginClass.h" |
| +#include "PluginDictionary.h" |
| +#include "PluginSettings.h" |
| +#include "PluginSystem.h" |
| +#ifdef SUPPORT_FILTER |
| +#include "PluginFilter.h" |
| +#endif |
| +#include "PluginMimeFilterClient.h" |
| +#include "PluginClient.h" |
| +#include "PluginClientFactory.h" |
| +#include "PluginHttpRequest.h" |
| +#include "PluginMutex.h" |
| +#include "DownloadSource.h" |
| +#include "sddl.h" |
| +#include "PluginUtil.h" |
| +#include "PluginUserSettings.h" |
| + |
| +#ifdef DEBUG_HIDE_EL |
| +DWORD profileTime = 0; |
| +#endif |
| + |
| +typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); |
| +typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPRECT); |
| +typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); |
| + |
| + |
| +HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; |
| +DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABLED, IDI_ICON_DEACTIVATED }; |
| + |
| +CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; |
| + |
| +CLOSETHEMEDATA pfnClose = NULL; |
| +DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; |
| +OPENTHEMEDATA pfnOpenThemeData = NULL; |
| + |
| +ATOM CPluginClass::s_atomPaneClass = NULL; |
| +HINSTANCE CPluginClass::s_hUxtheme = NULL; |
| +CSimpleArray<CPluginClass*> CPluginClass::s_instances; |
| +std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances; |
| + |
| +CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; |
| +CComAutoCriticalSection CPluginClass::s_criticalSectionBrowser; |
| +CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; |
| + |
| +CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; |
| + |
| +#ifdef SUPPORT_WHITELIST |
| +std::map<UINT,CString> CPluginClass::s_menuDomains; |
| +#endif |
| + |
| +bool CPluginClass::s_isPluginToBeUpdated = false; |
| + |
| +CPluginTab* CPluginClass::s_activeTab = NULL; |
| + |
| + |
| +CPluginClass::CPluginClass() |
| +{ |
| + //Use this line to debug memory leaks |
| + // _CrtDumpMemoryLeaks(); |
| + |
| + m_isAdviced = false; |
| + m_nConnectionID = 0; |
| + m_hTabWnd = NULL; |
| + m_hStatusBarWnd = NULL; |
| + m_hPaneWnd = NULL; |
| + m_nPaneWidth = 0; |
| + m_pWndProcStatus = NULL; |
| + m_hTheme = NULL; |
| + m_isInitializedOk = false; |
| + |
| + |
| + m_tab = new CPluginTab(this); |
| + |
| + // Load / create settings |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + |
| + CPluginSystem* system = CPluginSystem::GetInstance(); |
| + |
| + bool isMainTab = settings->IncrementTabCount(); |
| + |
| + if (isMainTab) |
| + { |
| + // Prepare settings |
| + settings->SetMainProcessId(); |
| + settings->SetMainUiThreadId(); |
| + |
| + // Ensure plugin version |
| + if (!settings->Has(SETTING_PLUGIN_VERSION)) |
| + { |
| + settings->SetString(SETTING_PLUGIN_VERSION, IEPLUGIN_VERSION); |
| + settings->SetFirstRunUpdate(); |
| + } |
| + |
| + // First run or deleted settings file (dictionary version = 1) |
| + if (settings->GetString(SETTING_DICTIONARY_VERSION, L"1").Compare(L"1") == 0) |
| + { |
| + settings->SetFirstRun(); |
| + } |
| + |
| + // Update? |
| + CString oldVersion = settings->GetString(SETTING_PLUGIN_VERSION); |
| + if (settings->IsFirstRunUpdate() || settings->GetString(SETTING_PLUGIN_UPDATE_VERSION) == IEPLUGIN_VERSION || oldVersion != IEPLUGIN_VERSION) |
| + { |
| + settings->SetString(SETTING_PLUGIN_VERSION, IEPLUGIN_VERSION); |
| + |
| + settings->Remove(SETTING_PLUGIN_UPDATE_TIME); |
| + settings->Remove(SETTING_PLUGIN_UPDATE_VERSION); |
| + settings->Remove(SETTING_PLUGIN_UPDATE_URL); |
| + |
| + settings->SetFirstRunUpdate(); |
| + } |
| + |
| + int info = settings->GetValue(SETTING_PLUGIN_INFO_PANEL, 0); |
| + |
| +#ifdef ENABLE_DEBUG_RESULT |
| + CPluginDebug::DebugResultClear(); |
| +#endif |
| + |
| +#ifdef ENABLE_DEBUG_INFO |
| + if (info == 0 || info > 2) |
| + { |
| + CPluginDebug::DebugClear(); |
| + } |
| +#endif // ENABLE_DEBUG_INFO |
| + |
| + settings->Write(false); |
| + } |
| +} |
| + |
| +CPluginClass::~CPluginClass() |
| +{ |
| + delete m_tab; |
| + |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + |
| + settings->DecrementTabCount(); |
| +} |
| + |
| + |
| +///////////////////////////////////////////////////////////////////////////// |
| +// Initialization |
| + |
| +HRESULT CPluginClass::FinalConstruct() |
| +{ |
| + return S_OK; |
| +} |
| + |
| +void CPluginClass::FinalRelease() |
| +{ |
| + s_criticalSectionBrowser.Lock(); |
| + { |
| + m_webBrowser2.Release(); |
| + } |
| + s_criticalSectionBrowser.Unlock(); |
| +} |
| + |
| + |
| +// This method tries to get a 'connection point' from the stored browser, which can be |
| +// used to attach or detach from the stream of browser events |
| +CComPtr<IConnectionPoint> CPluginClass::GetConnectionPoint() |
| +{ |
| + CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pContainer(GetBrowser()); |
| + if (!pContainer) |
| + { |
| + return NULL; |
| + } |
| + |
| + CComPtr<IConnectionPoint> pPoint; |
| + HRESULT hr = pContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &pPoint); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_FIND_CONNECTION_POINT, "Class::GetConnectionPoint - FindConnectionPoint") |
| + return NULL; |
| + } |
| + |
| + return pPoint; |
| +} |
| + |
| +// This method tries to get a 'connection point' from the stored browser, which can be |
| +// used to attach or detach from the stream of browser events |
| +CComPtr<IConnectionPoint> CPluginClass::GetConnectionPointPropSink() |
| +{ |
| + CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pContainer(GetBrowser()); |
| + if (!pContainer) |
| + { |
| + return NULL; |
| + } |
| + |
| + CComPtr<IConnectionPoint> pPoint; |
| + HRESULT hr = pContainer->FindConnectionPoint(IID_IPropertyNotifySink, &pPoint); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_FIND_CONNECTION_POINT, "Class::GetConnectionPoint - FindConnectionPoint") |
| + return NULL; |
| + } |
| + |
| + return pPoint; |
| +} |
| + |
| + |
| +HWND CPluginClass::GetBrowserHWND() const |
| +{ |
| + SHANDLE_PTR hBrowserWndHandle = NULL; |
| + |
| + CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| + if (browser) |
| + { |
| + HRESULT hr = browser->get_HWND(&hBrowserWndHandle); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_BROWSER_WINDOW, "Class::GetBrowserHWND - failed") |
| + } |
| + } |
| + |
| + return (HWND)hBrowserWndHandle; |
| +} |
| + |
| + |
| +CComQIPtr<IWebBrowser2> CPluginClass::GetBrowser() const |
| +{ |
| + CComQIPtr<IWebBrowser2> browser; |
| + |
| + s_criticalSectionBrowser.Lock(); |
| + { |
| + browser = m_webBrowser2; |
| + } |
| + s_criticalSectionBrowser.Unlock(); |
| + |
| + return browser; |
| +} |
| + |
| + |
| +CComQIPtr<IWebBrowser2> CPluginClass::GetAsyncBrowser() |
| +{ |
| + CComQIPtr<IWebBrowser2> browser; |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + browser = s_asyncWebBrowser2; |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + return browser; |
| +} |
| + |
| +CString CPluginClass::GetBrowserUrl() const |
| +{ |
| + CString url; |
| + |
| + CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| + if (browser) |
| + { |
| + CComBSTR bstrURL; |
| + |
| + if (SUCCEEDED(browser->get_LocationURL(&bstrURL))) |
| + { |
| + url = bstrURL; |
| + CPluginClient::UnescapeUrl(url); |
| + } |
| + } |
| + else |
| + { |
| + url = m_tab->GetDocumentUrl(); |
| + } |
| + |
| + return url; |
| +} |
| + |
| +void CPluginClass::LaunchUpdater(const CString& strPath) |
| +{ |
| + PROCESS_INFORMATION pi; |
| + ::ZeroMemory(&pi, sizeof(pi)); |
| + |
| + STARTUPINFO si; |
| + ::ZeroMemory(&si, sizeof(si)); |
| + si.cb = sizeof(si); |
| + si.wShowWindow = FALSE; |
| + CString cpath; |
| + if (strPath.Find(L".exe") == strPath.GetLength() - 4) |
| + { |
| + cpath = strPath; |
| + } |
| + else |
| + { |
| + cpath = _T("\"msiexec.exe\" /i \"") + strPath + _T("\" UPDATEPLUGIN=\"True\""); |
| + } |
| + |
| + if (!::CreateProcess(NULL, cpath.GetBuffer(), NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi)) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UPDATER, PLUGIN_ERROR_UPDATER_CREATE_PROCESS, "Class::Updater - Failed to start process"); |
| + return; |
| + } |
| +#ifndef AUTOMATIC_SHUTDOWN |
| + else |
| + { |
| + ::WaitForSingleObject(pi.hProcess, INFINITE); |
| + } |
| +#endif // not AUTOMATIC_SHUTDOWN |
| + |
| + ::CloseHandle(pi.hProcess); |
| + ::CloseHandle(pi.hThread); |
| +} |
| + |
| +DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) |
| +{ |
| + if (thisPtr == NULL) |
| + return 0; |
| + if (!((CPluginClass*)thisPtr)->InitObject(true)) |
| + { |
| + ((CPluginClass*)thisPtr)->Unadvice(); |
| + } |
| + |
| + if ((((CPluginClass*)thisPtr)->m_hPaneWnd == NULL) || (!((CPluginClass*)thisPtr)->IsStatusBarEnabled())) |
| + { |
| + ((CPluginClass*)thisPtr)->ShowStatusBar(); |
| + } |
| + return 0; |
| +} |
| + |
| + |
| + |
| +// This gets called when a new browser window is created (which also triggers the |
| +// creation of this object). The pointer passed in should be to a IWebBrowser2 |
| +// interface that represents the browser for the window. |
| +// it is also called when a tab is closed, this unknownSite will be null |
| +// so we should handle that it is called this way several times during a session |
| +STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
| +{ |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + CPluginSystem* system = CPluginSystem::GetInstance(); |
| + |
| + MULTIPLE_VERSIONS_CHECK(); |
| + |
| + if (unknownSite) |
| + { |
| + if (settings->IsMainProcess() && settings->IsMainUiThread()) |
| + { |
| + DEBUG_GENERAL(L"================================================================================\nMAIN TAB UI\n================================================================================") |
| + } |
| + else |
| + { |
| + DEBUG_GENERAL(L"================================================================================\nNEW TAB UI\n================================================================================") |
| + } |
| + |
| + HRESULT hr = ::CoInitialize(NULL); |
| + if (FAILED(hr)) |
| + { |
| + 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(); |
| + |
| + //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(); |
| + { |
| + if (settings->GetPluginEnabled()) |
| + { |
| + s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
| + } |
| + |
| + s_asyncWebBrowser2 = unknownSite; |
| + s_instances.Add(this); |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + try |
| + { |
| + // Check if loaded as BHO |
| + if (GetBrowser()) |
| + { |
| + CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); |
| + if (pPoint) |
| + { |
| + HRESULT hr = pPoint->Advise((IDispatch*)this, &m_nConnectionID); |
| + if (SUCCEEDED(hr)) |
| + { |
| + m_isAdviced = true; |
| + |
| + DWORD id; |
| + HANDLE handle = ::CreateThread(NULL, 0, StartInitObject, (LPVOID)this, NULL, &id); |
| + if (handle == NULL) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS, "Class::Thread - Failed to create main thread"); |
| + } |
| + |
| + } |
| + else |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, "Class::SetSite - Advice"); |
| + } |
| + } |
| + } |
| + else // Check if loaded as toolbar handler |
| + { |
| + CComPtr<IServiceProvider> pServiceProvider; |
| + |
| + HRESULT hr = unknownSite->QueryInterface(&pServiceProvider); |
| + if (SUCCEEDED(hr)) |
| + { |
| + if (pServiceProvider) |
| + { |
| + s_criticalSectionBrowser.Lock(); |
| + { |
| + HRESULT hr = pServiceProvider->QueryService(IID_IWebBrowserApp, &m_webBrowser2); |
| + if (SUCCEEDED(hr)) |
| + { |
| + 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)"); |
| + } |
| + } |
| + s_criticalSectionBrowser.Unlock(); |
| + } |
| + } |
| + 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) |
| + { |
| + Unadvice(); |
| + } |
| + } |
| + else |
| + { |
| + // Unadvice |
| + Unadvice(); |
| + |
| + // Destroy window |
| + if (m_pWndProcStatus) |
| + { |
| + ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWndProcStatus); |
| + |
| + m_pWndProcStatus = NULL; |
| + } |
| + |
| + if (m_hPaneWnd) |
| + { |
| + DestroyWindow(m_hPaneWnd); |
| + m_hPaneWnd = NULL; |
| + } |
| + |
| + m_hTabWnd = NULL; |
| + m_hStatusBarWnd = NULL; |
| + |
| + // Remove instance from the list, shutdown threads |
| + HANDLE hMainThread = NULL; |
| + HANDLE hTabThread = NULL; |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + s_instances.Remove(this); |
| + |
| + if (s_instances.GetSize() == 0) |
| + { |
| + if (settings->IsMainProcess() && settings->IsMainUiThread()) |
| + { |
| + hMainThread = s_hMainThread; |
| + s_hMainThread = NULL; |
| + } |
| + } |
| + |
| + std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetCurrentThreadId()); |
| + if (it != s_threadInstances.end()) |
| + { |
| + s_threadInstances.erase(it); |
| + } |
| + if (s_instances.GetSize() == 0) |
| + { |
| + CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
| + } |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + if (hMainThread != NULL) |
| + { |
| + s_isMainThreadDone = true; |
| + |
| + ::WaitForSingleObject(hMainThread, INFINITE); |
| + ::CloseHandle(hMainThread); |
| + } |
| + |
| + // Release browser interface |
| + s_criticalSectionBrowser.Lock(); |
| + { |
| + m_webBrowser2.Release(); |
| + } |
| + s_criticalSectionBrowser.Unlock(); |
| + |
| + if (settings->IsMainProcess() && settings->IsMainUiThread()) |
| + { |
| + DEBUG_GENERAL("================================================================================\nMAIN TAB UI - END\n================================================================================") |
| + } |
| + else |
| + { |
| + DEBUG_GENERAL("================================================================================\nNEW TAB UI - END\n================================================================================") |
| + } |
| + |
| + ::CoUninitialize(); |
| + } |
| + |
| + return IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); |
| +} |
| + |
| +bool CPluginClass::IsStatusBarEnabled() |
| +{ |
| + HKEY pHkey; |
| + HKEY pHkeySub; |
| + RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); |
| + DWORD trueth = 1; |
| + DWORD truethSize = sizeof(DWORD); |
| + RegOpenKey(pHkey, L"Software\\Microsoft\\Internet Explorer\\Main", &pHkeySub); |
| + LONG res = RegQueryValueEx(pHkeySub, L"StatusBarWeb", NULL, NULL, (BYTE*)&trueth, &truethSize); |
| + RegCloseKey(pHkey); |
| + if (res != ERROR_SUCCESS) |
| + { |
| + res = RegOpenKey(pHkey, L"Software\\Microsoft\\Internet Explorer\\MINIE", &pHkeySub); |
| + if (res == ERROR_SUCCESS) |
| + { |
| + LONG res = RegQueryValueEx(pHkeySub, L"ShowStatusBar", NULL, NULL, (BYTE*)&trueth, &truethSize); |
| + if (res == ERROR_SUCCESS) |
| + { |
| + RegCloseKey(pHkey); |
| + } |
| + } |
| + } |
| + return trueth == 1; |
| +} |
| + |
| +void CPluginClass::ShowStatusBar() |
| +{ |
| + VARIANT_BOOL isVisible; |
| + |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + |
| + CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); |
| + if (browser) |
| + { |
| + HRESULT hr = S_OK; |
| + hr = browser->get_StatusBar(&isVisible); |
| + if (SUCCEEDED(hr)) |
| + { |
| + if (!isVisible) |
| + { |
| + if (!settings->GetBool("statusbarasked", false)) |
| + { |
| + SHANDLE_PTR pBrowserHWnd; |
| + browser->get_HWND((SHANDLE_PTR*)&pBrowserHWnd); |
| + CPluginDictionary* dictionary = CPluginDictionary::GetInstance(false); |
| + settings->SetBool("statusbarasked", true); |
| + settings->Write(); |
| + |
| + HKEY pHkey; |
| + HKEY pHkeySub; |
| + LSTATUS regRes = 0; |
| + regRes = RegOpenCurrentUser(KEY_WRITE, &pHkey); |
| + |
| + // Do we have enough rights to enable a status bar? |
| + if (regRes != 0) |
| + { |
| + // We use the tab window here and in the next few calls, since the browser window may still not be available |
| + LRESULT res = MessageBox((HWND)m_hTabWnd, dictionary->Lookup("ERROR_CAN_NOT_ENABLE_STATUS_BAR"), |
| + dictionary->Lookup("ERROR_CAN_NOT_ENABLE_STATUS_BAR_TITLE"), MB_OK); |
| + return; |
| + } |
| + // Ask if a user wants to enable a status bar automatically |
| + LRESULT res = MessageBox((HWND)m_hTabWnd, dictionary->Lookup("ERROR_STATUS_BAR_DISABLED"), |
| + dictionary->Lookup("ERROR_STATUS_BAR_DISABLED_TITLE"), MB_YESNO); |
| + if (res == IDYES) |
| + { |
| + DWORD trueth = 1; |
| + regRes = RegOpenKey(pHkey, L"Software\\Microsoft\\Internet Explorer\\MINIE", &pHkeySub); |
| + regRes = RegSetValueEx(pHkeySub, L"ShowStatusBar", 0, REG_DWORD, (BYTE*)&trueth, sizeof(DWORD)); |
| + regRes = RegCloseKey(pHkeySub); |
| + regRes = RegOpenKey(pHkey, L"Software\\Microsoft\\Internet Explorer\\Main", &pHkeySub); |
| + regRes = RegSetValueEx(pHkeySub, L"StatusBarWeb", 0, REG_DWORD, (BYTE*)&trueth, sizeof(DWORD)); |
| + regRes = RegCloseKey(pHkeySub); |
| + hr = browser->put_StatusBar(TRUE); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_PUT_STATUSBAR, "Class::Enable statusbar"); |
| + } |
| + CreateStatusBarPane(); |
| + |
| + // We need to restart the tab now, to enable the status bar properly |
| + VARIANT vFlags; |
| + vFlags.vt = VT_I4; |
| + vFlags.intVal = navOpenInNewTab; |
| + |
| + CComBSTR curLoc; |
| + browser->get_LocationURL(&curLoc); |
| + HRESULT hr = browser->Navigate(curLoc, &vFlags, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + vFlags.intVal = navOpenInNewWindow; |
| + |
| + hr = browser->Navigate(CComBSTR(curLoc), &vFlags, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION, "Navigation::Failed") |
| + } |
| + } |
| + browser->Quit(); |
| + |
| + } |
| + } |
| + } |
| + } |
| + else |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_STATUSBAR, "Class::Get statusbar state"); |
| + } |
| + } |
| +} |
| + |
| +void CPluginClass::BeforeNavigate2(DISPPARAMS* pDispParams) |
| +{ |
| + |
| + if (pDispParams->cArgs < 7) |
| + { |
| + return; |
| + } |
| + //Register a mime filter if it's not registered yet |
| + if (s_mimeFilter == NULL) |
| + { |
| + s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
| + } |
| + |
| + // Get the IWebBrowser2 interface |
| + CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> WebBrowser2Ptr; |
| + VARTYPE vt = pDispParams->rgvarg[6].vt; |
| + if (vt == VT_DISPATCH) |
| + { |
| + WebBrowser2Ptr = pDispParams->rgvarg[6].pdispVal; |
| + } |
| + else |
| + { |
| + // Wrong type, return. |
| + return; |
| + } |
| + |
| + // Get the URL |
| + CString url; |
| + vt = pDispParams->rgvarg[5].vt; |
| + if (vt == VT_BYREF + VT_VARIANT) |
| + { |
| + url = pDispParams->rgvarg[5].pvarVal->bstrVal; |
| + |
| + CPluginClient::UnescapeUrl(url); |
| + } |
| + else |
| + { |
| + // Wrong type, return. |
| + return; |
| + } |
| + |
| + // If webbrowser2 is equal to top level browser (as set in SetSite), we are navigating new page |
| + CPluginClient* client = CPluginClient::GetInstance(); |
| + |
| + if (url.Find(L"javascript") == 0) |
| + { |
| + } |
| + else if (GetBrowser().IsEqualObject(WebBrowser2Ptr)) |
| + { |
| + m_tab->OnNavigate(url); |
| + |
| + DEBUG_GENERAL(L"================================================================================\nBegin main navigation url:" + url + "\n================================================================================") |
| + |
| +#ifdef ENABLE_DEBUG_RESULT |
| + CPluginDebug::DebugResultDomain(url); |
| +#endif |
| + |
| + UpdateStatusBar(); |
| + } |
| + else |
| + { |
| + DEBUG_NAVI(L"Navi::Begin navigation url:" + url) |
| + |
| +#ifdef SUPPORT_FRAME_CACHING |
| + m_tab->CacheFrame(url); |
| +#endif |
| + } |
| +} |
| +STDMETHODIMP CPluginClass::OnTabChanged(DISPPARAMS* pDispParams, WORD wFlags) |
| +{ |
| + bool newtabshown = pDispParams->rgvarg[1].intVal==3; |
| + if (newtabshown) |
| + { |
| + std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(GetCurrentThreadId()); |
| + if (it == s_threadInstances.end()) |
| + { |
| + s_threadInstances[::GetCurrentThreadId()] = this; |
| + |
| + |
| + if (!m_isInitializedOk) |
| + { |
| + m_isInitializedOk = true; |
| + if (!InitObject(true)) |
| + { |
| + // Unadvice(); |
| + } |
| + UpdateStatusBar(); |
| + } |
| + } |
| + } |
| + return VARIANT_TRUE; |
| +} |
| + |
| +// This gets called whenever there's a browser event |
| +STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) |
| +{ |
| + WCHAR tmp[256]; |
| + wsprintf(tmp, L"Invoke: %d\n", dispidMember); |
| + DEBUG_GENERAL(tmp); |
| + switch (dispidMember) |
| + { |
| + |
| + case DISPID_WINDOWSTATECHANGED: |
| + return OnTabChanged(pDispParams, wFlags); |
| + break; |
| + case DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREUPDATE: |
| + return VARIANT_TRUE; |
| + break; |
| + |
| + case DISPID_HTMLDOCUMENTEVENTS2_ONCLICK: |
| + return VARIANT_TRUE; |
| + break; |
| + |
| + case DISPID_EVMETH_ONLOAD: |
| + DEBUG_NAVI("Navi::OnLoad") |
| + return VARIANT_TRUE; |
| + break; |
| + |
| + case DISPID_EVMETH_ONCHANGE: |
| + return VARIANT_TRUE; |
| + |
| + case DISPID_EVMETH_ONMOUSEDOWN: |
| + return VARIANT_TRUE; |
| + |
| + case DISPID_EVMETH_ONMOUSEENTER: |
| + return VARIANT_TRUE; |
| + |
| + case DISPID_IHTMLIMGELEMENT_START: |
| + return VARIANT_TRUE; |
| + |
| + case STDDISPID_XOBJ_ERRORUPDATE: |
| + return VARIANT_TRUE; |
| + |
| + case STDDISPID_XOBJ_ONPROPERTYCHANGE: |
| + return VARIANT_TRUE; |
| + |
| + case DISPID_READYSTATECHANGE: |
| + DEBUG_NAVI("Navi::ReadyStateChange") |
| + return VARIANT_TRUE; |
| + |
| + case DISPID_BEFORENAVIGATE: |
| + DEBUG_NAVI("Navi::BeforeNavigate") |
| + return VARIANT_TRUE; |
| + case DISPID_COMMANDSTATECHANGE: |
| + if (m_hPaneWnd == NULL) |
| + { |
| + CreateStatusBarPane(); |
| + } |
| + else |
| + { |
| + RECT rect; |
| + BOOL rectRes = GetClientRect(m_hStatusBarWnd, &rect); |
| + if (rectRes == TRUE) |
| + { |
| + MoveWindow(m_hPaneWnd, rect.right - 200, 0, m_nPaneWidth, rect.bottom - rect.top, TRUE); |
| + } |
| + } |
| + break; |
| + case DISPID_STATUSTEXTCHANGE: |
| + break; |
| + |
| + case DISPID_BEFORENAVIGATE2: |
| + BeforeNavigate2(pDispParams); |
| + break; |
| + |
| + case DISPID_DOWNLOADBEGIN: |
| + { |
| + DEBUG_NAVI("Navi::Download Begin") |
| + } |
| + break; |
| + |
| + case DISPID_DOWNLOADCOMPLETE: |
| + { |
| + DEBUG_NAVI("Navi::Download Complete") |
| + |
| + CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| + if (browser) |
| + { |
| + m_tab->OnDownloadComplete(browser); |
| + } |
| + } |
| + break; |
| + |
| + case DISPID_DOCUMENTCOMPLETE: |
| + { |
| + DEBUG_NAVI("Navi::Document Complete") |
| + |
| + CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| + |
| + if (browser && pDispParams->cArgs >= 2 && pDispParams->rgvarg[1].vt == VT_DISPATCH) |
| + { |
| + CComQIPtr<IWebBrowser2> pBrowser = pDispParams->rgvarg[1].pdispVal; |
| + if (pBrowser) |
| + { |
| + CString url; |
| + CComBSTR bstrUrl; |
| + if (SUCCEEDED(pBrowser->get_LocationURL(&bstrUrl)) && ::SysStringLen(bstrUrl) > 0) |
| + { |
| + url = bstrUrl; |
| + |
| + CPluginClient::UnescapeUrl(url); |
| + |
| + m_tab->OnDocumentComplete(browser, url, browser.IsEqualObject(pBrowser)); |
| + } |
| + } |
| + } |
| + } |
| + break; |
| + |
| + case DISPID_ONQUIT: |
| + case DISPID_QUIT: |
| + { |
| + Unadvice(); |
| + } |
| + break; |
| + |
| + default: |
| + { |
| + CString did; |
| + did.Format(L"DispId:%u", dispidMember); |
| + |
| + DEBUG_NAVI(L"Navi::Default " + did) |
| + } |
| + |
| + // do nothing |
| + break; |
| + } |
| + |
| + return VARIANT_TRUE; |
| +} |
| + |
| +bool CPluginClass::InitObject(bool bBHO) |
| +{ |
| + // Load theme module |
| + |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + if (!s_hUxtheme) |
| + { |
| + s_hUxtheme = ::GetModuleHandle(_T("uxtheme.dll")); |
| + if (s_hUxtheme) |
| + { |
| + pfnClose = (CLOSETHEMEDATA)::GetProcAddress(s_hUxtheme, "CloseThemeData"); |
| + if (!pfnClose) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_CLOSE, "Class::InitObject - GetProcAddress(CloseThemeData)"); |
| + } |
| + |
| + pfnDrawThemeBackground = (DRAWTHEMEBACKGROUND)::GetProcAddress(s_hUxtheme, "DrawThemeBackground"); |
| + if (!pfnDrawThemeBackground) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_DRAW_BACKGROUND, "Class::InitObject - GetProcAddress(DrawThemeBackground)"); |
| + } |
| + |
| + pfnOpenThemeData = (OPENTHEMEDATA)::GetProcAddress(s_hUxtheme, "OpenThemeData"); |
| + if (!pfnOpenThemeData) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_OPEN, "Class::InitObject - GetProcAddress(pfnOpenThemeData)"); |
| + } |
| + } |
| + else |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME, "Class::InitObject - GetModuleHandle(uxtheme.dll)"); |
| + } |
| + } |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + // Register pane class |
| + if (!GetAtomPaneClass()) |
| + { |
| + WNDCLASSEX wcex; |
| + |
| + wcex.cbSize = sizeof(WNDCLASSEX); |
| + wcex.style = 0; |
| + wcex.lpfnWndProc = (WNDPROC)PaneWindowProc; |
| + wcex.cbClsExtra = 0; |
| + wcex.cbWndExtra = 0; |
| + wcex.hInstance = _Module.m_hInst; |
| + wcex.hIcon = NULL; |
| + wcex.hCursor = NULL; |
| + wcex.hbrBackground = NULL; |
| + wcex.lpszMenuName = NULL; |
| + wcex.lpszClassName = _T(STATUSBAR_PANE_NAME); |
| + wcex.hIconSm = NULL; |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + s_atomPaneClass = ::RegisterClassEx(&wcex); |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + if (!GetAtomPaneClass()) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_REGISTER_PANE_CLASS, "Class::InitObject - RegisterClassEx"); |
| + return false; |
| + } |
| + } |
| + |
| + |
| + // Create status pane |
| + if (bBHO) |
| + { |
| + if (!CreateStatusBarPane()) |
| + { |
| + return false; |
| + } |
| + } |
| + |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + |
| + // Create main thread |
| + if (GetMainThreadHandle() == NULL && settings->IsMainProcess() && settings->IsMainUiThread()) |
| + { |
| + DWORD id; |
| + HANDLE handle = ::CreateThread(NULL, 0, MainThreadProc, (LPVOID)m_tab, CREATE_SUSPENDED, &id); |
| + if (handle == NULL) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS, "Class::Thread - Failed to create main thread"); |
| + } |
| + |
| + s_hMainThread = handle; |
| + |
| + ::ResumeThread(handle); |
| + } |
| + |
| + return true; |
| +} |
| + |
| +bool CPluginClass::CreateStatusBarPane() |
| +{ |
| + DEBUG_GENERAL(L"Getting client"); |
| + |
| + CPluginClient* client = CPluginClient::GetInstance(); |
| + |
| + DEBUG_GENERAL(L"Getting ieversion"); |
| + |
| + if (client->GetIEVersion()< 7) |
| + |
| + return true; |
| + |
| + TCHAR szClassName[MAX_PATH]; |
| + DEBUG_GENERAL(L"Getting browser wnd"); |
| + // Get browser window and url |
| + HWND hBrowserWnd = GetBrowserHWND(); |
| + if (!hBrowserWnd) |
| + { |
| + DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_BROWSER, "Class::CreateStatusBarPane - No status bar") |
| + return false; |
| + } |
| + |
| + // Looking for a TabWindowClass window in IE7 |
| + // the last one should be parent for statusbar |
| + HWND hWndStatusBar = NULL; |
| + |
| + DEBUG_GENERAL(L"Locating status bar window"); |
| + |
| + HWND hTabWnd = ::GetWindow(hBrowserWnd, GW_CHILD); |
| + UINT amoundOfNewTabs = 0; |
| + HWND uniqueNewTab = NULL; |
| + while (hTabWnd) |
| + { |
| + memset(szClassName, 0, MAX_PATH); |
| + GetClassName(hTabWnd, szClassName, MAX_PATH); |
| + |
| + if (_tcscmp(szClassName, _T("TabWindowClass")) == 0 || _tcscmp(szClassName,_T("Frame Tab")) == 0) |
| + { |
| + // IE8 support |
| + HWND hTabWnd2 = hTabWnd; |
| + if (_tcscmp(szClassName,_T("Frame Tab")) == 0) |
| + { |
| + hTabWnd2 = ::FindWindowEx(hTabWnd2, NULL, _T("TabWindowClass"), NULL); |
| + } |
| + |
| + if (hTabWnd2) |
| + { |
| + DWORD nProcessId; |
| + ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); |
| + if (::GetCurrentProcessId() == nProcessId) |
| + { |
| + bool bExistingTab = false; |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + for (int i = 0; i < s_instances.GetSize(); i++) |
| + { |
| + if (s_instances[i]->m_hTabWnd == hTabWnd2) |
| + { |
| + |
| + bExistingTab = true; |
| + break; |
| + } |
| + } |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + if (!bExistingTab) |
| + { |
| + amoundOfNewTabs ++; |
| + uniqueNewTab = hTabWnd2; |
| + if (GetCurrentThreadId() == GetWindowThreadProcessId(hTabWnd2, NULL)) |
| + { |
| + hBrowserWnd = hTabWnd = hTabWnd2; |
| + break; |
| + } |
| + |
| + } |
| + } |
| + } |
| + } |
| + |
| + hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); |
| + } |
| + |
| + DEBUG_GENERAL(L"status bar window located"); |
| + |
| + HWND hWnd = ::GetWindow(hBrowserWnd, GW_CHILD); |
| + while (hWnd) |
| + { |
| + memset(szClassName, 0, MAX_PATH); |
| + ::GetClassName(hWnd, szClassName, MAX_PATH); |
| + |
| + if (_tcscmp(szClassName,_T("msctls_statusbar32")) == 0) |
| + { |
| + hWndStatusBar = hWnd; |
| + break; |
| + } |
| + |
| + hWnd = ::GetWindow(hWnd, GW_HWNDNEXT); |
| + } |
| + |
| + DEBUG_GENERAL(L"Status bar located 2"); |
| + |
| + if (!hWndStatusBar) |
| + { |
| + DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_WIN, "Class::CreateStatusBarPane - No status bar") |
| + return true; |
| + } |
| + |
| + // Calculate pane height |
| + CRect rcStatusBar; |
| + ::GetClientRect(hWndStatusBar, &rcStatusBar); |
| + |
| + if (rcStatusBar.Height() > 0) |
| + { |
| +#ifdef _DEBUG |
| + m_nPaneWidth = 70; |
| +#else |
| + m_nPaneWidth = min(rcStatusBar.Height(), 22); |
| +#endif |
| + } |
| + else |
| + { |
| +#ifdef _DEBUG |
| + m_nPaneWidth = 70; |
| +#else |
| + m_nPaneWidth = 22; |
| +#endif |
| + } |
| + // Create pane window |
| + HWND hWndNewPane = ::CreateWindowEx( |
| + NULL, |
| + MAKEINTATOM(GetAtomPaneClass()), |
| + _T(""), |
| + WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, |
| + rcStatusBar.Width() - 500,0,m_nPaneWidth,rcStatusBar.Height(), |
| + hWndStatusBar, |
| + (HMENU)3671, |
| + _Module.m_hInst, |
| + NULL); |
| + |
| + if (!hWndNewPane) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_CREATE_STATUSBAR_PANE, "Class::CreateStatusBarPane - CreateWindowEx") |
| + return false; |
| + } |
| + |
| + m_hTabWnd = hTabWnd; |
| + m_hStatusBarWnd = hWndStatusBar; |
| + m_hPaneWnd = hWndNewPane; |
| + |
| + UpdateTheme(); |
| + |
| + // Subclass status bar |
| + m_pWndProcStatus = (WNDPROC)SetWindowLongPtr(hWndStatusBar, GWLP_WNDPROC, (LPARAM)(WNDPROC)NewStatusProc); |
| + |
| + // Adjust pane |
| + UINT nPartCount = ::SendMessage(m_hStatusBarWnd, SB_GETPARTS, 0, 0); |
| + |
| + if (nPartCount > 1) |
| + { |
| + INT *pData = new INT[nPartCount]; |
| + |
| + ::SendMessage(m_hStatusBarWnd, SB_GETPARTS, nPartCount, (LPARAM)pData); |
| + ::SendMessage(m_hStatusBarWnd, SB_SETPARTS, nPartCount, (LPARAM)pData); |
| + |
| + delete[] pData; |
| + } |
| + HDC hdc = GetWindowDC(m_hStatusBarWnd); |
| + SendMessage(m_hStatusBarWnd, WM_PAINT, (WPARAM)hdc, 0); |
| + ReleaseDC(m_hStatusBarWnd, hdc); |
| + return true; |
| +}///////////////////////////////////////////////////////////////////////////// |
| +// Implementation |
| + |
| +void CPluginClass::CloseTheme() |
| +{ |
| + if (m_hTheme) |
| + { |
| + if (pfnClose) |
| + { |
| + pfnClose(m_hTheme); |
| + } |
| + |
| + m_hTheme = NULL; |
| + } |
| +} |
| + |
| +void CPluginClass::UpdateTheme() |
| +{ |
| + CloseTheme(); |
| + |
| + if (pfnOpenThemeData) |
| + { |
| + m_hTheme = pfnOpenThemeData(m_hPaneWnd, L"STATUS"); |
| + if (!m_hTheme) |
| + { |
| + } |
| + } |
| +} |
| + |
| + |
| +CPluginClass* CPluginClass::FindInstance(HWND hStatusBarWnd) |
| +{ |
| + CPluginClass* instance = NULL; |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + for (int i = 0; i < s_instances.GetSize(); i++) |
| + { |
| + if (s_instances[i]->m_hStatusBarWnd == hStatusBarWnd) |
| + { |
| + instance = s_instances[i]; |
| + break; |
| + } |
| + } |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + return instance; |
| +} |
| + |
| +CPluginTab* CPluginClass::GetTab() |
| +{ |
| + return m_tab; |
| +} |
| + |
| +CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) |
| +{ |
| + CPluginTab* tab = NULL; |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dwThreadId); |
| + if (it != s_threadInstances.end()) |
| + { |
| + tab = it->second->m_tab; |
| + } |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + return tab; |
| +} |
| + |
| + |
| +STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText) |
| +{ |
| + if (cCmds == 0) return E_INVALIDARG; |
| + if (prgCmds == 0) return E_POINTER; |
| + |
| + prgCmds[0].cmdf = OLECMDF_ENABLED; |
| + |
| + return S_OK; |
| +} |
| + |
| +HMENU CPluginClass::CreatePluginMenu(const CString& url) |
| +{ |
| + HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); |
| + |
| + HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); |
| + |
| + HMENU hMenuTrackPopup = GetSubMenu(hMenu, 0); |
| + |
| + SetMenuBar(hMenuTrackPopup, url); |
| + |
| + return hMenuTrackPopup; |
| +} |
| +BOOL CreateLowProcess(WCHAR* wszProcessName, WCHAR* cmdLine) |
| +{ |
| + |
| + BOOL fRet; |
| + HANDLE hToken = NULL; |
| + HANDLE hNewToken = NULL; |
| + PSID pIntegritySid = NULL; |
| + TOKEN_MANDATORY_LABEL TIL = {0}; |
| + PROCESS_INFORMATION ProcInfo = {0}; |
| + STARTUPINFO StartupInfo = {0}; |
| + |
| + |
| + |
| + // Low integrity SID |
| + WCHAR wszIntegritySid[20] = L"S-1-16-4096"; |
| + |
| + |
| + fRet = OpenProcessToken(GetCurrentProcess(), |
| + TOKEN_DUPLICATE | |
| + TOKEN_ADJUST_DEFAULT | |
| + TOKEN_QUERY | |
| + TOKEN_ASSIGN_PRIMARY, |
| + &hToken); |
| + |
| + if (!fRet) |
| + { |
| + goto CleanExit; |
| + } |
| + |
| + fRet = DuplicateTokenEx(hToken, |
| + 0, |
| + NULL, |
| + SecurityImpersonation, |
| + TokenPrimary, |
| + &hNewToken); |
| + |
| + if (!fRet) |
| + { |
| + goto CleanExit; |
| + } |
| + |
| + fRet = ConvertStringSidToSid(wszIntegritySid, &pIntegritySid); |
| + |
| + if (!fRet) |
| + { |
| + goto CleanExit; |
| + } |
| + |
| + |
| + TIL.Label.Attributes = SE_GROUP_INTEGRITY; |
| + TIL.Label.Sid = pIntegritySid; |
| + |
| + |
| + // |
| + // Set the process integrity level |
| + // |
| + |
| + fRet = SetTokenInformation(hNewToken, |
| + TokenIntegrityLevel, |
| + &TIL, |
| + sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)); |
| + |
| + if (!fRet) |
| + { |
| + goto CleanExit; |
| + } |
| + |
| + // |
| + // Create the new process at Low integrity |
| + // |
| + |
| + fRet = CreateProcessAsUser(hNewToken, |
| + wszProcessName, |
| + cmdLine, |
| + NULL, |
| + NULL, |
| + FALSE, |
| + 0, |
| + NULL, |
| + NULL, |
| + &StartupInfo, |
| + &ProcInfo); |
| + |
| + |
| +CleanExit: |
| + |
| + if (ProcInfo.hProcess != NULL) |
| + { |
| + CloseHandle(ProcInfo.hProcess); |
| + } |
| + |
| + if (ProcInfo.hThread != NULL) |
| + { |
| + CloseHandle(ProcInfo.hThread); |
| + } |
| + |
| + LocalFree(pIntegritySid); |
| + |
| + if (hNewToken != NULL) |
| + { |
| + CloseHandle(hNewToken); |
| + } |
| + |
| + if (hToken != NULL) |
| + { |
| + CloseHandle(hToken); |
| + } |
| + |
| + return fRet; |
| +} |
| + |
| +void CPluginClass::DisplayPluginMenu(HMENU hMenu, int nToolbarCmdID, POINT pt, UINT nMenuFlags) |
| +{ |
| + CPluginClient* client = CPluginClient::GetInstance(); |
| + |
| + CPluginSystem* system = CPluginSystem::GetInstance(); |
| + |
| + CString url; |
| + int navigationErrorId = 0; |
| + |
| + // Create menu parent window |
| + HWND hMenuWnd = ::CreateWindowEx( |
| + NULL, |
| + MAKEINTATOM(GetAtomPaneClass()), |
| + _T(""), |
| + 0, |
| + 0,0,0,0, |
| + NULL, |
| + NULL, |
| + _Module.m_hInst, |
| + NULL); |
| + |
| + if (!hMenuWnd) |
| + { |
| + DestroyMenu(hMenu); |
| + return; |
| + } |
| + |
| + // Display menu |
| + nMenuFlags |= TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON; |
| + |
| + int nCommand = ::TrackPopupMenu(hMenu, nMenuFlags, pt.x, pt.y, 0, hMenuWnd, 0); |
| + |
| + ::DestroyMenu(hMenu); |
| + ::DestroyWindow(hMenuWnd); |
| + |
| + switch (nCommand) |
| + { |
| + case ID_PLUGIN_UPDATE: |
| + { |
| + s_isPluginToBeUpdated = true; |
| + } |
| + break; |
| + |
| + case ID_PLUGIN_ENABLE: |
| + { |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + |
| + settings->TogglePluginEnabled(); |
| + |
| + // Enable / disable mime filter |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + if (settings->GetPluginEnabled()) |
| + { |
| + s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
| + } |
| + else |
| + { |
| + s_mimeFilter = NULL; |
| + |
| + CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
| + } |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| +#ifdef SUPPORT_WHITELIST |
| + client->ClearWhiteListCache(); |
| +#endif |
| + } |
| + break; |
| +#ifndef ENTERPRISE |
| + case ID_SETTINGS: |
| + { |
| + url = CString(UserSettingsFileUrl().c_str()); |
| + } |
| + break; |
| +#endif |
| + case ID_INVITEFRIENDS: |
| + { |
| + url = CPluginHttpRequest::GetStandardUrl(USERS_SCRIPT_INVITATION); |
| + navigationErrorId = PLUGIN_ERROR_NAVIGATION_INVITATION; |
| + } |
| + break; |
| + |
| + case ID_FAQ: |
| + { |
| + url = CPluginHttpRequest::GetStandardUrl(USERS_SCRIPT_FAQ); |
| + navigationErrorId = PLUGIN_ERROR_NAVIGATION_FAQ; |
| + } |
| + break; |
| + |
| + case ID_FEEDBACK: |
| + { |
| + CPluginHttpRequest httpRequest(USERS_SCRIPT_FEEDBACK); |
| + |
| + httpRequest.AddPluginId(); |
| + httpRequest.Add("reason", 0); |
| + httpRequest.Add(L"url", m_tab->GetDocumentUrl(), false); |
| + |
| + url = httpRequest.GetUrl(); |
| + navigationErrorId = PLUGIN_ERROR_NAVIGATION_FEEDBACK; |
| + } |
| + break; |
| + |
| + case ID_ABOUT: |
| + { |
| + url = CPluginHttpRequest::GetStandardUrl(USERS_SCRIPT_ABOUT); |
| + navigationErrorId = PLUGIN_ERROR_NAVIGATION_ABOUT; |
| + } |
| + break; |
| + |
| + default: |
| + |
| + break; |
| + } |
| + |
| + // Invalidate and redraw the control |
| + UpdateStatusBar(); |
| + |
| + CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
| + if (!url.IsEmpty() && browser) |
| + { |
| + VARIANT vFlags; |
| + vFlags.vt = VT_I4; |
| + vFlags.intVal = navOpenInNewTab; |
| + |
| + HRESULT hr = browser->Navigate(CComBSTR(url), &vFlags, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + vFlags.intVal = navOpenInNewWindow; |
| + |
| + hr = browser->Navigate(CComBSTR(url), &vFlags, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, navigationErrorId, "Navigation::Failed") |
| + } |
| + } |
| + } |
| +} |
| + |
| + |
| +bool CPluginClass::SetMenuBar(HMENU hMenu, const CString& url) |
| +{ |
| + CString ctext; |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| +#ifdef SUPPORT_WHITELIST |
| + s_menuDomains.clear(); |
| +#endif |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + CPluginTab* tab = GetTab(::GetCurrentThreadId()); |
| + if (!tab) |
| + { |
| + return false; |
| + } |
| + |
| + CPluginDictionary* dictionary = CPluginDictionary::GetInstance(); |
| + |
| + MENUITEMINFO fmii; |
| + memset(&fmii, 0, sizeof(MENUITEMINFO)); |
| + fmii.cbSize = sizeof(MENUITEMINFO); |
| + |
| + MENUITEMINFO miiSep; |
| + memset(&miiSep, 0, sizeof(MENUITEMINFO)); |
| + miiSep.cbSize = sizeof(MENUITEMINFO); |
| + miiSep.fMask = MIIM_TYPE | MIIM_FTYPE; |
| + miiSep.fType = MFT_SEPARATOR; |
| + |
| + CPluginClient* client = CPluginClient::GetInstance(); |
| + |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + |
| + settings->RefreshTab(); |
| + |
| + // Update settings |
| + m_tab->OnUpdateSettings(false); |
| + |
| + // Plugin update |
| + if (settings->IsPluginUpdateAvailable()) |
| + { |
| + ctext = dictionary->Lookup("MENU_UPDATE"); |
| + fmii.fMask = MIIM_STATE | MIIM_STRING; |
| + fmii.fState = MFS_ENABLED; |
| + fmii.dwTypeData = ctext.GetBuffer(); |
| + fmii.cch = ctext.GetLength(); |
| + ::SetMenuItemInfo(hMenu, ID_PLUGIN_UPDATE, FALSE, &fmii); |
| + } |
| + else |
| + { |
| + ::DeleteMenu(hMenu, ID_PLUGIN_UPDATE, FALSE); |
| + } |
| +#ifdef SUPPORT_WHITELIST |
| + { |
| + // White list domain |
| + ctext = dictionary->Lookup("MENU_DISABLE_ON"); |
| + fmii.fMask = MIIM_STRING | MIIM_STATE; |
| + fmii.fState = MFS_DISABLED; |
| + fmii.dwTypeData = ctext.GetBuffer(); |
| + fmii.cch = ctext.GetLength(); |
| + |
| + UINT index = WM_WHITELIST_DOMAIN; |
| + |
| + ::SetMenuItemInfo(hMenu, ID_WHITELISTDOMAIN, FALSE, &fmii); |
| + } |
| +#else |
| + { |
| + ::DeleteMenu(hMenu, ID_WHITELISTDOMAIN, FALSE); |
| + } |
| +#endif // SUPPORT_WHITELIST |
| + |
| + // Invite friends |
| + ctext = dictionary->Lookup("MENU_INVITE_FRIENDS"); |
| + fmii.fMask = MIIM_STATE | MIIM_STRING; |
| + fmii.fState = MFS_ENABLED; |
| + fmii.dwTypeData = ctext.GetBuffer(); |
| + fmii.cch = ctext.GetLength(); |
| + ::SetMenuItemInfo(hMenu, ID_INVITEFRIENDS, FALSE, &fmii); |
| + |
| + // FAQ |
| + ctext = dictionary->Lookup("MENU_FAQ"); |
| + fmii.fMask = MIIM_STATE | MIIM_STRING; |
| + fmii.fState = MFS_ENABLED; |
| + fmii.dwTypeData = ctext.GetBuffer(); |
| + fmii.cch = ctext.GetLength(); |
| + ::SetMenuItemInfo(hMenu, ID_FAQ, FALSE, &fmii); |
| + |
| + // About |
| + ctext = dictionary->Lookup("MENU_ABOUT"); |
| + fmii.fMask = MIIM_STATE | MIIM_STRING; |
| + fmii.fState = MFS_ENABLED; |
| + fmii.dwTypeData = ctext.GetBuffer(); |
| + fmii.cch = ctext.GetLength(); |
| + ::SetMenuItemInfo(hMenu, ID_ABOUT, FALSE, &fmii); |
| + |
| + // Feedback |
| + ctext = dictionary->Lookup("MENU_FEEDBACK"); |
| + fmii.fMask = MIIM_STATE | MIIM_STRING; |
| + fmii.fState = MFS_ENABLED; |
| + fmii.dwTypeData = ctext.GetBuffer(); |
| + fmii.cch = ctext.GetLength(); |
| + ::SetMenuItemInfo(hMenu, ID_FEEDBACK, FALSE, &fmii); |
| + |
| + // Plugin enable |
| + if (settings->GetPluginEnabled()) |
| + { |
| + ctext = dictionary->Lookup("MENU_DISABLE"); |
| + } |
| + else |
| + { |
| + ctext = dictionary->Lookup("MENU_ENABLE"); |
| + } |
| + fmii.fMask = MIIM_STATE | MIIM_STRING; |
| + fmii.fState = client ? MFS_ENABLED : MFS_DISABLED; |
| + fmii.dwTypeData = ctext.GetBuffer(); |
| + fmii.cch = ctext.GetLength(); |
| + ::SetMenuItemInfo(hMenu, ID_PLUGIN_ENABLE, FALSE, &fmii); |
| + |
| + // Settings |
| +#ifndef ENTERPRISE |
| + ctext = dictionary->Lookup("MENU_SETTINGS"); |
| + fmii.fMask = MIIM_STATE | MIIM_STRING; |
| + fmii.fState = MFS_ENABLED; |
| + fmii.dwTypeData = ctext.GetBuffer(); |
| + fmii.cch = ctext.GetLength(); |
| + ::SetMenuItemInfo(hMenu, ID_SETTINGS, FALSE, &fmii); |
| +#else |
| + RemoveMenu(hMenu, ID_SETTINGS, MF_BYCOMMAND); |
| + RemoveMenu(hMenu, 5, MF_BYPOSITION); |
| +#endif |
| + |
| + ctext.ReleaseBuffer(); |
| + |
| + return true; |
| +} |
| + |
| + |
| +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 E_FAIL; |
| + } |
| + |
| + // Check if button in toolbar was pressed |
| + int nIDCommand = -1; |
| + BOOL bRightAlign = FALSE; |
| + |
| + POINT pt; |
| + GetCursorPos(&pt); |
| + |
| + HWND hWndToolBar = ::WindowFromPoint(pt); |
| + |
| + DWORD nProcessId; |
| + ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); |
| + |
| + if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) |
| + { |
| + ::ScreenToClient(hWndToolBar, &pt); |
| + int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); |
| + |
| + if (nButton > 0) |
| + { |
| + TBBUTTON pTBBtn; |
| + memset(&pTBBtn, 0, sizeof(TBBUTTON)); |
| + |
| + if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) |
| + { |
| + RECT rcButton; |
| + nIDCommand = pTBBtn.idCommand; |
| + |
| + if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) |
| + { |
| + 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 |
| + { |
| + nFlags |= TPM_LEFTALIGN; |
| + } |
| + |
| + DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); |
| + |
| + return S_OK; |
| +} |
| + |
| +///////////////////////////////////////////////////////////////////////////// |
| +// Window procedures |
| + |
| +LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
| +{ |
| + // Find tab |
| + CPluginClass *pClass = FindInstance(hWnd); |
| + if (!pClass) |
| + { |
| + return DefWindowProc(hWnd, message, wParam, lParam); |
| + } |
| + |
| + // Process message |
| + switch (message) |
| + { |
| + case SB_SIMPLE: |
| + { |
| + ShowWindow(pClass->m_hPaneWnd, !wParam); |
| + break; |
| + } |
| + |
| + case WM_SYSCOLORCHANGE: |
| + { |
| + pClass->UpdateTheme(); |
| + break; |
| + } |
| + |
| + case SB_SETPARTS: |
| + { |
| + if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd)) |
| + { |
| + return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam); |
| + } |
| + |
| + int nParts = wParam; |
| + if (STATUSBAR_PANE_NUMBER >= nParts) |
| + { |
| + return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam); |
| + } |
| + |
| + HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts+1)); |
| + LPINT lpParts = (LPINT)LocalLock(hLocal); |
| + memcpy(lpParts, (void*)lParam, wParam*sizeof(int)); |
| + |
| + for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++) |
| + { |
| + lpParts[i] -= pClass->m_nPaneWidth; |
| + } |
| + LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, (LPARAM)lpParts); |
| + |
| + CRect rcPane; |
| + ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane); |
| + |
| + CRect rcClient; |
| + ::GetClientRect(hWnd, &rcClient); |
| + |
| + ::MoveWindow( |
| + pClass->m_hPaneWnd, |
| + lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth, |
| + 0, |
| + pClass->m_nPaneWidth, |
| + rcClient.Height(), |
| + TRUE); |
| + |
| + ::LocalFree(hLocal); |
| + |
| + |
| + return hRet; |
| + } |
| + |
| + default: |
| + break; |
| + } |
| + |
| + LRESULT result = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam); |
| + |
| + |
| + return result; |
| + |
| +} |
| + |
| + |
| +HICON CPluginClass::GetStatusBarIcon(const CString& url) |
| +{ |
| + // use the disable icon as defualt, if the client doesn't exists |
| + HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
| + |
| + CPluginTab* tab = GetTab(::GetCurrentThreadId()); |
| + if (tab) |
| + { |
| + CPluginClient* client = CPluginClient::GetInstance(); |
| + |
| +#ifdef PRODUCT_ADBLOCKPLUS |
| + if (!CPluginSettings::GetInstance()->IsPluginEnabled()) |
| + { |
| + } |
| +#ifdef SUPPORT_WHITELIST |
| + else if (client->IsUrlWhiteListed(url)) |
| + { |
| + hIcon = GetIcon(ICON_PLUGIN_DISABLED); |
| + } |
| +#endif // SUPPORT_WHITELIST |
| + else |
| + { |
| + //Deativate adblock icon if adblock limit reached |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + if (!settings->GetPluginEnabled()) { |
| + hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
| + return hIcon; |
| + } |
| + hIcon = GetIcon(ICON_PLUGIN_ENABLED); |
| + } |
| + |
| +#endif // PRODUCT_ADBLOCKPLUS |
| + } |
| + |
| + return hIcon; |
| +} |
| + |
| + |
| +LRESULT CALLBACK CPluginClass::PaneWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
| +{ |
| + // Find tab |
| + CPluginClass *pClass = FindInstance(GetParent(hWnd)); |
| + if (!pClass) |
| + { |
| + return ::DefWindowProc(hWnd, message, wParam, lParam); |
| + } |
| + |
| + CPluginSystem* system = CPluginSystem::GetInstance(); |
| + |
| + // Process message |
| + switch (message) |
| + { |
| + |
| + case WM_SETCURSOR: |
| + { |
| + ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); |
| + return TRUE; |
| + } |
| + case WM_PAINT: |
| + { |
| + PAINTSTRUCT ps; |
| + HDC hDC = ::BeginPaint(hWnd, &ps); |
| + |
| + CRect rcClient; |
| + ::GetClientRect(hWnd, &rcClient); |
| + |
| + int nDrawEdge = 0; |
| + |
| + // Old Windows background drawing |
| + if (pClass->m_hTheme == NULL) |
| + { |
| + ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); |
| + ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); |
| + |
| + nDrawEdge = 3; |
| + rcClient.left += 3; |
| + |
| + ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); |
| + } |
| + // Themed background drawing |
| + else |
| + { |
| + // Draw background |
| + if (pfnDrawThemeBackground) |
| + { |
| + CRect rc = rcClient; |
| + rc.right -= 2; |
| + pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); |
| + } |
| + |
| + // Copy separator picture to left side |
| + int nHeight = rcClient.Height(); |
| + int nWidth = rcClient.Width() - 2; |
| + |
| + for (int i = 0; i < 2; i++) |
| + { |
| + for (int j = 0; j < nHeight; j++) |
| + { |
| + COLORREF clr = ::GetPixel(hDC, i + nWidth, j); |
| + |
| + // Ignore black boxes (if source is obscured by other windows) |
| + if (clr != -1 && (GetRValue(clr) > 8 || GetGValue(clr) > 8 || GetBValue(clr) > 8)) |
| + { |
| + ::SetPixel(hDC, i, j, clr); |
| + } |
| + } |
| + } |
| + } |
| + |
| + // Draw icon |
| + if (CPluginClient::GetInstance()) |
| + { |
| + HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl()); |
| + |
| + int offx = (rcClient.Height() - 16)/2 + nDrawEdge; |
| + if (hIcon) |
| + { |
| + ::DrawIconEx(hDC, offx, (rcClient.Height() - 16)/2 + 2, hIcon, 16, 16, NULL, NULL, DI_NORMAL); |
| + offx += 22; |
| + } |
| +#ifdef _DEBUG |
| + // Display version |
| + HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT, 0, 0); |
| + HGDIOBJ hOldFont = ::SelectObject(hDC,hFont); |
| + |
| + CRect rcText = rcClient; |
| + rcText.left += offx; |
| + ::SetBkMode(hDC, TRANSPARENT); |
| + ::DrawText(hDC, _T(IEPLUGIN_VERSION), -1, &rcText, DT_WORD_ELLIPSIS|DT_LEFT|DT_SINGLELINE|DT_VCENTER); |
| + |
| + ::SelectObject(hDC, hOldFont); |
| +#endif // _DEBUG |
| + } |
| + |
| + // Done! |
| + EndPaint(hWnd, &ps); |
| + |
| + return 0; |
| + } |
| + |
| + case WM_LBUTTONUP: |
| + case WM_RBUTTONUP: |
| + { |
| + CString strURL = pClass->GetBrowserUrl(); |
| + if (strURL != pClass->GetTab()->GetDocumentUrl()) |
| + { |
| + pClass->GetTab()->SetDocumentUrl(strURL); |
| + } |
| + |
| +#ifdef SUPPORT_SHOW_PLUGIN_MENU |
| + // Create menu |
| + HMENU hMenu = pClass->CreatePluginMenu(strURL); |
| + if (!hMenu) |
| + { |
| + return 0; |
| + } |
| + |
| + // Display menu |
| + POINT pt; |
| + ::GetCursorPos(&pt); |
| + |
| + RECT rc; |
| + ::GetWindowRect(hWnd, &rc); |
| + |
| + if (rc.left >= 0 && rc.top >= 0) |
| + { |
| + pt.x = rc.left; |
| + pt.y = rc.top; |
| + } |
| + |
| + pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN|TPM_BOTTOMALIGN); |
| +#else |
| + CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); |
| + if (browser) |
| + { |
| + VARIANT vFlags; |
| + vFlags.vt = VT_I4; |
| + vFlags.intVal = navOpenInNewTab; |
| + |
| + HRESULT hr = browser->Navigate(BString(UserSettingsFileUrl()), &vFlags, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + vFlags.intVal = navOpenInNewWindow; |
| + |
| + hr = browser->Navigate(BString(UserSettingsFileUrl()), &vFlags, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_SETTINGS, "Navigation::Failed") |
| + } |
| + } |
| + } |
| +#endif |
| + } |
| + break; |
| + |
| +#ifndef ENTERPRISE |
| + |
| + case WM_LAUNCH_INFO: |
| + { |
| + // Set the status bar visible, if it isn't |
| + // Otherwise the user won't see the icon the first time |
| + |
| + if (wParam == 1) |
| + { |
| + // Redirect to welcome page |
| + VARIANT_BOOL isVisible; |
| + CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); |
| + if (browser) |
| + { |
| + HRESULT hr = S_OK; |
| + |
| + hr = browser->get_StatusBar(&isVisible); |
| + if (SUCCEEDED(hr)) |
| + { |
| + if (!isVisible) |
| + { |
| + CPluginDictionary* dictionary = CPluginDictionary::GetInstance(); |
| + |
| + LRESULT res = MessageBox(NULL, dictionary->Lookup("ERROR_STATUS_BAR_DISABLED"), dictionary->Lookup("ERROR_STATUS_BAR_DISABLED_TITLE"), MB_YESNO); |
| + if (res == IDYES) |
| + { |
| + hr = browser->put_StatusBar(TRUE); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_PUT_STATUSBAR, "Class::Enable statusbar"); |
| + } |
| + } |
| + } |
| + } |
| + else |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_STATUSBAR, "Class::Get statusbar state"); |
| + } |
| + |
| + CPluginSettings* settings = CPluginSettings::GetInstance(); |
| + |
| + CPluginHttpRequest httpRequest(USERS_SCRIPT_WELCOME); |
| + |
| + httpRequest.Add("errors", settings->GetErrorList()); |
| + |
| + |
| + hr = browser->Navigate(CComBSTR(httpRequest.GetUrl() + "&src=" + DOWNLOAD_SOURCE), NULL, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_WELCOME, "Navigation::Welcome page failed") |
| + } |
| + |
| + // Update settings server side on next IE start, as they have possibly changed |
| + settings->ForceConfigurationUpdateOnStart(); |
| + } |
| + } |
| + else |
| + { |
| + // Redirect to info page |
| + CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); |
| + if (browser) |
| + { |
| + CPluginHttpRequest httpRequest(USERS_SCRIPT_INFO); |
| + |
| + httpRequest.Add("info", wParam); |
| + |
| + VARIANT vFlags; |
| + vFlags.vt = VT_I4; |
| + vFlags.intVal = navOpenInNewTab; |
| + |
| + HRESULT hr = browser->Navigate(CComBSTR(httpRequest.GetUrl()), &vFlags, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + vFlags.intVal = navOpenInNewWindow; |
| + |
| + hr = browser->Navigate(CComBSTR(httpRequest.GetUrl()), &vFlags, NULL, NULL, NULL); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_INFO, "Navigation::Info page failed") |
| + } |
| + } |
| + } |
| + } |
| + } |
| + break; |
| +#endif |
| + |
| + case WM_DESTROY: |
| + break; |
| + case SC_CLOSE: |
| + break; |
| + |
| + case WM_UPDATEUISTATE: |
| + { |
| + CPluginTab* tab = GetTab(::GetCurrentThreadId()); |
| + if (tab) |
| + { |
| + tab->OnActivate(); |
| + } |
| + } |
| + break; |
| + } |
| + |
| + return DefWindowProc(hWnd, message, wParam, lParam); |
| +} |
| + |
| + |
| +void CPluginClass::UpdateStatusBar() |
| +{ |
| + DEBUG_GENERAL("*** Updating statusbar") |
| + |
| + if (m_hPaneWnd == NULL) |
| + { |
| + CreateStatusBarPane(); |
| + } |
| + if (m_hPaneWnd != NULL) |
| + { |
| + if (!::InvalidateRect(m_hPaneWnd, NULL, FALSE)) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_INVALIDATE_STATUSBAR, "Class::Invalidate statusbar"); |
| + } |
| + } |
| +} |
| + |
| + |
| +void CPluginClass::Unadvice() |
| +{ |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + if (m_isAdviced) |
| + { |
| + CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); |
| + if (pPoint) |
| + { |
| + HRESULT hr = pPoint->Unadvise(m_nConnectionID); |
| + if (FAILED(hr)) |
| + { |
| + DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVICE, "Class::Unadvice - Unadvise"); |
| + } |
| + } |
| + |
| + m_isAdviced = false; |
| + } |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| +} |
| + |
| +HICON CPluginClass::GetIcon(int type) |
| +{ |
| + HICON icon = NULL; |
| + |
| + s_criticalSectionLocal.Lock(); |
| + { |
| + if (!s_hIcons[type]) |
| + { |
| + s_hIcons[type] = ::LoadIcon(_Module.m_hInst, MAKEINTRESOURCE(s_hIconTypes[type])); |
| + if (!s_hIcons[type]) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_LOAD_ICON, "Class::GetIcon - LoadIcon") |
| + } |
| + } |
| + |
| + icon = s_hIcons[type]; |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + return icon; |
| +} |
| + |
| +ATOM CPluginClass::GetAtomPaneClass() |
| +{ |
| + return s_atomPaneClass; |
| +} |
| + |
| +HWND CPluginClass::GetTabHWND() const |
| +{ |
| + |
| + TCHAR szClassName[MAX_PATH]; |
| + // Get browser window and url |
| + HWND hBrowserWnd = GetBrowserHWND(); |
| + if (!hBrowserWnd) |
| + { |
| + DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_BROWSER, "Class::GetTabWindow - No tab window") |
| + s_criticalSectionWindow.Unlock(); |
| + |
| + return false; |
| + } |
| + |
| + // Looking for a TabWindowClass window in IE7 |
| + |
| + HWND hTabWnd = ::GetWindow(hBrowserWnd, GW_CHILD); |
| + while (hTabWnd) |
| + { |
| + memset(szClassName, 0, MAX_PATH); |
| + GetClassName(hTabWnd, szClassName, MAX_PATH); |
| + |
| + if (_tcscmp(szClassName, _T("TabWindowClass")) == 0 || _tcscmp(szClassName,_T("Frame Tab")) == 0) |
| + { |
| + // IE8 support |
| + HWND hTabWnd2 = hTabWnd; |
| + if (_tcscmp(szClassName,_T("Frame Tab")) == 0) |
| + { |
| + hTabWnd2 = ::FindWindowEx(hTabWnd2, NULL, _T("TabWindowClass"), NULL); |
| + } |
| + |
| + if (hTabWnd2) |
| + { |
| + DWORD nProcessId; |
| + ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); |
| + if (::GetCurrentProcessId() == nProcessId) |
| + { |
| + bool bExistingTab = false; |
| + s_criticalSectionLocal.Lock(); |
| + |
| + { |
| + for (int i = 0; i < s_instances.GetSize(); i++) |
| + { |
| + if (s_instances[i]->m_hTabWnd == hTabWnd2) |
| + { |
| + bExistingTab = true; |
| + break; |
| + } |
| + } |
| + } |
| + |
| + if (!bExistingTab) |
| + { |
| + hBrowserWnd = hTabWnd2; |
| + hTabWnd = hTabWnd2; |
| + s_criticalSectionLocal.Unlock(); |
| + break; |
| + } |
| + s_criticalSectionLocal.Unlock(); |
| + |
| + } |
| + } |
| + } |
| + |
| + hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); |
| + } |
| + |
| + return hTabWnd; |
| + |
| +} |