[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