From 9e1e50a4e7ff9a5f9c6a85371f862237434ef4b0 Mon Sep 17 00:00:00 2001 From: Rom Walton Date: Mon, 29 Dec 2014 23:09:54 -0500 Subject: [PATCH] HTMLGFX: Normalize the URLs configured by way of the configuration file. MSHTML would attempt to use HTTP when only a filename was given. --- samples/gfx_html/browser.idl | 10 +++ samples/gfx_html/browserctrl_win.cpp | 32 +++++++-- samples/gfx_html/browserctrl_win.h | 10 +-- samples/gfx_html/browserctrlsvc_win.cpp | 93 +++++++++++++++++++++++++ samples/gfx_html/browserctrlsvc_win.h | 63 +++++++++++++++++ samples/gfx_html/browserwnd_win.cpp | 90 ++++++++++++++++++------ samples/gfx_html/browserwnd_win.h | 2 +- win_build/htmlgfx.vcxproj | 10 +-- 8 files changed, 272 insertions(+), 38 deletions(-) create mode 100644 samples/gfx_html/browserctrlsvc_win.cpp create mode 100644 samples/gfx_html/browserctrlsvc_win.h diff --git a/samples/gfx_html/browser.idl b/samples/gfx_html/browser.idl index dd3274a978..44d41ef5ef 100644 --- a/samples/gfx_html/browser.idl +++ b/samples/gfx_html/browser.idl @@ -18,6 +18,16 @@ import "ocidl.idl"; interface IHTMLBrowserHost : IDispatch{ }; +[ + object, + uuid(D9E4A0D0-60F6-444C-93BC-7F3DF3281416), + dual, + nonextensible, + pointer_default(unique) +] +interface IHTMLBrowserHostSvc : IDispatch{ +}; + [ object, dual, diff --git a/samples/gfx_html/browserctrl_win.cpp b/samples/gfx_html/browserctrl_win.cpp index 3dfee343d8..fe1230f45a 100644 --- a/samples/gfx_html/browserctrl_win.cpp +++ b/samples/gfx_html/browserctrl_win.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include "win_util.h" #include "version.h" @@ -36,6 +38,7 @@ #include "browser_win.h" #include "browserlog.h" #include "browserctrlui_win.h" +#include "browserctrlsvc_win.h" #include "browserctrl_win.h" @@ -169,15 +172,34 @@ STDMETHODIMP CHTMLBrowserHost::CreateControlEx( } } } - + // Register a custom interface to extend the HTML Document Object Model // javascript: 'window.external' // - CComObject *pObject = NULL; - hr = CComObject::CreateInstance(&pObject); - if (SUCCEEDED(hr) && pObject != NULL) + CComObject *pUIObject = NULL; + hr = CComObject::CreateInstance(&pUIObject); + if (SUCCEEDED(hr) && pUIObject != NULL) { - SetExternalDispatch((IHTMLBrowserHostUI*)pObject); + SetExternalDispatch((IHTMLBrowserHostUI*)pUIObject); + } + + // Register an external com object to handle the service map stuff for + // IInternetSecurityManager. Attempting implement it locally leads + // to blowing the stack with recursive calls to QueryService(). + // + CComObject *pServicesObject = NULL; + hr = CComObject::CreateInstance(&pServicesObject); + if (SUCCEEDED(hr) && pServicesObject != NULL) + { + SetSite((IHTMLBrowserHostSvc*)pServicesObject); + + // Store the Host UI dispatch pointer so the custom Internet Security Manager + // can determine the acceptable cross-site query policies. + // + if (pUIObject) + { + pServicesObject->m_pHostUI = pUIObject; + } } } diff --git a/samples/gfx_html/browserctrl_win.h b/samples/gfx_html/browserctrl_win.h index 594493622a..a699c4192d 100644 --- a/samples/gfx_html/browserctrl_win.h +++ b/samples/gfx_html/browserctrl_win.h @@ -101,9 +101,6 @@ public: #endif /* __IDeveloperConsoleMessageReceiver_FWD_DEFINED__ */ - - - ///////////////////////////////////////////////////////////////////////////// // CHTMLBrowserHost class @@ -116,9 +113,7 @@ class ATL_NO_VTABLE CHTMLBrowserHost : { public: DECLARE_NO_REGISTRY() - DECLARE_PROTECT_FINAL_CONSTRUCT() DECLARE_POLY_AGGREGATABLE(CHTMLBrowserHost) - DECLARE_GET_CONTROLLING_UNKNOWN() BEGIN_COM_MAP(CHTMLBrowserHost) COM_INTERFACE_ENTRY(IHTMLBrowserHost) @@ -128,14 +123,15 @@ public: COM_INTERFACE_ENTRY_CHAIN(CAxHostWindow) END_COM_MAP() - static CWndClassInfo& GetWndClassInfo(); HRESULT FinalConstruct(); void FinalRelease(); virtual void OnFinalMessage(HWND hWnd); + HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL); + STDMETHOD(CreateControlEx)(LPCOLESTR lpszTricsData, HWND hWnd, IStream* pStream, IUnknown** ppUnk, REFIID iidAdvise, IUnknown* punkSink); @@ -147,14 +143,12 @@ public: STDMETHOD(WriteWithUrlAndLine)(LPCWSTR source, DEV_CONSOLE_MESSAGE_LEVEL level, int messageId, LPCWSTR messageText, LPCWSTR fileUrl, ULONG line); STDMETHOD(WriteWithUrlLineAndColumn)(LPCWSTR source, DEV_CONSOLE_MESSAGE_LEVEL level, int messageId, LPCWSTR messageText, LPCWSTR fileUrl, ULONG line, ULONG column); - // COM Interface - IDocHostShowUI // http://msdn.microsoft.com/en-us/library/aa770041(v=vs.85).aspx // STDMETHOD(ShowMessage)(HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT *plResult); STDMETHOD(ShowHelp)(HWND hwnd, LPOLESTR pszHelpFile, UINT uCommand, DWORD dwData, POINT ptMouse, IDispatch *pDispatchObjectHit); - // COM Interface - IOleCommandTarget // http://support.microsoft.com/kb/261003 // diff --git a/samples/gfx_html/browserctrlsvc_win.cpp b/samples/gfx_html/browserctrlsvc_win.cpp new file mode 100644 index 0000000000..ed30da8379 --- /dev/null +++ b/samples/gfx_html/browserctrlsvc_win.cpp @@ -0,0 +1,93 @@ +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2014-2015 University of California +// +// BOINC is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// BOINC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with BOINC. If not, see . + +#define _ATL_FREE_THREADED +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "win_util.h" +#include "version.h" +#include "boinc_api.h" +#include "diagnostics.h" +#include "filesys.h" +#include "browser_i.h" +#include "browser_win.h" +#include "browserlog.h" +#include "browserctrlui_win.h" +#include "browserctrlsvc_win.h" + + +HRESULT CHTMLBrowserHostServices::FinalConstruct() +{ + m_pHostUI = NULL; + return S_OK; +} + +void CHTMLBrowserHostServices::FinalRelease() +{ +} + +STDMETHODIMP CHTMLBrowserHostServices::SetSecuritySite(IInternetSecurityMgrSite *pSite) +{ + return INET_E_DEFAULT_ACTION; +} + +STDMETHODIMP CHTMLBrowserHostServices::GetSecuritySite(IInternetSecurityMgrSite **ppSite) +{ + return INET_E_DEFAULT_ACTION; +} + +STDMETHODIMP CHTMLBrowserHostServices::MapUrlToZone(LPCWSTR pwszUrl, DWORD *pdwZone, DWORD dwFlags) +{ + return INET_E_DEFAULT_ACTION; +} + +STDMETHODIMP CHTMLBrowserHostServices::GetSecurityId(LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) +{ + return INET_E_DEFAULT_ACTION; +} + +STDMETHODIMP CHTMLBrowserHostServices::ProcessUrlAction(LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved) +{ + return INET_E_DEFAULT_ACTION; +} + +STDMETHODIMP CHTMLBrowserHostServices::QueryCustomPolicy(LPCWSTR pwszUrl, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved) +{ + return INET_E_DEFAULT_ACTION; +} + +STDMETHODIMP CHTMLBrowserHostServices::SetZoneMapping(DWORD dwZone, LPCWSTR lpszPattern, DWORD dwFlags) +{ + return INET_E_DEFAULT_ACTION; +} + +STDMETHODIMP CHTMLBrowserHostServices::GetZoneMappings(DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags) +{ + return INET_E_DEFAULT_ACTION; +} diff --git a/samples/gfx_html/browserctrlsvc_win.h b/samples/gfx_html/browserctrlsvc_win.h new file mode 100644 index 0000000000..2e674fc31b --- /dev/null +++ b/samples/gfx_html/browserctrlsvc_win.h @@ -0,0 +1,63 @@ +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2014-2015 University of California +// +// BOINC is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// BOINC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with BOINC. If not, see . + +#ifndef _BROWSERCTRLSERVICES_WIN_H_ +#define _BROWSERCTRLSERVICES_WIN_H_ + +///////////////////////////////////////////////////////////////////////////// +// CHTMLBrowserHostServices class + +class ATL_NO_VTABLE CHTMLBrowserHostServices : + public CComObjectRoot, + public IDispatchImpl, + public IServiceProviderImpl, + public IInternetSecurityManager +{ +public: + BEGIN_COM_MAP(CHTMLBrowserHostServices) + COM_INTERFACE_ENTRY(IHTMLBrowserHostSvc) + COM_INTERFACE_ENTRY(IDispatch) + COM_INTERFACE_ENTRY(IServiceProvider) + COM_INTERFACE_ENTRY(IInternetSecurityManager) + END_COM_MAP() + + BEGIN_SERVICE_MAP(CHTMLBrowserHostServices) + SERVICE_ENTRY(SID_SInternetSecurityManager) + END_SERVICE_MAP() + + + HRESULT FinalConstruct(); + void FinalRelease(); + + + // COM Interface - IInternetSecurityManager + // http://msdn.microsoft.com/en-us/library/ie/ms537130(v=vs.85).aspx + // + STDMETHOD(SetSecuritySite)(IInternetSecurityMgrSite *pSite); + STDMETHOD(GetSecuritySite)(IInternetSecurityMgrSite **ppSite); + STDMETHOD(MapUrlToZone)(LPCWSTR pwszUrl, DWORD *pdwZone, DWORD dwFlags); + STDMETHOD(GetSecurityId)(LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved); + STDMETHOD(ProcessUrlAction)(LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved); + STDMETHOD(QueryCustomPolicy)(LPCWSTR pwszUrl, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved); + STDMETHOD(SetZoneMapping)(DWORD dwZone, LPCWSTR lpszPattern, DWORD dwFlags); + STDMETHOD(GetZoneMappings)(DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags); + + + CComPtr m_pHostUI; +}; + +#endif \ No newline at end of file diff --git a/samples/gfx_html/browserwnd_win.cpp b/samples/gfx_html/browserwnd_win.cpp index 7d8d05f376..27cbccb7ee 100644 --- a/samples/gfx_html/browserwnd_win.cpp +++ b/samples/gfx_html/browserwnd_win.cpp @@ -193,6 +193,11 @@ LRESULT CHTMLBrowserWnd::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& int retval = ERR_FREAD; HRESULT hr = E_FAIL; BOOL bExit = false; + std::string strDefaultURL; + std::string strRunningURL; + std::string strSuspendedURL; + std::string strNetworkSuspendedURL; + std::string strExitingURL; double dExitTimeout = 0.0; int temp = 0; CComQIPtr pHostUI; @@ -298,13 +303,33 @@ LRESULT CHTMLBrowserWnd::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& // Check for project configured state urls // - if (0 == parse_graphics(m_strDefaultURL, m_strRunningURL, m_strSuspendedURL, m_strNetworkSuspendedURL, m_strExitingURL)) + if (0 == parse_graphics(strDefaultURL, strRunningURL, strSuspendedURL, strNetworkSuspendedURL, strExitingURL)) { - if (m_strDefaultURL.size()) browserlog_msg("Configured default_url: '%s'.", m_strDefaultURL.c_str()); - if (m_strRunningURL.size()) browserlog_msg("Configured running_url: '%s'.", m_strRunningURL.c_str()); - if (m_strSuspendedURL.size()) browserlog_msg("Configured suspended_url: '%s'.", m_strSuspendedURL.c_str()); - if (m_strNetworkSuspendedURL.size()) browserlog_msg("Configured network_suspended_url: '%s'.", m_strNetworkSuspendedURL.c_str()); - if (m_strExitingURL.size()) browserlog_msg("Configured exiting_url: '%s'.", m_strExitingURL.c_str()); + if (strDefaultURL.size()) + { + m_strDefaultURL = NormalizeURL(strDefaultURL); + browserlog_msg("Configured default_url: '%s'.", m_strDefaultURL.c_str()); + } + if (strRunningURL.size()) + { + m_strRunningURL = NormalizeURL(strRunningURL); + browserlog_msg("Configured running_url: '%s'.", m_strRunningURL.c_str()); + } + if (strSuspendedURL.size()) + { + m_strSuspendedURL = NormalizeURL(strSuspendedURL); + browserlog_msg("Configured suspended_url: '%s'.", m_strSuspendedURL.c_str()); + } + if (strNetworkSuspendedURL.size()) + { + m_strNetworkSuspendedURL = NormalizeURL(strNetworkSuspendedURL); + browserlog_msg("Configured network_suspended_url: '%s'.", m_strNetworkSuspendedURL.c_str()); + } + if (strExitingURL.size()) + { + m_strExitingURL = NormalizeURL(strExitingURL); + browserlog_msg("Configured exiting_url: '%s'.", m_strExitingURL.c_str()); + } } @@ -339,39 +364,64 @@ STDMETHODIMP_(void) CHTMLBrowserWnd::OnNewWindow3(IDispatch** ppDisp, VARIANT_BO void CHTMLBrowserWnd::NavigateToStateURL(bool bForce) { - CComBSTR bstr; CComVariant v; + CComBSTR strTargetUL; char buf[256]; // Start out with the default URL - bstr = m_strDefaultURL.c_str(); + strTargetUL = m_strDefaultURL.c_str(); // See if we need to override the default if ((status.abort_request || status.quit_request || status.no_heartbeat) && !m_strExitingURL.empty()) { - bstr = m_strExitingURL.c_str(); + strTargetUL = m_strExitingURL.c_str(); } else if (status.suspended && !m_strSuspendedURL.empty()) { - bstr = m_strSuspendedURL.c_str(); + strTargetUL = m_strSuspendedURL.c_str(); } else if (status.network_suspended && !m_strNetworkSuspendedURL.empty()) { - bstr = m_strNetworkSuspendedURL.c_str(); + strTargetUL = m_strNetworkSuspendedURL.c_str(); } else if (!m_strRunningURL.empty()) { - bstr = m_strRunningURL.c_str(); + strTargetUL = m_strRunningURL.c_str(); } // Are we running a vboxwrapper job? If so, does it expose a webapi port number? - if ((m_bVboxwrapperJob && m_lWebAPIPort) && (bstr.Length() == 0)) { + if ((m_bVboxwrapperJob && m_lWebAPIPort) && (strTargetUL.Length() == 0)) { _snprintf(buf, sizeof(buf), "http://localhost:%d/", m_lWebAPIPort); - bstr = buf; + strTargetUL = buf; } // If nothing has been approved to the point, use the embedded HTML page - if (bstr.Length() == 0) { - bstr = m_strEmbeddedURL; + if (strTargetUL.Length() == 0) { + strTargetUL = m_strEmbeddedURL; } // Navigate to URL - if ((m_strCurrentURL != bstr) || bForce) { - browserlog_msg("State Change Detected (%S).", bstr.m_str); - m_strCurrentURL = bstr; - m_pBrowserCtrl->Navigate(bstr, &v, &v, &v, &v); + if ((m_strCurrentURL != strTargetUL) || bForce) { + browserlog_msg("State Change Detected (%S).", strTargetUL.m_str); + m_strCurrentURL = strTargetUL; + m_pBrowserCtrl->Navigate(strTargetUL, &v, &v, &v, &v); } } + +std::string CHTMLBrowserWnd::NormalizeURL(std::string& url) +{ + std::string strNormalized; + char buf[256]; + + if (starts_with(url, "http://") || starts_with(url, "https://")) + { + strNormalized = url; + } + else + { + // Assume it is a local file + + // Configure a base url using the file protocol pointing to the slot directory + // + _getcwd(buf, sizeof(buf)); + strNormalized = "file://"; + strNormalized += buf; + strNormalized += "/"; + strNormalized += url; + } + + return strNormalized; +} diff --git a/samples/gfx_html/browserwnd_win.h b/samples/gfx_html/browserwnd_win.h index aa9a0ebce0..220bef86cc 100644 --- a/samples/gfx_html/browserwnd_win.h +++ b/samples/gfx_html/browserwnd_win.h @@ -59,7 +59,7 @@ public: // void NavigateToStateURL(bool bForce); - + std::string NormalizeURL(std::string& url); CComObject* m_pBrowserHost; CComQIPtr m_pBrowserCtrl; diff --git a/win_build/htmlgfx.vcxproj b/win_build/htmlgfx.vcxproj index a9d4717f02..31e6811179 100644 --- a/win_build/htmlgfx.vcxproj +++ b/win_build/htmlgfx.vcxproj @@ -138,7 +138,7 @@ $(IntDir);..;%(AdditionalIncludeDirectories) - libcmt.lib;libcpmt.lib;atls.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;wsock32.lib;psapi.lib;%(AdditionalDependencies) + libcmt.lib;libcpmt.lib;atls.lib;comsuppw.lib;urlmon.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;wsock32.lib;psapi.lib;%(AdditionalDependencies) $(TargetDir)\$(TargetFileName) true true @@ -190,7 +190,7 @@ $(IntDir);..;%(AdditionalIncludeDirectories) - libcmt.lib;libcpmt.lib;atls.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;wsock32.lib;psapi.lib;%(AdditionalDependencies) + libcmt.lib;libcpmt.lib;atls.lib;comsuppw.lib;urlmon.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;wsock32.lib;psapi.lib;%(AdditionalDependencies) $(TargetDir)\$(TargetFileName) true true @@ -238,7 +238,7 @@ $(IntDir);..;%(AdditionalIncludeDirectories) - libcmtd.lib;libcpmtd.lib;atlsd.lib;comsuppwd.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;psapi.lib;wsock32.lib;%(AdditionalDependencies) + libcmtd.lib;libcpmtd.lib;atlsd.lib;comsuppwd.lib;urlmon.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;psapi.lib;wsock32.lib;%(AdditionalDependencies) $(TargetDir)\$(TargetFileName) true true @@ -286,7 +286,7 @@ $(IntDir);..;%(AdditionalIncludeDirectories) - libcmtd.lib;libcpmtd.lib;atlsd.lib;comsuppwd.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;wsock32.lib;psapi.lib;%(AdditionalDependencies) + libcmtd.lib;libcpmtd.lib;atlsd.lib;comsuppwd.lib;urlmon.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;wsock32.lib;psapi.lib;%(AdditionalDependencies) $(TargetDir)\$(TargetFileName) true true @@ -310,6 +310,7 @@ + @@ -320,6 +321,7 @@ +