You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
429 lines
10 KiB
429 lines
10 KiB
|
|
//
|
|
// CActiveScriptEngine.cpp
|
|
//
|
|
// Contains the definitions for the ActiveScriptEngine used in TBScript.
|
|
//
|
|
// Copyright (C) 2001 Microsoft Corporation
|
|
//
|
|
// Author: a-devjen (Devin Jenson)
|
|
//
|
|
|
|
|
|
#include "CActiveScriptEngine.h"
|
|
#include <crtdbg.h>
|
|
|
|
|
|
// CActiveScriptEngine::CActiveScriptEngine
|
|
//
|
|
// The constructor, simply grabs references to the dispatch objects
|
|
// we are using in this object.
|
|
//
|
|
// No return value.
|
|
|
|
CActiveScriptEngine::CActiveScriptEngine(CTBGlobal *TBGlobalPtr,
|
|
CTBShell *TBShellPtr)
|
|
{
|
|
// Start out at a zero reference count
|
|
RefCount = 0;
|
|
|
|
// Grab the pointers
|
|
TBGlobal = TBGlobalPtr;
|
|
TBShell = TBShellPtr;
|
|
|
|
// Ensure COM has been initialized
|
|
CoInitialize(NULL);
|
|
|
|
// Add a reference to the dispatches
|
|
if (TBGlobal != NULL)
|
|
TBGlobal->AddRef();
|
|
|
|
if (TBShell != NULL)
|
|
TBShell->AddRef();
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::~CActiveScriptEngine
|
|
//
|
|
// The destructor, release pointers from the dispatch objects.
|
|
//
|
|
// No return value.
|
|
|
|
CActiveScriptEngine::~CActiveScriptEngine(void)
|
|
{
|
|
// Remove a reference from the dispatche
|
|
if (TBGlobal != NULL)
|
|
TBGlobal->Release();
|
|
|
|
TBGlobal = NULL;
|
|
|
|
// Remove a reference from the dispatche
|
|
if (TBShell != NULL)
|
|
TBShell->Release();
|
|
|
|
TBShell = NULL;
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
// Begin the IUnknown inherited interface
|
|
//
|
|
//
|
|
|
|
|
|
// CActiveScriptEngine::QueryInterface
|
|
//
|
|
// This is a COM exported method used for retrieving the interface.
|
|
//
|
|
// Returns S_OK on success, or E_NOINTERFACE on failure.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::QueryInterface(REFIID RefIID, void **vObject)
|
|
{
|
|
// This interface is either IUnknown or IActiveScriptSite - nothing else
|
|
if (RefIID == IID_IUnknown || RefIID == IID_IActiveScriptSite)
|
|
*vObject = (IActiveScriptSite *)this;
|
|
|
|
// We received an unsupported RefIID
|
|
else {
|
|
|
|
// De-reference the passed in pointer and error out
|
|
*vObject = NULL;
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
// Add a reference
|
|
if (*vObject != NULL)
|
|
((IUnknown*)*vObject)->AddRef();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::AddRef
|
|
//
|
|
// Simply increments a number indicating the number of objects that contain
|
|
// a reference to this object.
|
|
//
|
|
// Returns the new reference count.
|
|
|
|
STDMETHODIMP_(ULONG) CActiveScriptEngine::AddRef(void)
|
|
{
|
|
return InterlockedIncrement(&RefCount);
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::Release
|
|
//
|
|
// Simply decrements a number indicating the number of objects that contain
|
|
// a reference to this object. If the resulting reference count is zero,
|
|
// no objects contain a reference handle, therefore delete itself from
|
|
// memory as it is no longer used.
|
|
//
|
|
// Returns the new reference count.
|
|
|
|
STDMETHODIMP_(ULONG) CActiveScriptEngine::Release(void)
|
|
{
|
|
// Decrememt
|
|
if (InterlockedDecrement(&RefCount) != 0)
|
|
|
|
// Return the new value
|
|
return RefCount;
|
|
|
|
// It is 0, so delete itself
|
|
delete this;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
// Begin the IActiveScript inherited interface
|
|
//
|
|
//
|
|
|
|
|
|
// CActiveScriptEngine::GetItemInfo
|
|
//
|
|
// Retreives a memory pointer to the specified (local) interface code or
|
|
// a reference handle.
|
|
//
|
|
// Returns S_OK, E_INVALIDARG, E_POINTER, or TYPE_E_ELEMENTNOTFOUND.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::GetItemInfo(LPCOLESTR Name,
|
|
DWORD ReturnMask, IUnknown **UnknownItem, ITypeInfo **TypeInfo)
|
|
{
|
|
// Initialize
|
|
IUnknown *TBInterface = NULL;
|
|
|
|
// If we are going to handle a specific item, NULL it's destination
|
|
// pointer out. We also use this opportunity to validate some
|
|
// argument pointers.
|
|
__try {
|
|
|
|
if (ReturnMask & SCRIPTINFO_IUNKNOWN)
|
|
*UnknownItem = NULL;
|
|
|
|
if (ReturnMask & SCRIPTINFO_ITYPEINFO)
|
|
*TypeInfo = NULL;
|
|
|
|
// This check is to make sure nothing else was passed into the mask
|
|
if (ReturnMask & ~(SCRIPTINFO_ITYPEINFO | SCRIPTINFO_IUNKNOWN)) {
|
|
|
|
// This should never happen, so ASSERT!
|
|
_ASSERT(FALSE);
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
// If the handler was executed, we got a bad pointer
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
// This should never happen, so ASSERT!
|
|
_ASSERT(FALSE);
|
|
|
|
return E_POINTER;
|
|
}
|
|
|
|
// Freaky things...
|
|
_ASSERT(TBGlobal != NULL);
|
|
_ASSERT(TBShell != NULL);
|
|
|
|
// Scan which item we are referring to
|
|
|
|
if (wcscmp(Name, OLESTR("Global")) == 0) {
|
|
|
|
// Check if the call wants the actual module code
|
|
if (ReturnMask & SCRIPTINFO_ITYPEINFO) {
|
|
|
|
// Check to make sure we have a valid TypeInfo
|
|
_ASSERT(TBGlobal->TypeInfo != NULL);
|
|
|
|
*TypeInfo = TBGlobal->TypeInfo;
|
|
}
|
|
|
|
// Check if the call wants the Dispatch
|
|
if (ReturnMask & SCRIPTINFO_IUNKNOWN) {
|
|
|
|
*UnknownItem = TBGlobal;
|
|
|
|
TBGlobal->AddRef();
|
|
}
|
|
}
|
|
|
|
else if (wcscmp(Name, OLESTR("TS")) == 0) {
|
|
|
|
// Check if the call wants the actual module code
|
|
if (ReturnMask & SCRIPTINFO_ITYPEINFO) {
|
|
|
|
// Check to make sure we have a valid TypeInfo
|
|
_ASSERT(TBShell->TypeInfo != NULL);
|
|
|
|
*TypeInfo = TBShell->TypeInfo;
|
|
}
|
|
|
|
// Check if the call wants the Dispatch
|
|
if (ReturnMask & SCRIPTINFO_IUNKNOWN) {
|
|
|
|
*UnknownItem = TBShell;
|
|
|
|
TBShell->AddRef();
|
|
}
|
|
}
|
|
|
|
else
|
|
|
|
// We don't have an object by that name!
|
|
return TYPE_E_ELEMENTNOTFOUND;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::OnScriptError
|
|
//
|
|
// This event is executed when a script error occurs.
|
|
//
|
|
// Returns S_OK on success or an OLE defined error on failure.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::OnScriptError(IActiveScriptError *ScriptError)
|
|
{
|
|
// Initialize
|
|
OLECHAR *ErrorData;
|
|
OLECHAR *Message;
|
|
DWORD Cookie;
|
|
LONG CharPos;
|
|
ULONG LineNum;
|
|
BSTR LineError = NULL;
|
|
EXCEPINFO ExceptInfo = { 0 };
|
|
OLECHAR *ScriptText = NULL;
|
|
|
|
// Get script error data
|
|
ScriptError->GetSourcePosition(&Cookie, &LineNum, &CharPos);
|
|
ScriptError->GetSourceLineText(&LineError);
|
|
ScriptError->GetExceptionInfo(&ExceptInfo);
|
|
|
|
ScriptText = LineError ? LineError :
|
|
(ExceptInfo.bstrHelpFile ? ExceptInfo.bstrHelpFile : NULL);
|
|
|
|
// Allocate a data buffer for use with our error data
|
|
ErrorData = (OLECHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024);
|
|
|
|
if (ErrorData == NULL)
|
|
return E_OUTOFMEMORY;
|
|
|
|
// Format the error code into text
|
|
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM, 0, ExceptInfo.scode,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPWSTR)&Message, 0, NULL) == 0)
|
|
|
|
Message = NULL;
|
|
|
|
// Make it pretty for whatever data is provided
|
|
if (ExceptInfo.bstrSource != NULL && Message != NULL)
|
|
wsprintfW(ErrorData, OLESTR("%s\n%s [Line: %d]"),
|
|
Message, ExceptInfo.bstrSource, LineNum);
|
|
|
|
else if (Message != NULL)
|
|
wsprintfW(ErrorData, OLESTR("%s\n[Line: %d]"), Message, LineNum);
|
|
|
|
else if (ExceptInfo.bstrSource != NULL)
|
|
wsprintfW(ErrorData, OLESTR("Unknown Exception\n%s [Line: %d]"),
|
|
ExceptInfo.bstrSource, LineNum);
|
|
|
|
else
|
|
wsprintfW(ErrorData, OLESTR("Unknown Exception\n[Line: %d]"), LineNum);
|
|
|
|
if (ScriptText != NULL) {
|
|
|
|
// Format a long-readable string
|
|
wsprintfW(ErrorData, OLESTR("%s\n\n%s:\n\n%s"),
|
|
ErrorData,
|
|
ExceptInfo.bstrDescription, ScriptText);
|
|
}
|
|
|
|
else {
|
|
|
|
// Format a readable string
|
|
wsprintfW(ErrorData, OLESTR("%s\n\n%s"),
|
|
ErrorData, ExceptInfo.bstrDescription);
|
|
}
|
|
|
|
// Deallocate temporary strings
|
|
SysFreeString(LineError);
|
|
SysFreeString(ExceptInfo.bstrSource);
|
|
SysFreeString(ExceptInfo.bstrDescription);
|
|
SysFreeString(ExceptInfo.bstrHelpFile);
|
|
|
|
if (Message != NULL) {
|
|
|
|
LocalFree(Message);
|
|
Message = NULL;
|
|
}
|
|
|
|
// Tell the user about our error
|
|
MessageBoxW(GetDesktopWindow(), ErrorData,
|
|
OLESTR("TBScript Parse Error"), MB_SETFOREGROUND);
|
|
|
|
// Free the data buffer
|
|
HeapFree(GetProcessHeap(), 0, ErrorData);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::GetLCID
|
|
//
|
|
// Retreives the LCID of the interface.
|
|
//
|
|
// Returns S_OK on success or E_POINTER on failure.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::GetLCID(LCID *Lcid)
|
|
{
|
|
// Get the LCID on this user-defined pointer
|
|
__try {
|
|
|
|
*Lcid = GetUserDefaultLCID();
|
|
}
|
|
|
|
// If the handler was executed, we got a bad pointer
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
// This should never happen, so ASSERT!
|
|
_ASSERT(FALSE);
|
|
|
|
return E_POINTER;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::GetDocVersionString
|
|
//
|
|
// Unsupported, returns E_NOTIMPL.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::GetDocVersionString(BSTR *Version)
|
|
{
|
|
// Get the LCID on this user-defined pointer
|
|
__try {
|
|
|
|
*Version = NULL;
|
|
}
|
|
|
|
// If the handler was executed, we got a bad pointer
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
// This should never happen, so ASSERT!
|
|
_ASSERT(FALSE);
|
|
}
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::OnScriptTerminate
|
|
//
|
|
// Unsupported, returns S_OK.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::OnScriptTerminate(const VARIANT *varResult,
|
|
const EXCEPINFO *ExceptInfo)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::OnStateChange
|
|
//
|
|
// Unsupported, returns S_OK.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::OnStateChange(SCRIPTSTATE ScriptState)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::OnEnterScript
|
|
//
|
|
// Unsupported, returns S_OK.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::OnEnterScript(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// CActiveScriptEngine::OnLeaveScript
|
|
//
|
|
// Unsupported, returns S_OK.
|
|
|
|
STDMETHODIMP CActiveScriptEngine::OnLeaveScript(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|