From cde38841d30ca9380ffd0881b6afb9be5bb782a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= Date: Fri, 6 Dec 2019 13:46:13 +0100 Subject: [PATCH] vbscript: Implement ScriptTypeInfo_GetIDsOfNames. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gabriel Ivăncescu Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- 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 d19107fd811..c031b801668 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 d14b73ce824..d79be9e6e7d 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 6e6f3867559..6dbf56d29a7 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(); }