diff options
Diffstat (limited to 'private/oleauto/tests/disptest/cinvref.cpp')
-rw-r--r-- | private/oleauto/tests/disptest/cinvref.cpp | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/private/oleauto/tests/disptest/cinvref.cpp b/private/oleauto/tests/disptest/cinvref.cpp new file mode 100644 index 000000000..ca10f566d --- /dev/null +++ b/private/oleauto/tests/disptest/cinvref.cpp @@ -0,0 +1,545 @@ +/*** +*cinvref.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CInvokeByRefSuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> +#include "disptest.h" +#include "tstsuite.h" + +ASSERTDATA + + +extern OLECHAR FAR* g_szCDispTst; + +struct TEST{ + HRESULT (*pfnTest)(IDispatch FAR*, int, int); + NAMEDESC namedesc; + OLECHAR FAR* szName; + VARTYPE vt; +}; + +#if VBA2 +OLECHAR FAR* rgszUI1Ref[] = { OLESTR("ui1ref"), OLESTR("pbval") }; +OLECHAR FAR* rgszUI1RefC[] = { OLESTR("ui1refC"), OLESTR("pbval") }; +#endif //VBA2 +OLECHAR FAR* rgszI2Ref[] = { OLESTR("i2ref"), OLESTR("psval") }; +OLECHAR FAR* rgszI2RefC[] = { OLESTR("i2refC"), OLESTR("psval") }; +OLECHAR FAR* rgszI4Ref[] = { OLESTR("i4ref"), OLESTR("plval") }; +OLECHAR FAR* rgszI4RefC[] = { OLESTR("i4refC"), OLESTR("plval") }; +OLECHAR FAR* rgszR4Ref[] = { OLESTR("r4ref"), OLESTR("pfltval") }; +OLECHAR FAR* rgszR4RefC[] = { OLESTR("r4refC"), OLESTR("pfltval") }; +OLECHAR FAR* rgszR8Ref[] = { OLESTR("r8ref"), OLESTR("pdblval") }; +OLECHAR FAR* rgszR8RefC[] = { OLESTR("r8refC"), OLESTR("pdblval") }; +OLECHAR FAR* rgszCyRef[] = { OLESTR("cyref"), OLESTR("pcyval") }; +OLECHAR FAR* rgszCyRefC[] = { OLESTR("cyrefC"), OLESTR("pcyval") }; +OLECHAR FAR* rgszBstrRef[] = { OLESTR("bstrref"), OLESTR("pbstr") }; +OLECHAR FAR* rgszBstrRefC[] = { OLESTR("bstrrefC"), OLESTR("pbstr") }; +OLECHAR FAR* rgszWBstrRef[] = { OLESTR("wbstrref"), OLESTR("pwbstr") }; +OLECHAR FAR* rgszWBstrRefC[] = { OLESTR("wbstrrefC"), OLESTR("pwbstr") }; +OLECHAR FAR* rgszDateRef[] = { OLESTR("dateref"), OLESTR("pdate") }; +OLECHAR FAR* rgszDateRefC[] = { OLESTR("daterefC"), OLESTR("pdate") }; +OLECHAR FAR* rgszErrorRef[] = { OLESTR("scoderef"), OLESTR("pscode") }; +OLECHAR FAR* rgszErrorRefC[] = { OLESTR("scoderefC"), OLESTR("pscode") }; +OLECHAR FAR* rgszBoolRef[] = { OLESTR("boolref"), OLESTR("pbool") }; +OLECHAR FAR* rgszBoolRefC[] = { OLESTR("boolrefC"), OLESTR("pbool") }; +OLECHAR FAR* rgszDispRef[] = { OLESTR("dispref"), OLESTR("ppdisp") }; + +HRESULT DefByRefTest(IDispatch FAR*, int, int); +HRESULT DispByRefTest(IDispatch FAR*, int, int); + +#if OE_WIN32 +#define TESTCASE(X,Y) X, {rgsz ## Y, DIM( rgsz ## Y)}, L#Y +#else +#define TESTCASE(X,Y) X, {rgsz ## Y, DIM( rgsz ## Y)}, #Y +#endif + +static TEST rgtest[] = +{ + // UNDONE: move this back to the end once its debugged + { TESTCASE(DispByRefTest, DispRef), VT_DISPATCH} + + , { TESTCASE(DefByRefTest, I2Ref), VT_I2} + , { TESTCASE(DefByRefTest, I2RefC), VT_I2} +#if VBA2 + , { TESTCASE(DefByRefTest, UI1Ref), VT_UI1} + , { TESTCASE(DefByRefTest, UI1RefC), VT_UI1} +#endif //VBA2 + , { TESTCASE(DefByRefTest, I4Ref), VT_I4} + , { TESTCASE(DefByRefTest, I4RefC), VT_I4} + , { TESTCASE(DefByRefTest, R4Ref), VT_R4} + , { TESTCASE(DefByRefTest, R8Ref), VT_R8} +#if OE_WIN32 && 0 + , { TESTCASE(DefByRefTest, R4RefC), VT_R4} + , { TESTCASE(DefByRefTest, R8RefC), VT_R8} +#endif + , { TESTCASE(DefByRefTest, CyRef), VT_CY} + , { TESTCASE(DefByRefTest, CyRefC), VT_CY} + , { TESTCASE(DefByRefTest, DateRef), VT_DATE} +#if OE_WIN32 && 0 + , { TESTCASE(DefByRefTest, DateRefC), VT_DATE} +#endif + , { TESTCASE(DefByRefTest, BstrRef), VT_BSTR} + , { TESTCASE(DefByRefTest, BstrRefC), VT_BSTR} + , { TESTCASE(DefByRefTest, ErrorRef), VT_ERROR} + , { TESTCASE(DefByRefTest, ErrorRefC), VT_ERROR} + , { TESTCASE(DefByRefTest, BoolRef), VT_BOOL} + , { TESTCASE(DefByRefTest, BoolRefC), VT_BOOL} + + // REVIEW: needs tests for ByRef IUnknown and IDispatch +}; + +SUITE_CONSTRUCTION_IMPL(CInvokeByRefSuite) + +SUITE_IUNKNOWN_IMPL(CInvokeByRefSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CInvokeByRefSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Invoke ByRef"), pbstr); +} + +STDMETHODIMP +CInvokeByRefSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("invref.log"), pbstr); +} + +STDMETHODIMP +CInvokeByRefSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CInvokeByRefSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + TCHAR *szFmt; + TCHAR buf[128]; + +#if HC_MPW + szFmt = "IDispatch::Invoke(%s)"; +#else + szFmt = TSTR("IDispatch::Invoke(%Fs)"); +#endif + + SPRINTF(buf, szFmt, STRING(rgtest[iTest].szName)); + *pbstr = SysAllocString(WIDESTRING(buf)); + return NOERROR; +} + +#define VT_MAXSIZE VT_UI1 + 1 + +VARIANT g_varRefMem[VT_MAXSIZE]; +VARIANTARG g_vargRef[VT_MAXSIZE]; + +static HRESULT +init() +{ + int i; + CY cy; + VARIANT FAR* pvarRef; + VARIANTARG FAR* pvarg; + + for(i = 0; i < DIM(g_vargRef); ++i){ + V_VT(&g_vargRef[i]) = VT_EMPTY; + V_VT(&g_varRefMem[i]) = VT_EMPTY; + } + +#define VAR_MAKE_BYREF(TYPE, VALUE) \ + pvarRef = &g_varRefMem[VT_ ## TYPE]; \ + pvarg = &g_vargRef[VT_ ## TYPE]; \ + V_VT(pvarRef) = VT_ ## TYPE; \ + V_ ## TYPE ## (pvarRef) = VALUE; \ + V_VT(pvarg) = VT_ ## TYPE | VT_BYREF; \ + V_BYREF(pvarg) = &V_NONE(pvarRef); + +#if VBA2 + VAR_MAKE_BYREF(UI1, 41); +#endif //VBA2 + + VAR_MAKE_BYREF(I2, 42); + + VAR_MAKE_BYREF(I4, 43L); + + VAR_MAKE_BYREF(R4, (float) 42.42); + + VAR_MAKE_BYREF(R8, 43.43); + + cy.Hi=107, cy.Lo=66; + VAR_MAKE_BYREF(CY, cy); + + VAR_MAKE_BYREF(DATE, 107.66); + + VAR_MAKE_BYREF(BSTR, SysAllocString(OLESTR("a binary string"))); + + VAR_MAKE_BYREF(ERROR, S_OK); + + VAR_MAKE_BYREF(BOOL, -1); + + return NOERROR; + +#undef VAR_MAKE_BYREF +} + +static HRESULT +clear() +{ + int i; + + for(i = 0; i < DIM(g_vargRef); ++i) + IfFailRet(VariantClearAll(&g_vargRef[i])); + + return NOERROR; +} + +HRESULT +DefByRefTest(IDispatch FAR* pdisp, int iTest, int fNamed) +{ + VARTYPE vt; + unsigned int uArgErr; + VARIANT varResult; + DISPID FAR* rgdispid; + DISPPARAMS dispparams; + HRESULT hresult, hresultTmp; + VARIANTARG vargExpected, vargExpectedRef; + + + vt = rgtest[iTest].vt; + ASSERT(vt < DIM(g_vargRef)); + + IfFailGo(init(), LError0); + ASSERT((V_VT(&g_vargRef[vt]) & VT_BYREF) != 0); + + IfFailGo( + GetDISPIDs(pdisp, &rgtest[iTest].namedesc, &rgdispid), + LError1); + + // build a variant for the expected out parameter. + // + VariantInit(&vargExpected); + + MEMCPY(&vargExpectedRef, &g_varRefMem[vt], sizeof(vargExpectedRef)); + + V_VT(&vargExpectedRef) = vt; + + // update the in value in the same way we expect the callee to... + // + switch(vt){ +#if VBA2 + case VT_UI1: + ++V_UI1(&vargExpectedRef); + break; +#endif //VBA2 + case VT_I2: + ++V_I2(&vargExpectedRef); + break; + case VT_I4: + ++V_I4(&vargExpectedRef); + break; + case VT_R4: + V_R4(&vargExpectedRef) += (float)1.0; + break; + case VT_R8: + case VT_DATE: + V_R8(&vargExpectedRef) += 1.0; + break; + case VT_CY: + ++V_CY(&vargExpectedRef).Hi; + ++V_CY(&vargExpectedRef).Lo; + break; + case VT_BSTR: + V_BSTR(&vargExpectedRef) = SysAllocString(V_BSTR(&vargExpectedRef)); +#if OE_WIN32 + _wcsupr(V_BSTR(&vargExpectedRef)); +#else + STRUPR(V_BSTR(&vargExpectedRef)); +#endif + break; + case VT_ERROR: + V_ERROR(&vargExpectedRef) = E_FAIL; + break; + case VT_BOOL: + V_BOOL(&vargExpectedRef) = 0; + break; + default: + ASSERT(UNREACHED); + break; + } + + V_VT(&vargExpected) = VT_BYREF | vt; + V_BYREF(&vargExpected) = &V_NONE(&vargExpectedRef); + + dispparams.cArgs = 1; + dispparams.rgvarg = &g_vargRef[rgtest[iTest].vt]; + if(fNamed){ + dispparams.cNamedArgs = 1; + dispparams.rgdispidNamedArgs = &rgdispid[1]; + }else{ + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + } + + uArgErr = 0; + VariantInit(&varResult); + IfFailGo( + DoInvoke(pdisp, rgdispid[0], &dispparams, &varResult, NULL, &uArgErr), + LError2); + + if(V_VT(&varResult) != VT_ERROR + || V_ERROR(&varResult) != NOERROR + || !VariantCompare(&dispparams.rgvarg[0], &vargExpected)) + { + hresult = RESULT(E_FAIL); + goto LError2; + } + + hresult = NOERROR; + +LError2:; + hresultTmp = VariantClear(&varResult); + ASSERT(hresultTmp == NOERROR); + + hresultTmp = VariantClearAll(&dispparams.rgvarg[0]); + ASSERT(hresultTmp == NOERROR); + + hresultTmp = VariantClearAll(&vargExpected); + ASSERT(hresultTmp == NOERROR); + + delete rgdispid; + +LError1:; + hresultTmp = clear(); + ASSERT(hresultTmp == NOERROR); + +LError0:; + return hresult; +} + +/*** +*HRESULT CInvokeByRefSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CInvokeByRefSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CInvokeByRefSuite::DoTest(unsigned int iTest) +{ + HRESULT hresult; + IDispatch FAR* pdisp; +#if OE_WIN32 && 0 + IDispatchW FAR* pdispW; +#endif + + if(iTest >= DIM(rgtest)) + return RESULT(E_FAIL); + + pdisp = NULL; + + IfFailRet(CreateObject(g_szCDispTst, &pdisp)); + IfFailGo(rgtest[iTest].pfnTest(pdisp, iTest, FALSE), LError0); + IfFailGo(rgtest[iTest].pfnTest(pdisp, iTest, TRUE), LError0); + + hresult = NOERROR; + +LError0:; + if(pdisp != NULL) + pdisp->Release(); + + return hresult; +} + + +// +// A little do-nothing IDispatch object +// + +class CNopDisp : public IDispatch +{ +public: + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); + STDMETHOD_(unsigned long, AddRef)(void); + STDMETHOD_(unsigned long, Release)(void); + + STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo); + + STDMETHOD(GetTypeInfo)(unsigned int itinfo, + LCID lcid, + ITypeInfo FAR* FAR* pptinfo); + + STDMETHOD(GetIDsOfNames)(REFIID riid, + OLECHAR FAR* FAR* rgszNames, + unsigned int cNames, + LCID lcid, + DISPID FAR* rgdispid); + + STDMETHOD(Invoke)(DISPID dispidMember, + REFIID riid, + LCID lcid, + unsigned short wFlags, + DISPPARAMS FAR* pdispparams, + VARIANT FAR* pvarResult, + EXCEPINFO FAR* pexcepinfo, + unsigned int FAR* puArgErr); + + CNopDisp(); + +private: + unsigned long m_cRefs; +}; + +CNopDisp::CNopDisp() +{ + m_cRefs = 1; +} + +STDMETHODIMP +CNopDisp::QueryInterface(REFIID riid, void FAR* FAR* ppv) +{ + if(riid == IID_IUnknown || riid == IID_IDispatch){ + *ppv = this; + }else{ + *ppv = NULL; + return RESULT(E_NOINTERFACE); + } + ++m_cRefs; + return NOERROR; +} + +STDMETHODIMP_(unsigned long) +CNopDisp::AddRef() +{ + return ++m_cRefs; +} + +STDMETHODIMP_(unsigned long) +CNopDisp::Release() +{ + if(--m_cRefs == 0){ + delete this; + return 0; + } + return m_cRefs; +} + +STDMETHODIMP +CNopDisp::GetTypeInfoCount(unsigned int FAR* pctinfo) +{ + *pctinfo = 0; + return NOERROR; +} + +STDMETHODIMP +CNopDisp::GetTypeInfo(unsigned int itinfo, + LCID lcid, + ITypeInfo FAR* FAR* pptinfo) +{ + return RESULT(DISP_E_BADINDEX); // we dont return any +} + +STDMETHODIMP +CNopDisp::GetIDsOfNames(REFIID riid, + OLECHAR FAR* FAR* rgszNames, + unsigned int cNames, + LCID lcid, + DISPID FAR* rgdispid) +{ + return RESULT(DISP_E_UNKNOWNNAME); // because there are no names +} + +STDMETHODIMP +CNopDisp::Invoke(DISPID dispidMember, + REFIID riid, + LCID lcid, + unsigned short wFlags, + DISPPARAMS FAR* pdispparams, + VARIANT FAR* pvarResult, + EXCEPINFO FAR* pexcepinfo, + unsigned int FAR* puArgErr) +{ + return RESULT(DISP_E_MEMBERNOTFOUND); // because there are no members +} + + + +// Tests passing a ByRef IDispatch* +HRESULT +DispByRefTest(IDispatch FAR* pdisp, int unused1, int unused2) +{ + DISPID dispid; + HRESULT hresult; + VARIANTARG varg; + VARIANT varResult; + unsigned int uArgErr = 0; + DISPPARAMS dispparams; + OLECHAR FAR* rgszNames[1]; + IDispatch FAR* pdispLocal; + + pdispLocal = NULL; + + if((pdispLocal = new CNopDisp()) == NULL) + return RESULT(E_OUTOFMEMORY); + + rgszNames[0] = OLESTR("dispref"); + IfFailGo(pdisp->GetIDsOfNames(IID_NULL, + rgszNames, 1, + LOCALE_USER_DEFAULT, + &dispid), Error); + + + V_VT(&varg) = VT_BYREF | VT_DISPATCH; + V_DISPATCHREF(&varg) = &pdispLocal; + + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + dispparams.rgvarg = &varg; + dispparams.rgdispidNamedArgs = NULL; + + VariantInit(&varResult); + + IfFailGo(DoInvoke(pdisp, + dispid, + &dispparams, + &varResult, + NULL, + &uArgErr), Error); + + if(V_VT(&varResult) != VT_ERROR || V_ERROR(&varResult) != NOERROR){ + hresult = RESULT(E_FAIL); + goto Error; + } + + hresult = NOERROR; + +Error:; + if(pdispLocal != NULL) + pdispLocal->Release(); + return hresult; +} + + |