summaryrefslogtreecommitdiffstats
path: root/private/oleauto/tests/disptest/cinvref.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'private/oleauto/tests/disptest/cinvref.cpp')
-rw-r--r--private/oleauto/tests/disptest/cinvref.cpp545
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;
+}
+
+