oleaut32: Added test showing need to QueryInterface on dual interface in ITypeInfo::Invoke.
This commit is contained in:
parent
082e39f951
commit
6971db7ee3
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
|
#define CONST_VTABLE
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ocidl.h>
|
#include <ocidl.h>
|
||||||
|
@ -210,6 +211,72 @@ static void end_host_object(DWORD tid, HANDLE thread)
|
||||||
CloseHandle(thread);
|
CloseHandle(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ItestDual TestDual, TestDualDisp;
|
||||||
|
|
||||||
|
static HRESULT WINAPI TestDual_QueryInterface(ItestDual *iface, REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch)) {
|
||||||
|
*ppvObject = &TestDualDisp;
|
||||||
|
return S_OK;
|
||||||
|
}else if(IsEqualGUID(riid, &IID_ItestDual)) {
|
||||||
|
*ppvObject = &TestDual;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppvObject = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI TestDual_AddRef(ItestDual *iface)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI TestDual_Release(ItestDual *iface)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI TestDual_GetTypeInfoCount(ItestDual *iface, UINT *pctinfo)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI TestDual_GetTypeInfo(ItestDual *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI TestDual_GetIDsOfNames(ItestDual *iface, REFIID riid, LPOLESTR *rgszNames,
|
||||||
|
UINT cNames, LCID lcid, DISPID *rgDispId)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI TestDual_Invoke(ItestDual *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
|
||||||
|
WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
|
||||||
|
UINT *puArgErr)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItestDualVtbl TestDualVtbl = {
|
||||||
|
TestDual_QueryInterface,
|
||||||
|
TestDual_AddRef,
|
||||||
|
TestDual_Release,
|
||||||
|
TestDual_GetTypeInfoCount,
|
||||||
|
TestDual_GetTypeInfo,
|
||||||
|
TestDual_GetIDsOfNames,
|
||||||
|
TestDual_Invoke
|
||||||
|
};
|
||||||
|
|
||||||
|
static ItestDual TestDual = { &TestDualVtbl };
|
||||||
|
static ItestDual TestDualDisp = { &TestDualVtbl };
|
||||||
|
|
||||||
typedef struct Widget
|
typedef struct Widget
|
||||||
{
|
{
|
||||||
const IWidgetVtbl *lpVtbl;
|
const IWidgetVtbl *lpVtbl;
|
||||||
|
@ -553,6 +620,77 @@ static const struct IWidgetVtbl Widget_VTable =
|
||||||
Widget_CloneInterface
|
Widget_CloneInterface
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI StaticWidget_QueryInterface(IStaticWidget *iface, REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
if (IsEqualIID(riid, &IID_IStaticWidget) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
|
||||||
|
{
|
||||||
|
IStaticWidget_AddRef(iface);
|
||||||
|
*ppvObject = iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppvObject = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI StaticWidget_AddRef(IStaticWidget *iface)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI StaticWidget_Release(IStaticWidget *iface)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI StaticWidget_GetTypeInfoCount(IStaticWidget *iface, UINT *pctinfo)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI StaticWidget_GetTypeInfo(IStaticWidget *iface, UINT iTInfo, LCID lcid,
|
||||||
|
ITypeInfo **ppTInfo)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI StaticWidget_GetIDsOfNames(IStaticWidget *iface, REFIID riid, LPOLESTR *rgszNames,
|
||||||
|
UINT cNames, LCID lcid, DISPID *rgDispId)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI StaticWidget_Invoke(IStaticWidget *iface, DISPID dispIdMember, REFIID riid,
|
||||||
|
LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
|
||||||
|
UINT *puArgErr)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI StaticWidget_TestDual(IStaticWidget *iface, ItestDual *p)
|
||||||
|
{
|
||||||
|
trace("TestDual()\n");
|
||||||
|
todo_wine
|
||||||
|
ok(p == &TestDual, "wrong ItestDual\n");
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IStaticWidgetVtbl StaticWidgetVtbl = {
|
||||||
|
StaticWidget_QueryInterface,
|
||||||
|
StaticWidget_AddRef,
|
||||||
|
StaticWidget_Release,
|
||||||
|
StaticWidget_GetTypeInfoCount,
|
||||||
|
StaticWidget_GetTypeInfo,
|
||||||
|
StaticWidget_GetIDsOfNames,
|
||||||
|
StaticWidget_Invoke,
|
||||||
|
StaticWidget_TestDual
|
||||||
|
};
|
||||||
|
|
||||||
|
static IStaticWidget StaticWidget = { &StaticWidgetVtbl };
|
||||||
|
|
||||||
typedef struct KindaEnum
|
typedef struct KindaEnum
|
||||||
{
|
{
|
||||||
|
@ -577,31 +715,44 @@ static HRESULT register_current_module_typelib(void)
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IWidget *Widget_Create(void)
|
static ITypeInfo *get_type_info(REFIID riid)
|
||||||
{
|
{
|
||||||
Widget *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
ITypeInfo *pTypeInfo;
|
||||||
HRESULT hr;
|
|
||||||
ITypeLib *pTypeLib;
|
ITypeLib *pTypeLib;
|
||||||
|
HRESULT hr;
|
||||||
This->lpVtbl = &Widget_VTable;
|
|
||||||
This->refs = 1;
|
|
||||||
|
|
||||||
hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &pTypeLib);
|
hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &pTypeLib);
|
||||||
ok_ole_success(hr, LoadRegTypeLib);
|
ok_ole_success(hr, LoadRegTypeLib);
|
||||||
if (SUCCEEDED(hr))
|
if (FAILED(hr))
|
||||||
{
|
return NULL;
|
||||||
ITypeInfo *pTypeInfo;
|
|
||||||
hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IWidget, &pTypeInfo);
|
hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, riid, &pTypeInfo);
|
||||||
ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
|
ITypeLib_Release(pTypeLib);
|
||||||
if (SUCCEEDED(hr))
|
ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
|
||||||
{
|
if (FAILED(hr))
|
||||||
This->pDispatchUnknown = NULL;
|
return NULL;
|
||||||
hr = CreateStdDispatch((IUnknown *)&This->lpVtbl, This, pTypeInfo, &This->pDispatchUnknown);
|
|
||||||
ok_ole_success(hr, CreateStdDispatch);
|
return pTypeInfo;
|
||||||
ITypeInfo_Release(pTypeInfo);
|
}
|
||||||
}
|
|
||||||
ITypeLib_Release(pTypeLib);
|
static IWidget *Widget_Create(void)
|
||||||
}
|
{
|
||||||
|
Widget *This;
|
||||||
|
ITypeInfo *pTypeInfo;
|
||||||
|
HRESULT hr = E_FAIL;
|
||||||
|
|
||||||
|
pTypeInfo = get_type_info(&IID_IWidget);
|
||||||
|
if(!pTypeInfo)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
||||||
|
This->lpVtbl = &Widget_VTable;
|
||||||
|
This->refs = 1;
|
||||||
|
This->pDispatchUnknown = NULL;
|
||||||
|
|
||||||
|
hr = CreateStdDispatch((IUnknown *)&This->lpVtbl, This, pTypeInfo, &This->pDispatchUnknown);
|
||||||
|
ok_ole_success(hr, CreateStdDispatch);
|
||||||
|
ITypeInfo_Release(pTypeInfo);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
return (IWidget *)&This->lpVtbl;
|
return (IWidget *)&This->lpVtbl;
|
||||||
|
@ -1167,6 +1318,34 @@ static void test_DispCallFunc(void)
|
||||||
IWidget_Release(pWidget);
|
IWidget_Release(pWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_StaticWidget(void)
|
||||||
|
{
|
||||||
|
ITypeInfo *type_info;
|
||||||
|
DISPPARAMS dispparams;
|
||||||
|
VARIANTARG vararg[4];
|
||||||
|
EXCEPINFO excepinfo;
|
||||||
|
VARIANT varresult;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
type_info = get_type_info(&IID_IStaticWidget);
|
||||||
|
|
||||||
|
/* call TestDual */
|
||||||
|
dispparams.cNamedArgs = 0;
|
||||||
|
dispparams.cArgs = 1;
|
||||||
|
dispparams.rgdispidNamedArgs = NULL;
|
||||||
|
dispparams.rgvarg = vararg;
|
||||||
|
V_VT(vararg) = VT_DISPATCH;
|
||||||
|
V_DISPATCH(vararg) = (IDispatch*)&TestDualDisp;
|
||||||
|
VariantInit(&varresult);
|
||||||
|
hr = ITypeInfo_Invoke(type_info, &StaticWidget, DISPID_TM_TESTDUAL, DISPATCH_METHOD,
|
||||||
|
&dispparams, &varresult, &excepinfo, NULL);
|
||||||
|
ok_ole_success(hr, IDispatch_Invoke);
|
||||||
|
ok(V_VT(&varresult) == VT_EMPTY, "vt %x\n", V_VT(&varresult));
|
||||||
|
VariantClear(&varresult);
|
||||||
|
|
||||||
|
ITypeInfo_Release(type_info);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(tmarshal)
|
START_TEST(tmarshal)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -1178,6 +1357,7 @@ START_TEST(tmarshal)
|
||||||
|
|
||||||
test_typelibmarshal();
|
test_typelibmarshal();
|
||||||
test_DispCallFunc();
|
test_DispCallFunc();
|
||||||
|
test_StaticWidget();
|
||||||
|
|
||||||
hr = UnRegisterTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, 1);
|
hr = UnRegisterTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, 1);
|
||||||
ok_ole_success(hr, UnRegisterTypeLib);
|
ok_ole_success(hr, UnRegisterTypeLib);
|
||||||
|
|
|
@ -46,6 +46,17 @@ library TestTypelib
|
||||||
HRESULT anotherfn(void);
|
HRESULT anotherfn(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[
|
||||||
|
odl,
|
||||||
|
oleautomation,
|
||||||
|
dual,
|
||||||
|
uuid(3f7e06fe-0bce-46f0-8b7d-3a68393c7967)
|
||||||
|
]
|
||||||
|
interface ItestDual : IDispatch
|
||||||
|
{
|
||||||
|
HRESULT test();
|
||||||
|
}
|
||||||
|
|
||||||
[
|
[
|
||||||
odl,
|
odl,
|
||||||
uuid(a1f8cae3-c947-4c5f-b57d-c87b9b5f3586),
|
uuid(a1f8cae3-c947-4c5f-b57d-c87b9b5f3586),
|
||||||
|
@ -105,7 +116,18 @@ library TestTypelib
|
||||||
|
|
||||||
[propget, id(DISPID_TM_CLONEINTERFACE)]
|
[propget, id(DISPID_TM_CLONEINTERFACE)]
|
||||||
HRESULT CloneInterface([out, retval] ISomethingFromDispatch **ppVal);
|
HRESULT CloneInterface([out, retval] ISomethingFromDispatch **ppVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
[
|
||||||
|
odl,
|
||||||
|
uuid(a1f8cae3-c947-3c5f-a57c-c88b9b6f3586),
|
||||||
|
oleautomation,
|
||||||
|
dual
|
||||||
|
]
|
||||||
|
interface IStaticWidget : IDispatch
|
||||||
|
{
|
||||||
|
[id(DISPID_TM_TESTDUAL)]
|
||||||
|
HRESULT TestDual([in] ItestDual *p);
|
||||||
}
|
}
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -32,5 +32,6 @@
|
||||||
#define DISPID_TM_VARARG 13
|
#define DISPID_TM_VARARG 13
|
||||||
#define DISPID_TM_ERROR 14
|
#define DISPID_TM_ERROR 14
|
||||||
#define DISPID_TM_CLONEINTERFACE 15
|
#define DISPID_TM_CLONEINTERFACE 15
|
||||||
|
#define DISPID_TM_TESTDUAL 16
|
||||||
|
|
||||||
#define DISPID_NOA_BSTRRET 1
|
#define DISPID_NOA_BSTRRET 1
|
||||||
|
|
Loading…
Reference in New Issue