[PATCH 7/9] vbscript: Implement ScriptTypeInfo_GetIDsOfNames.

Gabriel Ivăncescu gabrielopcode at gmail.com
Tue Oct 15 09:54:58 CDT 2019


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/vbscript/vbdisp.c        | 45 +++++++++++++++++++++++++++++++++--
 dlls/vbscript/vbscript.h      |  1 +
 dlls/vbscript/vbscript_main.c | 25 +++++++++++++++++++
 3 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 783662a..cb04bf9 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -937,10 +937,51 @@ static HRESULT WINAPI ScriptTypeInfo_GetIDsOfNames(ITypeInfo *iface, LPOLESTR *r
         MEMBERID *pMemId)
 {
     ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+    struct script_typeinfo_func *func, *endf;
+    struct script_typeinfo_var *var, *endv;
+    UINT i, j, num_args;
+    const WCHAR *name;
+    HRESULT hr = S_OK;
 
-    FIXME("(%p)->(%p %u %p)\n", This, rgszNames, cNames, pMemId);
+    TRACE("(%p)->(%p %u %p)\n", This, rgszNames, cNames, pMemId);
 
-    return E_NOTIMPL;
+    if (!rgszNames || !cNames || !pMemId) return E_INVALIDARG;
+
+    for (i = 0; i < cNames; i++) pMemId[i] = MEMBERID_NIL;
+    name = rgszNames[0];
+
+    for (func = This->funcs, endf = func + This->num_funcs; func != endf; func++)
+    {
+        if (wcsicmp(name, func->name)) continue;
+        pMemId[0] = func->memid;
+        num_args  = func->num_args;
+
+        for(i = 1; i < cNames; i++)
+        {
+            name = rgszNames[i];
+            for (j = 0; j < num_args; j++)
+                if (!wcsicmp(name, func->arg_names[j]))
+                    break;
+            if (j < num_args)
+                pMemId[i] = j;
+            else
+                hr = DISP_E_UNKNOWNNAME;
+        }
+        return hr;
+    }
+
+    for (var = This->vars, endv = var + This->num_vars; var != endv; var++)
+    {
+        if (wcsicmp(name, var->name)) continue;
+        pMemId[0] = var->memid;
+        return S_OK;
+    }
+
+    /* Look into the inherited IDispatch */
+    hr = get_IDispatch_typeinfo(&iface);
+    if (FAILED(hr)) return hr;
+
+    return ITypeInfo_GetIDsOfNames(iface, rgszNames, cNames, pMemId);
 }
 
 static HRESULT WINAPI ScriptTypeInfo_Invoke(ITypeInfo *iface, PVOID pvInstance, MEMBERID memid, WORD wFlags,
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 654e827..24ba40a 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -382,6 +382,7 @@ TID_LIST
 
 HRESULT get_typeinfo(tid_t,ITypeInfo**) DECLSPEC_HIDDEN;
 void release_regexp_typelib(void) DECLSPEC_HIDDEN;
+HRESULT get_IDispatch_typeinfo(ITypeInfo**) DECLSPEC_HIDDEN;
 
 static inline BOOL is_int32(double d)
 {
diff --git a/dlls/vbscript/vbscript_main.c b/dlls/vbscript/vbscript_main.c
index 3a8019a..caa39b4 100644
--- a/dlls/vbscript/vbscript_main.c
+++ b/dlls/vbscript/vbscript_main.c
@@ -37,6 +37,7 @@ static HINSTANCE vbscript_hinstance;
 
 static ITypeLib *typelib;
 static ITypeInfo *typeinfos[LAST_tid];
+static ITypeInfo *IDispatch_typeinfo;
 
 static REFIID tid_ids[] = {
 #define XDIID(iface) &DIID_ ## iface,
@@ -95,6 +96,29 @@ static void release_typelib(void)
     ITypeLib_Release(typelib);
 }
 
+HRESULT get_IDispatch_typeinfo(ITypeInfo **out)
+{
+    ITypeInfo *typeinfo;
+    ITypeLib *typelib;
+    HRESULT hr;
+
+    if (!IDispatch_typeinfo)
+    {
+        hr = LoadRegTypeLib(&IID_StdOle, STDOLE_MAJORVERNUM, STDOLE_MINORVERNUM, STDOLE_LCID, &typelib);
+        if (FAILED(hr)) return hr;
+
+        hr = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IDispatch, &typeinfo);
+        ITypeLib_Release(typelib);
+        if (FAILED(hr)) return hr;
+
+        if (InterlockedCompareExchangePointer((void**)(&IDispatch_typeinfo), typeinfo, NULL))
+            ITypeInfo_Release(typeinfo);
+    }
+
+    *out = IDispatch_typeinfo;
+    return S_OK;
+}
+
 BSTR get_vbscript_string(int id)
 {
     WCHAR buf[512];
@@ -316,6 +340,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
         break;
     case DLL_PROCESS_DETACH:
         if (lpv) break;
+        if (IDispatch_typeinfo) ITypeInfo_Release(IDispatch_typeinfo);
         release_typelib();
         release_regexp_typelib();
     }
-- 
2.21.0




More information about the wine-devel mailing list