From: "Gabriel Ivăncescu" Subject: [PATCH 11/13] msscript.ocx: Implement ScriptModuleCollection_Add. Message-Id: <8b3b840d91933fdd17fd48a980cd853ab60614cc.1586442574.git.gabrielopcode@gmail.com> Date: Thu, 9 Apr 2020 17:34:38 +0300 In-Reply-To: <311c32ff785fcd554c8d64166530bcc63090f724.1586442574.git.gabrielopcode@gmail.com> References: <311c32ff785fcd554c8d64166530bcc63090f724.1586442574.git.gabrielopcode@gmail.com> Signed-off-by: Gabriel Ivăncescu --- dlls/msscript.ocx/msscript.c | 42 ++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c index e3b7b86..f0a4853 100644 --- a/dlls/msscript.ocx/msscript.c +++ b/dlls/msscript.ocx/msscript.c @@ -197,6 +197,11 @@ static void release_typelib(void) 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; @@ -1096,10 +1101,43 @@ static HRESULT WINAPI ScriptModuleCollection_Add(IScriptModuleCollection *iface, VARIANT *object, IScriptModule **ppmod) { ScriptControl *This = impl_from_IScriptModuleCollection(iface); + ScriptModule *mod, **mods; + HRESULT hr; - FIXME("(%p)->(%s %s %p)\n", This, wine_dbgstr_w(name), wine_dbgstr_variant(object), ppmod); + TRACE("(%p)->(%s %s %p)\n", This, wine_dbgstr_w(name), wine_dbgstr_variant(object), ppmod); - return E_NOTIMPL; + if (!ppmod) return E_POINTER; + if (!name || V_VT(object) != VT_DISPATCH || find_module(This, name) != ~0) + return E_INVALIDARG; + if (!This->host) return E_FAIL; + + /* See if we need to grow the array */ + if (is_power_of_2(This->num_modules)) + { + mods = heap_realloc(This->modules, This->num_modules * 2 * sizeof(*This->modules)); + if (!mods) return E_OUTOFMEMORY; + This->modules = mods; + } + + mod = alloc_module(This, name); + if (!mod) return E_OUTOFMEMORY; + + /* If no object, Windows only calls AddNamedItem without adding a NULL object */ + if (V_DISPATCH(object)) + hr = add_script_object(This->host, name, V_DISPATCH(object), 0); + else + hr = IActiveScript_AddNamedItem(This->host->script, name, SCRIPTITEM_CODEONLY); + + if (FAILED(hr)) + { + destroy_module(mod); + return hr; + } + This->modules[This->num_modules++] = mod; + + *ppmod = &mod->IScriptModule_iface; + IScriptModule_AddRef(*ppmod); + return S_OK; } static const IScriptModuleCollectionVtbl ScriptModuleCollectionVtbl = { -- 2.21.0