From ba2e6fb2bec63a0ecb23c29b4f0d61ba57dc8c33 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 7 Dec 2016 13:33:58 +0300 Subject: [PATCH] scrrun: Added IProvideClassInfo support for dictionary. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/scrrun/dictionary.c | 8 ++++- dlls/scrrun/scrrun.c | 77 ++++++++++++++++++++++++++++++++++++++++-- dlls/scrrun/scrrun_private.h | 8 +++++ dlls/scrrun/tests/dictionary.c | 27 +++++++++++++++ 4 files changed, 116 insertions(+), 4 deletions(-) diff --git a/dlls/scrrun/dictionary.c b/dlls/scrrun/dictionary.c index 3c8fc825728..7ebf4a4f872 100644 --- a/dlls/scrrun/dictionary.c +++ b/dlls/scrrun/dictionary.c @@ -65,6 +65,7 @@ struct keyitem_pair { typedef struct { + struct provideclassinfo classinfo; IDictionary IDictionary_iface; LONG ref; @@ -386,6 +387,10 @@ static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, { *obj = &This->IDictionary_iface; } + else if (IsEqualIID(riid, &IID_IProvideClassInfo)) + { + *obj = &This->classinfo.IProvideClassInfo_iface; + } else if ( IsEqualGUID( riid, &IID_IDispatchEx )) { TRACE("Interface IDispatchEx not supported - returning NULL\n"); @@ -404,7 +409,7 @@ static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, return E_NOINTERFACE; } - IDictionary_AddRef(iface); + IUnknown_AddRef((IUnknown*)*obj); return S_OK; } @@ -901,6 +906,7 @@ HRESULT WINAPI Dictionary_CreateInstance(IClassFactory *factory,IUnknown *outer, list_init(&This->notifier); memset(This->buckets, 0, sizeof(This->buckets)); + init_classinfo(&CLSID_Dictionary, (IUnknown *)&This->IDictionary_iface, &This->classinfo); *obj = &This->IDictionary_iface; return S_OK; diff --git a/dlls/scrrun/scrrun.c b/dlls/scrrun/scrrun.c index 5201f1f6b69..42b62b65148 100644 --- a/dlls/scrrun/scrrun.c +++ b/dlls/scrrun/scrrun.c @@ -23,6 +23,7 @@ #include "windef.h" #include "winbase.h" #include "ole2.h" +#include "olectl.h" #include "rpcproxy.h" #include @@ -35,6 +36,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(scrrun); static HINSTANCE scrrun_instance; +static inline struct provideclassinfo *impl_from_IProvideClassInfo(IProvideClassInfo *iface) +{ + return CONTAINING_RECORD(iface, struct provideclassinfo, IProvideClassInfo_iface); +} + typedef HRESULT (*fnCreateInstance)(LPVOID *ppObj); static HRESULT WINAPI scrruncf_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv ) @@ -118,6 +124,9 @@ static HRESULT load_typelib(void) HRESULT hres; ITypeLib *tl; + if(typelib) + return S_OK; + hres = LoadRegTypeLib(&LIBID_Scripting, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); if(FAILED(hres)) { ERR("LoadRegTypeLib failed: %08x\n", hres); @@ -129,13 +138,21 @@ static HRESULT load_typelib(void) return hres; } +static HRESULT get_typeinfo_of_guid(const GUID *guid, ITypeInfo **tinfo) +{ + HRESULT hres; + + if(FAILED(hres = load_typelib())) + return hres; + + return ITypeLib_GetTypeInfoOfGuid(typelib, guid, tinfo); +} + HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) { HRESULT hres; - if (!typelib) - hres = load_typelib(); - if (!typelib) + if (FAILED(hres = load_typelib())) return hres; if(!typeinfos[tid]) { @@ -170,6 +187,60 @@ static void release_typelib(void) ITypeLib_Release(typelib); } +static HRESULT WINAPI provideclassinfo_QueryInterface(IProvideClassInfo *iface, REFIID riid, void **obj) +{ + struct provideclassinfo *This = impl_from_IProvideClassInfo(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IProvideClassInfo)) { + *obj = iface; + IProvideClassInfo_AddRef(iface); + return S_OK; + } + else + return IUnknown_QueryInterface(This->outer, riid, obj); + + *obj = NULL; + WARN("interface %s not supported\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI provideclassinfo_AddRef(IProvideClassInfo *iface) +{ + struct provideclassinfo *This = impl_from_IProvideClassInfo(iface); + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI provideclassinfo_Release(IProvideClassInfo *iface) +{ + struct provideclassinfo *This = impl_from_IProvideClassInfo(iface); + return IUnknown_Release(This->outer); +} + +static HRESULT WINAPI provideclassinfo_GetClassInfo(IProvideClassInfo *iface, ITypeInfo **ti) +{ + struct provideclassinfo *This = impl_from_IProvideClassInfo(iface); + + TRACE("(%p)->(%p)\n", This, ti); + + return get_typeinfo_of_guid(This->guid, ti); +} + +static const IProvideClassInfoVtbl provideclassinfovtbl = { + provideclassinfo_QueryInterface, + provideclassinfo_AddRef, + provideclassinfo_Release, + provideclassinfo_GetClassInfo +}; + +void init_classinfo(const GUID *guid, IUnknown *outer, struct provideclassinfo *classinfo) +{ + classinfo->IProvideClassInfo_iface.lpVtbl = &provideclassinfovtbl; + classinfo->outer = outer; + classinfo->guid = guid; +} + BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) { TRACE("%p, %u, %p\n", hinst, reason, reserved); diff --git a/dlls/scrrun/scrrun_private.h b/dlls/scrrun/scrrun_private.h index 43b20a9ee50..e2023f967ad 100644 --- a/dlls/scrrun/scrrun_private.h +++ b/dlls/scrrun/scrrun_private.h @@ -38,6 +38,14 @@ typedef enum tid_t HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) DECLSPEC_HIDDEN; +struct provideclassinfo { + IProvideClassInfo IProvideClassInfo_iface; + IUnknown *outer; + const GUID *guid; +}; + +extern void init_classinfo(const GUID *guid, IUnknown *outer, struct provideclassinfo *classinfo) DECLSPEC_HIDDEN; + static inline void *heap_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); diff --git a/dlls/scrrun/tests/dictionary.c b/dlls/scrrun/tests/dictionary.c index a94782f0e21..78922b75bd9 100644 --- a/dlls/scrrun/tests/dictionary.c +++ b/dlls/scrrun/tests/dictionary.c @@ -30,6 +30,31 @@ #include "scrrun.h" +#define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__) +static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line) +{ + IProvideClassInfo *classinfo; + TYPEATTR *attr; + ITypeInfo *ti; + HRESULT hr; + + hr = IDispatch_QueryInterface(disp, &IID_IProvideClassInfo, (void **)&classinfo); + ok_(__FILE__,line) (hr == S_OK, "Failed to get IProvideClassInfo, %#x.\n", hr); + + hr = IProvideClassInfo_GetClassInfo(classinfo, &ti); + ok_(__FILE__,line) (hr == S_OK, "GetClassInfo() failed, %#x.\n", hr); + + hr = ITypeInfo_GetTypeAttr(ti, &attr); + ok_(__FILE__,line) (hr == S_OK, "GetTypeAttr() failed, %#x.\n", hr); + + ok_(__FILE__,line) (IsEqualGUID(&attr->guid, guid), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr->guid), + wine_dbgstr_guid(guid)); + + IProvideClassInfo_Release(classinfo); + ITypeInfo_ReleaseTypeAttr(ti, attr); + ITypeInfo_Release(ti); +} + static void test_interfaces(void) { static const WCHAR key_add[] = {'a', 0}; @@ -60,6 +85,8 @@ static void test_interfaces(void) hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE); + test_provideclassinfo(disp, &CLSID_Dictionary); + V_VT(&key) = VT_BSTR; V_BSTR(&key) = SysAllocString(key_add); V_VT(&value) = VT_BSTR; -- 2.11.4.GIT