From: "Gabriel Ivăncescu" Subject: [PATCH 7/9] vbscript: Implement ScriptTypeInfo_GetIDsOfNames. Message-Id: Date: Tue, 15 Oct 2019 17:54:58 +0300 In-Reply-To: References: Signed-off-by: Gabriel Ivăncescu --- 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