scrrun: Added IProvideClassInfo support for dictionary.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2016-12-07 13:33:58 +03:00 committed by Alexandre Julliard
parent 62cb1f8d6f
commit ba2e6fb2be
4 changed files with 116 additions and 4 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;