Commit 722c28cb authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

wshom: Added IProvideClassInfo support for implemented interfaces.

parent 31fcbb6b
...@@ -31,6 +31,31 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); ...@@ -31,6 +31,31 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
#define EXPECT_HR(hr,hr_exp) \ #define EXPECT_HR(hr,hr_exp) \
ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp) ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
#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_wshshell(void) static void test_wshshell(void)
{ {
static const WCHAR notepadW[] = {'n','o','t','e','p','a','d','.','e','x','e',0}; static const WCHAR notepadW[] = {'n','o','t','e','p','a','d','.','e','x','e',0};
...@@ -66,10 +91,11 @@ static void test_wshshell(void) ...@@ -66,10 +91,11 @@ static void test_wshshell(void)
hr = IDispatch_QueryInterface(disp, &IID_IWshShell3, (void**)&shell); hr = IDispatch_QueryInterface(disp, &IID_IWshShell3, (void**)&shell);
EXPECT_HR(hr, S_OK); EXPECT_HR(hr, S_OK);
IDispatch_Release(disp); test_provideclassinfo(disp, &IID_IWshShell3);
hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
EXPECT_HR(hr, E_NOINTERFACE); EXPECT_HR(hr, E_NOINTERFACE);
IDispatch_Release(disp);
hr = IUnknown_QueryInterface(shell, &IID_IWshShell3, (void**)&sh3); hr = IUnknown_QueryInterface(shell, &IID_IWshShell3, (void**)&sh3);
EXPECT_HR(hr, S_OK); EXPECT_HR(hr, S_OK);
...@@ -87,6 +113,7 @@ static void test_wshshell(void) ...@@ -87,6 +113,7 @@ static void test_wshshell(void)
hr = IWshShell3_get_SpecialFolders(sh3, &coll); hr = IWshShell3_get_SpecialFolders(sh3, &coll);
EXPECT_HR(hr, S_OK); EXPECT_HR(hr, S_OK);
test_provideclassinfo(coll, &IID_IWshCollection);
hr = IWshCollection_QueryInterface(coll, &IID_IFolderCollection, (void**)&folders); hr = IWshCollection_QueryInterface(coll, &IID_IFolderCollection, (void**)&folders);
EXPECT_HR(hr, E_NOINTERFACE); EXPECT_HR(hr, E_NOINTERFACE);
...@@ -128,6 +155,7 @@ static void test_wshshell(void) ...@@ -128,6 +155,7 @@ static void test_wshshell(void)
SysFreeString(str); SysFreeString(str);
hr = IDispatch_QueryInterface(shortcut, &IID_IWshShortcut, (void**)&shcut); hr = IDispatch_QueryInterface(shortcut, &IID_IWshShortcut, (void**)&shcut);
EXPECT_HR(hr, S_OK); EXPECT_HR(hr, S_OK);
test_provideclassinfo(shortcut, &IID_IWshShortcut);
hr = IWshShortcut_get_Arguments(shcut, NULL); hr = IWshShortcut_get_Arguments(shcut, NULL);
ok(hr == E_POINTER, "got 0x%08x\n", hr); ok(hr == E_POINTER, "got 0x%08x\n", hr);
...@@ -155,6 +183,7 @@ static void test_wshshell(void) ...@@ -155,6 +183,7 @@ static void test_wshshell(void)
hr = IWshEnvironment_get_Item(env, NULL, NULL); hr = IWshEnvironment_get_Item(env, NULL, NULL);
ok(hr == E_POINTER, "got 0x%08x\n", hr); ok(hr == E_POINTER, "got 0x%08x\n", hr);
test_provideclassinfo(env, &IID_IWshEnvironment);
ret = (BSTR)0x1; ret = (BSTR)0x1;
hr = IWshEnvironment_get_Item(env, NULL, &ret); hr = IWshEnvironment_get_Item(env, NULL, &ret);
......
...@@ -663,4 +663,12 @@ library IWshRuntimeLibrary ...@@ -663,4 +663,12 @@ library IWshRuntimeLibrary
coclass WshNetwork { coclass WshNetwork {
[default] interface IWshNetwork2; [default] interface IWshNetwork2;
} }
[
uuid(08fed191-be19-11d3-a28b-00104bd35090),
threading(apartment)
]
coclass WshExec {
[default] interface IWshExec;
}
} }
...@@ -663,4 +663,12 @@ library IWshRuntimeLibrary ...@@ -663,4 +663,12 @@ library IWshRuntimeLibrary
coclass WshNetwork { coclass WshNetwork {
[default] interface IWshNetwork2; [default] interface IWshNetwork2;
} }
[
uuid(08fed191-be19-11d3-a28b-00104bd35090),
threading(apartment)
]
coclass WshExec {
[default] interface IWshExec;
}
} }
...@@ -28,6 +28,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(wshom); ...@@ -28,6 +28,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(wshom);
static HINSTANCE wshom_instance; static HINSTANCE wshom_instance;
static inline struct provideclassinfo *impl_from_IProvideClassInfo(IProvideClassInfo *iface)
{
return CONTAINING_RECORD(iface, struct provideclassinfo, IProvideClassInfo_iface);
}
static ITypeLib *typelib; static ITypeLib *typelib;
static ITypeInfo *typeinfos[LAST_tid]; static ITypeInfo *typeinfos[LAST_tid];
...@@ -45,6 +50,9 @@ static HRESULT load_typelib(void) ...@@ -45,6 +50,9 @@ static HRESULT load_typelib(void)
HRESULT hres; HRESULT hres;
ITypeLib *tl; ITypeLib *tl;
if(typelib)
return S_OK;
hres = LoadRegTypeLib(&LIBID_IWshRuntimeLibrary, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); hres = LoadRegTypeLib(&LIBID_IWshRuntimeLibrary, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
if(FAILED(hres)) { if(FAILED(hres)) {
ERR("LoadRegTypeLib failed: %08x\n", hres); ERR("LoadRegTypeLib failed: %08x\n", hres);
...@@ -56,13 +64,21 @@ static HRESULT load_typelib(void) ...@@ -56,13 +64,21 @@ static HRESULT load_typelib(void)
return hres; 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 get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
{ {
HRESULT hres; HRESULT hres;
if (!typelib) if (FAILED(hres = load_typelib()))
hres = load_typelib();
if (!typelib)
return hres; return hres;
if(!typeinfos[tid]) { if(!typeinfos[tid]) {
...@@ -98,6 +114,56 @@ void release_typelib(void) ...@@ -98,6 +114,56 @@ void release_typelib(void)
ITypeLib_Release(typelib); 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);
}
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;
}
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{ {
*ppv = NULL; *ppv = NULL;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "ole2.h" #include "ole2.h"
#include "olectl.h"
/* typelibs */ /* typelibs */
typedef enum tid_t { typedef enum tid_t {
...@@ -37,4 +38,12 @@ typedef enum tid_t { ...@@ -37,4 +38,12 @@ typedef enum tid_t {
HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) DECLSPEC_HIDDEN; 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;
HRESULT WINAPI WshShellFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN; HRESULT WINAPI WshShellFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment