[PATCH v3 04/11] msscript.ocx: Implement IScriptModuleCollection::get_Item.

Gabriel Ivăncescu gabrielopcode at gmail.com
Tue Jun 2 07:55:50 CDT 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/msscript.ocx/msscript.c       | 63 +++++++++++++++++++++++++++++-
 dlls/msscript.ocx/tests/msscript.c | 32 ++++++++++++---
 2 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index 91e1e94..b1e455b 100644
--- a/dlls/msscript.ocx/msscript.c
+++ b/dlls/msscript.ocx/msscript.c
@@ -602,6 +602,23 @@ static void release_modules(ScriptControl *control)
     heap_free(control->modules);
 }
 
+static UINT find_module(ScriptControl *control, BSTR name)
+{
+    UINT i, len = SysStringLen(name);
+
+    if (len == sizeof("Global") - 1 && !wcsicmp(name, L"Global"))
+        return 0;
+
+    for (i = 1; i < control->num_modules; i++)
+    {
+        BSTR modname = control->modules[i].name;
+        if (SysStringLen(modname) == len && !wcsicmp(name, modname))
+            return i;
+    }
+
+    return ~0;
+}
+
 static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv)
 {
     ScriptModule *This = impl_from_IScriptModule(iface);
@@ -793,6 +810,26 @@ static const IScriptModuleVtbl ScriptModuleVtbl = {
     ScriptModule_Run
 };
 
+static HRESULT grab_module_object(ScriptControl *control, UINT index)
+{
+    struct module *module = &control->modules[index];
+
+    if (module->object)
+        IScriptModule_AddRef(&module->object->IScriptModule_iface);
+    else
+    {
+        if (!(module->object = heap_alloc(sizeof(*module->object))))
+            return E_OUTOFMEMORY;
+
+        module->object->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl;
+        module->object->ref = 1;
+        module->object->idx = index;
+        module->object->control = control;
+        IScriptControl_AddRef(&control->IScriptControl_iface);
+    }
+    return S_OK;
+}
+
 static HRESULT WINAPI ScriptModuleCollection_QueryInterface(IScriptModuleCollection *iface, REFIID riid, void **ppv)
 {
     ScriptControl *This = impl_from_IScriptModuleCollection(iface);
@@ -899,10 +936,32 @@ static HRESULT WINAPI ScriptModuleCollection_get_Item(IScriptModuleCollection *i
         IScriptModule **ppmod)
 {
     ScriptControl *This = impl_from_IScriptModuleCollection(iface);
+    HRESULT hr;
+    UINT i;
 
-    FIXME("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppmod);
+    TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppmod);
 
-    return E_NOTIMPL;
+    if (!ppmod) return E_POINTER;
+
+    if (V_VT(&index) == VT_BSTR)
+    {
+        i = find_module(This, V_BSTR(&index));
+        if (i == ~0) 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->num_modules) return 0x800a0009;
+    }
+
+    hr = grab_module_object(This, i);
+    if (FAILED(hr)) return hr;
+
+    *ppmod = &This->modules[i].object->IScriptModule_iface;
+    return S_OK;
 }
 
 static HRESULT WINAPI ScriptModuleCollection_get_Count(IScriptModuleCollection *iface, LONG *plCount)
diff --git a/dlls/msscript.ocx/tests/msscript.c b/dlls/msscript.ocx/tests/msscript.c
index 9acf60e..a7b301d 100644
--- a/dlls/msscript.ocx/tests/msscript.c
+++ b/dlls/msscript.ocx/tests/msscript.c
@@ -2168,9 +2168,9 @@ static void test_IScriptControl_get_Modules(void)
     V_VT(&var) = VT_I4;
     V_I4(&var) = -1;
     hr = IScriptModuleCollection_get_Item(mods, var, NULL);
-    todo_wine ok(hr == E_POINTER, "IScriptModuleCollection_get_Item returned: 0x%08x.\n", hr);
+    ok(hr == E_POINTER, "IScriptModuleCollection_get_Item returned: 0x%08x.\n", hr);
     hr = IScriptModuleCollection_get_Item(mods, var, &mod);
-    todo_wine ok(hr == 0x800a0009, "IScriptModuleCollection_get_Item returned: 0x%08x.\n", hr);
+    ok(hr == 0x800a0009, "IScriptModuleCollection_get_Item returned: 0x%08x.\n", hr);
 
     V_VT(&var) = VT_EMPTY;
     str = SysAllocString(L"foobar");
@@ -2205,19 +2205,28 @@ static void test_IScriptControl_get_Modules(void)
     V_VT(&var) = VT_I4;
     V_I4(&var) = count + 1;
     hr = IScriptModuleCollection_get_Item(mods, var, &mod);
-    todo_wine ok(hr == 0x800a0009, "IScriptModuleCollection_get_Item returned: 0x%08x.\n", hr);
+    ok(hr == 0x800a0009, "IScriptModuleCollection_get_Item returned: 0x%08x.\n", hr);
     V_VT(&var) = VT_BSTR;
     V_BSTR(&var) = SysAllocString(L"non-existent module");
     hr = IScriptModuleCollection_get_Item(mods, var, &mod);
-    todo_wine ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "IScriptModuleCollection_get_Item returned: 0x%08x.\n", hr);
+    ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "IScriptModuleCollection_get_Item returned: 0x%08x.\n", hr);
     ok(V_VT(&var) == VT_BSTR, "var type not BSTR, got %d.\n", V_VT(&var));
     VariantClear(&var);
 
     V_VT(&var) = VT_I4;
     V_I4(&var) = 1;
     hr = IScriptModuleCollection_get_Item(mods, var, &mod);
-    todo_wine ok(hr == S_OK, "IScriptModuleCollection_get_Item failed: 0x%08x.\n", hr);
-    if (hr == S_OK) IScriptModule_Release(mod);
+    ok(hr == S_OK, "IScriptModuleCollection_get_Item failed: 0x%08x.\n", hr);
+    hr = IScriptModule_get_Name(mod, NULL);
+    todo_wine ok(hr == E_POINTER, "IScriptModule_get_Name returned: 0x%08x.\n", hr);
+    hr = IScriptModule_get_Name(mod, &str);
+    todo_wine ok(hr == S_OK, "IScriptModule_get_Name failed: 0x%08x.\n", hr);
+    if (hr == S_OK) SysFreeString(str);
+    str = SysAllocString(L"function add(a, b) { return a + b; }\n");
+    hr = IScriptModule_AddCode(mod, str);
+    todo_wine ok(hr == S_OK, "IScriptModule_AddCode failed: 0x%08x.\n", hr);
+    IScriptModule_Release(mod);
+    SysFreeString(str);
 
     V_VT(&var) = VT_BSTR;
     V_BSTR(&var) = SysAllocString(L"some other module");
@@ -2233,6 +2242,17 @@ static void test_IScriptControl_get_Modules(void)
     todo_wine ok(hr == S_OK, "IScriptModuleCollection_get_Item failed: 0x%08x.\n", hr);
     if (hr == S_OK) IScriptModule_Release(mod);
 
+    /* The 'Global' module is the same as the script control */
+    str = SysAllocString(L"add(10, 5)");
+    hr = IScriptControl_Eval(sc, str, &var);
+    todo_wine ok(hr == S_OK, "IScriptControl_Eval failed: 0x%08x.\n", hr);
+    todo_wine ok(V_VT(&var) == VT_I4 && V_I4(&var) == 15, "V_VT(var) = %d, V_I4(var) = %d.\n", V_VT(&var), V_I4(&var));
+    SysFreeString(str);
+    str = SysAllocString(L"sub(10, 5)");
+    hr = IScriptControl_Eval(sc, str, &var);
+    ok(FAILED(hr), "IScriptControl_Eval succeeded: 0x%08x.\n", hr);
+    SysFreeString(str);
+
     str = SysAllocString(L"vbscript");
     hr = IScriptControl_put_Language(sc, str);
     ok(hr == S_OK, "IScriptControl_put_Language failed: 0x%08x.\n", hr);
-- 
2.21.0




More information about the wine-devel mailing list