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:
parent
267e8e3eeb
commit
82c5d08acc
|
@ -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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue