diff --git a/dlls/oleaut32/dispatch.c b/dlls/oleaut32/dispatch.c index 760f8aaf305..f743bcbf618 100644 --- a/dlls/oleaut32/dispatch.c +++ b/dlls/oleaut32/dispatch.c @@ -39,8 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); -static IDispatch * StdDispatch_Construct(IUnknown * punkOuter, void * pvThis, ITypeInfo * pTypeInfo); - /****************************************************************************** * DispInvoke (OLEAUT32.30) * @@ -169,32 +167,6 @@ done: return hr; } -/****************************************************************************** - * CreateStdDispatch [OLEAUT32.32] - * - * Create and return a standard IDispatch object. - * - * RETURNS - * Success: S_OK. ppunkStdDisp contains the new object. - * Failure: An HRESULT error code. - * - * NOTES - * Outer unknown appears to be completely ignored. - */ -HRESULT WINAPI CreateStdDispatch( - IUnknown* punkOuter, - void* pvThis, - ITypeInfo* ptinfo, - IUnknown** ppunkStdDisp) -{ - TRACE("(%p, %p, %p, %p)\n", punkOuter, pvThis, ptinfo, ppunkStdDisp); - - *ppunkStdDisp = (LPUNKNOWN)StdDispatch_Construct(punkOuter, pvThis, ptinfo); - if (!*ppunkStdDisp) - return E_OUTOFMEMORY; - return S_OK; -} - /****************************************************************************** * IDispatch {OLEAUT32} @@ -451,25 +423,44 @@ static const IDispatchVtbl StdDispatch_VTable = StdDispatch_Invoke }; -static IDispatch * StdDispatch_Construct( - IUnknown * punkOuter, - void * pvThis, - ITypeInfo * pTypeInfo) +/****************************************************************************** + * CreateStdDispatch [OLEAUT32.32] + * + * Create and return a standard IDispatch object. + * + * RETURNS + * Success: S_OK. ppunkStdDisp contains the new object. + * Failure: An HRESULT error code. + * + * NOTES + * Outer unknown appears to be completely ignored. + */ +HRESULT WINAPI CreateStdDispatch( + IUnknown* punkOuter, + void* pvThis, + ITypeInfo* ptinfo, + IUnknown** stddisp) { - StdDispatch * pStdDispatch; + StdDispatch *pStdDispatch; + + TRACE("(%p, %p, %p, %p)\n", punkOuter, pvThis, ptinfo, stddisp); + + if (!pvThis || !ptinfo || !stddisp) + return E_INVALIDARG; pStdDispatch = CoTaskMemAlloc(sizeof(StdDispatch)); if (!pStdDispatch) - return &pStdDispatch->IDispatch_iface; + return E_OUTOFMEMORY; pStdDispatch->IDispatch_iface.lpVtbl = &StdDispatch_VTable; pStdDispatch->pvThis = pvThis; - pStdDispatch->pTypeInfo = pTypeInfo; + pStdDispatch->pTypeInfo = ptinfo; pStdDispatch->ref = 1; /* we keep a reference to the type info so prevent it from * being destroyed until we are done with it */ - ITypeInfo_AddRef(pTypeInfo); + ITypeInfo_AddRef(ptinfo); + *stddisp = (IUnknown*)&pStdDispatch->IDispatch_iface; - return &pStdDispatch->IDispatch_iface; + return S_OK; } diff --git a/dlls/oleaut32/tests/dispatch.c b/dlls/oleaut32/tests/dispatch.c index 0f52241f996..ff63a7d592a 100644 --- a/dlls/oleaut32/tests/dispatch.c +++ b/dlls/oleaut32/tests/dispatch.c @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS +#define CONST_VTABLE + #include #include #include @@ -267,7 +270,74 @@ static void test_DispGetParam(void) VariantClear(&result); } +static HRESULT WINAPI unk_QI(IUnknown *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + return S_OK; + } + else + { + *obj = NULL; + return E_NOINTERFACE; + } +} + +static ULONG WINAPI unk_AddRef(IUnknown *iface) +{ + return 2; +} + +static ULONG WINAPI unk_Release(IUnknown *iface) +{ + return 1; +} + +static const IUnknownVtbl unkvtbl = +{ + unk_QI, + unk_AddRef, + unk_Release +}; + +static IUnknown test_unk = { &unkvtbl }; + +static void test_CreateStdDispatch(void) +{ + static const WCHAR stdole2W[] = {'s','t','d','o','l','e','2','.','t','l','b',0}; + ITypeLib *tl; + ITypeInfo *ti; + IUnknown *unk; + HRESULT hr; + + hr = CreateStdDispatch(NULL, NULL, NULL, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = CreateStdDispatch(NULL, NULL, NULL, &unk); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = LoadTypeLib(stdole2W, &tl); + ok(hr == S_OK, "got %08x\n", hr); + hr = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IUnknown, &ti); + ok(hr == S_OK, "got %08x\n", hr); + ITypeLib_Release(tl); + + hr = CreateStdDispatch(NULL, &test_unk, NULL, &unk); + ok(hr == E_INVALIDARG, "got %08x\n", hr); + + hr = CreateStdDispatch(NULL, NULL, ti, &unk); + ok(hr == E_INVALIDARG, "got %08x\n", hr); + + hr = CreateStdDispatch(NULL, &test_unk, ti, &unk); + ok(hr == S_OK, "got %08x\n", hr); + IUnknown_Release(unk); + + ITypeInfo_Release(ti); +} + START_TEST(dispatch) { test_DispGetParam(); + test_CreateStdDispatch(); }