HRESULT R_convertRObjectToDCOM(SEXP obj, VARIANT *var) { HRESULT status; int type = R_typeof(obj); if(!var) return(S_FALSE); #ifdef RDCOM_VERBOSE errorLog("Type of argument %d\n", type); #endif if(type == EXTPTRSXP && EXTPTR_TAG(obj) == Rf_install("R_VARIANT")) { VARIANT *tmp; tmp = (VARIANT *) R_ExternalPtrAddr(obj); if(tmp) { //XXX VariantCopy(var, tmp); return(S_OK); } } if(ISCOMIDispatch(obj)) { IDispatch *ptr; ptr = (IDispatch *) derefRIDispatch(obj); V_VT(var) = VT_DISPATCH; V_DISPATCH(var) = ptr; //XX ptr->AddRef(); return(S_OK); } if(ISSInstanceOf(obj, "COMDate")) { double val; val = NUMERIC_DATA(GET_SLOT(obj, Rf_install(".Data")))[0]; V_VT(var) = VT_DATE; V_DATE(var) = val; return(S_OK); } else if(ISSInstanceOf(obj, "COMCurrency")) { double val; val = NUMERIC_DATA(GET_SLOT(obj, Rf_install(".Data")))[0]; V_VT(var) = VT_R8; V_R8(var) = val; VariantChangeType(var, var, 0, VT_CY); return(S_OK); } else if(ISSInstanceOf(obj, "COMDecimal")) { double val; val = NUMERIC_DATA(GET_SLOT(obj, Rf_install(".Data")))[0]; V_VT(var) = VT_R8; V_R8(var) = val; VariantChangeType(var, var, 0, VT_DECIMAL); return(S_OK); } /* We have a complex object and we are not going to try to convert it directly but instead create an COM server object to represent it to the outside world. */ if((type == VECSXP && Rf_length(GET_NAMES(obj))) || Rf_length(GET_CLASS(obj)) > 0 || isMatrix(obj)) { status = createGenericCOMObject(obj, var); if(status == S_OK) return(S_OK); } if(Rf_length(obj) == 0) { V_VT(var) = VT_VOID; return(S_OK); } if(type == VECSXP || Rf_length(obj) > 1) { createRDCOMArray(obj, var); return(S_OK); } switch(type) { case STRSXP: V_VT(var) = VT_BSTR; V_BSTR(var) = AsBstr(getRString(obj, 0)); break; case INTSXP: V_VT(var) = VT_I4; V_I4(var) = R_integerScalarValue(obj, 0); break; case REALSXP: V_VT(var) = VT_R8; V_R8(var) = R_realScalarValue(obj, 0); break; case LGLSXP: V_VT(var) = VT_BOOL; V_BOOL(var) = R_logicalScalarValue(obj, 0) ? VARIANT_TRUE : VARIANT_FALSE; break; case VECSXP: break; } return(S_OK); }
bool variant_as_string( DEBUGHELPER *pH, const VARIANT &var, std::string *ret ) { if (var.vt & VT_VECTOR) return false; if (var.vt & VT_RESERVED) return false; if (var.vt & VT_ARRAY) return safearray_as_string( pH, reinterpret_cast<DWORDLONG>(var.parray), ret); if (var.vt & VT_BYREF) { // Construct a fake variant with the byref-value in it. VARTYPE vt = var.vt & ~VT_BYREF; long size = vartype_len(vt); VARIANT var2; var2.vt = vt; long source=reinterpret_cast<long>(var.byref); void *dest; if( vt == VT_VARIANT) dest = &var2; else { var2.vt=vt; dest = &(var2.bVal); } if(!ReadMem(pH,source, size, dest)) return false; std::string retval; if( ! variant_as_string( pH, var2, &retval)) return false; retval += "]"; *ret = "[" + retval; return true; } std::ostringstream os; switch (var.vt & VT_TYPEMASK ) { case VT_I2: os << V_I2(&var); break; case VT_I4: os << V_I4(&var); break; //case VT_I8: os << V_I8(&var); break; case VT_R4: os << V_R4(&var); break; case VT_R8: os << V_R8(&var); break; case VT_UNKNOWN: case VT_DISPATCH: os << "0x" << std::hex << (long )V_DISPATCH(&var); break; case VT_BOOL: os << (V_BOOL(&var)==VARIANT_FALSE?"False":"True"); break; case VT_I1: os << "'" << V_I1(&var) << "'" ; break; case VT_UI1: os << "'" << V_UI1(&var) << "'" ; break; case VT_UI2: os << V_UI2(&var); break; case VT_UI4: os << V_UI4(&var); break; case VT_INT: os << V_INT(&var); break; case VT_UINT: os << V_UINT(&var); break; case VT_ERROR: os << "error"; break; case VT_CY: os << (((double)(V_CY(&var).int64))/10000.); break; case VT_DATE: return date_as_string(V_DATE(&var), ret); break; case VT_BSTR: { long pBSTR = reinterpret_cast<long>( V_BSTR(&var) ); // if (!ReadMem(pH, reinterpret_cast<DWORDLONG>( V_BSTR(&var) ), &pBSTR)) return false; std::string ret; if (!bstr_as_string( pH, pBSTR , &ret )) return false; os << ret; }break; case VT_EMPTY: os << '@'; break; case VT_NULL: os << "null"; break; break; default: return false; } *ret = os.str(); return true; }
void EventProxy::convertJavaVariant(VARIANT *java, VARIANT *com) { switch (com->vt) { case VT_DISPATCH: { switch (java->vt) { case VT_DISPATCH: { V_DISPATCH(com) = V_DISPATCH(java); break; } case VT_DISPATCH | VT_BYREF: { V_DISPATCH(com) = *V_DISPATCHREF(java); break; } } break; } case VT_DISPATCH | VT_BYREF: { switch (java->vt) { case VT_DISPATCH: { *V_DISPATCHREF(com) = V_DISPATCH(java); break; } case VT_DISPATCH | VT_BYREF: { *V_DISPATCHREF(com) = *V_DISPATCHREF(java); break; } } break; } case VT_BOOL: { switch (java->vt) { case VT_BOOL: { V_BOOL(com) = V_BOOL(java); break; } case VT_BOOL | VT_BYREF: { V_BOOL(com) = *V_BOOLREF(java); break; } } break; } case VT_BOOL | VT_BYREF: { switch (java->vt) { case VT_BOOL: { *V_BOOLREF(com) = V_BOOL(java); break; } case VT_BOOL | VT_BYREF: { *V_BOOLREF(com) = *V_BOOLREF(java); break; } } break; } case VT_UI1: { switch (java->vt) { case VT_UI1: { V_UI1(com) = V_UI1(java); break; } case VT_UI1 | VT_BYREF: { V_UI1(com) = *V_UI1REF(java); break; } } break; } case VT_UI1 | VT_BYREF: { switch (java->vt) { case VT_UI1: { *V_UI1REF(com) = V_UI1(java); break; } case VT_UI1 | VT_BYREF: { *V_UI1REF(com) = *V_UI1REF(java); break; } } break; } case VT_I2: { switch (java->vt) { case VT_I2: { V_I2(com) = V_I2(java); break; } case VT_I2 | VT_BYREF: { V_I2(com) = *V_I2REF(java); break; } } break; } case VT_I2 | VT_BYREF: { switch (java->vt) { case VT_I2: { *V_I2REF(com) = V_I2(java); break; } case VT_I2 | VT_BYREF: { *V_I2REF(com) = *V_I2REF(java); break; } } break; } case VT_I4: { switch (java->vt) { case VT_I4: { V_I4(com) = V_I4(java); break; } case VT_I4 | VT_BYREF: { V_I4(com) = *V_I4REF(java); break; } } break; } case VT_I4 | VT_BYREF: { switch (java->vt) { case VT_I4: { *V_I4REF(com) = V_I4(java); break; } case VT_I4 | VT_BYREF: { *V_I4REF(com) = *V_I4REF(java); break; } } break; } case VT_R4: { switch (java->vt) { case VT_R4: { V_R4(com) = V_R4(java); break; } case VT_R4 | VT_BYREF: { V_R4(com) = *V_R4REF(java); break; } } break; } case VT_R4 | VT_BYREF: { switch (java->vt) { case VT_R4: { *V_R4REF(com) = V_R4(java); break; } case VT_R4 | VT_BYREF: { *V_R4REF(com) = *V_R4REF(java); break; } } break; } case VT_R8: { switch (java->vt) { case VT_R8: { V_R8(com) = V_R8(java); break; } case VT_R8 | VT_BYREF: { V_R8(com) = *V_R8REF(java); break; } } break; } case VT_R8 | VT_BYREF: { switch (java->vt) { case VT_R8: { *V_R8REF(com) = V_R8(java); break; } case VT_R8 | VT_BYREF: { *V_R8REF(com) = *V_R8REF(java); break; } } break; } case VT_I1: { switch (java->vt) { case VT_I1: { V_I1(com) = V_I1(java); break; } case VT_I1 | VT_BYREF: { V_I1(com) = *V_I1REF(java); break; } } break; } case VT_I1 | VT_BYREF: { switch (java->vt) { case VT_I1: { *V_I1REF(com) = V_I1(java); break; } case VT_I1 | VT_BYREF: { *V_I1REF(com) = *V_I1REF(java); break; } } break; } case VT_UI2: { switch (java->vt) { case VT_UI2: { V_UI2(com) = V_UI2(java); break; } case VT_UI2 | VT_BYREF: { V_UI2(com) = *V_UI2REF(java); break; } } break; } case VT_UI2 | VT_BYREF: { switch (java->vt) { case VT_UI2: { *V_UI2REF(com) = V_UI2(java); break; } case VT_UI2 | VT_BYREF: { *V_UI2REF(com) = *V_UI2REF(java); break; } } break; } case VT_UI4: { switch (java->vt) { case VT_UI4: { V_UI4(com) = V_UI4(java); break; } case VT_UI4 | VT_BYREF: { V_UI4(com) = *V_UI4REF(java); break; } } break; } case VT_UI4 | VT_BYREF: { switch (java->vt) { case VT_UI4: { *V_UI4REF(com) = V_UI4(java); break; } case VT_UI4 | VT_BYREF: { *V_UI4REF(com) = *V_UI4REF(java); break; } } break; } case VT_INT: { switch (java->vt) { case VT_INT: { V_INT(com) = V_INT(java); break; } case VT_INT | VT_BYREF: { V_INT(com) = *V_INTREF(java); break; } } break; } case VT_INT | VT_BYREF: { switch (java->vt) { case VT_INT: { *V_INTREF(com) = V_INT(java); break; } case VT_INT | VT_BYREF: { *V_INTREF(com) = *V_INTREF(java); break; } } break; } case VT_UINT: { switch (java->vt) { case VT_UINT: { V_UINT(com) = V_UINT(java); break; } case VT_UINT | VT_BYREF: { V_UINT(com) = *V_UINTREF(java); break; } } break; } case VT_UINT | VT_BYREF: { switch (java->vt) { case VT_UINT: { *V_UINTREF(com) = V_UINT(java); break; } case VT_UINT | VT_BYREF: { *V_UINTREF(com) = *V_UINTREF(java); break; } } break; } case VT_CY: { switch (java->vt) { case VT_CY: { V_CY(com) = V_CY(java); break; } case VT_CY | VT_BYREF: { V_CY(com) = *V_CYREF(java); break; } } break; } case VT_CY | VT_BYREF: { switch (java->vt) { case VT_CY: { *V_CYREF(com) = V_CY(java); break; } case VT_CY | VT_BYREF: { *V_CYREF(com) = *V_CYREF(java); break; } } break; } case VT_DATE: { switch (java->vt) { case VT_DATE: { V_DATE(com) = V_DATE(java); break; } case VT_DATE | VT_BYREF: { V_DATE(com) = *V_DATEREF(java); break; } } break; } case VT_DATE | VT_BYREF: { switch (java->vt) { case VT_DATE: { *V_DATEREF(com) = V_DATE(java); break; } case VT_DATE | VT_BYREF: { *V_DATEREF(com) = *V_DATEREF(java); break; } } break; } case VT_BSTR: { switch (java->vt) { case VT_BSTR: { V_BSTR(com) = V_BSTR(java); break; } case VT_BSTR | VT_BYREF: { V_BSTR(com) = *V_BSTRREF(java); break; } } break; } case VT_BSTR | VT_BYREF: { switch (java->vt) { case VT_BSTR: { *V_BSTRREF(com) = V_BSTR(java); break; } case VT_BSTR | VT_BYREF: { *V_BSTRREF(com) = *V_BSTRREF(java); break; } } break; } case VT_DECIMAL: { switch (java->vt) { case VT_DECIMAL: { V_DECIMAL(com) = V_DECIMAL(java); break; } case VT_DECIMAL | VT_BYREF: { V_DECIMAL(com) = *V_DECIMALREF(java); break; } } break; } case VT_DECIMAL | VT_BYREF: { switch (java->vt) { case VT_DECIMAL: { *V_DECIMALREF(com) = V_DECIMAL(java); break; } case VT_DECIMAL | VT_BYREF: { *V_DECIMALREF(com) = *V_DECIMALREF(java); break; } } break; } } }
static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt) { V_VT(var) = vt; if (vt == (VT_VARIANT|VT_BYREF)) { V_VARIANTREF(var) = realvar; } else { if (V_VT(realvar) != (vt & ~VT_BYREF)) { rb_raise(eWIN32OLERuntimeError, "variant type mismatch"); } switch(vt & ~VT_BYREF) { case VT_I1: V_I1REF(var) = &V_I1(realvar); break; case VT_UI1: V_UI1REF(var) = &V_UI1(realvar); break; case VT_I2: V_I2REF(var) = &V_I2(realvar); break; case VT_UI2: V_UI2REF(var) = &V_UI2(realvar); break; case VT_I4: V_I4REF(var) = &V_I4(realvar); break; case VT_UI4: V_UI4REF(var) = &V_UI4(realvar); break; case VT_R4: V_R4REF(var) = &V_R4(realvar); break; case VT_R8: V_R8REF(var) = &V_R8(realvar); break; #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) #ifdef V_I8REF case VT_I8: V_I8REF(var) = &V_I8(realvar); break; #endif #ifdef V_UI8REF case VT_UI8: V_UI8REF(var) = &V_UI8(realvar); break; #endif #endif case VT_INT: V_INTREF(var) = &V_INT(realvar); break; case VT_UINT: V_UINTREF(var) = &V_UINT(realvar); break; case VT_CY: V_CYREF(var) = &V_CY(realvar); break; case VT_DATE: V_DATEREF(var) = &V_DATE(realvar); break; case VT_BSTR: V_BSTRREF(var) = &V_BSTR(realvar); break; case VT_DISPATCH: V_DISPATCHREF(var) = &V_DISPATCH(realvar); break; case VT_ERROR: V_ERRORREF(var) = &V_ERROR(realvar); break; case VT_BOOL: V_BOOLREF(var) = &V_BOOL(realvar); break; case VT_UNKNOWN: V_UNKNOWNREF(var) = &V_UNKNOWN(realvar); break; case VT_ARRAY: V_ARRAYREF(var) = &V_ARRAY(realvar); break; default: rb_raise(eWIN32OLERuntimeError, "unknown type specified(setting BYREF):%d", vt); break; } } }
static HRESULT ExtractArgument(VARIANT * pvArg, WCHAR chIdentifier, BOOL * pbFreeArg, va_list * marker) { HRESULT hr = NOERROR; *pbFreeArg = FALSE; if (chIdentifier == L'T') chIdentifier = (dh_g_bIsUnicodeMode ? L'S' : L's'); switch (chIdentifier) { case L'd': V_VT(pvArg) = VT_I4; V_I4(pvArg) = va_arg(*marker, LONG); break; case L'u': V_VT(pvArg) = VT_UI4; V_UI4(pvArg) = va_arg(*marker, ULONG); break; case L'e': V_VT(pvArg) = VT_R8; V_R8(pvArg) = va_arg(*marker, DOUBLE); break; case L'b': V_VT(pvArg) = VT_BOOL; V_BOOL(pvArg) = ( va_arg(*marker, BOOL) ? VARIANT_TRUE : VARIANT_FALSE ); break; case L'v': *pvArg = *va_arg(*marker, VARIANT *); break; case L'm': V_VT(pvArg) = VT_ERROR; V_ERROR(pvArg) = DISP_E_PARAMNOTFOUND; break; case L'B': V_VT(pvArg) = VT_BSTR; V_BSTR(pvArg) = va_arg(*marker, BSTR); break; case L'S': { LPOLESTR szTemp = va_arg(*marker, LPOLESTR); V_VT(pvArg) = VT_BSTR; V_BSTR(pvArg) = SysAllocString(szTemp); if (V_BSTR(pvArg) == NULL && szTemp != NULL) hr = E_OUTOFMEMORY; *pbFreeArg = TRUE; break; } case L's': V_VT(pvArg) = VT_BSTR; hr = ConvertAnsiStrToBStr(va_arg(*marker, LPSTR), &V_BSTR(pvArg)); *pbFreeArg = TRUE; break; case L'o': V_VT(pvArg) = VT_DISPATCH; V_DISPATCH(pvArg) = va_arg(*marker, IDispatch *); break; case L'O': V_VT(pvArg) = VT_UNKNOWN; V_UNKNOWN(pvArg) = va_arg(*marker, IUnknown *); break; case L'D': V_VT(pvArg) = VT_DATE; V_DATE(pvArg) = va_arg(*marker, DATE); break; case L't': V_VT(pvArg) = VT_DATE; hr = ConvertTimeTToVariantTime(va_arg(*marker, time_t), &V_DATE(pvArg)); break; case L'W': V_VT(pvArg) = VT_DATE; hr = ConvertSystemTimeToVariantTime(va_arg(*marker, SYSTEMTIME *), &V_DATE(pvArg)); break; case L'f': V_VT(pvArg) = VT_DATE; hr = ConvertFileTimeToVariantTime(va_arg(*marker, FILETIME *), &V_DATE(pvArg)); break; case L'p': #ifndef _WIN64 V_VT(pvArg) = VT_I4; V_I4(pvArg) = (LONG) va_arg(*marker, LPVOID); #else V_VT(pvArg) = VT_I8; V_I8(pvArg) = (LONGLONG) va_arg(*marker, LPVOID); #endif break; default: hr = E_INVALIDARG; DEBUG_NOTIFY_INVALID_IDENTIFIER(chIdentifier); break; } return hr; }
HRESULT dhGetValueV(LPCWSTR szIdentifier, void * pResult, IDispatch * pDisp, LPCOLESTR szMember, va_list * marker) { VARIANT vtResult; VARTYPE returnType; HRESULT hr; DH_ENTER(L"GetValueV"); if (!pResult || !szIdentifier) return DH_EXIT(E_INVALIDARG, szMember); if (*szIdentifier == L'%') szIdentifier++; switch(*szIdentifier) { case L'd': returnType = VT_I4; break; case L'u': returnType = VT_UI4; break; case L'e': returnType = VT_R8; break; case L'b': returnType = VT_BOOL; break; case L'v': returnType = VT_EMPTY; break; case L'B': returnType = VT_BSTR; break; case L'S': returnType = VT_BSTR; break; case L's': returnType = VT_BSTR; break; case L'T': returnType = VT_BSTR; break; case L'o': returnType = VT_DISPATCH; break; case L'O': returnType = VT_UNKNOWN; break; case L't': returnType = VT_DATE; break; case L'W': returnType = VT_DATE; break; case L'f': returnType = VT_DATE; break; case L'D': returnType = VT_DATE; break; #ifndef _WIN64 case L'p': returnType = VT_I4; break; #else case L'p': returnType = VT_I8; break; #endif default: DEBUG_NOTIFY_INVALID_IDENTIFIER(*szIdentifier); return DH_EXIT(E_INVALIDARG, szMember); } hr = dhInvokeV(DISPATCH_PROPERTYGET|DISPATCH_METHOD, returnType, &vtResult, pDisp, szMember, marker); if (FAILED(hr)) return DH_EXIT(hr, szMember); switch(*szIdentifier) { case L'd': *((LONG *) pResult) = V_I4(&vtResult); break; case L'u': *((ULONG *) pResult) = V_UI4(&vtResult); break; case L'e': *((DOUBLE *) pResult) = V_R8(&vtResult); break; case L'b': *((BOOL *) pResult) = V_BOOL(&vtResult); break; case L'v': *((VARIANT *) pResult) = vtResult; break; case L'B': *((BSTR *) pResult) = V_BSTR(&vtResult); break; case L'S': *((LPWSTR *) pResult) = V_BSTR(&vtResult); break; case L's': hr = ConvertBStrToAnsiStr(V_BSTR(&vtResult), (LPSTR *) pResult); SysFreeString(V_BSTR(&vtResult)); break; case L'T': if (dh_g_bIsUnicodeMode) { *((LPWSTR *) pResult) = V_BSTR(&vtResult); } else { hr = ConvertBStrToAnsiStr(V_BSTR(&vtResult), (LPSTR *) pResult); SysFreeString(V_BSTR(&vtResult)); } break; case L'o': *((IDispatch **) pResult) = V_DISPATCH(&vtResult); if (V_DISPATCH(&vtResult) == NULL) hr = E_NOINTERFACE; break; case L'O': *((IUnknown **) pResult) = V_UNKNOWN(&vtResult); if (V_UNKNOWN(&vtResult) == NULL) hr = E_NOINTERFACE; break; case L't': hr = ConvertVariantTimeToTimeT(V_DATE(&vtResult), (time_t *) pResult); break; case L'W': hr = ConvertVariantTimeToSystemTime(V_DATE(&vtResult), (SYSTEMTIME *) pResult); break; case L'f': hr = ConvertVariantTimeToFileTime(V_DATE(&vtResult), (FILETIME *) pResult); break; case L'D': *((DATE *) pResult) = V_DATE(&vtResult); break; case L'p': #ifndef _WIN64 *((LPVOID *) pResult) = (LPVOID) V_I4(&vtResult); #else *((LPVOID *) pResult) = (LPVOID) V_I8(&vtResult); #endif break; } return DH_EXIT(hr, szMember); }
//////////////////////////////////////////////////////// // CompareVariant // //////////////////////////////////////////////////////// LONG CompareVariant ( VARIANT *pVar1, //@parm [in]: Pointer to the variant in the consumer's buffer. VARIANT *pVar2, //@parm [in]: Pointer to the variant at the backend. BOOL fCaseSensitive ) { //Handle NULL cases... if(pVar1==NULL || pVar2==NULL) { if(pVar1 == pVar2) return TRUE; return FALSE; } // The variant has to be the same type if (V_VT(pVar1) != V_VT(pVar2)) return FALSE; // Return FALSE if vt is ORed with VT_RESERVED if (V_VT(pVar1) & VT_RESERVED) return FALSE; // Return TRUE is the vt is VT_EMPTY or VT_NULL if (V_VT(pVar1)==VT_EMPTY || V_VT(pVar1)==VT_NULL) return TRUE; switch(V_VT(pVar1)) { case VT_UI1: return V_UI1(pVar1) == V_UI1(pVar2); case VT_I2: return V_I2(pVar1) == V_I2(pVar2); case VT_I4: return V_I4(pVar1) == V_I4(pVar2); case VT_R4: return V_R4(pVar1) == V_R4(pVar2); case VT_R8: return V_R8(pVar1) == V_R8(pVar2); case VT_BOOL: return V_BOOL(pVar1) == V_BOOL(pVar2); case VT_ERROR: return V_ERROR(pVar1) == V_ERROR(pVar2); case VT_CY: return memcmp(&V_CY(pVar1), &V_CY(pVar2),8)==0; case VT_DATE: return V_DATE(pVar1) == V_DATE(pVar2); case VT_BSTR: if(fCaseSensitive) return wcscmp(V_BSTR(pVar1), V_BSTR(pVar2)); else return _wcsicmp(V_BSTR(pVar1), V_BSTR(pVar2)); // As we are not testing OLE object, return FALSE for VT_UNKNOWN case VT_UNKNOWN: return FALSE; // As we are not testing OLE object, return FALSE for VT_DISPATCH case VT_DISPATCH: return FALSE; case VT_I2 | VT_BYREF: return *V_I2REF(pVar1) == *V_I2REF(pVar2); case VT_I4 | VT_BYREF: return *V_I4REF(pVar1) == *V_I4REF(pVar2); case VT_R4 | VT_BYREF: return *V_R4REF(pVar1) == *V_R4REF(pVar2); case VT_R8 | VT_BYREF: return *V_R8REF(pVar1) == *V_R8REF(pVar2); case VT_BOOL | VT_BYREF: return *V_BOOLREF(pVar1) == *V_BOOLREF(pVar2); case VT_ERROR | VT_BYREF: return *V_ERRORREF(pVar1) == *V_ERRORREF(pVar2); case VT_CY | VT_BYREF: return memcmp(V_CYREF(pVar1), V_CYREF(pVar2),8)==0; case VT_DATE | VT_BYREF: return *V_DATEREF(pVar1) == *V_DATEREF(pVar2); case VT_BSTR | VT_BYREF: if(fCaseSensitive) return wcscmp(*V_BSTRREF(pVar1), *V_BSTRREF(pVar2)); else return _wcsicmp(*V_BSTRREF(pVar1), *V_BSTRREF(pVar2)); // As we are not testing OLE object, return FALSE for VT_UNKNOWN case VT_UNKNOWN | VT_BYREF: return FALSE; // As we are not testing OLE object, return FALSE for VT_DISPATCH case VT_DISPATCH | VT_BYREF: return FALSE; } return FALSE; }
HRESULT CContextPlugin::WriteContextInformation( HANDLE hFile, IWMSContext *pContext ) { HRESULT hr = S_OK; ContextNameHint *pContextHintValues = NULL; DWORD nValue = 0; WMS_CONTEXT_TYPE wmsContextType = WMS_UNKNOWN_CONTEXT_TYPE; WCHAR wstrBuffer[MAX_PATH]; DWORD cbWritten = 0; DWORD dwRet = 0; if( NULL == pContext ) { // There is no Context, nothing to write return( hr ); } hr = pContext->GetContextType( &wmsContextType ); if( FAILED( hr ) ) { return( hr ); } ZeroMemory( wstrBuffer, MAX_PATH * sizeof( WCHAR ) ); switch( wmsContextType ) { case WMS_USER_CONTEXT_TYPE: // Create a header for this context type wcsncpy_s( wstrBuffer,MAX_PATH, CONTEXT_SAMPLE_USER_CONTEXT_HEADER, MAX_PATH ); pContextHintValues = const_cast<ContextNameHint *>(CContextPlugin::s_UserContextHintValues); break; case WMS_PRESENTATION_CONTEXT_TYPE: // Create a header for this context type wcsncpy_s( wstrBuffer, MAX_PATH,CONTEXT_SAMPLE_PRESENTATION_CONTEXT_HEADER, MAX_PATH ); pContextHintValues = const_cast<ContextNameHint *>(CContextPlugin::s_PresentationContextHintValues); break; case WMS_COMMAND_REQUEST_CONTEXT_TYPE: // Create a header for this context type wcsncpy_s( wstrBuffer,MAX_PATH, CONTEXT_SAMPLE_COMMAND_REQUEST_CONTEXT_HEADER, MAX_PATH ); pContextHintValues = const_cast<ContextNameHint *>(CContextPlugin::s_CommandContextHintValues); break; case WMS_COMMAND_RESPONSE_CONTEXT_TYPE: // Create a header for this context type wcsncpy_s( wstrBuffer,MAX_PATH, CONTEXT_SAMPLE_COMMAND_RESPONSE_CONTEXT_HEADER, MAX_PATH ); pContextHintValues = const_cast<ContextNameHint *>(CContextPlugin::s_CommandContextHintValues); break; } if( !::WriteFile( hFile, (LPVOID) wstrBuffer, DWORD(wcslen( wstrBuffer ) * sizeof( WCHAR )), &cbWritten, NULL ) ) { dwRet = GetLastError(); hr = HRESULT_FROM_WIN32( dwRet ); // Failed to write the header should we still continue // No! return( hr ); } if( NULL == pContextHintValues ) { return( E_UNEXPECTED ); } // Now we loop until -1 and Write the data while( ( NULL != pContextHintValues[nValue].wstrContextName ) && ( -1 != pContextHintValues[nValue].lContextHint ) ) { VARIANT varValue; VariantInit( &varValue ); ZeroMemory( wstrBuffer, MAX_PATH * sizeof( WCHAR ) ); hr = pContext->GetValue( pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, &varValue, 0 ); if( SUCCEEDED( hr ) ) { // Write string with data information switch( V_VT( &varValue ) ) { case VT_BSTR: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_BSTR_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_BSTR( &varValue ) ); break; case VT_I4: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_I4_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_I4( &varValue ), V_I4( &varValue ) ); break; case VT_UI8: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_UI8_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_UI8( &varValue ) ); break; case VT_CY: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_CY_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_CY( &varValue ) ); break; case VT_DATE: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_DATE_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_DATE( &varValue ) ); break; case VT_DECIMAL: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_DECIMAL_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_DECIMAL( &varValue ) ); break; case VT_UNKNOWN: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_UNKNOWN_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_UNKNOWN( &varValue ) ); break; case VT_DISPATCH: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_DISPATCH_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_DISPATCH( &varValue ) ); break; default: _snwprintf_s( wstrBuffer,MAX_PATH, MAX_PATH, CONTEXT_SAMPLE_ARRAY_TYPE_STRING, pContextHintValues[nValue].wstrContextName, pContextHintValues[nValue].lContextHint, V_ARRAY( &varValue ) ); break; } if( !::WriteFile( hFile, (LPVOID) wstrBuffer, DWORD(wcslen( wstrBuffer ) * sizeof( WCHAR )), &cbWritten, NULL ) ) { dwRet = GetLastError(); hr = HRESULT_FROM_WIN32( dwRet ); } } else { // Value probably didn't exist for this event, don't worry about it // good place to put breakpoint hr = S_OK; } // It doesn't hurt to do a VariantClear on an Empty Variant, this way we won't leak anything. VariantClear( &varValue ); nValue ++; } return( hr ); }
HRESULT CTCPropBagOnRegKey::_WriteSafeArray(CRegKey& key, const _bstr_t& strPropName, VARIANT* pVar) { ASSERT(V_ISARRAY(pVar)); ASSERT(lstrlen(strPropName)); // Get the SAFEARRAY pointer from the variant SAFEARRAY* psa = V_ARRAY(pVar); if (IsBadReadPtr(psa)) return E_POINTER; // Only support 1-dimensional arrays (currently) if (1 != SafeArrayGetDim(psa)) return E_INVALIDARG; // Get the element size of the safe array UINT cbElement = SafeArrayGetElemsize(psa); // Get the safe array type from the variant VARTYPE vt = V_VT(pVar) & ~VT_ARRAY; // Check for supported types and validate the element size switch (vt) { case VT_BOOL: if (sizeof(V_BOOL(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_I1: if (sizeof(V_I1(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_I2: if (sizeof(V_I2(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_I4: if (sizeof(V_I4(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_UI1: if (sizeof(V_UI1(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_UI2: if (sizeof(V_UI2(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_UI4: if (sizeof(V_UI4(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_ERROR: if (sizeof(V_ERROR(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_R4: if (sizeof(V_R4(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_R8: if (sizeof(V_R8(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_DECIMAL: if (sizeof(V_DECIMAL(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_CY: if (sizeof(V_CY(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_DATE: if (sizeof(V_DATE(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_BSTR: if (sizeof(V_BSTR(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_UNKNOWN: if (sizeof(V_UNKNOWN(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_DISPATCH: if (sizeof(V_DISPATCH(pVar)) != cbElement) return E_UNEXPECTED; break; case VT_VARIANT: if (sizeof(V_VARIANTREF(pVar)) != cbElement) return E_UNEXPECTED; break; default: return E_UNEXPECTED; } // Get the upper and lower bounds of the safe array HRESULT hr; LONG lUBound = 0, lLBound = 0; if (FAILED(hr = SafeArrayGetUBound(psa, 1, &lUBound))) return hr; if (FAILED(hr = SafeArrayGetLBound(psa, 1, &lLBound))) return hr; UINT nElements = lUBound - lLBound + 1; // Create a subkey with the specified name key.DeleteValue(strPropName); key.RecurseDeleteKey(strPropName); CRegKey subkey; if (!subkey.Open(key, strPropName)) return HRESULT_FROM_WIN32(GetLastError()); // Get access to the safe array data BYTE* pElement = NULL; if (FAILED(hr = SafeArrayAccessData(psa, (void**)&pElement))) return hr; // Write the variant type value subkey.WriteDWord(m_szVariantType, DWORD(V_VT(pVar))); // Write the element count value subkey.WriteDWord(m_szElementCount, DWORD(nElements)); // Write the lower bound value, if not 0 if (lLBound) subkey.WriteDWord(m_szLowerBound, DWORD(lLBound)); // Special handling for arrays of variants _bstr_t strText; if (VT_VARIANT == vt) { // Write each variant array element to the registry for (UINT i = 0; i < nElements; i++, pElement += cbElement) { // Format the value name strText.Format(m_szElementFmt, i); // Write the variant array element to the registry subkey if (FAILED(hr = WriteVariant(subkey, strText, (VARIANT*)pElement))) { TRACE1("CTCPropBagOnRegKey::_WriteSafeArray(\"%s\", pVar): ", strPropName); TRACE2("WriteVariant(subkey, \"%s\", &var) returned 0x%08X\n", strText, hr); } } } else { // Write each array element to the registry VARIANT var; V_VT(&var) = vt; for (UINT i = 0; i < nElements; i++, pElement += cbElement) { // Copy the array element to the data portion of the VARIANT memcpy(&V_NONE(&var), pElement, cbElement); // Format the value name strText.Format(m_szElementFmt, i); // Write the variant to the registry subkey if (FAILED(hr = WriteVariant(subkey, strText, &var))) { TRACE1("CTCPropBagOnRegKey::_WriteSafeArray(\"%s\", pVar): ", strPropName); TRACE2("WriteVariant(subkey, \"%s\", &var) returned 0x%08X\n", strText, hr); } } } // Release access to the safe array data VERIFY(SUCCEEDED(SafeArrayUnaccessData(psa))); // Indicate success return S_OK; }