|
|
// esh.cpp: implementation of the CEventScriptHandler class.
//
//////////////////////////////////////////////////////////////////////
//#include "stdafx.h"
#include <esh.h>
#include <scripto.h>
#include <pbag.h>
#include <stags.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CEventScriptHandler::CEventScriptHandler() { m_cNamedProps = 0; m_pScripto = NULL; m_pBag = new CPropBag; VariantInit(&m_varErrorResponse); VariantInit(&m_varScriptResponse); }
CEventScriptHandler::~CEventScriptHandler()
{ if( m_pBag != NULL ) m_pBag->Release();
if( m_pScripto != NULL ) m_pScripto->Release(); }
STDMETHODIMP CEventScriptHandler::SetScript(BSTR bstrFileName) { HRESULT hr = NOERROR; HANDLE hFile = INVALID_HANDLE_VALUE; CStreamFile* pstmFile = NULL;
if( bstrFileName == NULL ) return E_POINTER;
if( m_pBag == NULL ) return E_OUTOFMEMORY;
hFile = CreateFileW(bstrFileName,GENERIC_READ,FILE_SHARE_READ,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if( hFile == INVALID_HANDLE_VALUE ) { hr = HRGetLastError(); goto exit; }
pstmFile = new CStreamFile(hFile,TRUE); if( pstmFile == NULL ) { CloseHandle(hFile); hr = E_OUTOFMEMORY; goto exit; }
hr = SetScript((IStream*)pstmFile);
exit: if( pstmFile != NULL ) pstmFile->Release();
return hr; }
STDMETHODIMP CEventScriptHandler::SetScript(IStream * pstmScript) { HRESULT hr = NOERROR; VARIANT var; IUnknown* pUnk = NULL;
if( pstmScript == NULL ) return E_POINTER;
if( m_pBag == NULL ) return E_OUTOFMEMORY;
hr = pstmScript->QueryInterface(IID_IUnknown,(void**)&pUnk); if(FAILED(hr)) goto exit;
// put the script stream into the bag
V_VT(&var) = VT_UNKNOWN; V_UNKNOWN(&var) = (IUnknown*)pUnk; hr = m_pBag->Write(wszScriptTextProp, &var); VariantClear(&var); exit: return hr; }
STDMETHODIMP CEventScriptHandler::AddGlobalVariable(BSTR bstrName, VARIANT varVariable) { HRESULT hr = NOERROR; WCHAR wszBagProp[64] = {0}; VARIANT var;
if( bstrName == NULL ) return E_POINTER;
if( m_pBag == NULL ) return E_OUTOFMEMORY;
VariantInit(&var); m_cNamedProps++;
// add the name
V_VT(&var) = VT_BSTR; V_BSTR(&var) = SysAllocString(bstrName); wsprintfW(wszBagProp, L"%ls%ld", wszNamedPropIDPrefix, m_cNamedProps); hr = m_pBag->Write(wszBagProp, &var); VariantClear(&var); if(FAILED(hr)) goto exit;
// add the value
wsprintfW(wszBagProp, L"%ls%ld", wszNamedUnkPtrPrefix, m_cNamedProps); hr = m_pBag->Write(wszBagProp, &varVariable); if(FAILED(hr)) goto exit;
// not a NamedSource (for connection points)
V_VT(&var) = VT_BOOL; V_BOOL(&var) = VARIANT_FALSE; wsprintfW(wszBagProp, L"%ls%ld", wszNamedSourcesPrefix, m_cNamedProps); hr = m_pBag->Write(wszBagProp, &var); if(FAILED(hr)) goto exit;
exit: return hr; }
STDMETHODIMP CEventScriptHandler::AddConnectionPoint(BSTR bstrName, IConnectionPointContainer * pContainer) { HRESULT hr = NOERROR; WCHAR wszBagProp[64] = {0}; VARIANT var;
if( bstrName == NULL || pContainer == NULL ) return E_POINTER;
if( m_pBag == NULL ) return E_OUTOFMEMORY;
VariantInit(&var); m_cNamedProps++;
// add the name
V_VT(&var) = VT_BSTR; V_BSTR(&var) = SysAllocString(bstrName); wsprintfW(wszBagProp, L"%ls%ld", wszNamedPropIDPrefix, m_cNamedProps); hr = m_pBag->Write(wszBagProp, &var); VariantClear(&var); if(FAILED(hr)) goto exit;
// add the value as IUnknown*
V_VT(&var) = VT_UNKNOWN; hr = pContainer->QueryInterface(IID_IUnknown, (void**)&V_UNKNOWN(&var)); if(FAILED(hr)) goto exit; wsprintfW(wszBagProp, L"%ls%ld", wszNamedUnkPtrPrefix, m_cNamedProps); hr = m_pBag->Write(wszBagProp, &var); VariantClear(&var); if(FAILED(hr)) goto exit;
// the object is a NamedSource, so we will connect to
// script functions that look like <Object>_xxx
V_VT(&var) = VT_BOOL; V_BOOL(&var) = VARIANT_TRUE; wsprintfW(wszBagProp, L"%ls%ld", wszNamedSourcesPrefix, m_cNamedProps); hr = m_pBag->Write(wszBagProp, &var); if(FAILED(hr)) goto exit;
exit: return hr; }
STDMETHODIMP CEventScriptHandler::ASPSyntax(BOOL fIsASPSyntax) { HRESULT hr = NOERROR; VARIANT var;
if( m_pBag == NULL ) return E_OUTOFMEMORY;
V_VT(&var) = VT_BOOL; V_BOOL(&var) = fIsASPSyntax ? VARIANT_TRUE : VARIANT_FALSE ; hr = m_pBag->Write(wszASPSyntaxProp, &var);
return hr; }
STDMETHODIMP CEventScriptHandler::AllowCreateObject(BOOL fCreateObjectAllowed) { HRESULT hr = NOERROR; VARIANT var;
if( m_pBag == NULL ) return E_OUTOFMEMORY;
V_VT(&var) = VT_BOOL; V_BOOL(&var) = fCreateObjectAllowed ? VARIANT_TRUE : VARIANT_FALSE ; hr = m_pBag->Write(wszEnableCreateObjects, &var);
return hr; }
STDMETHODIMP CEventScriptHandler::MaxExecutionTime(DWORD dwMaxExecutionTime) { HRESULT hr = NOERROR; VARIANT var;
if( m_pBag == NULL ) return E_OUTOFMEMORY;
V_VT(&var) = VT_UI4; V_UI4(&var) = dwMaxExecutionTime; hr = m_pBag->Write(wszMaxExecutionTimeProp, &var);
return hr; }
STDMETHODIMP CEventScriptHandler::StartScript() { HRESULT hr = NOERROR; VARIANT var;
if( m_pBag == NULL ) return E_OUTOFMEMORY;
if( m_pScripto != NULL ) return RestartScript();
// write the number of named props to pBag
V_VT(&var) = VT_UI4; V_UI4(&var) = m_cNamedProps; hr = m_pBag->Write(wszNumNamedPropsProp, &var); if(FAILED(hr)) goto exit;
// create the scripto object
hr = CoCreateInstance(CLSID_Scripto, NULL, CLSCTX_INPROC_SERVER, IID_IScripto, (void**)&m_pScripto); if(FAILED(hr)) goto exit;
// init the script
hr = m_pScripto->InitScript(m_pBag); if( FAILED(hr) ) { VariantClear(&m_varErrorResponse); m_pBag->Read(wszErrorResponse, &m_varErrorResponse, NULL); } else { VariantClear(&m_varScriptResponse); m_pBag->Read(wszScriptResponse, &m_varScriptResponse, NULL); }
exit: return hr; }
STDMETHODIMP CEventScriptHandler::RestartScript() { HRESULT hr = NOERROR;
if( m_pScripto == NULL ) return E_OUTOFMEMORY;
if( !m_fScriptStopped ) StopScript();
hr = m_pScripto->ReInitScript(NULL);
return hr; }
STDMETHODIMP CEventScriptHandler::StopScript() { HRESULT hr = NOERROR;
if( m_pScripto == NULL ) return E_OUTOFMEMORY;
hr = m_pScripto->DeActivateScript(FALSE); m_fScriptStopped = TRUE;
return hr; }
STDMETHODIMP CEventScriptHandler::ExecuteConnectionPoint(IConnectionPoint* pConnectionPoint, DISPID dispid) { HRESULT hr = NOERROR; IEnumConnections* pConnections = NULL; CONNECTDATA ConnectData = {0}; LPDISPATCH pConnection = NULL; DWORD cConnections = 0; DISPPARAMS NoArgs = {NULL, NULL, 0, 0}; bool fGotOne = false;
if( pConnectionPoint == NULL ) return E_POINTER;
if( m_pScripto == NULL ) return E_OUTOFMEMORY;
// find out if the script has any connections for this event
hr = pConnectionPoint->EnumConnections(&pConnections); if(hr == S_FALSE) { // No connection points.
hr = DISP_E_UNKNOWNNAME; goto exit; } else if( FAILED(hr) ) goto exit;
hr = pConnections->Reset(); if( FAILED(hr) ) goto exit;
// loop through each connection and execute its associated code
do { hr = pConnections->Next(1, &ConnectData, &cConnections); if(SUCCEEDED(hr)) { if(cConnections) { hr = ConnectData.pUnk->QueryInterface(IID_IDispatch, (void**)&pConnection); if(SUCCEEDED(hr)) { // try to invoke - this may fail non-fatally
hr = pConnection->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &NoArgs, NULL, NULL, NULL); if(hr != DISP_E_UNKNOWNNAME) { // we at least got one connection point
fGotOne = true;
if( FAILED(hr) ) { // event execution failed
VariantClear(&m_varErrorResponse); m_pBag->Read(wszErrorResponse, &m_varErrorResponse, NULL); m_pScripto->Abort(); } else { VariantClear(&m_varScriptResponse); m_pBag->Read(wszScriptResponse, &m_varScriptResponse, NULL); m_pScripto->Complete(); } }
pConnection->Release(); pConnection = NULL; } ConnectData.pUnk->Release(); ConnectData.pUnk = NULL; } else { // means we are done - no more connections
// if we got at least one to work then we consider it
// a success
hr = fGotOne ? S_OK : DISP_E_UNKNOWNNAME; } } } while(SUCCEEDED(hr) && cConnections);
// tell scripto whether we are happy campers or not
if(SUCCEEDED(hr)) { m_pScripto->Complete(); } else { m_pScripto->Abort(); }
// must leave scripto in the deactived state so that it can be
// called again on another thread
m_pScripto->DeActivateScript(false);
exit: if( pConnections ) pConnections->Release(); return hr; }
|