1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/dlls/msscript.ocx/msscript.c
Gabriel Ivăncescu 4aaaae1586 msscript.ocx: Add the ScriptError stub implementation.
The error object has to be separate from the control, as it can be referenced
while the control is released. It is also available even without a script
host, and in fact the same object will be used (same address) when a host
is instantiated.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
2020-08-25 10:28:25 +02:00

3923 lines
109 KiB
C

/*
* Copyright 2015 Jacek Caban for CodeWeavers
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "windows.h"
#include "initguid.h"
#include "dispex.h"
#include "ole2.h"
#include "olectl.h"
#include "objsafe.h"
#include "activscp.h"
#include "rpcproxy.h"
#include "msscript.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
#include "wine/debug.h"
#include "wine/heap.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(msscript);
#ifdef _WIN64
#define IActiveScriptParse_Release IActiveScriptParse64_Release
#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
#else
#define IActiveScriptParse_Release IActiveScriptParse32_Release
#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
#endif
struct ScriptControl;
typedef struct ConnectionPoint ConnectionPoint;
typedef struct ScriptProcedureCollection ScriptProcedureCollection;
typedef struct ScriptHost ScriptHost;
struct ConnectionPoint {
IConnectionPoint IConnectionPoint_iface;
ScriptControl *control;
const IID *riid;
ConnectionPoint *next;
};
struct named_item {
struct list entry;
BSTR name;
IDispatch *disp;
};
struct module_enum {
IEnumVARIANT IEnumVARIANT_iface;
LONG ref;
UINT pos;
ScriptHost *host;
ScriptControl *control;
};
typedef struct {
IScriptModule IScriptModule_iface;
LONG ref;
BSTR name;
ScriptHost *host;
IDispatch *script_dispatch;
ITypeInfo *script_typeinfo;
ITypeComp *script_typecomp;
ScriptProcedureCollection *procedures;
} ScriptModule;
typedef struct {
IScriptProcedure IScriptProcedure_iface;
LONG ref;
ULONG hash;
struct list entry;
BSTR name;
USHORT num_args;
VARTYPE ret_type;
} ScriptProcedure;
struct ScriptProcedureCollection {
IScriptProcedureCollection IScriptProcedureCollection_iface;
LONG ref;
LONG count;
ScriptModule *module;
struct list hash_table[43];
};
struct procedure_enum {
IEnumVARIANT IEnumVARIANT_iface;
LONG ref;
WORD pos;
WORD count;
ScriptProcedureCollection *procedures;
};
typedef struct {
IScriptError IScriptError_iface;
LONG ref;
} ScriptError;
struct ScriptHost {
IActiveScriptSite IActiveScriptSite_iface;
IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
IServiceProvider IServiceProvider_iface;
LONG ref;
IActiveScript *script;
IActiveScriptParse *parse;
SCRIPTSTATE script_state;
CLSID clsid;
unsigned int module_count;
struct list named_items;
};
struct ScriptControl {
IScriptControl IScriptControl_iface;
IPersistStreamInit IPersistStreamInit_iface;
IOleObject IOleObject_iface;
IOleControl IOleControl_iface;
IQuickActivate IQuickActivate_iface;
IViewObjectEx IViewObjectEx_iface;
IPointerInactive IPointerInactive_iface;
IConnectionPointContainer IConnectionPointContainer_iface;
LONG ref;
IOleClientSite *site;
SIZEL extent;
LONG timeout;
VARIANT_BOOL allow_ui;
VARIANT_BOOL use_safe_subset;
/* connection points */
ConnectionPoint *cp_list;
ConnectionPoint cp_scsource;
ConnectionPoint cp_propnotif;
/* IViewObject sink */
IAdviseSink *view_sink;
DWORD view_sink_flags;
/* modules */
ScriptModule **modules;
IScriptModuleCollection IScriptModuleCollection_iface;
ScriptHost *host;
ScriptError *error;
};
static HINSTANCE msscript_instance;
typedef enum tid_t {
IScriptControl_tid,
IScriptError_tid,
IScriptModuleCollection_tid,
IScriptModule_tid,
IScriptProcedureCollection_tid,
IScriptProcedure_tid,
LAST_tid
} tid_t;
static ITypeLib *typelib;
static ITypeInfo *typeinfos[LAST_tid];
static REFIID tid_ids[] = {
&IID_IScriptControl,
&IID_IScriptError,
&IID_IScriptModuleCollection,
&IID_IScriptModule,
&IID_IScriptProcedureCollection,
&IID_IScriptProcedure
};
static HRESULT load_typelib(void)
{
HRESULT hres;
ITypeLib *tl;
hres = LoadRegTypeLib(&LIBID_MSScriptControl, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
if(FAILED(hres)) {
ERR("LoadRegTypeLib failed: %08x\n", hres);
return hres;
}
if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
ITypeLib_Release(tl);
return hres;
}
static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
{
HRESULT hres;
if (!typelib)
hres = load_typelib();
if (!typelib)
return hres;
if(!typeinfos[tid]) {
ITypeInfo *ti;
hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
if(FAILED(hres)) {
ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
return hres;
}
if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
ITypeInfo_Release(ti);
}
*typeinfo = typeinfos[tid];
ITypeInfo_AddRef(typeinfos[tid]);
return S_OK;
}
static void release_typelib(void)
{
unsigned i;
if(!typelib)
return;
for(i = 0; i < ARRAY_SIZE(typeinfos); i++)
if(typeinfos[i])
ITypeInfo_Release(typeinfos[i]);
ITypeLib_Release(typelib);
}
static inline BOOL is_power_of_2(unsigned x)
{
return !(x & (x - 1));
}
static void clear_named_items(ScriptHost *host)
{
struct named_item *item, *item1;
LIST_FOR_EACH_ENTRY_SAFE(item, item1, &host->named_items, struct named_item, entry) {
list_remove(&item->entry);
SysFreeString(item->name);
IDispatch_Release(item->disp);
heap_free(item);
}
}
static struct named_item *host_get_named_item(ScriptHost *host, const WCHAR *nameW)
{
struct named_item *item;
LIST_FOR_EACH_ENTRY(item, &host->named_items, struct named_item, entry) {
if (!wcscmp(item->name, nameW))
return item;
}
return NULL;
}
static HRESULT get_script_dispatch(ScriptModule *module, IDispatch **disp)
{
if (!module->script_dispatch)
{
HRESULT hr = IActiveScript_GetScriptDispatch(module->host->script,
module->name, &module->script_dispatch);
if (FAILED(hr)) return hr;
}
*disp = module->script_dispatch;
return S_OK;
}
static HRESULT get_script_typeinfo(ScriptModule *module, ITypeInfo **typeinfo)
{
IDispatch *disp;
HRESULT hr;
if (!module->script_typeinfo)
{
hr = get_script_dispatch(module, &disp);
if (FAILED(hr)) return hr;
hr = IDispatch_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &module->script_typeinfo);
if (FAILED(hr)) return hr;
}
*typeinfo = module->script_typeinfo;
return S_OK;
}
static HRESULT get_script_typecomp(ScriptModule *module, ITypeInfo *typeinfo, ITypeComp **typecomp)
{
HRESULT hr;
if (!module->script_typecomp)
{
hr = ITypeInfo_QueryInterface(typeinfo, &IID_ITypeComp, (void**)&module->script_typecomp);
if (FAILED(hr)) return hr;
}
*typecomp = module->script_typecomp;
return S_OK;
}
static void uncache_module_objects(ScriptModule *module)
{
if (module->script_dispatch)
{
IDispatch_Release(module->script_dispatch);
module->script_dispatch = NULL;
}
if (module->script_typeinfo)
{
ITypeInfo_Release(module->script_typeinfo);
module->script_typeinfo = NULL;
}
if (module->script_typecomp)
{
ITypeComp_Release(module->script_typecomp);
module->script_typecomp = NULL;
}
if (module->procedures)
module->procedures->count = -1;
}
static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state)
{
HRESULT hr;
hr = IActiveScript_SetScriptState(host->script, state);
if (SUCCEEDED(hr))
host->script_state = state;
return hr;
}
static HRESULT start_script(ScriptHost *host)
{
HRESULT hr = S_OK;
if (host->script_state != SCRIPTSTATE_STARTED)
hr = set_script_state(host, SCRIPTSTATE_STARTED);
return hr;
}
static HRESULT add_script_object(ScriptHost *host, BSTR name, IDispatch *object, DWORD flags)
{
struct named_item *item;
HRESULT hr;
if (host_get_named_item(host, name))
return E_INVALIDARG;
item = heap_alloc(sizeof(*item));
if (!item)
return E_OUTOFMEMORY;
item->name = SysAllocString(name);
if (!item->name)
{
heap_free(item);
return E_OUTOFMEMORY;
}
IDispatch_AddRef(item->disp = object);
list_add_tail(&host->named_items, &item->entry);
hr = IActiveScript_AddNamedItem(host->script, name, flags);
if (FAILED(hr))
{
list_remove(&item->entry);
IDispatch_Release(item->disp);
SysFreeString(item->name);
heap_free(item);
return hr;
}
return hr;
}
static HRESULT parse_script_text(ScriptModule *module, BSTR script_text, DWORD flag, VARIANT *res)
{
EXCEPINFO excepinfo;
HRESULT hr;
hr = start_script(module->host);
if (FAILED(hr)) return hr;
uncache_module_objects(module);
hr = IActiveScriptParse_ParseScriptText(module->host->parse, script_text, module->name,
NULL, NULL, 0, 1, flag, res, &excepinfo);
/* FIXME: more error handling */
return hr;
}
static HRESULT run_procedure(ScriptModule *module, BSTR procedure_name, SAFEARRAY *args, VARIANT *res)
{
IDispatchEx *dispex;
IDispatch *disp;
DISPPARAMS dp;
DISPID dispid;
HRESULT hr;
UINT i;
hr = start_script(module->host);
if (FAILED(hr)) return hr;
hr = get_script_dispatch(module, &disp);
if (FAILED(hr)) return hr;
hr = IDispatch_GetIDsOfNames(disp, &IID_NULL, &procedure_name, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) return hr;
dp.cArgs = args->rgsabound[0].cElements;
dp.rgdispidNamedArgs = NULL;
dp.cNamedArgs = 0;
dp.rgvarg = heap_alloc(dp.cArgs * sizeof(*dp.rgvarg));
if (!dp.rgvarg) return E_OUTOFMEMORY;
hr = SafeArrayLock(args);
if (SUCCEEDED(hr))
{
/* The DISPPARAMS are stored in reverse order */
for (i = 0; i < dp.cArgs; i++)
dp.rgvarg[i] = *(VARIANT*)((char*)(args->pvData) + (dp.cArgs - i - 1) * args->cbElements);
SafeArrayUnlock(args);
hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if (FAILED(hr))
{
hr = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, &dp, res, NULL, NULL);
}
else
{
hr = IDispatchEx_InvokeEx(dispex, dispid, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, &dp, res, NULL, NULL);
IDispatchEx_Release(dispex);
}
}
heap_free(dp.rgvarg);
return hr;
}
static inline ScriptControl *impl_from_IScriptControl(IScriptControl *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IScriptControl_iface);
}
static inline ScriptControl *impl_from_IOleObject(IOleObject *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IOleObject_iface);
}
static inline ScriptControl *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IPersistStreamInit_iface);
}
static inline ScriptControl *impl_from_IOleControl(IOleControl *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IOleControl_iface);
}
static inline ScriptControl *impl_from_IQuickActivate(IQuickActivate *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IQuickActivate_iface);
}
static inline ScriptControl *impl_from_IViewObjectEx(IViewObjectEx *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IViewObjectEx_iface);
}
static inline ScriptControl *impl_from_IPointerInactive(IPointerInactive *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IPointerInactive_iface);
}
static inline ScriptControl *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IConnectionPointContainer_iface);
}
static inline ScriptProcedure *impl_from_IScriptProcedure(IScriptProcedure *iface)
{
return CONTAINING_RECORD(iface, ScriptProcedure, IScriptProcedure_iface);
}
static inline ScriptProcedureCollection *impl_from_IScriptProcedureCollection(IScriptProcedureCollection *iface)
{
return CONTAINING_RECORD(iface, ScriptProcedureCollection, IScriptProcedureCollection_iface);
}
static inline ScriptControl *impl_from_IScriptModuleCollection(IScriptModuleCollection *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IScriptModuleCollection_iface);
}
static inline ScriptModule *impl_from_IScriptModule(IScriptModule *iface)
{
return CONTAINING_RECORD(iface, ScriptModule, IScriptModule_iface);
}
static inline ScriptError *impl_from_IScriptError(IScriptError *iface)
{
return CONTAINING_RECORD(iface, ScriptError, IScriptError_iface);
}
static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
{
return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
}
static inline ScriptHost *impl_from_IActiveScriptSite(IActiveScriptSite *iface)
{
return CONTAINING_RECORD(iface, ScriptHost, IActiveScriptSite_iface);
}
static inline ScriptHost *impl_from_IActiveScriptSiteWindow(IActiveScriptSiteWindow *iface)
{
return CONTAINING_RECORD(iface, ScriptHost, IActiveScriptSiteWindow_iface);
}
static inline ScriptHost *impl_from_IServiceProvider(IServiceProvider *iface)
{
return CONTAINING_RECORD(iface, ScriptHost, IServiceProvider_iface);
}
static inline struct module_enum *module_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
{
return CONTAINING_RECORD(iface, struct module_enum, IEnumVARIANT_iface);
}
static inline struct procedure_enum *procedure_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
{
return CONTAINING_RECORD(iface, struct procedure_enum, IEnumVARIANT_iface);
}
/* IActiveScriptSite */
static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = &This->IActiveScriptSite_iface;
}else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) {
TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This, ppv);
*ppv = &This->IActiveScriptSite_iface;
}else if(IsEqualGUID(&IID_IActiveScriptSiteWindow, riid)) {
TRACE("(%p)->(IID_IActiveScriptSiteWindow %p)\n", This, ppv);
*ppv = &This->IActiveScriptSiteWindow_iface;
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
*ppv = &This->IServiceProvider_iface;
}else {
FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
clear_named_items(This);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *lcid)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
TRACE("(%p, %p)\n", This, lcid);
*lcid = GetUserDefaultLCID();
return S_OK;
}
static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, DWORD mask,
IUnknown **unk, ITypeInfo **ti)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
struct named_item *item;
TRACE("(%p, %s, %#x, %p, %p)\n", This, debugstr_w(name), mask, unk, ti);
item = host_get_named_item(This, name);
if (!item)
return TYPE_E_ELEMENTNOTFOUND;
if (mask != SCRIPTINFO_IUNKNOWN) {
FIXME("mask %#x is not supported\n", mask);
return E_NOTIMPL;
}
*unk = (IUnknown*)item->disp;
IUnknown_AddRef(*unk);
return S_OK;
}
static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *version)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
FIXME("(%p, %p)\n", This, version);
return E_NOTIMPL;
}
static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface, const VARIANT *result,
const EXCEPINFO *ei)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
FIXME("(%p, %s, %p)\n", This, debugstr_variant(result), ei);
return E_NOTIMPL;
}
static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE state)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
FIXME("(%p, %d)\n", This, state);
return E_NOTIMPL;
}
static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *script_error)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
FIXME("(%p, %p)\n", This, script_error);
return E_NOTIMPL;
}
static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
ActiveScriptSite_QueryInterface,
ActiveScriptSite_AddRef,
ActiveScriptSite_Release,
ActiveScriptSite_GetLCID,
ActiveScriptSite_GetItemInfo,
ActiveScriptSite_GetDocVersionString,
ActiveScriptSite_OnScriptTerminate,
ActiveScriptSite_OnStateChange,
ActiveScriptSite_OnScriptError,
ActiveScriptSite_OnEnterScript,
ActiveScriptSite_OnLeaveScript
};
/* IActiveScriptSiteWindow */
static HRESULT WINAPI ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow *iface, REFIID riid, void **obj)
{
ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, obj);
}
static ULONG WINAPI ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow *iface)
{
ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface);
}
static ULONG WINAPI ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow *iface)
{
ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
return IActiveScriptSite_Release(&This->IActiveScriptSite_iface);
}
static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *iface, HWND *hwnd)
{
ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
FIXME("(%p, %p)\n", This, hwnd);
return E_NOTIMPL;
}
static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow *iface, BOOL enable)
{
ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
FIXME("(%p, %d)\n", This, enable);
return E_NOTIMPL;
}
static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = {
ActiveScriptSiteWindow_QueryInterface,
ActiveScriptSiteWindow_AddRef,
ActiveScriptSiteWindow_Release,
ActiveScriptSiteWindow_GetWindow,
ActiveScriptSiteWindow_EnableModeless
};
/* IServiceProvider */
static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj)
{
ScriptHost *This = impl_from_IServiceProvider(iface);
return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, obj);
}
static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
{
ScriptHost *This = impl_from_IServiceProvider(iface);
return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface);
}
static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
{
ScriptHost *This = impl_from_IServiceProvider(iface);
return IActiveScriptSite_Release(&This->IActiveScriptSite_iface);
}
static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID service,
REFIID riid, void **obj)
{
ScriptHost *This = impl_from_IServiceProvider(iface);
FIXME("(%p)->(%s %s %p)\n", This, debugstr_guid(service), debugstr_guid(riid), obj);
return E_NOTIMPL;
}
static const IServiceProviderVtbl ServiceProviderVtbl = {
ServiceProvider_QueryInterface,
ServiceProvider_AddRef,
ServiceProvider_Release,
ServiceProvider_QueryService
};
static HRESULT WINAPI ScriptProcedure_QueryInterface(IScriptProcedure *iface, REFIID riid, void **ppv)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&IID_IScriptProcedure, riid))
{
*ppv = &This->IScriptProcedure_iface;
}
else
{
WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ScriptProcedure_AddRef(IScriptProcedure *iface)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI ScriptProcedure_Release(IScriptProcedure *iface)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
{
list_remove(&This->entry);
SysFreeString(This->name);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI ScriptProcedure_GetTypeInfoCount(IScriptProcedure *iface, UINT *pctinfo)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
TRACE("(%p)->(%p)\n", This, pctinfo);
*pctinfo = 1;
return S_OK;
}
static HRESULT WINAPI ScriptProcedure_GetTypeInfo(IScriptProcedure *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
return get_typeinfo(IScriptProcedure_tid, ppTInfo);
}
static HRESULT WINAPI ScriptProcedure_GetIDsOfNames(IScriptProcedure *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
hr = get_typeinfo(IScriptProcedure_tid, &typeinfo);
if (SUCCEEDED(hr))
{
hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptProcedure_Invoke(IScriptProcedure *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
hr = get_typeinfo(IScriptProcedure_tid, &typeinfo);
if(SUCCEEDED(hr))
{
hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptProcedure_get_Name(IScriptProcedure *iface, BSTR *pbstrName)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
TRACE("(%p)->(%p)\n", This, pbstrName);
if (!pbstrName) return E_POINTER;
*pbstrName = SysAllocString(This->name);
return *pbstrName ? S_OK : E_OUTOFMEMORY;
}
static HRESULT WINAPI ScriptProcedure_get_NumArgs(IScriptProcedure *iface, LONG *pcArgs)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
TRACE("(%p)->(%p)\n", This, pcArgs);
if (!pcArgs) return E_POINTER;
*pcArgs = This->num_args;
return S_OK;
}
static HRESULT WINAPI ScriptProcedure_get_HasReturnValue(IScriptProcedure *iface, VARIANT_BOOL *pfHasReturnValue)
{
ScriptProcedure *This = impl_from_IScriptProcedure(iface);
TRACE("(%p)->(%p)\n", This, pfHasReturnValue);
if (!pfHasReturnValue) return E_POINTER;
*pfHasReturnValue = (This->ret_type == VT_VOID) ? VARIANT_FALSE : VARIANT_TRUE;
return S_OK;
}
static const IScriptProcedureVtbl ScriptProcedureVtbl = {
ScriptProcedure_QueryInterface,
ScriptProcedure_AddRef,
ScriptProcedure_Release,
ScriptProcedure_GetTypeInfoCount,
ScriptProcedure_GetTypeInfo,
ScriptProcedure_GetIDsOfNames,
ScriptProcedure_Invoke,
ScriptProcedure_get_Name,
ScriptProcedure_get_NumArgs,
ScriptProcedure_get_HasReturnValue
};
/* This function always releases the FUNCDESC passed in */
static HRESULT get_script_procedure(ScriptProcedureCollection *procedures, ITypeInfo *typeinfo,
FUNCDESC *desc, IScriptProcedure **procedure)
{
struct list *proc_list;
ScriptProcedure *proc;
ULONG hash;
HRESULT hr;
BSTR str;
UINT len;
hr = ITypeInfo_GetNames(typeinfo, desc->memid, &str, 1, &len);
if (FAILED(hr)) goto done;
len = SysStringLen(str);
hash = LHashValOfNameSys(sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32, LOCALE_USER_DEFAULT, str);
proc_list = &procedures->hash_table[hash % ARRAY_SIZE(procedures->hash_table)];
/* Try to find it in the hash table */
LIST_FOR_EACH_ENTRY(proc, proc_list, ScriptProcedure, entry)
{
if (proc->hash == hash && SysStringLen(proc->name) == len &&
!memcmp(proc->name, str, len * sizeof(*str)))
{
SysFreeString(str);
IScriptProcedure_AddRef(&proc->IScriptProcedure_iface);
*procedure = &proc->IScriptProcedure_iface;
goto done;
}
}
if (!(proc = heap_alloc(sizeof(*proc))))
{
hr = E_OUTOFMEMORY;
SysFreeString(str);
goto done;
}
proc->IScriptProcedure_iface.lpVtbl = &ScriptProcedureVtbl;
proc->ref = 1;
proc->hash = hash;
proc->name = str;
proc->num_args = desc->cParams + desc->cParamsOpt;
proc->ret_type = desc->elemdescFunc.tdesc.vt;
list_add_tail(proc_list, &proc->entry);
*procedure = &proc->IScriptProcedure_iface;
done:
ITypeInfo_ReleaseFuncDesc(typeinfo, desc);
return hr;
}
static HRESULT WINAPI procedure_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
{
struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumVARIANT, riid))
{
*ppv = &This->IEnumVARIANT_iface;
}
else
{
WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI procedure_enum_AddRef(IEnumVARIANT *iface)
{
struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI procedure_enum_Release(IEnumVARIANT *iface)
{
struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
{
IScriptProcedureCollection_Release(&This->procedures->IScriptProcedureCollection_iface);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI procedure_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
{
struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
FUNCDESC *desc;
ITypeInfo *ti;
UINT i, num;
HRESULT hr;
TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
if (!rgVar) return E_POINTER;
if (!This->procedures->module->host) return E_FAIL;
hr = start_script(This->procedures->module->host);
if (FAILED(hr)) return hr;
hr = get_script_typeinfo(This->procedures->module, &ti);
if (FAILED(hr)) return hr;
num = min(celt, This->count - This->pos);
for (i = 0; i < num; i++)
{
hr = ITypeInfo_GetFuncDesc(ti, This->pos + i, &desc);
if (FAILED(hr)) break;
hr = get_script_procedure(This->procedures, ti, desc, (IScriptProcedure**)&V_DISPATCH(rgVar + i));
if (FAILED(hr)) break;
V_VT(rgVar + i) = VT_DISPATCH;
}
if (FAILED(hr))
{
while (i--)
VariantClear(rgVar + i);
if (pCeltFetched) *pCeltFetched = 0;
return hr;
}
This->pos += i;
if (pCeltFetched) *pCeltFetched = i;
return i == celt ? S_OK : S_FALSE;
}
static HRESULT WINAPI procedure_enum_Skip(IEnumVARIANT *iface, ULONG celt)
{
struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
TRACE("(%p)->(%u)\n", This, celt);
if (This->count - This->pos < celt)
{
This->pos = This->count;
return S_FALSE;
}
This->pos += celt;
return S_OK;
}
static HRESULT WINAPI procedure_enum_Reset(IEnumVARIANT *iface)
{
struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
TRACE("(%p)\n", This);
This->pos = 0;
return S_OK;
}
static HRESULT WINAPI procedure_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
{
struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
struct procedure_enum *clone;
TRACE("(%p)->(%p)\n", This, ppEnum);
if (!ppEnum) return E_POINTER;
if (!(clone = heap_alloc(sizeof(*clone))))
return E_OUTOFMEMORY;
*clone = *This;
clone->ref = 1;
IScriptProcedureCollection_AddRef(&This->procedures->IScriptProcedureCollection_iface);
*ppEnum = &clone->IEnumVARIANT_iface;
return S_OK;
}
static const IEnumVARIANTVtbl procedure_enum_vtbl = {
procedure_enum_QueryInterface,
procedure_enum_AddRef,
procedure_enum_Release,
procedure_enum_Next,
procedure_enum_Skip,
procedure_enum_Reset,
procedure_enum_Clone
};
static HRESULT WINAPI ScriptProcedureCollection_QueryInterface(IScriptProcedureCollection *iface, REFIID riid, void **ppv)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&IID_IScriptProcedureCollection, riid))
{
*ppv = &This->IScriptProcedureCollection_iface;
}
else
{
WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ScriptProcedureCollection_AddRef(IScriptProcedureCollection *iface)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI ScriptProcedureCollection_Release(IScriptProcedureCollection *iface)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
LONG ref = InterlockedDecrement(&This->ref);
UINT i;
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
{
/* Unlink any dangling items from the hash table */
for (i = 0; i < ARRAY_SIZE(This->hash_table); i++)
list_remove(&This->hash_table[i]);
This->module->procedures = NULL;
IScriptModule_Release(&This->module->IScriptModule_iface);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI ScriptProcedureCollection_GetTypeInfoCount(IScriptProcedureCollection *iface, UINT *pctinfo)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
TRACE("(%p)->(%p)\n", This, pctinfo);
*pctinfo = 1;
return S_OK;
}
static HRESULT WINAPI ScriptProcedureCollection_GetTypeInfo(IScriptProcedureCollection *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
return get_typeinfo(IScriptProcedureCollection_tid, ppTInfo);
}
static HRESULT WINAPI ScriptProcedureCollection_GetIDsOfNames(IScriptProcedureCollection *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
hr = get_typeinfo(IScriptProcedureCollection_tid, &typeinfo);
if (SUCCEEDED(hr))
{
hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptProcedureCollection_Invoke(IScriptProcedureCollection *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
hr = get_typeinfo(IScriptProcedureCollection_tid, &typeinfo);
if(SUCCEEDED(hr))
{
hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptProcedureCollection_get__NewEnum(IScriptProcedureCollection *iface, IUnknown **ppenumProcedures)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
struct procedure_enum *proc_enum;
TYPEATTR *attr;
ITypeInfo *ti;
UINT count;
HRESULT hr;
TRACE("(%p)->(%p)\n", This, ppenumProcedures);
if (!ppenumProcedures) return E_POINTER;
if (!This->module->host) return E_FAIL;
hr = start_script(This->module->host);
if (FAILED(hr)) return hr;
hr = get_script_typeinfo(This->module, &ti);
if (FAILED(hr)) return hr;
hr = ITypeInfo_GetTypeAttr(ti, &attr);
if (FAILED(hr)) return hr;
count = attr->cFuncs;
ITypeInfo_ReleaseTypeAttr(ti, attr);
if (!(proc_enum = heap_alloc(sizeof(*proc_enum))))
return E_OUTOFMEMORY;
proc_enum->IEnumVARIANT_iface.lpVtbl = &procedure_enum_vtbl;
proc_enum->ref = 1;
proc_enum->pos = 0;
proc_enum->count = count;
proc_enum->procedures = This;
IScriptProcedureCollection_AddRef(&This->IScriptProcedureCollection_iface);
*ppenumProcedures = (IUnknown*)&proc_enum->IEnumVARIANT_iface;
return S_OK;
}
static HRESULT WINAPI ScriptProcedureCollection_get_Item(IScriptProcedureCollection *iface, VARIANT index,
IScriptProcedure **ppdispProcedure)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
ITypeInfo *typeinfo;
FUNCDESC *desc;
HRESULT hr;
TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppdispProcedure);
if (!ppdispProcedure) return E_POINTER;
if (!This->module->host) return E_FAIL;
hr = start_script(This->module->host);
if (FAILED(hr)) return hr;
hr = get_script_typeinfo(This->module, &typeinfo);
if (FAILED(hr)) return hr;
if (V_VT(&index) == VT_BSTR)
{
struct list *proc_list;
ScriptProcedure *proc;
ITypeComp *comp;
BINDPTR bindptr;
DESCKIND kind;
ULONG hash;
UINT len;
len = SysStringLen(V_BSTR(&index));
hash = LHashValOfNameSys(sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32, LOCALE_USER_DEFAULT, V_BSTR(&index));
proc_list = &This->hash_table[hash % ARRAY_SIZE(This->hash_table)];
/* Try to find it in the hash table */
LIST_FOR_EACH_ENTRY(proc, proc_list, ScriptProcedure, entry)
{
if (proc->hash == hash && SysStringLen(proc->name) == len &&
!memcmp(proc->name, V_BSTR(&index), len * sizeof(WCHAR)))
{
IScriptProcedure_AddRef(&proc->IScriptProcedure_iface);
*ppdispProcedure = &proc->IScriptProcedure_iface;
return S_OK;
}
}
hr = get_script_typecomp(This->module, typeinfo, &comp);
if (FAILED(hr)) return hr;
hr = ITypeComp_Bind(comp, V_BSTR(&index), hash, INVOKE_FUNC, &typeinfo, &kind, &bindptr);
if (FAILED(hr)) return hr;
switch (kind)
{
case DESCKIND_FUNCDESC:
hr = get_script_procedure(This, typeinfo, bindptr.lpfuncdesc, ppdispProcedure);
ITypeInfo_Release(typeinfo);
return hr;
case DESCKIND_IMPLICITAPPOBJ:
case DESCKIND_VARDESC:
ITypeInfo_ReleaseVarDesc(typeinfo, bindptr.lpvardesc);
ITypeInfo_Release(typeinfo);
break;
case DESCKIND_TYPECOMP:
ITypeComp_Release(bindptr.lptcomp);
break;
default:
break;
}
return CTL_E_ILLEGALFUNCTIONCALL;
}
hr = VariantChangeType(&index, &index, 0, VT_INT);
if (FAILED(hr)) return hr;
if (V_INT(&index) <= 0) return 0x800a0009;
hr = ITypeInfo_GetFuncDesc(typeinfo, V_INT(&index) - 1, &desc);
if (FAILED(hr)) return hr;
return get_script_procedure(This, typeinfo, desc, ppdispProcedure);
}
static HRESULT WINAPI ScriptProcedureCollection_get_Count(IScriptProcedureCollection *iface, LONG *plCount)
{
ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
TYPEATTR *attr;
ITypeInfo *ti;
HRESULT hr;
TRACE("(%p)->(%p)\n", This, plCount);
if (!plCount) return E_POINTER;
if (!This->module->host) return E_FAIL;
hr = start_script(This->module->host);
if (FAILED(hr)) return hr;
if (This->count == -1)
{
hr = get_script_typeinfo(This->module, &ti);
if (FAILED(hr)) return hr;
hr = ITypeInfo_GetTypeAttr(ti, &attr);
if (FAILED(hr)) return hr;
This->count = attr->cFuncs;
ITypeInfo_ReleaseTypeAttr(ti, attr);
}
*plCount = This->count;
return S_OK;
}
static const IScriptProcedureCollectionVtbl ScriptProcedureCollectionVtbl = {
ScriptProcedureCollection_QueryInterface,
ScriptProcedureCollection_AddRef,
ScriptProcedureCollection_Release,
ScriptProcedureCollection_GetTypeInfoCount,
ScriptProcedureCollection_GetTypeInfo,
ScriptProcedureCollection_GetIDsOfNames,
ScriptProcedureCollection_Invoke,
ScriptProcedureCollection_get__NewEnum,
ScriptProcedureCollection_get_Item,
ScriptProcedureCollection_get_Count
};
static void detach_script_host(ScriptHost *host)
{
if (--host->module_count)
return;
if (host->script) {
IActiveScript_Close(host->script);
IActiveScript_Release(host->script);
}
if (host->parse)
IActiveScriptParse_Release(host->parse);
host->parse = NULL;
host->script = NULL;
}
static void detach_module(ScriptModule *module)
{
ScriptHost *host = module->host;
if (host) {
module->host = NULL;
detach_script_host(host);
IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
}
}
static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv)
{
ScriptModule *This = impl_from_IScriptModule(iface);
if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&IID_IScriptModule, riid))
{
*ppv = &This->IScriptModule_iface;
}
else
{
WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ScriptModule_AddRef(IScriptModule *iface)
{
ScriptModule *This = impl_from_IScriptModule(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI ScriptModule_Release(IScriptModule *iface)
{
ScriptModule *This = impl_from_IScriptModule(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
{
detach_module(This);
SysFreeString(This->name);
uncache_module_objects(This);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI ScriptModule_GetTypeInfoCount(IScriptModule *iface, UINT *pctinfo)
{
ScriptModule *This = impl_from_IScriptModule(iface);
TRACE("(%p)->(%p)\n", This, pctinfo);
*pctinfo = 1;
return S_OK;
}
static HRESULT WINAPI ScriptModule_GetTypeInfo(IScriptModule *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
{
ScriptModule *This = impl_from_IScriptModule(iface);
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
return get_typeinfo(IScriptModule_tid, ppTInfo);
}
static HRESULT WINAPI ScriptModule_GetIDsOfNames(IScriptModule *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
ScriptModule *This = impl_from_IScriptModule(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
hr = get_typeinfo(IScriptModule_tid, &typeinfo);
if (SUCCEEDED(hr))
{
hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptModule_Invoke(IScriptModule *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ScriptModule *This = impl_from_IScriptModule(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
hr = get_typeinfo(IScriptModule_tid, &typeinfo);
if(SUCCEEDED(hr))
{
hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptModule_get_Name(IScriptModule *iface, BSTR *pbstrName)
{
ScriptModule *This = impl_from_IScriptModule(iface);
TRACE("(%p)->(%p)\n", This, pbstrName);
if (!pbstrName) return E_POINTER;
if (!This->host) return E_FAIL;
*pbstrName = SysAllocString(This->name ? This->name : L"Global");
return *pbstrName ? S_OK : E_OUTOFMEMORY;
}
static HRESULT WINAPI ScriptModule_get_CodeObject(IScriptModule *iface, IDispatch **ppdispObject)
{
ScriptModule *This = impl_from_IScriptModule(iface);
HRESULT hr;
TRACE("(%p)->(%p)\n", This, ppdispObject);
if (!This->host) return E_FAIL;
hr = start_script(This->host);
if (FAILED(hr)) return hr;
hr = get_script_dispatch(This, ppdispObject);
if (FAILED(hr)) return hr;
IDispatch_AddRef(*ppdispObject);
return hr;
}
static HRESULT WINAPI ScriptModule_get_Procedures(IScriptModule *iface, IScriptProcedureCollection **ppdispProcedures)
{
ScriptModule *This = impl_from_IScriptModule(iface);
TRACE("(%p)->(%p)\n", This, ppdispProcedures);
if (!This->host)
return E_FAIL;
if (This->procedures)
IScriptProcedureCollection_AddRef(&This->procedures->IScriptProcedureCollection_iface);
else
{
ScriptProcedureCollection *procs;
UINT i;
if (!(procs = heap_alloc(sizeof(*procs))))
return E_OUTOFMEMORY;
procs->IScriptProcedureCollection_iface.lpVtbl = &ScriptProcedureCollectionVtbl;
procs->ref = 1;
procs->count = -1;
procs->module = This;
for (i = 0; i < ARRAY_SIZE(procs->hash_table); i++)
list_init(&procs->hash_table[i]);
This->procedures = procs;
IScriptModule_AddRef(&This->IScriptModule_iface);
}
*ppdispProcedures = &This->procedures->IScriptProcedureCollection_iface;
return S_OK;
}
static HRESULT WINAPI ScriptModule_AddCode(IScriptModule *iface, BSTR code)
{
ScriptModule *This = impl_from_IScriptModule(iface);
TRACE("(%p)->(%s)\n", This, debugstr_w(code));
if (!This->host)
return E_FAIL;
return parse_script_text(This, code, SCRIPTTEXT_ISVISIBLE, NULL);
}
static HRESULT WINAPI ScriptModule_Eval(IScriptModule *iface, BSTR expression, VARIANT *res)
{
ScriptModule *This = impl_from_IScriptModule(iface);
TRACE("(%p)->(%s, %p)\n", This, debugstr_w(expression), res);
if (!res)
return E_POINTER;
V_VT(res) = VT_EMPTY;
if (!This->host)
return E_FAIL;
return parse_script_text(This, expression, SCRIPTTEXT_ISEXPRESSION, res);
}
static HRESULT WINAPI ScriptModule_ExecuteStatement(IScriptModule *iface, BSTR statement)
{
ScriptModule *This = impl_from_IScriptModule(iface);
TRACE("(%p)->(%s)\n", This, debugstr_w(statement));
if (!This->host)
return E_FAIL;
return parse_script_text(This, statement, 0, NULL);
}
static HRESULT WINAPI ScriptModule_Run(IScriptModule *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
{
ScriptModule *This = impl_from_IScriptModule(iface);
SAFEARRAY *sa;
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
if (!parameters || !res) return E_POINTER;
if (!(sa = *parameters)) return E_POINTER;
V_VT(res) = VT_EMPTY;
if (sa->cDims == 0) return DISP_E_BADINDEX;
if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
if (!This->host) return E_FAIL;
return run_procedure(This, procedure_name, sa, res);
}
static const IScriptModuleVtbl ScriptModuleVtbl = {
ScriptModule_QueryInterface,
ScriptModule_AddRef,
ScriptModule_Release,
ScriptModule_GetTypeInfoCount,
ScriptModule_GetTypeInfo,
ScriptModule_GetIDsOfNames,
ScriptModule_Invoke,
ScriptModule_get_Name,
ScriptModule_get_CodeObject,
ScriptModule_get_Procedures,
ScriptModule_AddCode,
ScriptModule_Eval,
ScriptModule_ExecuteStatement,
ScriptModule_Run
};
static HRESULT WINAPI module_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
{
struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumVARIANT, riid))
{
*ppv = &This->IEnumVARIANT_iface;
}
else
{
WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI module_enum_AddRef(IEnumVARIANT *iface)
{
struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI module_enum_Release(IEnumVARIANT *iface)
{
struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
{
IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
IScriptControl_Release(&This->control->IScriptControl_iface);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI module_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
{
struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
unsigned int i, num;
TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
if (!rgVar) return E_POINTER;
if (This->host != This->control->host) return E_FAIL;
num = min(celt, This->host->module_count - This->pos);
for (i = 0; i < num; i++)
{
V_VT(rgVar + i) = VT_DISPATCH;
V_DISPATCH(rgVar + i) = (IDispatch*)(&This->control->modules[This->pos++]->IScriptModule_iface);
IDispatch_AddRef(V_DISPATCH(rgVar + i));
}
if (pCeltFetched) *pCeltFetched = i;
return i == celt ? S_OK : S_FALSE;
}
static HRESULT WINAPI module_enum_Skip(IEnumVARIANT *iface, ULONG celt)
{
struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
TRACE("(%p)->(%u)\n", This, celt);
if (This->host != This->control->host) return E_FAIL;
if (This->host->module_count - This->pos < celt)
{
This->pos = This->host->module_count;
return S_FALSE;
}
This->pos += celt;
return S_OK;
}
static HRESULT WINAPI module_enum_Reset(IEnumVARIANT *iface)
{
struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
TRACE("(%p)\n", This);
if (This->host != This->control->host) return E_FAIL;
This->pos = 0;
return S_OK;
}
static HRESULT WINAPI module_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
{
struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
struct module_enum *clone;
TRACE("(%p)->(%p)\n", This, ppEnum);
if (!ppEnum) return E_POINTER;
if (This->host != This->control->host) return E_FAIL;
if (!(clone = heap_alloc(sizeof(*clone))))
return E_OUTOFMEMORY;
*clone = *This;
clone->ref = 1;
IActiveScriptSite_AddRef(&This->host->IActiveScriptSite_iface);
IScriptControl_AddRef(&This->control->IScriptControl_iface);
*ppEnum = &clone->IEnumVARIANT_iface;
return S_OK;
}
static const IEnumVARIANTVtbl module_enum_vtbl = {
module_enum_QueryInterface,
module_enum_AddRef,
module_enum_Release,
module_enum_Next,
module_enum_Skip,
module_enum_Reset,
module_enum_Clone
};
static ScriptModule *create_module(ScriptHost *host, BSTR name)
{
ScriptModule *module;
if (!(module = heap_alloc_zero(sizeof(*module)))) return NULL;
module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl;
module->ref = 1;
if (name && !(module->name = SysAllocString(name)))
{
heap_free(module);
return NULL;
}
module->host = host;
IActiveScriptSite_AddRef(&host->IActiveScriptSite_iface);
return module;
}
static void release_modules(ScriptControl *control, BOOL force_detach)
{
unsigned int i, module_count = control->host->module_count;
for (i = 0; i < module_count; i++) {
if (force_detach) detach_module(control->modules[i]);
IScriptModule_Release(&control->modules[i]->IScriptModule_iface);
}
heap_free(control->modules);
}
static ScriptModule *find_module(ScriptControl *control, BSTR name)
{
unsigned int i;
if (!wcsicmp(name, L"Global"))
return control->modules[0];
for (i = 1; i < control->host->module_count; i++)
{
if (!wcsicmp(name, control->modules[i]->name))
return control->modules[i];
}
return NULL;
}
static HRESULT WINAPI ScriptModuleCollection_QueryInterface(IScriptModuleCollection *iface, REFIID riid, void **ppv)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&IID_IScriptModuleCollection, riid))
{
*ppv = &This->IScriptModuleCollection_iface;
}
else
{
WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ScriptModuleCollection_AddRef(IScriptModuleCollection *iface)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
return IScriptControl_AddRef(&This->IScriptControl_iface);
}
static ULONG WINAPI ScriptModuleCollection_Release(IScriptModuleCollection *iface)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
return IScriptControl_Release(&This->IScriptControl_iface);
}
static HRESULT WINAPI ScriptModuleCollection_GetTypeInfoCount(IScriptModuleCollection *iface, UINT *pctinfo)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
TRACE("(%p)->(%p)\n", This, pctinfo);
*pctinfo = 1;
return S_OK;
}
static HRESULT WINAPI ScriptModuleCollection_GetTypeInfo(IScriptModuleCollection *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
return get_typeinfo(IScriptModuleCollection_tid, ppTInfo);
}
static HRESULT WINAPI ScriptModuleCollection_GetIDsOfNames(IScriptModuleCollection *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
hr = get_typeinfo(IScriptModuleCollection_tid, &typeinfo);
if (SUCCEEDED(hr))
{
hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptModuleCollection_Invoke(IScriptModuleCollection *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
hr = get_typeinfo(IScriptModuleCollection_tid, &typeinfo);
if(SUCCEEDED(hr))
{
hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptModuleCollection_get__NewEnum(IScriptModuleCollection *iface, IUnknown **ppenumContexts)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
struct module_enum *module_enum;
TRACE("(%p)->(%p)\n", This, ppenumContexts);
if (!ppenumContexts) return E_POINTER;
if (!This->host) return E_FAIL;
if (!(module_enum = heap_alloc(sizeof(*module_enum))))
return E_OUTOFMEMORY;
module_enum->IEnumVARIANT_iface.lpVtbl = &module_enum_vtbl;
module_enum->ref = 1;
module_enum->pos = 0;
module_enum->host = This->host;
module_enum->control = This;
IActiveScriptSite_AddRef(&This->host->IActiveScriptSite_iface);
IScriptControl_AddRef(&This->IScriptControl_iface);
*ppenumContexts = (IUnknown*)&module_enum->IEnumVARIANT_iface;
return S_OK;
}
static HRESULT WINAPI ScriptModuleCollection_get_Item(IScriptModuleCollection *iface, VARIANT index,
IScriptModule **ppmod)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
ScriptModule *module;
unsigned int i;
HRESULT hr;
TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppmod);
if (!ppmod) return E_POINTER;
if (!This->host) return E_FAIL;
if (V_VT(&index) == VT_BSTR)
{
module = find_module(This, V_BSTR(&index));
if (!module) return CTL_E_ILLEGALFUNCTIONCALL;
}
else
{
hr = VariantChangeType(&index, &index, 0, VT_INT);
if (FAILED(hr)) return hr;
i = V_INT(&index) - 1;
if (i >= This->host->module_count) return 0x800a0009;
module = This->modules[i];
}
*ppmod = &module->IScriptModule_iface;
IScriptModule_AddRef(*ppmod);
return S_OK;
}
static HRESULT WINAPI ScriptModuleCollection_get_Count(IScriptModuleCollection *iface, LONG *plCount)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
TRACE("(%p)->(%p)\n", This, plCount);
if (!plCount) return E_POINTER;
if (!This->host) return E_FAIL;
*plCount = This->host->module_count;
return S_OK;
}
static HRESULT WINAPI ScriptModuleCollection_Add(IScriptModuleCollection *iface, BSTR name,
VARIANT *object, IScriptModule **ppmod)
{
ScriptControl *This = impl_from_IScriptModuleCollection(iface);
ScriptModule *module, **modules;
ScriptHost *host = This->host;
HRESULT hr;
TRACE("(%p)->(%s %s %p)\n", This, wine_dbgstr_w(name), wine_dbgstr_variant(object), ppmod);
if (!ppmod) return E_POINTER;
if (!name || V_VT(object) != VT_DISPATCH) return E_INVALIDARG;
if (!host) return E_FAIL;
if (find_module(This, name)) return E_INVALIDARG;
/* See if we need to grow the array */
if (is_power_of_2(host->module_count))
{
modules = heap_realloc(This->modules, host->module_count * 2 * sizeof(*This->modules));
if (!modules) return E_OUTOFMEMORY;
This->modules = modules;
}
if (!(module = create_module(host, name)))
return E_OUTOFMEMORY;
/* If no object, Windows only calls AddNamedItem without adding a NULL object */
if (V_DISPATCH(object))
hr = add_script_object(host, name, V_DISPATCH(object), 0);
else
hr = IActiveScript_AddNamedItem(host->script, name, SCRIPTITEM_CODEONLY);
if (FAILED(hr))
{
IScriptModule_Release(&module->IScriptModule_iface);
return hr;
}
This->modules[host->module_count++] = module;
*ppmod = &module->IScriptModule_iface;
IScriptModule_AddRef(*ppmod);
return S_OK;
}
static const IScriptModuleCollectionVtbl ScriptModuleCollectionVtbl = {
ScriptModuleCollection_QueryInterface,
ScriptModuleCollection_AddRef,
ScriptModuleCollection_Release,
ScriptModuleCollection_GetTypeInfoCount,
ScriptModuleCollection_GetTypeInfo,
ScriptModuleCollection_GetIDsOfNames,
ScriptModuleCollection_Invoke,
ScriptModuleCollection_get__NewEnum,
ScriptModuleCollection_get_Item,
ScriptModuleCollection_get_Count,
ScriptModuleCollection_Add
};
static HRESULT WINAPI ScriptError_QueryInterface(IScriptError *iface, REFIID riid, void **ppv)
{
ScriptError *This = impl_from_IScriptError(iface);
if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&IID_IScriptError, riid))
{
*ppv = &This->IScriptError_iface;
}
else
{
WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ScriptError_AddRef(IScriptError *iface)
{
ScriptError *This = impl_from_IScriptError(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI ScriptError_Release(IScriptError *iface)
{
ScriptError *This = impl_from_IScriptError(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
{
heap_free(This);
}
return ref;
}
static HRESULT WINAPI ScriptError_GetTypeInfoCount(IScriptError *iface, UINT *pctinfo)
{
ScriptError *This = impl_from_IScriptError(iface);
TRACE("(%p)->(%p)\n", This, pctinfo);
*pctinfo = 1;
return S_OK;
}
static HRESULT WINAPI ScriptError_GetTypeInfo(IScriptError *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
{
ScriptError *This = impl_from_IScriptError(iface);
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
return get_typeinfo(IScriptError_tid, ppTInfo);
}
static HRESULT WINAPI ScriptError_GetIDsOfNames(IScriptError *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
ScriptError *This = impl_from_IScriptError(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
hr = get_typeinfo(IScriptError_tid, &typeinfo);
if (SUCCEEDED(hr))
{
hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptError_Invoke(IScriptError *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ScriptError *This = impl_from_IScriptError(iface);
ITypeInfo *typeinfo;
HRESULT hr;
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
hr = get_typeinfo(IScriptError_tid, &typeinfo);
if(SUCCEEDED(hr))
{
hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
ITypeInfo_Release(typeinfo);
}
return hr;
}
static HRESULT WINAPI ScriptError_get_Number(IScriptError *iface, LONG *plNumber)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->(%p)\n", This, plNumber);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptError_get_Source(IScriptError *iface, BSTR *pbstrSource)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->(%p)\n", This, pbstrSource);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptError_get_Description(IScriptError *iface, BSTR *pbstrDescription)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->(%p)\n", This, pbstrDescription);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptError_get_HelpFile(IScriptError *iface, BSTR *pbstrHelpFile)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->(%p)\n", This, pbstrHelpFile);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptError_get_HelpContext(IScriptError *iface, LONG *plHelpContext)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->(%p)\n", This, plHelpContext);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptError_get_Text(IScriptError *iface, BSTR *pbstrText)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->(%p)\n", This, pbstrText);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptError_get_Line(IScriptError *iface, LONG *plLine)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->(%p)\n", This, plLine);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptError_get_Column(IScriptError *iface, LONG *plColumn)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->(%p)\n", This, plColumn);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptError_Clear(IScriptError *iface)
{
ScriptError *This = impl_from_IScriptError(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static const IScriptErrorVtbl ScriptErrorVtbl = {
ScriptError_QueryInterface,
ScriptError_AddRef,
ScriptError_Release,
ScriptError_GetTypeInfoCount,
ScriptError_GetTypeInfo,
ScriptError_GetIDsOfNames,
ScriptError_Invoke,
ScriptError_get_Number,
ScriptError_get_Source,
ScriptError_get_Description,
ScriptError_get_HelpFile,
ScriptError_get_HelpContext,
ScriptError_get_Text,
ScriptError_get_Line,
ScriptError_get_Column,
ScriptError_Clear
};
static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
{
IObjectSafety *objsafety;
ScriptHost *host;
HRESULT hr;
*ret = NULL;
host = heap_alloc(sizeof(*host));
if (!host)
return E_OUTOFMEMORY;
host->IActiveScriptSite_iface.lpVtbl = &ActiveScriptSiteVtbl;
host->IActiveScriptSiteWindow_iface.lpVtbl = &ActiveScriptSiteWindowVtbl;
host->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
host->ref = 1;
host->script = NULL;
host->parse = NULL;
host->clsid = *clsid;
host->module_count = 1;
list_init(&host->named_items);
hr = CoCreateInstance(&host->clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
&IID_IActiveScript, (void**)&host->script);
if (FAILED(hr)) {
WARN("Failed to create an instance for %s, %#x\n", debugstr_guid(clsid), hr);
goto failed;
}
hr = IActiveScript_QueryInterface(host->script, &IID_IObjectSafety, (void**)&objsafety);
if (FAILED(hr)) {
FIXME("Could not get IObjectSafety, %#x\n", hr);
goto failed;
}
hr = IObjectSafety_SetInterfaceSafetyOptions(objsafety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA, 0);
IObjectSafety_Release(objsafety);
if (FAILED(hr)) {
FIXME("SetInterfaceSafetyOptions failed, %#x\n", hr);
goto failed;
}
hr = IActiveScript_SetScriptSite(host->script, &host->IActiveScriptSite_iface);
if (FAILED(hr)) {
WARN("SetScriptSite failed, %#x\n", hr);
goto failed;
}
hr = IActiveScript_QueryInterface(host->script, &IID_IActiveScriptParse, (void**)&host->parse);
if (FAILED(hr)) {
WARN("Failed to get IActiveScriptParse, %#x\n", hr);
goto failed;
}
hr = IActiveScriptParse_InitNew(host->parse);
if (FAILED(hr)) {
WARN("InitNew failed, %#x\n", hr);
goto failed;
}
host->script_state = SCRIPTSTATE_INITIALIZED;
*ret = host;
return S_OK;
failed:
detach_script_host(host);
return hr;
}
static HRESULT WINAPI ScriptControl_QueryInterface(IScriptControl *iface, REFIID riid, void **ppv)
{
ScriptControl *This = impl_from_IScriptControl(iface);
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = &This->IScriptControl_iface;
}else if(IsEqualGUID(&IID_IDispatch, riid)) {
TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
*ppv = &This->IScriptControl_iface;
}else if(IsEqualGUID(&IID_IScriptControl, riid)) {
TRACE("(%p)->(IID_IScriptControl %p)\n", This, ppv);
*ppv = &This->IScriptControl_iface;
}else if(IsEqualGUID(&IID_IOleObject, riid)) {
TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
*ppv = &This->IOleObject_iface;
}else if(IsEqualGUID(&IID_IPersistStreamInit, riid)) {
TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
*ppv = &This->IPersistStreamInit_iface;
}else if(IsEqualGUID(&IID_IPersist, riid)) {
TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
*ppv = &This->IPersistStreamInit_iface;
}else if(IsEqualGUID(&IID_IOleControl, riid)) {
TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
*ppv = &This->IOleControl_iface;
}else if(IsEqualGUID(&IID_IQuickActivate, riid)) {
TRACE("(%p)->(IID_IQuickActivate %p)\n", This, ppv);
*ppv = &This->IQuickActivate_iface;
}else if(IsEqualGUID(&IID_IViewObject, riid)) {
TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv);
*ppv = &This->IViewObjectEx_iface;
}else if(IsEqualGUID(&IID_IViewObject2, riid)) {
TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv);
*ppv = &This->IViewObjectEx_iface;
}else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
TRACE("(%p)->(IID_IViewObjectEx %p)\n", This, ppv);
*ppv = &This->IViewObjectEx_iface;
}else if(IsEqualGUID(&IID_IPointerInactive, riid)) {
TRACE("(%p)->(IID_IPointerInactive %p)\n", This, ppv);
*ppv = &This->IPointerInactive_iface;
}else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
*ppv = &This->IConnectionPointContainer_iface;
}else {
FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ScriptControl_AddRef(IScriptControl *iface)
{
ScriptControl *This = impl_from_IScriptControl(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
{
ScriptControl *This = impl_from_IScriptControl(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
if (This->site)
IOleClientSite_Release(This->site);
if (This->host)
{
release_modules(This, FALSE);
IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
}
IScriptError_Release(&This->error->IScriptError_iface);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI ScriptControl_GetTypeInfoCount(IScriptControl *iface, UINT *pctinfo)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%p)\n", This, pctinfo);
*pctinfo = 1;
return S_OK;
}
static HRESULT WINAPI ScriptControl_GetTypeInfo(IScriptControl *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
return get_typeinfo(IScriptControl_tid, ppTInfo);
}
static HRESULT WINAPI ScriptControl_GetIDsOfNames(IScriptControl *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
ScriptControl *This = impl_from_IScriptControl(iface);
ITypeInfo *typeinfo;
HRESULT hres;
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
hres = get_typeinfo(IScriptControl_tid, &typeinfo);
if(SUCCEEDED(hres)) {
hres = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
ITypeInfo_Release(typeinfo);
}
return hres;
}
static HRESULT WINAPI ScriptControl_Invoke(IScriptControl *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ScriptControl *This = impl_from_IScriptControl(iface);
ITypeInfo *typeinfo;
HRESULT hres;
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
hres = get_typeinfo(IScriptControl_tid, &typeinfo);
if(SUCCEEDED(hres)) {
hres = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
ITypeInfo_Release(typeinfo);
}
return hres;
}
static HRESULT WINAPI ScriptControl_get_Language(IScriptControl *iface, BSTR *p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
LPOLESTR progidW;
HRESULT hr;
TRACE("(%p)->(%p)\n", This, p);
if (!p)
return E_POINTER;
*p = NULL;
if (!This->host)
return S_OK;
hr = ProgIDFromCLSID(&This->host->clsid, &progidW);
if (FAILED(hr))
return hr;
*p = SysAllocString(progidW);
CoTaskMemFree(progidW);
return *p ? S_OK : E_OUTOFMEMORY;
}
static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR language)
{
ScriptControl *This = impl_from_IScriptControl(iface);
CLSID clsid;
HRESULT hres;
TRACE("(%p)->(%s)\n", This, debugstr_w(language));
if (language && FAILED(CLSIDFromProgID(language, &clsid)))
return CTL_E_INVALIDPROPERTYVALUE;
if (This->host) {
release_modules(This, TRUE);
IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
This->host = NULL;
}
if (!language)
return S_OK;
hres = init_script_host(&clsid, &This->host);
if (FAILED(hres))
return hres;
/* Alloc global module */
This->modules = heap_alloc_zero(sizeof(*This->modules));
if (This->modules) {
This->modules[0] = create_module(This->host, NULL);
if (!This->modules[0]) {
heap_free(This->modules);
This->modules = NULL;
hres = E_OUTOFMEMORY;
}
}
else
hres = E_OUTOFMEMORY;
if (FAILED(hres)) {
detach_script_host(This->host);
This->host = NULL;
}
return hres;
}
static HRESULT WINAPI ScriptControl_get_State(IScriptControl *iface, ScriptControlStates *p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
SCRIPTSTATE state;
HRESULT hres;
TRACE("(%p)->(%p)\n", This, p);
if(!p)
return E_POINTER;
if(!This->host)
return E_FAIL;
hres = IActiveScript_GetScriptState(This->host->script, &state);
if (FAILED(hres)) return hres;
switch (state)
{
case SCRIPTSTATE_INITIALIZED:
case SCRIPTSTATE_STARTED:
*p = Initialized;
break;
case SCRIPTSTATE_CONNECTED:
*p = Connected;
break;
default:
WARN("unexpected state %d\n", state);
return E_FAIL;
}
return S_OK;
}
static HRESULT WINAPI ScriptControl_put_State(IScriptControl *iface, ScriptControlStates state)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%x)\n", This, state);
if(!This->host)
return E_FAIL;
if(state != Initialized && state != Connected)
return CTL_E_INVALIDPROPERTYVALUE;
return IActiveScript_SetScriptState(This->host->script, state == Connected ? SCRIPTSTATE_CONNECTED : SCRIPTSTATE_STARTED);
}
static HRESULT WINAPI ScriptControl_put_SitehWnd(IScriptControl *iface, LONG hwnd)
{
ScriptControl *This = impl_from_IScriptControl(iface);
FIXME("(%p)->(%x)\n", This, hwnd);
return S_OK;
}
static HRESULT WINAPI ScriptControl_get_SitehWnd(IScriptControl *iface, LONG *p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptControl_get_Timeout(IScriptControl *iface, LONG *p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%p)\n", This, p);
if (!p)
return E_POINTER;
*p = This->timeout;
return S_OK;
}
static HRESULT WINAPI ScriptControl_put_Timeout(IScriptControl *iface, LONG timeout)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%d)\n", This, timeout);
if (timeout < -1)
return CTL_E_INVALIDPROPERTYVALUE;
if (timeout != -1)
FIXME("execution timeout ignored\n");
This->timeout = timeout;
return S_OK;
}
static HRESULT WINAPI ScriptControl_get_AllowUI(IScriptControl *iface, VARIANT_BOOL *p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%p)\n", This, p);
if(!p)
return E_POINTER;
*p = This->allow_ui;
return S_OK;
}
static HRESULT WINAPI ScriptControl_put_AllowUI(IScriptControl *iface, VARIANT_BOOL allow_ui)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%x)\n", This, allow_ui);
This->allow_ui = allow_ui;
return S_OK;
}
static HRESULT WINAPI ScriptControl_get_UseSafeSubset(IScriptControl *iface, VARIANT_BOOL *p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%p)\n", This, p);
if(!p)
return E_POINTER;
*p = This->use_safe_subset;
return S_OK;
}
static HRESULT WINAPI ScriptControl_put_UseSafeSubset(IScriptControl *iface, VARIANT_BOOL use_safe_subset)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%x)\n", This, use_safe_subset);
This->use_safe_subset = use_safe_subset;
return S_OK;
}
static HRESULT WINAPI ScriptControl_get_Modules(IScriptControl *iface, IScriptModuleCollection **p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%p)\n", This, p);
if (!This->host) return E_FAIL;
*p = &This->IScriptModuleCollection_iface;
IScriptControl_AddRef(iface);
return S_OK;
}
static HRESULT WINAPI ScriptControl_get_Error(IScriptControl *iface, IScriptError **p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%p)\n", This, p);
if (!p) return E_POINTER;
*p = &This->error->IScriptError_iface;
IScriptError_AddRef(*p);
return S_OK;
}
static HRESULT WINAPI ScriptControl_get_CodeObject(IScriptControl *iface, IDispatch **p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%p)\n", This, p);
if (!This->host) return E_FAIL;
return IScriptModule_get_CodeObject(&This->modules[0]->IScriptModule_iface, p);
}
static HRESULT WINAPI ScriptControl_get_Procedures(IScriptControl *iface, IScriptProcedureCollection **p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%p)\n", This, p);
if (!This->host) return E_FAIL;
return IScriptModule_get_Procedures(&This->modules[0]->IScriptModule_iface, p);
}
static HRESULT WINAPI ScriptControl__AboutBox(IScriptControl *iface)
{
ScriptControl *This = impl_from_IScriptControl(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptControl_AddObject(IScriptControl *iface, BSTR name, IDispatch *object, VARIANT_BOOL add_members)
{
ScriptControl *This = impl_from_IScriptControl(iface);
DWORD flags = SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE;
TRACE("(%p)->(%s %p %x)\n", This, debugstr_w(name), object, add_members);
if (!object)
return E_INVALIDARG;
if (!This->host)
return E_FAIL;
if (add_members)
flags |= SCRIPTITEM_GLOBALMEMBERS;
return add_script_object(This->host, name, object, flags);
}
static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)\n", This);
if (!This->host)
return E_FAIL;
clear_named_items(This->host);
return set_script_state(This->host, SCRIPTSTATE_INITIALIZED);
}
static HRESULT WINAPI ScriptControl_AddCode(IScriptControl *iface, BSTR code)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%s).\n", This, debugstr_w(code));
if (!This->host)
return E_FAIL;
return parse_script_text(This->modules[0], code, SCRIPTTEXT_ISVISIBLE, NULL);
}
static HRESULT WINAPI ScriptControl_Eval(IScriptControl *iface, BSTR expression, VARIANT *res)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%s, %p).\n", This, debugstr_w(expression), res);
if (!res)
return E_POINTER;
V_VT(res) = VT_EMPTY;
if (!This->host)
return E_FAIL;
return parse_script_text(This->modules[0], expression, SCRIPTTEXT_ISEXPRESSION, res);
}
static HRESULT WINAPI ScriptControl_ExecuteStatement(IScriptControl *iface, BSTR statement)
{
ScriptControl *This = impl_from_IScriptControl(iface);
TRACE("(%p)->(%s)\n", This, debugstr_w(statement));
if (!This->host)
return E_FAIL;
return parse_script_text(This->modules[0], statement, 0, NULL);
}
static HRESULT WINAPI ScriptControl_Run(IScriptControl *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
{
ScriptControl *This = impl_from_IScriptControl(iface);
SAFEARRAY *sa;
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
if (!parameters || !res) return E_POINTER;
if (!(sa = *parameters)) return E_POINTER;
V_VT(res) = VT_EMPTY;
if (sa->cDims == 0) return DISP_E_BADINDEX;
if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
if (!This->host) return E_FAIL;
return run_procedure(This->modules[0], procedure_name, sa, res);
}
static const IScriptControlVtbl ScriptControlVtbl = {
ScriptControl_QueryInterface,
ScriptControl_AddRef,
ScriptControl_Release,
ScriptControl_GetTypeInfoCount,
ScriptControl_GetTypeInfo,
ScriptControl_GetIDsOfNames,
ScriptControl_Invoke,
ScriptControl_get_Language,
ScriptControl_put_Language,
ScriptControl_get_State,
ScriptControl_put_State,
ScriptControl_put_SitehWnd,
ScriptControl_get_SitehWnd,
ScriptControl_get_Timeout,
ScriptControl_put_Timeout,
ScriptControl_get_AllowUI,
ScriptControl_put_AllowUI,
ScriptControl_get_UseSafeSubset,
ScriptControl_put_UseSafeSubset,
ScriptControl_get_Modules,
ScriptControl_get_Error,
ScriptControl_get_CodeObject,
ScriptControl_get_Procedures,
ScriptControl__AboutBox,
ScriptControl_AddObject,
ScriptControl_Reset,
ScriptControl_AddCode,
ScriptControl_Eval,
ScriptControl_ExecuteStatement,
ScriptControl_Run
};
static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **obj)
{
ScriptControl *This = impl_from_IOleObject(iface);
return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
}
static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
{
ScriptControl *This = impl_from_IOleObject(iface);
return IScriptControl_AddRef(&This->IScriptControl_iface);
}
static ULONG WINAPI OleObject_Release(IOleObject *iface)
{
ScriptControl *This = impl_from_IOleObject(iface);
return IScriptControl_Release(&This->IScriptControl_iface);
}
static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *site)
{
ScriptControl *This = impl_from_IOleObject(iface);
TRACE("(%p)->(%p)\n", This, site);
if (This->site)
IOleClientSite_Release(This->site);
if ((This->site = site))
IOleClientSite_AddRef(site);
return S_OK;
}
static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **site)
{
ScriptControl *This = impl_from_IOleObject(iface);
TRACE("(%p)->(%p)\n", This, site);
if (!site)
return E_POINTER;
if ((*site = This->site))
IOleClientSite_AddRef(*site);
return S_OK;
}
static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR containerapp, LPCOLESTR containerobj)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%s %s)\n", This, debugstr_w(containerapp), debugstr_w(containerobj));
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD save)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%d)\n", This, save);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD which, IMoniker *moniker)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%d %p)\n", This, which, moniker);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD assign, DWORD which, IMoniker **moniker)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%d %d %p)\n", This, assign, which, moniker);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *dataobj, BOOL creation,
DWORD reserved)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%p %d %d)\n", This, dataobj, creation, reserved);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD reserved, IDataObject **dataobj)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%d %p)\n", This, reserved, dataobj);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG verb, LPMSG msg, IOleClientSite *active_site,
LONG index, HWND hwndParent, LPCRECT rect)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%d %p %p %d %p %p)\n", This, verb, msg, active_site, index, hwndParent, rect);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **enumoleverb)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%p)\n", This, enumoleverb);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_Update(IOleObject *iface)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *clsid)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%p)\n", This, clsid);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD form_of_type, LPOLESTR *usertype)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%d %p)\n", This, form_of_type, usertype);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%d %p)\n", This, aspect, size);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
{
ScriptControl *This = impl_from_IOleObject(iface);
TRACE("(%p)->(%d %p)\n", This, aspect, size);
if (aspect != DVASPECT_CONTENT)
return DV_E_DVASPECT;
*size = This->extent;
return S_OK;
}
static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *sink, DWORD *connection)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%p %p)\n", This, sink, connection);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD connection)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%d)\n", This, connection);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **enumadvise)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%p)\n", This, enumadvise);
return E_NOTIMPL;
}
static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD aspect, DWORD *status)
{
ScriptControl *This = impl_from_IOleObject(iface);
TRACE("(%p)->(%d %p)\n", This, aspect, status);
return OleRegGetMiscStatus(&CLSID_ScriptControl, aspect, status);
}
static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *logpal)
{
ScriptControl *This = impl_from_IOleObject(iface);
FIXME("(%p)->(%p)\n", This, logpal);
return E_NOTIMPL;
}
static const IOleObjectVtbl OleObjectVtbl = {
OleObject_QueryInterface,
OleObject_AddRef,
OleObject_Release,
OleObject_SetClientSite,
OleObject_GetClientSite,
OleObject_SetHostNames,
OleObject_Close,
OleObject_SetMoniker,
OleObject_GetMoniker,
OleObject_InitFromData,
OleObject_GetClipboardData,
OleObject_DoVerb,
OleObject_EnumVerbs,
OleObject_Update,
OleObject_IsUpToDate,
OleObject_GetUserClassID,
OleObject_GetUserType,
OleObject_SetExtent,
OleObject_GetExtent,
OleObject_Advise,
OleObject_Unadvise,
OleObject_EnumAdvise,
OleObject_GetMiscStatus,
OleObject_SetColorScheme
};
static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface, REFIID riid, void **obj)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
}
static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
return IScriptControl_AddRef(&This->IScriptControl_iface);
}
static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
return IScriptControl_Release(&This->IScriptControl_iface);
}
static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *clsid)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
FIXME("(%p)->(%p)\n", This, clsid);
return E_NOTIMPL;
}
static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, IStream *stream)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
FIXME("(%p)->(%p)\n", This, stream);
return E_NOTIMPL;
}
static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, IStream *stream, BOOL clear_dirty)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
FIXME("(%p)->(%p %d)\n", This, stream, clear_dirty);
return E_NOTIMPL;
}
static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, ULARGE_INTEGER *size)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
FIXME("(%p)->(%p)\n", This, size);
return E_NOTIMPL;
}
static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
{
ScriptControl *This = impl_from_IPersistStreamInit(iface);
FIXME("(%p)\n", This);
return S_OK;
}
static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
PersistStreamInit_QueryInterface,
PersistStreamInit_AddRef,
PersistStreamInit_Release,
PersistStreamInit_GetClassID,
PersistStreamInit_IsDirty,
PersistStreamInit_Load,
PersistStreamInit_Save,
PersistStreamInit_GetSizeMax,
PersistStreamInit_InitNew
};
static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **obj)
{
ScriptControl *This = impl_from_IOleControl(iface);
return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
}
static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
{
ScriptControl *This = impl_from_IOleControl(iface);
return IScriptControl_AddRef(&This->IScriptControl_iface);
}
static ULONG WINAPI OleControl_Release(IOleControl *iface)
{
ScriptControl *This = impl_from_IOleControl(iface);
return IScriptControl_Release(&This->IScriptControl_iface);
}
static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *info)
{
ScriptControl *This = impl_from_IOleControl(iface);
TRACE("(%p)->(%p)\n", This, info);
if (!info)
return E_POINTER;
info->hAccel = NULL;
info->cAccel = 0;
return S_OK;
}
static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *msg)
{
ScriptControl *This = impl_from_IOleControl(iface);
FIXME("(%p)->(%p)\n", This, msg);
return E_NOTIMPL;
}
static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispid)
{
ScriptControl *This = impl_from_IOleControl(iface);
FIXME("(%p)->(%#x)\n", This, dispid);
return E_NOTIMPL;
}
static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL freeze)
{
ScriptControl *This = impl_from_IOleControl(iface);
FIXME("(%p)->(%d)\n", This, freeze);
return E_NOTIMPL;
}
static const IOleControlVtbl OleControlVtbl = {
OleControl_QueryInterface,
OleControl_AddRef,
OleControl_Release,
OleControl_GetControlInfo,
OleControl_OnMnemonic,
OleControl_OnAmbientPropertyChange,
OleControl_FreezeEvents
};
static HRESULT WINAPI QuickActivate_QueryInterface(IQuickActivate *iface, REFIID riid, void **obj)
{
ScriptControl *This = impl_from_IQuickActivate(iface);
return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
}
static ULONG WINAPI QuickActivate_AddRef(IQuickActivate *iface)
{
ScriptControl *This = impl_from_IQuickActivate(iface);
return IScriptControl_AddRef(&This->IScriptControl_iface);
}
static ULONG WINAPI QuickActivate_Release(IQuickActivate *iface)
{
ScriptControl *This = impl_from_IQuickActivate(iface);
return IScriptControl_Release(&This->IScriptControl_iface);
}
static HRESULT WINAPI QuickActivate_QuickActivate(IQuickActivate *iface, QACONTAINER *container, QACONTROL *control)
{
ScriptControl *This = impl_from_IQuickActivate(iface);
FIXME("(%p)->(%p %p)\n", This, container, control);
return E_NOTIMPL;
}
static HRESULT WINAPI QuickActivate_SetContentExtent(IQuickActivate *iface, SIZEL *size)
{
ScriptControl *This = impl_from_IQuickActivate(iface);
FIXME("(%p)->(%p)\n", This, size);
return E_NOTIMPL;
}
static HRESULT WINAPI QuickActivate_GetContentExtent(IQuickActivate *iface, SIZEL *size)
{
ScriptControl *This = impl_from_IQuickActivate(iface);
FIXME("(%p)->(%p)\n", This, size);
return E_NOTIMPL;
}
static const IQuickActivateVtbl QuickActivateVtbl = {
QuickActivate_QueryInterface,
QuickActivate_AddRef,
QuickActivate_Release,
QuickActivate_QuickActivate,
QuickActivate_SetContentExtent,
QuickActivate_GetContentExtent
};
static HRESULT WINAPI ViewObject_QueryInterface(IViewObjectEx *iface, REFIID riid, void **obj)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
}
static ULONG WINAPI ViewObject_AddRef(IViewObjectEx *iface)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
return IScriptControl_AddRef(&This->IScriptControl_iface);
}
static ULONG WINAPI ViewObject_Release(IViewObjectEx *iface)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
return IScriptControl_Release(&This->IScriptControl_iface);
}
static HRESULT WINAPI ViewObject_Draw(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
DVTARGETDEVICE *device, HDC target_dev, HDC hdc_draw, const RECTL *bounds, const RECTL *win_bounds,
BOOL (STDMETHODCALLTYPE *fn_continue)(ULONG_PTR cont), ULONG_PTR cont)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d %d %p %p %p %p %p %p %p %lu)\n", This, drawaspect, index, aspect, device, target_dev,
hdc_draw, bounds, win_bounds, fn_continue, cont);
return E_NOTIMPL;
}
static HRESULT WINAPI ViewObject_GetColorSet(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
DVTARGETDEVICE *device, HDC hic_target, LOGPALETTE **colorset)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d %d %p %p %p %p)\n", This, drawaspect, index, aspect, device, hic_target,
colorset);
return E_NOTIMPL;
}
static HRESULT WINAPI ViewObject_Freeze(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
DWORD *freeze)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d %d %p %p)\n", This, drawaspect, index, aspect, freeze);
return E_NOTIMPL;
}
static HRESULT WINAPI ViewObject_Unfreeze(IViewObjectEx *iface, DWORD freeze)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d)\n", This, freeze);
return E_NOTIMPL;
}
static HRESULT WINAPI ViewObject_SetAdvise(IViewObjectEx *iface, DWORD aspects, DWORD flags, IAdviseSink *sink)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
TRACE("(%p)->(%d %#x %p)\n", This, aspects, flags, sink);
if (aspects != DVASPECT_CONTENT)
return DV_E_DVASPECT;
This->view_sink_flags = flags;
if (This->view_sink)
IAdviseSink_Release(This->view_sink);
This->view_sink = sink;
if (This->view_sink)
IAdviseSink_AddRef(This->view_sink);
return S_OK;
}
static HRESULT WINAPI ViewObject_GetAdvise(IViewObjectEx *iface, DWORD *aspects, DWORD *flags, IAdviseSink **sink)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
TRACE("(%p)->(%p %p %p)\n", This, aspects, flags, sink);
if (aspects)
*aspects = DVASPECT_CONTENT;
if (flags)
*flags = This->view_sink_flags;
if (sink) {
*sink = This->view_sink;
if (*sink)
IAdviseSink_AddRef(*sink);
}
return S_OK;
}
static HRESULT WINAPI ViewObject_GetExtent(IViewObjectEx *iface, DWORD draw_aspect, LONG index,
DVTARGETDEVICE *device, SIZEL *size)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d %d %p %p)\n", This, draw_aspect, index, device, size);
return E_NOTIMPL;
}
static HRESULT WINAPI ViewObject_GetRect(IViewObjectEx *iface, DWORD aspect, RECTL *rect)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d %p)\n", This, aspect, rect);
return E_NOTIMPL;
}
static HRESULT WINAPI ViewObject_GetViewStatus(IViewObjectEx *iface, DWORD *status)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
TRACE("(%p)->(%p)\n", This, status);
*status = VIEWSTATUS_OPAQUE;
return S_OK;
}
static HRESULT WINAPI ViewObject_QueryHitPoint(IViewObjectEx *iface, DWORD aspect, const RECT *bounds,
POINT pt, LONG close_hint, DWORD *hit_result)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d %s %s %d %p)\n", This, aspect, wine_dbgstr_rect(bounds), wine_dbgstr_point(&pt), close_hint, hit_result);
return E_NOTIMPL;
}
static HRESULT WINAPI ViewObject_QueryHitRect(IViewObjectEx *iface, DWORD aspect, const RECT *bounds,
const RECT *loc, LONG close_hint, DWORD *hit_result)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d %s %s %d %p)\n", This, aspect, wine_dbgstr_rect(bounds), wine_dbgstr_rect(loc), close_hint, hit_result);
return E_NOTIMPL;
}
static HRESULT WINAPI ViewObject_GetNaturalExtent(IViewObjectEx *iface, DWORD aspect, LONG index,
DVTARGETDEVICE *device, HDC target_hdc, DVEXTENTINFO *extent_info, SIZEL *size)
{
ScriptControl *This = impl_from_IViewObjectEx(iface);
FIXME("(%p)->(%d %d %p %p %p %p)\n", This, aspect, index, device, target_hdc, extent_info, size);
return E_NOTIMPL;
}
static const IViewObjectExVtbl ViewObjectExVtbl = {
ViewObject_QueryInterface,
ViewObject_AddRef,
ViewObject_Release,
ViewObject_Draw,
ViewObject_GetColorSet,
ViewObject_Freeze,
ViewObject_Unfreeze,
ViewObject_SetAdvise,
ViewObject_GetAdvise,
ViewObject_GetExtent,
ViewObject_GetRect,
ViewObject_GetViewStatus,
ViewObject_QueryHitPoint,
ViewObject_QueryHitRect,
ViewObject_GetNaturalExtent
};
static HRESULT WINAPI PointerInactive_QueryInterface(IPointerInactive *iface, REFIID riid, void **obj)
{
ScriptControl *This = impl_from_IPointerInactive(iface);
return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
}
static ULONG WINAPI PointerInactive_AddRef(IPointerInactive *iface)
{
ScriptControl *This = impl_from_IPointerInactive(iface);
return IScriptControl_AddRef(&This->IScriptControl_iface);
}
static ULONG WINAPI PointerInactive_Release(IPointerInactive *iface)
{
ScriptControl *This = impl_from_IPointerInactive(iface);
return IScriptControl_Release(&This->IScriptControl_iface);
}
static HRESULT WINAPI PointerInactive_GetActivationPolicy(IPointerInactive *iface, DWORD *policy)
{
ScriptControl *This = impl_from_IPointerInactive(iface);
TRACE("(%p)->(%p)\n", This, policy);
if (!policy)
return E_POINTER;
*policy = 0;
return S_OK;
}
static HRESULT WINAPI PointerInactive_OnInactiveMouseMove(IPointerInactive *iface, const RECT *bounds,
LONG x, LONG y, DWORD key_state)
{
ScriptControl *This = impl_from_IPointerInactive(iface);
FIXME("(%p)->(%s %d %d %#x)\n", This, wine_dbgstr_rect(bounds), x, y, key_state);
return E_NOTIMPL;
}
static HRESULT WINAPI PointerInactive_OnInactiveSetCursor(IPointerInactive *iface, const RECT *bounds,
LONG x, LONG y, DWORD msg, BOOL set_always)
{
ScriptControl *This = impl_from_IPointerInactive(iface);
FIXME("(%p)->(%s %d %d %#x %d)\n", This, wine_dbgstr_rect(bounds), x, y, msg, set_always);
return E_NOTIMPL;
}
static const IPointerInactiveVtbl PointerInactiveVtbl = {
PointerInactive_QueryInterface,
PointerInactive_AddRef,
PointerInactive_Release,
PointerInactive_GetActivationPolicy,
PointerInactive_OnInactiveMouseMove,
PointerInactive_OnInactiveSetCursor
};
static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, REFIID riid, void **obj)
{
ScriptControl *This = impl_from_IConnectionPointContainer(iface);
return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
}
static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
{
ScriptControl *This = impl_from_IConnectionPointContainer(iface);
return IScriptControl_AddRef(&This->IScriptControl_iface);
}
static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
{
ScriptControl *This = impl_from_IConnectionPointContainer(iface);
return IScriptControl_Release(&This->IScriptControl_iface);
}
static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, IEnumConnectionPoints **enum_points)
{
ScriptControl *This = impl_from_IConnectionPointContainer(iface);
FIXME("(%p)->(%p)\n", This, enum_points);
return E_NOTIMPL;
}
static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, IConnectionPoint **cp)
{
ScriptControl *This = impl_from_IConnectionPointContainer(iface);
ConnectionPoint *iter;
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), cp);
*cp = NULL;
for (iter = This->cp_list; iter; iter = iter->next) {
if (IsEqualIID(iter->riid, riid))
*cp = &iter->IConnectionPoint_iface;
}
if (*cp) {
IConnectionPoint_AddRef(*cp);
return S_OK;
}
FIXME("unsupported connection point %s\n", debugstr_guid(riid));
return CONNECT_E_NOCONNECTION;
}
static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
ConnectionPointContainer_QueryInterface,
ConnectionPointContainer_AddRef,
ConnectionPointContainer_Release,
ConnectionPointContainer_EnumConnectionPoints,
ConnectionPointContainer_FindConnectionPoint
};
static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
REFIID riid, void **ppv)
{
ConnectionPoint *This = impl_from_IConnectionPoint(iface);
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = &This->IConnectionPoint_iface;
}else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
*ppv = &This->IConnectionPoint_iface;
}else {
FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
{
ConnectionPoint *This = impl_from_IConnectionPoint(iface);
return IConnectionPointContainer_AddRef(&This->control->IConnectionPointContainer_iface);
}
static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
{
ConnectionPoint *This = impl_from_IConnectionPoint(iface);
return IConnectionPointContainer_Release(&This->control->IConnectionPointContainer_iface);
}
static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *iid)
{
ConnectionPoint *This = impl_from_IConnectionPoint(iface);
TRACE("(%p)->(%p)\n", This, iid);
*iid = *This->riid;
return S_OK;
}
static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
IConnectionPointContainer **container)
{
ConnectionPoint *This = impl_from_IConnectionPoint(iface);
TRACE("(%p)->(%p)\n", This, container);
if (!container)
return E_POINTER;
*container = &This->control->IConnectionPointContainer_iface;
IConnectionPointContainer_AddRef(*container);
return S_OK;
}
static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *unk_sink,
DWORD *cookie)
{
ConnectionPoint *This = impl_from_IConnectionPoint(iface);
FIXME("(%p)->(%p %p)\n", This, unk_sink, cookie);
return E_NOTIMPL;
}
static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD cookie)
{
ConnectionPoint *This = impl_from_IConnectionPoint(iface);
FIXME("(%p)->(%d)\n", This, cookie);
return E_NOTIMPL;
}
static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
IEnumConnections **ppEnum)
{
ConnectionPoint *This = impl_from_IConnectionPoint(iface);
FIXME("(%p)->(%p): stub\n", This, ppEnum);
return E_NOTIMPL;
}
static const IConnectionPointVtbl ConnectionPointVtbl =
{
ConnectionPoint_QueryInterface,
ConnectionPoint_AddRef,
ConnectionPoint_Release,
ConnectionPoint_GetConnectionInterface,
ConnectionPoint_GetConnectionPointContainer,
ConnectionPoint_Advise,
ConnectionPoint_Unadvise,
ConnectionPoint_EnumConnections
};
static void ConnectionPoint_Init(ConnectionPoint *cp, ScriptControl *sc, REFIID riid)
{
cp->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl;
cp->control = sc;
cp->riid = riid;
cp->next = sc->cp_list;
sc->cp_list = cp;
}
static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
{
ScriptControl *script_control;
DWORD dpi_x, dpi_y;
HRESULT hres;
HDC hdc;
TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
script_control = heap_alloc_zero(sizeof(*script_control));
if(!script_control)
return E_OUTOFMEMORY;
script_control->error = heap_alloc_zero(sizeof(*script_control->error));
if(!script_control->error)
{
heap_free(script_control);
return E_OUTOFMEMORY;
}
script_control->IScriptControl_iface.lpVtbl = &ScriptControlVtbl;
script_control->IPersistStreamInit_iface.lpVtbl = &PersistStreamInitVtbl;
script_control->IOleObject_iface.lpVtbl = &OleObjectVtbl;
script_control->IOleControl_iface.lpVtbl = &OleControlVtbl;
script_control->IQuickActivate_iface.lpVtbl = &QuickActivateVtbl;
script_control->IViewObjectEx_iface.lpVtbl = &ViewObjectExVtbl;
script_control->IPointerInactive_iface.lpVtbl = &PointerInactiveVtbl;
script_control->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
script_control->IScriptModuleCollection_iface.lpVtbl = &ScriptModuleCollectionVtbl;
script_control->ref = 1;
script_control->timeout = 10000;
script_control->allow_ui = VARIANT_TRUE;
script_control->use_safe_subset = VARIANT_FALSE;
script_control->error->IScriptError_iface.lpVtbl = &ScriptErrorVtbl;
script_control->error->ref = 1;
ConnectionPoint_Init(&script_control->cp_scsource, script_control, &DIID_DScriptControlSource);
ConnectionPoint_Init(&script_control->cp_propnotif, script_control, &IID_IPropertyNotifySink);
hdc = GetDC(0);
dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(0, hdc);
script_control->extent.cx = MulDiv(38, 2540, dpi_x);
script_control->extent.cy = MulDiv(38, 2540, dpi_y);
hres = IScriptControl_QueryInterface(&script_control->IScriptControl_iface, riid, ppv);
IScriptControl_Release(&script_control->IScriptControl_iface);
return hres;
}
/******************************************************************
* DllMain (msscript.ocx.@)
*/
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
{
TRACE("(%p %d %p)\n", instance, reason, reserved);
switch(reason) {
case DLL_WINE_PREATTACH:
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
msscript_instance = instance;
DisableThreadLibraryCalls(instance);
break;
case DLL_PROCESS_DETACH:
if(!reserved)
release_typelib();
break;
}
return TRUE;
}
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
*ppv = iface;
}else if(IsEqualGUID(&IID_IClassFactory, riid)) {
TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
*ppv = iface;
}
if(*ppv) {
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
return E_NOINTERFACE;
}
static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
{
TRACE("(%p)\n", iface);
return 2;
}
static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
{
TRACE("(%p)\n", iface);
return 1;
}
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
{
TRACE("(%p)->(%x)\n", iface, fLock);
return S_OK;
}
static const IClassFactoryVtbl ScriptControlFactoryVtbl = {
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
ScriptControl_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory ScriptControlFactory = { &ScriptControlFactoryVtbl };
/***********************************************************************
* DllGetClassObject (msscript.ocx.@)
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
if(IsEqualGUID(&CLSID_ScriptControl, rclsid)) {
TRACE("(CLSID_ScriptControl %s %p)\n", debugstr_guid(riid), ppv);
return IClassFactory_QueryInterface(&ScriptControlFactory, riid, ppv);
}
FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
return CLASS_E_CLASSNOTAVAILABLE;
}
/***********************************************************************
* DllCanUnloadNow (msscript.ocx.@)
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
TRACE("\n");
return S_FALSE;
}
/***********************************************************************
* DllRegisterServer (msscript.ocx.@)
*/
HRESULT WINAPI DllRegisterServer(void)
{
TRACE("()\n");
return __wine_register_resources(msscript_instance);
}
/***********************************************************************
* DllUnregisterServer (msscript.ocx.@)
*/
HRESULT WINAPI DllUnregisterServer(void)
{
TRACE("()\n");
return __wine_unregister_resources(msscript_instance);
}