Windows2003-3790/inetcore/wininet/autoconf/cscpsite.cpp
2020-09-30 16:53:55 +02:00

456 lines
11 KiB
C++

#include "cscpsite.h"
#include <objsafe.h>
/*******************************************************************************
* CScriptSite Functions
********************************************************************************/
CScriptSite::CScriptSite()
{
m_refCount = 1;
m_pios = NULL;
m_pasp = NULL;
m_pScriptDispatch = NULL;
m_Scriptdispid = -1;
m_fInitialized = FALSE;
}
CScriptSite::~CScriptSite()
{
if (m_fInitialized)
DeInit();
}
STDMETHODIMP CScriptSite::QueryInterface(REFIID riid, PVOID *ppvObject)
{
if (riid == IID_IUnknown)
{
*ppvObject = (LPVOID)(LPUNKNOWN)static_cast<IActiveScriptSite *>(this);
}
else if (riid == IID_IActiveScriptSite)
{
*ppvObject = (LPVOID)static_cast<IActiveScriptSite *>(this);
}
else if (riid == IID_IServiceProvider)
{
*ppvObject = (LPVOID)static_cast<IServiceProvider *>(this);
}
else if (riid == IID_IInternetHostSecurityManager)
{
*ppvObject = (LPVOID)static_cast<IInternetHostSecurityManager *>(this);
}
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP CScriptSite::Init(AUTO_PROXY_HELPER_APIS* pAPHA, LPCSTR szScript)
{
CHAR szClassId[64];
CLSID clsid;
HRESULT hr = S_OK;
BSTR bstrClsID = NULL;
BSTR bstrScriptText = NULL;
BSTR rgbstrNames[1] = {L"FindProxyForURL"};
EXCEPINFO exceptinfo;
IObjectSafety * pIObjSafety = NULL;
// pAPHA can be null - it is checked in the autoproxy object!
if (!szScript)
return E_POINTER;
if (m_fInitialized)
return hr;
// CoCreateInstance the JScript engine.
// Get the class id of the desired language engine
hr = GetScriptEngineClassIDFromName(
"JavaScript",
szClassId,
sizeof(szClassId)
);
if (FAILED(hr)) {
return E_FAIL;
}
//convert CLSID string to clsid
bstrClsID = BSTRFROMANSI(szClassId);
if (!bstrClsID)
goto exit;
hr = CLSIDFromString(bstrClsID, &clsid);
SysFreeString(bstrClsID);
if (FAILED(hr))
goto exit;
// Instantiate the script engine
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void**)&m_pios);
if (FAILED(hr))
goto exit;
// Get the IActiveScriptParse interface, if any
hr = m_pios->QueryInterface(IID_IActiveScriptParse, (void**) &m_pasp);
if (FAILED(hr))
goto exit;
hr = m_pasp->InitNew();
if (FAILED(hr))
goto exit;
// SetScriptSite to this
hr = m_pios->SetScriptSite((IActiveScriptSite *)this);
if (FAILED(hr))
goto exit;
hr = m_pios->SetScriptState(SCRIPTSTATE_INITIALIZED);
//
// Inform the script engine that this host implements
// the IInternetHostSecurityManager interface, which
// is used to prevent the script code from using any
// ActiveX objects.
//
hr = m_pios->QueryInterface(IID_IObjectSafety, (void **)&pIObjSafety);
if (SUCCEEDED(hr) && (pIObjSafety != NULL))
{
pIObjSafety->SetInterfaceSafetyOptions(IID_NULL,
INTERFACE_USES_SECURITY_MANAGER,
INTERFACE_USES_SECURITY_MANAGER);
pIObjSafety->Release();
pIObjSafety = NULL;
}
// AddNamedItem for pUnk and set m_punkJSProxy to pUnk.
// If we added JSProxy to the name space the store away the JSProxy objects punk.
m_punkJSProxy = new CJSProxy;
if( !m_punkJSProxy )
{
hr = E_OUTOFMEMORY;
goto exit;
}
m_punkJSProxy->Init(pAPHA);
hr = m_pios->AddNamedItem(L"JSProxy",SCRIPTITEM_ISVISIBLE | SCRIPTITEM_GLOBALMEMBERS);
if (FAILED(hr))
goto exit;
// Convert the ANSI script text to a bstr.
bstrScriptText = BSTRFROMANSI(szScript);
if (!bstrScriptText)
{
hr = E_OUTOFMEMORY;
goto exit;
}
// Add the script text to the parser
hr = m_pasp->ParseScriptText(
bstrScriptText,
NULL,
NULL,
NULL,
0,
0,
SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE,
NULL,
&exceptinfo);
SysFreeString(bstrScriptText);
if (FAILED(hr))
goto exit;
hr = m_pios->SetScriptState(SCRIPTSTATE_STARTED);
if (FAILED(hr))
goto exit;
// Now get the script dispatch and find the DISPID for the method just added. since this is a single use dll
// I can do this otherwise this would be bad.
hr = m_pios->GetScriptDispatch(NULL,&m_pScriptDispatch);
if (FAILED(hr))
goto exit;
hr = m_pScriptDispatch->GetIDsOfNames(IID_NULL,rgbstrNames,1,LOCALE_SYSTEM_DEFAULT,&m_Scriptdispid);
if (FAILED(hr))
goto exit;
m_fInitialized = TRUE;
return hr;
exit: // we come here if something fails - release everything and set to null.
if (m_pios)
{
m_pios->Close();
m_pios->Release();
}
if (m_pasp)
m_pasp->Release();
if (m_pScriptDispatch)
m_pScriptDispatch->Release();
m_pios = NULL;
m_pasp = NULL;
m_pScriptDispatch = NULL;
m_Scriptdispid = -1;
return hr;
}
STDMETHODIMP CScriptSite::DeInit()
{
HRESULT hr = S_OK;
if (m_pios)
{
hr = m_pios->Close();
m_pios->Release();
}
if (m_pasp)
m_pasp->Release();
if (m_pScriptDispatch)
m_pScriptDispatch->Release();
m_pios = NULL;
m_pasp = NULL;
m_pScriptDispatch = NULL;
m_Scriptdispid = -1;
m_fInitialized = FALSE;
return hr;
}
STDMETHODIMP CScriptSite::RunScript(LPCSTR szURL, LPCSTR szHost, LPSTR* result)
{
HRESULT hr = S_OK;
UINT puArgErr = 0;
EXCEPINFO excep;
VARIANT varresult;
DISPPARAMS dispparams;
VARIANT args[2]; // We always call with 2 args!
if (!szURL || !szHost || !result)
return E_POINTER;
VariantInit(&varresult);
*result = NULL;
dispparams.cArgs = 2;
VariantInit(&args[0]);
VariantInit(&args[1]);
args[0].vt = VT_BSTR;
args[1].vt = VT_BSTR;
args[0].bstrVal = BSTRFROMANSI(szHost);
args[1].bstrVal = BSTRFROMANSI(szURL);
if (args[0].bstrVal==NULL || args[1].bstrVal==NULL)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
dispparams.rgvarg = args;
dispparams.cNamedArgs = 0;
dispparams.rgdispidNamedArgs = NULL;
// Call invoke on the stored dispid
hr = m_pScriptDispatch->Invoke(m_Scriptdispid,
IID_NULL,LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&varresult,
&excep,
&puArgErr);
if (FAILED(hr))
goto Cleanup;
// convert result into bstr and return ansi version of the string!
if (varresult.vt == VT_BSTR)
{
MAKE_ANSIPTR_FROMWIDE(rescpy, varresult.bstrVal);
*result = (LPSTR) GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,lstrlen(rescpy)+1);
if (!*result)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
lstrcpy(*result,rescpy);
}
else
{
VARIANT resvar;
VariantInit(&resvar);
hr = VariantChangeType(&resvar,&varresult,NULL,VT_BSTR);
if (SUCCEEDED(hr))
{
MAKE_ANSIPTR_FROMWIDE(rescpy, resvar.bstrVal);
*result = (LPSTR) GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,lstrlen(rescpy)+1);
if (!*result)
{
hr = E_OUTOFMEMORY;
VariantClear(&resvar);
goto Cleanup;
}
lstrcpy(*result,rescpy);
}
else
*result = NULL;
VariantClear(&resvar);
}
Cleanup:
VariantClear(&varresult);
VariantClear(&args[0]);
VariantClear(&args[1]);
return hr;
}
STDMETHODIMP CScriptSite::GetLCID(LCID *plcid)
{
UNREFERENCED_PARAMETER(plcid);
return E_NOTIMPL;
}
STDMETHODIMP CScriptSite::GetItemInfo(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppunkItem, ITypeInfo **ppTypeInfo)
{
UNREFERENCED_PARAMETER(ppTypeInfo);
if (!pstrName || !ppunkItem)
return E_POINTER;
if ((StrCmpW(L"JSProxy",pstrName) == 0) && (dwReturnMask == SCRIPTINFO_IUNKNOWN))
{
*ppunkItem = (LPUNKNOWN)(IDispatch*)(CJSProxy*)m_punkJSProxy;
(*ppunkItem)->AddRef();
return S_OK;
}
else
return TYPE_E_ELEMENTNOTFOUND;
}
STDMETHODIMP CScriptSite::GetDocVersionString(BSTR *pstrVersionString)
{
UNREFERENCED_PARAMETER(pstrVersionString);
return E_NOTIMPL;
}
// I am not interested it the transitioning of state or the status of where we are in
// the executing of the script.
STDMETHODIMP CScriptSite::OnScriptTerminate(const VARIANT *pvarResult,const EXCEPINFO *pexcepinfo)
{
UNREFERENCED_PARAMETER(pvarResult);
UNREFERENCED_PARAMETER(pexcepinfo);
return S_OK;
}
STDMETHODIMP CScriptSite::OnStateChange(SCRIPTSTATE ssScriptState)
{
UNREFERENCED_PARAMETER(ssScriptState);
return S_OK;
}
STDMETHODIMP CScriptSite::OnScriptError(IActiveScriptError *pase)
{
UNREFERENCED_PARAMETER(pase);
return S_OK;
}
STDMETHODIMP CScriptSite::OnEnterScript()
{
return S_OK;
}
STDMETHODIMP CScriptSite::OnLeaveScript()
{
return S_OK;
}
//
// IServiceProvider
//
// Implemented to help wire up the script engine with our
// IInternetHostSecurityManager interface.
//
STDMETHODIMP CScriptSite::QueryService(
REFGUID guidService,
REFIID riid,
void ** ppvObject)
{
if (guidService == SID_SInternetHostSecurityManager)
{
return QueryInterface(riid, ppvObject);
}
else
{
return E_NOINTERFACE;
}
}
//
// IInternetHostSecurityManager
//
// Implemented to prevent the script code from using ActiveX objects.
//
STDMETHODIMP CScriptSite::GetSecurityId(
BYTE * pbSecurityId,
DWORD * pcbSecurityId,
DWORD_PTR dwReserved)
{
UNREFERENCED_PARAMETER(pbSecurityId);
UNREFERENCED_PARAMETER(pcbSecurityId);
UNREFERENCED_PARAMETER(dwReserved);
return E_NOTIMPL;
}
STDMETHODIMP CScriptSite::ProcessUrlAction(
DWORD dwAction,
BYTE * pPolicy,
DWORD cbPolicy,
BYTE * pContext,
DWORD cbContext,
DWORD dwFlags,
DWORD dwReserved)
{
UNREFERENCED_PARAMETER(dwAction);
UNREFERENCED_PARAMETER(pContext);
UNREFERENCED_PARAMETER(cbContext);
UNREFERENCED_PARAMETER(dwFlags);
UNREFERENCED_PARAMETER(dwReserved);
//
// Deny the script any capabilites. In particular, this
// will disallow the script code from instantiating
// ActiveX objects.
//
if (cbPolicy == sizeof(DWORD))
{
*(DWORD *)pPolicy = URLPOLICY_DISALLOW;
}
return S_FALSE; // S_FALSE means the policy != URLPOLICY_ALLOW.
}
STDMETHODIMP CScriptSite::QueryCustomPolicy(
REFGUID guidKey,
BYTE ** ppPolicy,
DWORD * pcbPolicy,
BYTE * pContext,
DWORD cbContext,
DWORD dwReserved)
{
UNREFERENCED_PARAMETER(guidKey);
UNREFERENCED_PARAMETER(ppPolicy);
UNREFERENCED_PARAMETER(pcbPolicy);
UNREFERENCED_PARAMETER(pContext);
UNREFERENCED_PARAMETER(cbContext);
UNREFERENCED_PARAMETER(dwReserved);
return E_NOTIMPL;
}