/*** *testhelp.cpp * * Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. * Information Contained Herein Is Proprietary and Confidential. * *Purpose: * This file contains IDispatch test helpers. * * *Revision History: * * [00] 09-Nov-92 bradlo: Created. * *Implementation Notes: * *****************************************************************************/ #include #include #include #include "common.h" #include "dispdbug.h" #include "testhelp.h" #include "cunk.h" #include "cdisp.h" ASSERTDATA //--------------------------------------------------------------------- // BSTR Helpers //--------------------------------------------------------------------- /*** *PUBLIC BuildBstr(BSTR*, ...) *Purpose: * Build a BSTR that is a concatination of the given list of strings. * *Entry: * ... * *Exit: * return value = HRESULT, * S_OK * E_OUTOFMEMORY * * *pbstr = pointer to the constructed BSTR * ***********************************************************************/ extern "C" CDECL_(HRESULT) BuildBstr(BSTR FAR* pbstr, OLECHAR FAR* szName) { *pbstr = SysAllocString(szName); return NOERROR; } //--------------------------------------------------------------------- // VARIANT Utilities //--------------------------------------------------------------------- /*** *HRESULT VariantClearAll *Purpose: * Release the given variang, and if its a ByRef also release any * resources it may be pointing at. * *Entry: * pvarg = the variant to clear * *Exit: * return value = HRESULT * ***********************************************************************/ STDAPI VariantClearAll(VARIANTARG FAR* pvarg) { HRESULT hresult; if(V_ISBYREF(pvarg)){ switch(V_VT(pvarg) & ~VT_BYREF){ case VT_BSTR: SysFreeString(*V_BSTRREF(pvarg)); break; case VT_ARRAY: hresult = SafeArrayDestroy(*V_ARRAYREF(pvarg)); ASSERT(hresult == NOERROR); break; case VT_UNKNOWN: if(*V_UNKNOWNREF(pvarg) != NULL) (*V_UNKNOWNREF(pvarg))->Release(); break; case VT_DISPATCH: if(*V_DISPATCHREF(pvarg) != NULL) (*V_DISPATCHREF(pvarg))->Release(); break; } } return VariantClear(pvarg); } extern "C" int VariantCompare(VARIANT FAR* pvarLeft, VARIANT FAR* pvarRight) { void FAR* pvLeft, FAR* pvRight; if(V_VT(pvarLeft) != V_VT(pvarRight)) return FALSE; if(V_ISBYREF(pvarLeft)){ pvLeft = V_BYREF(pvarLeft); pvRight = V_BYREF(pvarRight); }else{ pvLeft = (void FAR*)&V_NONE(pvarLeft); pvRight = (void FAR*)&V_NONE(pvarRight); } switch(V_VT(pvarLeft) & ~VT_BYREF){ #if VBA2 case VT_UI1: return *(unsigned char FAR*)pvLeft == *(unsigned char FAR*)pvRight; #endif //VBA2 case VT_I2: case VT_BOOL: return *(short FAR*)pvLeft == *(short FAR*)pvRight; case VT_I4: case VT_ERROR: return *(long FAR*)pvLeft == *(long FAR*)pvRight; case VT_R4: return *(float FAR*)pvLeft == *(float FAR*)pvRight; case VT_R8: case VT_DATE: return *(double FAR*)pvLeft == *(double FAR*)pvRight; case VT_CY: return(((CY FAR*)pvLeft)->Hi == ((CY FAR*)pvRight)->Hi && ((CY FAR*)pvLeft)->Lo == ((CY FAR*)pvRight)->Lo); case VT_BSTR: return !STRCMP(STRING(*((BSTR FAR*)pvLeft)), STRING(*((BSTR FAR*)pvRight))); default: ASSERT(UNREACHED); } return FALSE; } #if 0 /*** *VARIANTARG VariantCreate(VARTYPE, ...) *Purpose: * Build and return a VARIANTARG using the given VARTYPE and value. * *Entry: * vt = the VARTYPE of the variant to create. * *Exit: * return value = VARIANTARG. The constructed VARIANTARG, returned by value. * ***********************************************************************/ extern "C" VARIANTARG VariantCreate(VARTYPE vt, ...) { OLECHAR FAR* sz; va_list args; HRESULT hresult; VARIANTARG varg; va_start(args, vt); V_VT(&varg) = vt; switch(vt & ~(VT_BYREF)){ case VT_EMPTY: break; case VT_NULL: V_I4(&varg) = 0L; break; #if VBA2 case VT_UI1: V_UI1(&varg) = va_arg(args, unsigned char); #endif //VBA2 case VT_I2: V_I2(&varg) = va_arg(args, short); break; case VT_BOOL: V_BOOL(&varg) = va_arg(args, short); break; case VT_I4: V_I4(&varg) = va_arg(args, long); break; case VT_ERROR: V_ERROR(&varg) = va_arg(args, long); break; case VT_R4: V_R4(&varg) = (float)va_arg(args, double); break; case VT_R8: V_R8(&varg) = va_arg(args, double); break; case VT_DATE: V_DATE(&varg) = va_arg(args, double); break; case VT_CY: V_CY(&varg) = va_arg(args, CY); break; case VT_BSTR: sz = va_arg(args, OLECHAR FAR*); V_BSTR(&varg) = SysAllocString(sz); break; case VT_UNKNOWN: hresult = CUnk::Create(&V_UNKNOWN(&varg)); ASSERT(hresult == NOERROR); break; case VT_DISPATCH: hresult = CDisp::Create(&V_DISPATCH(&varg)); ASSERT(hresult == NOERROR); break; default: ASSERT(UNREACHED); break; } if(V_ISBYREF(&varg)){ VARIANT FAR* pvarRef = va_arg(args, VARIANT FAR*); *pvarRef = varg; V_BYREF(&varg) = &V_NONE(pvarRef); } return varg; } #endif //--------------------------------------------------------------------- // SafeArray Helpers //--------------------------------------------------------------------- /*** *PUBLIC HRESULT first_element(unsigned int, SAFEARRAYBOUND*, long*) *Purpose: * Initialize the given array indices from the given SAFEARRAYBOUNDS. * *Entry: * cDims = count of array dimentions * rgsabound = the SafeArray bounds * *Exit: * return value = HRESULT, * S_OK * * rgIndices = indices initialized to the first element of the array * ***********************************************************************/ extern "C" HRESULT first_element( unsigned int cDims, SAFEARRAYBOUND FAR* rgsabound, long FAR* rgIndices) { unsigned int i; for(i = 0; i < cDims; ++i) rgIndices[i] = rgsabound[cDims-i-1].lLbound; return NOERROR; } /*** *PUBLIC HRESULT next_element(unsigned int, SAFEARRAYBOUND*, long*) *Purpose: * Increment the given array indices to address the next element in * the array (if there is one). * *Entry: * cDims = count of array dimentions * rgsabound = the SafeArray bounds * rgIndices = current array index * *Exit: * return value = HRESULT, * S_OK * S_FALSE - no more elements * ***********************************************************************/ extern "C" HRESULT next_element( unsigned int cDims, SAFEARRAYBOUND FAR* rgsabound, long FAR* rgIndices) { int i, iRev; long ubound; for(i = 0; i < (int)cDims; ++i){ // the bounds are stored in reverse-textual order in the descriptor iRev = cDims-i-1; ubound = rgsabound[iRev].lLbound + rgsabound[iRev].cElements; if(++rgIndices[i] < ubound) return NOERROR; rgIndices[i] = rgsabound[iRev].lLbound; } return RESULT(S_FALSE); } /*** *PUBLIC long LongOfIndices(unsigned int, long*) *Purpose: * return a long that is a function of the given array of indices. * *Entry: * cDims = count of dimentions in the array * rgIndices = an array of indices * *Exit: * return value = long, sum of array indices * ***********************************************************************/ extern "C" long LongOfIndices(unsigned int cDims, long FAR* rgIndices) { unsigned int i; long l; short s; l = 0L; for(i = 0; i < cDims; ++i){ l *= 10; l += rgIndices[i]; } s = (short)l; return (long)s; } /*** *PUBLIC HRESULT SafeArrayCreateIdentity(VARTYPE, SARRAYDESC*, SAFEARRAY**) *Purpose: * Build an "identity" SafeArray of the given VARTYPE, where we define * an identity array to be an array whose elements, when coerced to * VT_I4 are equal to the sum of the elements array indices. * *Entry: * vt = the VARTYPE of the SafeArray we are to construct * psarraydesc = pointer to structure describing shape of the SafeArray * *Exit: * return value = HRESULT * * *ppsa = SAFEARRAY FAR* * ***********************************************************************/ extern "C" HRESULT SafeArrayCreateIdentity( VARTYPE vt, SARRAYDESC FAR* psarraydesc, SAFEARRAY FAR* FAR* ppsa) { unsigned int cDims; void FAR* pv; HRESULT hresult; SAFEARRAY FAR* psa; VARIANT varI4, var; long FAR* rgIndices; SAFEARRAYBOUND FAR* rgsabound; // verify (and possibly adjust) the given VARTYPE. switch(vt){ case VT_DATE: vt = VT_R8; // REVIEW: no date coersions yet, so treat it like R8 break; case VT_ERROR: vt = VT_I4; // cannot convert to/from error, so treat like I4 break; #if VBA2 case VT_UI1: #endif //VBA2 case VT_I2: case VT_I4: case VT_R4: case VT_R8: case VT_CY: case VT_BSTR: case VT_BOOL: case VT_UNKNOWN: case VT_DISPATCH: case VT_VARIANT: break; default: // unsupported/unknown VARTYPE return RESULT(DISP_E_BADVARTYPE); } cDims = psarraydesc->cDims; rgsabound = psarraydesc->rgsabound; psa = SafeArrayCreate(vt, cDims, rgsabound); if(psa == NULL) return RESULT(E_OUTOFMEMORY); rgIndices = new FAR long[cDims]; if(rgIndices == NULL) goto LError0; VariantInit(&var); for(hresult = first_element(cDims, psa->rgsabound, rgIndices); hresult == NOERROR; hresult = next_element(cDims, psa->rgsabound, rgIndices)) { V_VT(&varI4) = VT_I4; V_I4(&varI4) = LongOfIndices(cDims, rgIndices); VariantInit(&var); switch(vt){ case VT_CY: // REVIEW: until we have coersions to/from variant V_VT(&var) = vt; V_CY(&var).Lo = V_I4(&varI4); V_CY(&var).Hi = V_I4(&varI4); pv = (void FAR*)&V_NONE(&var); goto LPutElement; case VT_BSTR: IfFailGo(VariantChangeType(&var, &varI4, 0, VT_BSTR), LError1); pv = (void FAR*)V_BSTR(&var); goto LPutElement; case VT_UNKNOWN: V_VT(&var) = vt; IfFailGo(CUnk::Create(&V_UNKNOWN(&var)), LError1); pv = (void FAR*)V_UNKNOWN(&var); goto LPutElement; case VT_DISPATCH: V_VT(&var) = vt; IfFailGo(CDisp::Create(&V_DISPATCH(&var)), LError1); pv = (void FAR*)V_DISPATCH(&var); goto LPutElement; case VT_VARIANT: pv = (void FAR*)&varI4; goto LPutElement; default: #if VBA2 // hack to keep the test passing. Using 254 instead of 255 because // of increment/decrement tests if (vt == VT_UI1 && (unsigned long)V_I4(&varI4) > 254) { V_I4(&varI4) = 254; } #endif //VBA2 IfFailGo(VariantChangeType(&var, &varI4, 0, vt), LError1); pv = (void FAR*)&V_NONE(&var); /* FALLTHROUGH */ LPutElement:; IfFailGo(SafeArrayPutElement(psa, rgIndices, pv), LError1); hresult = VariantClear(&var); ASSERT(hresult == NOERROR); break; } } if(HRESULT_FAILED(hresult)) goto LError1; delete rgIndices; *ppsa = psa; return hresult; LError1:; delete rgIndices; LError0:; SafeArrayDestroy(psa); *ppsa = NULL; return hresult; } /*** *HRESULT SafeArrayValidateIdentity(VARTYPE, SAFEARRAY*, long) *Purpose: * Verify that the given SafeArray is an identity array (as we * have defined it. * *Entry: * vt = the VARTYPE of the array * psa = pointer to the SafeArray descriptor * offset = the ammount each element is supposed to be off from * its 'identity' value. * *Exit: * return value = HRESULT * ***********************************************************************/ extern "C" HRESULT SafeArrayValidateIdentity(VARTYPE vt, SAFEARRAY FAR* psa, long offset) { void FAR* pv; HRESULT hresult; long FAR* pIndices; VARIANTARG varGet, varBaseline; switch(vt){ case VT_DATE: vt = VT_R8; // REVIEW: no date coersions yet, so pretend... goto LCommon; case VT_ERROR: vt = VT_I4; goto LCommon; #if VBA2 case VT_UI1: #endif //VBA2 case VT_I2: case VT_I4: case VT_R4: case VT_R8: case VT_CY: case VT_BSTR: case VT_BOOL: case VT_UNKNOWN: case VT_DISPATCH: LCommon:; pv = &V_NONE(&varGet); break; case VT_VARIANT: pv = &varGet; break; default: ASSERT(UNREACHED); break; } pIndices = new FAR long[psa->cDims]; if(pIndices == NULL) return RESULT(E_OUTOFMEMORY); VariantInit(&varGet); VariantInit(&varBaseline); for(hresult = first_element(psa->cDims, psa->rgsabound, pIndices); hresult == NOERROR; hresult = next_element(psa->cDims, psa->rgsabound, pIndices)) { // build the reference variant V_VT(&varBaseline) = VT_I4; V_I4(&varBaseline) = LongOfIndices(psa->cDims, pIndices) + offset; // extract the data from the current index // IfFailGo(SafeArrayGetElement(psa, pIndices, pv), LError0); if(vt != VT_VARIANT) V_VT(&varGet) = vt; // compare the extracted data against our reference. switch(vt){ case VT_CY: // REVIEW: special case CY until we have rt coersions. if (V_CY(&varGet).Hi != V_I4(&varBaseline) || V_CY(&varGet).Lo != (unsigned long)V_I4(&varBaseline)) hresult = RESULT(E_FAIL); break; case VT_VARIANT: IfFailGo( VariantChangeType(&varBaseline, &varBaseline, 0, V_VT(&varGet)), LError0); goto LCmp; case VT_BOOL: case VT_UNKNOWN: case VT_DISPATCH: #if OE_WIN32 && 0 case VT_DISPATCHW: #endif // REVIEW: havn't figured a good test for these yet... break; #if VBA2 case VT_UI1: if (V_UI1(&varGet) >= 254) goto DoneCheck; // possible overflow, so don't check // fall through to check #endif //VBA2 default: // coerce the baseline to the type of the extracted data. IfFailGo( VariantChangeType(&varBaseline, &varBaseline, 0, vt), LError0); LCmp:; if(!VariantCompare(&varGet, &varBaseline)) hresult = RESULT(E_FAIL); } DoneCheck: VariantClear(&varGet); VariantClear(&varBaseline); if(HRESULT_FAILED(hresult)) goto LError0; } LError0:; delete pIndices; return hresult; } /*** *void DbPrIndices(unsigned int, long*) *Purpose: * Print the given SafeArray indices. * *Entry: * cDims = count of array dimentions * rgindices = array of indices * *Exit: * None * ***********************************************************************/ extern "C" void DbPrIndices(unsigned int cDims, long FAR* rgindices) { unsigned int u; DbPrintf("["); for(u = 0; u < cDims; ++u){ DbPrintf("%ld", rgindices[u]); if(u+1 < cDims) DbPrintf(","); } DbPrintf("]"); } /*** *void DbPrSafeArray(SAFEARRAY*) *Purpose: * Dump the given SafeArray (the descriptor and some of its contents) * to the debug window. * *Entry: * psa = pointer to the SAFEARRAY to dump. * vt = the VARTYPE of the array data (VT_EMPTY indicates UNKNOWN) * *Exit: * None * ***********************************************************************/ extern "C" void DbPrSafeArray(SAFEARRAY FAR* psa, VARTYPE vt) { unsigned int i; long pIndices[10]; #if 1 # define MAX_ROWS 1 #else # define MAX_ROWS 3 #endif if(psa == NULL){ DbPrintf("psa == NULL\n"); return; } ASSERT((vt & (VT_ARRAY | VT_BYREF)) == 0); // verify that the features bits correspond to the given VARTYPE switch(vt){ case VT_BSTR: ASSERT(psa->fFeatures & FADF_BSTR); break; case VT_VARIANT: ASSERT(psa->fFeatures & FADF_VARIANT); break; case VT_UNKNOWN: ASSERT(psa->fFeatures & FADF_UNKNOWN); break; case VT_DISPATCH: ASSERT(psa->fFeatures & FADF_DISPATCH); break; } DbPrintf("psa => cDims=%d (", (int)psa->cDims); for(i = 0; i < psa->cDims; ++i){ DbPrintf("%lu:%ld", psa->rgsabound[i].cElements, psa->rgsabound[i].lLbound); if(i+1 < psa->cDims) DbPrintf(","); } DbPrintf(") cbElem=%d cLocks=%d fFeatures=0x%x", (int)psa->cbElements, (int)psa->cLocks, (int)psa->fFeatures); DbPrintf(" ["); if(psa->fFeatures != 0){ if(psa->fFeatures & FADF_AUTO) DbPrintf("Auto"); if(psa->fFeatures & FADF_STATIC) DbPrintf("Stat"); if(psa->fFeatures & FADF_FIXEDSIZE) DbPrintf("Fixed"); if(psa->fFeatures & FADF_BSTR) DbPrintf("Bstr"); if(psa->fFeatures & FADF_VARIANT) DbPrintf("Var"); if(psa->fFeatures & FADF_UNKNOWN) DbPrintf("Unk"); if(psa->fFeatures & FADF_DISPATCH) DbPrintf("Disp"); } DbPrintf("]"); // Dump at least some of the array contents, *if* we know the // type of the data and the array has a reasonable number of // indices. // if(vt != VT_EMPTY && psa->cDims < DIM(pIndices)){ void FAR* pv; VARIANT var; int count, rows; rows = 0; count = 0; VariantInit(&var); pv = (void FAR*)&var; DbPrintf("\n"); HRESULT hresult; for(hresult = first_element(psa->cDims, psa->rgsabound, pIndices); hresult == NOERROR; hresult = next_element(psa->cDims, psa->rgsabound, pIndices)) { SafeArrayGetElement(psa, pIndices, pv); DbPrIndices(psa->cDims, pIndices); DbPrintf("="); DbPrData(pv, vt); DbPrintf(" "); // release the element, as appropriate switch(vt){ case VT_BSTR: SysFreeString(*(BSTR FAR*)pv); break; case VT_VARIANT: VariantClear((VARIANT*)pv); break; case VT_UNKNOWN: case VT_DISPATCH: #if OE_WIN32 && 0 case VT_DISPATCHW: #endif if(*(IUnknown FAR* FAR*)pv != NULL) (*(IUnknown FAR* FAR*)pv)->Release(); break; } if((++count % 5) == 0){ DbPrintf("\n"); if(++rows >= MAX_ROWS) return; } } } DbPrintf("\n"); #undef MAX_ROWS } //--------------------------------------------------------------------- // Invoke Helpers //--------------------------------------------------------------------- /*** *HRESULT GetDISPIDs(IDispatch*, NAMEDESC*, DISPID**) *Purpose: * Helper for translating an array of names into an array of DISPIDs * via IDispatch::GetIDsOfNames(). * *Entry: * pdisp = the IDispatch* * pnd = pointer to a name descriptor * *Exit: * return value = HRESULT * * *prgdispid = array filled with DISPIDs corresponding to the given names * ***********************************************************************/ extern "C" HRESULT GetDISPIDs( IDispatch FAR* pdisp, NAMEDESC FAR* pnd, DISPID FAR* FAR* prgdispid) { HRESULT hresult; DISPID FAR* rgdispid; rgdispid = new FAR DISPID[pnd->cNames]; IfFailGo( pdisp->GetIDsOfNames( IID_NULL, pnd->rgszNames, pnd->cNames, LOCALE_SYSTEM_DEFAULT, rgdispid), LError0); *prgdispid = rgdispid; return NOERROR; LError0:; delete rgdispid; return hresult; } /*** *HRESULT DoInvoke(...) *Purpose: * Execute 'Invoke' on the given IDispatch* and log results to the * debug window. * *Entry: * ... * *Exit: * return value = HRESULT * ***********************************************************************/ extern "C" HRESULT DoInvoke( IDispatch FAR* pdisp, DISPID dispidMember, DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo, unsigned int FAR* puArgErr) { HRESULT hresult; unsigned int i, c; VARIANTARG FAR* pvarg; TCHAR buf[512], *psz; psz = buf; SPRINTF(buf, TSTR("IDispatch::Invoke(%ld, ["), dispidMember); psz = psz + STRLEN(buf); c = pdispparams->cNamedArgs; for(i = 0; i < c; ++i){ SPRINTF(psz, (i+1 < c) ? TSTR("%d,") : TSTR("%d"), pdispparams->rgdispidNamedArgs[i]); psz += STRLEN(psz); } SPRINTF(psz, TSTR("][")); psz += STRLEN(psz); c = pdispparams->cArgs; for(i = 0; i < c; ++i){ pvarg = &pdispparams->rgvarg[i]; SPRINTF(psz, (i+1 < c) ? TSTR("%s, ") : TSTR("%s"), SzOfVarg(pvarg)); psz += STRLEN(psz); } SPRINTF(psz, TSTR("],);\n")); psz += STRLEN(psz); ASSERT(psz < &buf[DIM(buf)]); DbPrintf((char FAR*) buf); hresult = pdisp->Invoke( dispidMember, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, pdispparams, pvarResult, pexcepinfo, puArgErr); psz = buf; SPRINTF(psz, TSTR(" = %s"), DbSzOfScode(GetScode(hresult))); psz += STRLEN(psz); SPRINTF(psz, TSTR(", pvarResult = %s"), pvarResult == NULL ? "NULL" : SzOfVarg(pvarResult)); psz += STRLEN(psz); if(puArgErr == NULL){ SPRINTF(psz, TSTR(", puArgErr = NULL\n")); }else{ SPRINTF(psz, TSTR(", *puArgErr = %d\n"), (int)*puArgErr); } psz += STRLEN(psz); ASSERT(psz < &buf[DIM(buf)]); DbPrintf((char FAR*) buf); return hresult; } /*** *PUBLIC BOOL IsBadInvokeParams(...) *Purpose: * Validate the given IDispatch::Invoke parameters. * *Entry: * ... * *Exit: * return value = BOOL, TRUE if bad params, FALSE if not. * ***********************************************************************/ extern "C" int IsBadInvokeParams( DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags, DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo, unsigned int FAR* puArgErr) { #if OE_MAC // REVIEW: enable this for the mac when we have the proper stubs UNUSED(dispidMember); UNUSED(lcid); UNUSED(wFlags); UNUSED(pdispparams); UNUSED(pexcepinfo); UNUSED(puArgErr); #else unsigned int size; if(IsBadReadPtr(pdispparams, sizeof(*pdispparams))) return TRUE; if(pdispparams->cArgs > 0){ size = pdispparams->cArgs * sizeof(pdispparams->rgvarg[0]); if(IsBadReadPtr(pdispparams->rgvarg, size)) return TRUE; } if(pdispparams->cNamedArgs > 0){ size = pdispparams->cNamedArgs * sizeof(pdispparams->rgdispidNamedArgs[0]); if(IsBadReadPtr(pdispparams->rgdispidNamedArgs, size)) return TRUE; } if(pvarResult != NULL){ if(IsBadWritePtr(pvarResult, sizeof(*pvarResult))) return TRUE; } if(pexcepinfo != NULL){ if(IsBadWritePtr(pexcepinfo, sizeof(*pexcepinfo))) return TRUE; } if(puArgErr != NULL){ if(IsBadWritePtr(puArgErr, sizeof(*puArgErr))) return TRUE; } #endif return FALSE; } #if OE_WIN32 extern "C" char FAR* ConvertStrWtoA(OLECHAR FAR* strIn, char FAR* buf, UINT size) { int badConversion = FALSE; WideCharToMultiByte(CP_ACP, NULL, strIn, -1, buf, size, NULL, &badConversion); return buf; } extern "C" char FAR* DbAnsiString(OLECHAR FAR* strIn) { static char buf[256]; return (ConvertStrWtoA(strIn, buf, 256)); } extern "C" OLECHAR FAR* ConvertStrAtoW(char FAR* strIn, OLECHAR FAR* buf, UINT size) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strIn, -1, buf, size) ; return buf; } extern "C" OLECHAR FAR* DbWideString(char FAR* strIn) { static OLECHAR buf[256]; return (ConvertStrAtoW(strIn, buf, 256)); } #endif /*** *char *DbSzOfScode(SCODE) *Purpose: * Return a string representing the given SCODE. * *Entry: * sc = the SCODE to return the string of. * *Exit: * return value = char*, the string representing the given SCODE. * ***********************************************************************/ extern "C" TCHAR FAR* DbSzOfScode(SCODE sc) { static TCHAR buf[64]; #if defined(UNICODE) #define DBSZOFSCODE(SC, SCTRY) if(SC == SCTRY){return L#SCTRY;}else; #else #define DBSZOFSCODE(SC, SCTRY) if(SC == SCTRY){return #SCTRY;}else; #endif DBSZOFSCODE(sc,S_OK); DBSZOFSCODE(sc,S_FALSE); DBSZOFSCODE(sc,E_UNEXPECTED); DBSZOFSCODE(sc,E_NOTIMPL); DBSZOFSCODE(sc,E_OUTOFMEMORY); DBSZOFSCODE(sc,E_INVALIDARG); DBSZOFSCODE(sc,E_NOINTERFACE); DBSZOFSCODE(sc,E_POINTER); DBSZOFSCODE(sc,E_HANDLE); DBSZOFSCODE(sc,E_ABORT); // REVIEW: ntole2 and mac compobj.h not in sync yet... // #if !defined(WIN32) && !defined(_MAC) DBSZOFSCODE(sc,E_FAIL); DBSZOFSCODE(sc,E_ACCESSDENIED); DBSZOFSCODE(sc,REGDB_E_READREGDB); DBSZOFSCODE(sc,REGDB_E_WRITEREGDB); DBSZOFSCODE(sc,REGDB_E_KEYMISSING); DBSZOFSCODE(sc,REGDB_E_INVALIDVALUE); DBSZOFSCODE(sc,REGDB_E_CLASSNOTREG); DBSZOFSCODE(sc,REGDB_E_IIDNOTREG); DBSZOFSCODE(sc,CO_E_NOTINITIALIZED); DBSZOFSCODE(sc,CO_E_ALREADYINITIALIZED); DBSZOFSCODE(sc,CO_E_CANTDETERMINECLASS); DBSZOFSCODE(sc,CO_E_CLASSSTRING); DBSZOFSCODE(sc,CO_E_IIDSTRING); DBSZOFSCODE(sc,CO_E_APPNOTFOUND); DBSZOFSCODE(sc,CO_E_APPSINGLEUSE); DBSZOFSCODE(sc,CO_E_ERRORINAPP); DBSZOFSCODE(sc,CO_E_DLLNOTFOUND); DBSZOFSCODE(sc,CO_E_ERRORINDLL); DBSZOFSCODE(sc,CO_E_WRONGOSFORAPP); DBSZOFSCODE(sc,CO_E_OBJNOTREG); DBSZOFSCODE(sc,CO_E_OBJISREG); DBSZOFSCODE(sc,CO_E_OBJNOTCONNECTED); DBSZOFSCODE(sc,CO_E_APPDIDNTREG); DBSZOFSCODE(sc,CO_E_APPDIDNTREG); #endif #if 0 DBSZOFSCODE(sc,RPC_E_BUSY); DBSZOFSCODE(sc,RPC_E_MSG_REJECTED); DBSZOFSCODE(sc,RPC_E_CONNECTION_LOST); #endif DBSZOFSCODE(sc,RPC_E_SERVER_DIED); #if 0 DBSZOFSCODE(sc,RPC_E_CANCELLED); DBSZOFSCODE(sc,RPC_E_DISPATCH_ASYNCCALL); #endif DBSZOFSCODE(sc,OLE_E_NOCONNECTION); DBSZOFSCODE(sc,OLE_E_NOTRUNNING); #if 0 DBSZOFSCODE(sc,OLE_E_NOTSUPPORTED); DBSZOFSCODE(sc,OLE_E_REGDB_KEY); DBSZOFSCODE(sc,OLE_E_REGDB_FMT); #endif DBSZOFSCODE(sc,DISP_E_UNKNOWNINTERFACE); DBSZOFSCODE(sc,DISP_E_MEMBERNOTFOUND); DBSZOFSCODE(sc,DISP_E_PARAMNOTFOUND); DBSZOFSCODE(sc,DISP_E_TYPEMISMATCH); DBSZOFSCODE(sc,DISP_E_UNKNOWNNAME); DBSZOFSCODE(sc,DISP_E_NONAMEDARGS); DBSZOFSCODE(sc,DISP_E_BADVARTYPE); DBSZOFSCODE(sc,DISP_E_EXCEPTION); DBSZOFSCODE(sc,DISP_E_OVERFLOW); DBSZOFSCODE(sc,DISP_E_BADINDEX); DBSZOFSCODE(sc,DISP_E_UNKNOWNLCID); DBSZOFSCODE(sc,DISP_E_ARRAYISLOCKED); // otherwise its unknown SPRINTF(buf, TSTR("SCODE(0x%lX)"), sc); return buf; #undef DBSZOFSCODE } LOCAL TCHAR *rgszVtNames[] = { TSTR("VT_EMPTY") , TSTR("VT_NULL") , TSTR("VT_I2") , TSTR("VT_I4") , TSTR("VT_R4") , TSTR("VT_R8") , TSTR("VT_CY") , TSTR("VT_DATE") , TSTR("VT_BSTR") , TSTR("VT_DISPATCH") , TSTR("VT_ERROR") , TSTR("VT_BOOL") , TSTR("VT_VARIANT") , TSTR("VT_UNKNOWN") // max VARIANT vartype , TSTR("invalid_vartype") // 14 is unused , TSTR("invalid_vartype") // 15 is unused , TSTR("VT_I1") , TSTR("VT_UI1") , TSTR("VT_UI2") , TSTR("VT_UI4") , TSTR("VT_I8") , TSTR("VT_UI8") , TSTR("VT_INT") , TSTR("VT_UINT") , TSTR("VT_VOID") , TSTR("VT_HRESULT") , TSTR("VT_PTR") , TSTR("VT_SAFEARRAY") , TSTR("VT_CARRAY") , TSTR("VT_USERDEFINED") , TSTR("VT_LPSTR") , TSTR("VT_LPWSTR") }; extern "C" TCHAR FAR* DbSzOfVt(VARTYPE vt) { TCHAR *p; VARTYPE vtBase; static TCHAR buf[32]; if(vt & VT_RESERVED) return TSTR("?"); p = buf; if(vt & VT_BYREF) *p++ = TSTR('&'); vtBase = vt & ~(VT_RESERVED|VT_BYREF|VT_ARRAY); if(vtBase >= DIM(rgszVtNames)){ *p++ = TSTR('?'); }else{ STRCPY(p, rgszVtNames[vtBase]); p += STRLEN(p); } if(vt & VT_ARRAY){ *p++ = TSTR('['); *p++ = TSTR(']'); } *p = TSTR('\0'); return buf; }