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:
parent
62cb1f8d6f
commit
ba2e6fb2be
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue