[PATCH 12/13] msscript.ocx: Implement ScriptModule enumerator.

Gabriel Ivăncescu gabrielopcode at gmail.com
Thu Apr 9 09:34:39 CDT 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/msscript.ocx/msscript.c | 150 ++++++++++++++++++++++++++++++++++-
 1 file changed, 148 insertions(+), 2 deletions(-)

diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index f0a4853..a691413 100644
--- a/dlls/msscript.ocx/msscript.c
+++ b/dlls/msscript.ocx/msscript.c
@@ -65,6 +65,13 @@ struct named_item {
     IDispatch *disp;
 };
 
+struct script_mod_enum {
+    IEnumVARIANT IEnumVARIANT_iface;
+    LONG ref;
+    UINT pos;
+    ScriptControl *control;
+};
+
 typedef struct ScriptModule {
     IScriptModule IScriptModule_iface;
     LONG ref;
@@ -430,6 +437,11 @@ static inline ScriptHost *impl_from_IServiceProvider(IServiceProvider *iface)
     return CONTAINING_RECORD(iface, ScriptHost, IServiceProvider_iface);
 }
 
+static inline struct script_mod_enum *script_mod_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
+{
+    return CONTAINING_RECORD(iface, struct script_mod_enum, IEnumVARIANT_iface);
+}
+
 /* IActiveScriptSite */
 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
 {
@@ -935,6 +947,127 @@ static const IScriptModuleVtbl ScriptModuleVtbl = {
     ScriptModule_Run
 };
 
+static HRESULT WINAPI script_mod_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
+{
+    struct script_mod_enum *This = script_mod_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 script_mod_enum_AddRef(IEnumVARIANT *iface)
+{
+    struct script_mod_enum *This = script_mod_enum_from_IEnumVARIANT(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI script_mod_enum_Release(IEnumVARIANT *iface)
+{
+    struct script_mod_enum *This = script_mod_enum_from_IEnumVARIANT(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if (!ref)
+    {
+        IScriptControl_Release(&This->control->IScriptControl_iface);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI script_mod_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
+{
+    struct script_mod_enum *This = script_mod_enum_from_IEnumVARIANT(iface);
+    UINT i, num;
+
+    TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
+
+    if (!rgVar) return E_POINTER;
+
+    num = min(celt, This->control->num_modules - 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 script_mod_enum_Skip(IEnumVARIANT *iface, ULONG celt)
+{
+    struct script_mod_enum *This = script_mod_enum_from_IEnumVARIANT(iface);
+
+    TRACE("(%p)->(%u)\n", This, celt);
+
+    if (This->control->num_modules - This->pos < celt)
+    {
+        This->pos = This->control->num_modules;
+        return S_FALSE;
+    }
+    This->pos += celt;
+    return S_OK;
+}
+
+static HRESULT WINAPI script_mod_enum_Reset(IEnumVARIANT *iface)
+{
+    struct script_mod_enum *This = script_mod_enum_from_IEnumVARIANT(iface);
+
+    TRACE("(%p)\n", This);
+
+    This->pos = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI script_mod_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
+{
+    struct script_mod_enum *This = script_mod_enum_from_IEnumVARIANT(iface);
+    struct script_mod_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;
+    IScriptControl_AddRef(&This->control->IScriptControl_iface);
+
+    *ppEnum = &clone->IEnumVARIANT_iface;
+    return S_OK;
+}
+
+static const IEnumVARIANTVtbl script_mod_enum_vtbl = {
+    script_mod_enum_QueryInterface,
+    script_mod_enum_AddRef,
+    script_mod_enum_Release,
+    script_mod_enum_Next,
+    script_mod_enum_Skip,
+    script_mod_enum_Reset,
+    script_mod_enum_Clone
+};
+
 static ScriptModule *alloc_module(ScriptControl *control, BSTR name)
 {
     ScriptModule *module = heap_alloc_zero(sizeof(*module));
@@ -1049,10 +1182,23 @@ static HRESULT WINAPI ScriptModuleCollection_Invoke(IScriptModuleCollection *ifa
 static HRESULT WINAPI ScriptModuleCollection_get__NewEnum(IScriptModuleCollection *iface, IUnknown **ppenumContexts)
 {
     ScriptControl *This = impl_from_IScriptModuleCollection(iface);
+    struct script_mod_enum *mod_enum;
 
-    FIXME("(%p)->(%p)\n", This, ppenumContexts);
+    TRACE("(%p)->(%p)\n", This, ppenumContexts);
 
-    return E_NOTIMPL;
+    if (!ppenumContexts) return E_POINTER;
+
+    if (!(mod_enum = heap_alloc(sizeof(*mod_enum))))
+        return E_OUTOFMEMORY;
+
+    mod_enum->IEnumVARIANT_iface.lpVtbl = &script_mod_enum_vtbl;
+    mod_enum->ref = 1;
+    mod_enum->pos = 0;
+    mod_enum->control = This;
+    IScriptControl_AddRef(&This->IScriptControl_iface);
+
+    *ppenumContexts = (IUnknown*)&mod_enum->IEnumVARIANT_iface;
+    return S_OK;
 }
 
 static HRESULT WINAPI ScriptModuleCollection_get_Item(IScriptModuleCollection *iface, VARIANT index,
-- 
2.21.0




More information about the wine-devel mailing list