[PATCH 2/3] scrrun: Added IProvideClassInfo support for dictionary

Nikolay Sivov nsivov at codeweavers.com
Wed Dec 7 04:33:58 CST 2016


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 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 3c8fc82..7ebf4a4 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 5201f1f..42b62b6 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 <initguid.h>
@@ -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 43b20a9..e2023f9 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 a94782f..78922b7 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.10.2




More information about the wine-patches mailing list