msscript: Implement AddObject().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2016-07-21 20:34:11 +03:00 committed by Alexandre Julliard
parent 267e8e3eeb
commit 82c5d08acc
2 changed files with 236 additions and 11 deletions

View File

@ -28,6 +28,7 @@
#include "msscript.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(msscript);
@ -55,6 +56,12 @@ struct ConnectionPoint {
ConnectionPoint *next;
};
struct named_item {
struct list entry;
BSTR name;
IDispatch *disp;
};
typedef struct ScriptHost {
IActiveScriptSite IActiveScriptSite_iface;
IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
@ -64,6 +71,8 @@ typedef struct ScriptHost {
IActiveScript *script;
IActiveScriptParse *parse;
CLSID clsid;
struct list named_items;
} ScriptHost;
struct ScriptControl {
@ -173,6 +182,29 @@ static void release_typelib(void)
ITypeLib_Release(typelib);
}
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 (!lstrcmpW(item->name, nameW))
return item;
}
return NULL;
}
static inline ScriptControl *impl_from_IScriptControl(IScriptControl *iface)
{
return CONTAINING_RECORD(iface, ScriptControl, IScriptControl_iface);
@ -293,8 +325,10 @@ static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref)
if(!ref) {
clear_named_items(This);
heap_free(This);
}
return ref;
}
@ -309,14 +343,27 @@ static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *l
return S_OK;
}
static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, DWORD returnmask,
IUnknown **item, ITypeInfo **ti)
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;
FIXME("(%p, %s, %#x, %p, %p)\n", This, debugstr_w(name), returnmask, item, ti);
TRACE("(%p, %s, %#x, %p, %p)\n", This, debugstr_w(name), mask, unk, ti);
return E_NOTIMPL;
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)
@ -488,6 +535,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
host->script = NULL;
host->parse = NULL;
host->clsid = *clsid;
list_init(&host->named_items);
hr = CoCreateInstance(&host->clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
&IID_IActiveScript, (void**)&host->script);
@ -840,8 +888,42 @@ static HRESULT WINAPI ScriptControl__AboutBox(IScriptControl *iface)
static HRESULT WINAPI ScriptControl_AddObject(IScriptControl *iface, BSTR name, IDispatch *object, VARIANT_BOOL add_members)
{
ScriptControl *This = impl_from_IScriptControl(iface);
FIXME("(%p)->(%s %p %x)\n", This, debugstr_w(name), object, add_members);
return E_NOTIMPL;
DWORD flags = SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE;
struct named_item *item;
HRESULT hr;
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 (host_get_named_item(This->host, name))
return E_INVALIDARG;
item = heap_alloc(sizeof(*item));
if (!item)
return E_OUTOFMEMORY;
item->name = SysAllocString(name);
IDispatch_AddRef(item->disp = object);
list_add_tail(&This->host->named_items, &item->entry);
if (add_members)
flags |= SCRIPTITEM_GLOBALMEMBERS;
hr = IActiveScript_AddNamedItem(This->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 WINAPI ScriptControl_Reset(IScriptControl *iface)
@ -853,6 +935,7 @@ static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface)
if (!This->host)
return E_FAIL;
clear_named_items(This->host);
return IActiveScript_SetScriptState(This->host->script, SCRIPTSTATE_INITIALIZED);
}

View File

@ -95,6 +95,7 @@ DEFINE_EXPECT(Close);
DEFINE_EXPECT(SetScriptSite);
DEFINE_EXPECT(QI_IActiveScriptParse);
DEFINE_EXPECT(SetScriptState_INITIALIZED);
DEFINE_EXPECT(AddNamedItem);
#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
static void _expect_ref(IUnknown* obj, ULONG ref, int line)
@ -318,11 +319,13 @@ static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface)
return E_NOTIMPL;
}
static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface,
LPCOLESTR pstrName, DWORD dwFlags)
static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface, LPCOLESTR name, DWORD flags)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
static const WCHAR oW[] = {'o',0};
CHECK_EXPECT(AddNamedItem);
ok(!lstrcmpW(name, oW), "got name %s\n", wine_dbgstr_w(name));
ok(flags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS), "got flags %#x\n", flags);
return S_OK;
}
static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
@ -1086,6 +1089,144 @@ static void test_Reset(void)
skip("Could not register TestScript engine\n");
}
static HRESULT WINAPI disp_QI(IDispatch *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) {
*obj = iface;
IDispatch_AddRef(iface);
return S_OK;
}
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI disp_AddRef(IDispatch *iface)
{
return 2;
}
static ULONG WINAPI disp_Release(IDispatch *iface)
{
return 1;
}
static HRESULT WINAPI disp_GetTypeInfoCount(IDispatch *iface, UINT *count)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI disp_GetTypeInfo(IDispatch *iface, UINT index, LCID lcid, ITypeInfo **ti)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI disp_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names,
UINT cnames, LCID lcid, DISPID *dispid)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI disp_Invoke(IDispatch *iface, DISPID dispid, REFIID riid, LCID lcid,
WORD flags, DISPPARAMS *dispparams, VARIANT *result, EXCEPINFO *ei, UINT *arg_err)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static const IDispatchVtbl dispvtbl = {
disp_QI,
disp_AddRef,
disp_Release,
disp_GetTypeInfoCount,
disp_GetTypeInfo,
disp_GetIDsOfNames,
disp_Invoke
};
static IDispatch testdisp = { &dispvtbl };
static void test_AddObject(void)
{
static const WCHAR oW[] = {'o',0};
IScriptControl *sc;
BSTR str, objname;
HRESULT hr;
hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
&IID_IScriptControl, (void**)&sc);
ok(hr == S_OK, "got 0x%08x\n", hr);
objname = SysAllocString(oW);
hr = IScriptControl_AddObject(sc, objname, NULL, VARIANT_FALSE);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_FALSE);
ok(hr == E_FAIL, "got 0x%08x\n", hr);
str = SysAllocString(vbW);
hr = IScriptControl_put_Language(sc, str);
ok(hr == S_OK, "got 0x%08x\n", hr);
SysFreeString(str);
hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_TRUE);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IScriptControl_Reset(sc);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_TRUE);
ok(hr == S_OK, "got 0x%08x\n", hr);
IScriptControl_Release(sc);
/* custom script engine */
if (register_script_engine()) {
static const WCHAR testscriptW[] = {'t','e','s','t','s','c','r','i','p','t',0};
hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
&IID_IScriptControl, (void**)&sc);
ok(hr == S_OK, "got 0x%08x\n", hr);
SET_EXPECT(CreateInstance);
SET_EXPECT(SetInterfaceSafetyOptions);
SET_EXPECT(SetScriptSite);
SET_EXPECT(QI_IActiveScriptParse);
SET_EXPECT(InitNew);
str = SysAllocString(testscriptW);
hr = IScriptControl_put_Language(sc, str);
ok(hr == S_OK, "got 0x%08x\n", hr);
SysFreeString(str);
hr = IScriptControl_AddObject(sc, objname, NULL, VARIANT_FALSE);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
SET_EXPECT(AddNamedItem);
hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_TRUE);
ok(hr == S_OK, "got 0x%08x\n", hr);
CHECK_CALLED(AddNamedItem);
hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_TRUE);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
init_registry(FALSE);
SET_EXPECT(Close);
IScriptControl_Release(sc);
CHECK_CALLED(Close);
}
else
skip("Could not register TestScript engine\n");
SysFreeString(objname);
}
START_TEST(msscript)
{
IUnknown *unk;
@ -1111,6 +1252,7 @@ START_TEST(msscript)
test_pointerinactive();
test_timeout();
test_Reset();
test_AddObject();
CoUninitialize();
}