Gabriel Ivăncescu : vbscript: Implement ScriptTypeInfo_GetIDsOfNames.

Alexandre Julliard julliard at winehq.org
Fri Dec 6 16:06:39 CST 2019


Module: wine
Branch: master
Commit: cde38841d30ca9380ffd0881b6afb9be5bb782a9
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=cde38841d30ca9380ffd0881b6afb9be5bb782a9

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Fri Dec  6 13:46:13 2019 +0100

vbscript: Implement ScriptTypeInfo_GetIDsOfNames.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 d19107fd81..c031b80166 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -723,10 +723,51 @@ static HRESULT WINAPI ScriptTypeInfo_GetIDsOfNames(ITypeInfo *iface, LPOLESTR *r
         MEMBERID *pMemId)
 {
     ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+    ITypeInfo *disp_typeinfo;
+    const WCHAR *name;
+    HRESULT hr = S_OK;
+    int i, j, arg;
 
-    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 (i = 0; i < This->num_funcs; i++)
+    {
+        function_t *func = This->funcs[i].func;
+
+        if (wcsicmp(name, func->name)) continue;
+        pMemId[0] = This->funcs[i].memid;
+
+        for (j = 1; j < cNames; j++)
+        {
+            name = rgszNames[j];
+            for (arg = func->arg_cnt; --arg >= 0;)
+                if (!wcsicmp(name, func->args[arg].name))
+                    break;
+            if (arg >= 0)
+                pMemId[j] = arg;
+            else
+                hr = DISP_E_UNKNOWNNAME;
+        }
+        return hr;
+    }
+
+    for (i = 0; i < This->num_vars; i++)
+    {
+        if (wcsicmp(name, This->disp->global_vars[i]->name)) continue;
+        pMemId[0] = i + 1;
+        return S_OK;
+    }
+
+    /* Look into the inherited IDispatch */
+    hr = get_dispatch_typeinfo(&disp_typeinfo);
+    if (FAILED(hr)) return hr;
+
+    return ITypeInfo_GetIDsOfNames(disp_typeinfo, 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 d14b73ce82..d79be9e6e7 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -374,6 +374,7 @@ void detach_global_objects(script_ctx_t*) DECLSPEC_HIDDEN;
 HRESULT get_builtin_id(BuiltinDisp*,const WCHAR*,DISPID*) DECLSPEC_HIDDEN;
 
 void release_regexp_typelib(void) DECLSPEC_HIDDEN;
+HRESULT get_dispatch_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 6e6f386755..6dbf56d29a 100644
--- a/dlls/vbscript/vbscript_main.c
+++ b/dlls/vbscript/vbscript_main.c
@@ -34,6 +34,7 @@ WINE_DECLARE_DEBUG_CHANNEL(heap);
 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 
 static HINSTANCE vbscript_hinstance;
+static ITypeInfo *dispatch_typeinfo;
 
 BSTR get_vbscript_string(int id)
 {
@@ -180,6 +181,29 @@ heap_pool_t *heap_pool_mark(heap_pool_t *heap)
     return heap;
 }
 
+HRESULT get_dispatch_typeinfo(ITypeInfo **out)
+{
+    ITypeInfo *typeinfo;
+    ITypeLib *typelib;
+    HRESULT hr;
+
+    if (!dispatch_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**)&dispatch_typeinfo, typeinfo, NULL))
+            ITypeInfo_Release(typeinfo);
+    }
+
+    *out = dispatch_typeinfo;
+    return S_OK;
+}
+
 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
 {
     *ppv = NULL;
@@ -256,6 +280,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
         break;
     case DLL_PROCESS_DETACH:
         if (lpv) break;
+        if (dispatch_typeinfo) ITypeInfo_Release(dispatch_typeinfo);
         release_regexp_typelib();
     }
 




More information about the wine-cvs mailing list