HRESULT STDMETHODCALLTYPE CProjectItemInfo::get_InfoProperty(TC_PROJECT_NODE_INFO_PROP PropID, VARIANT * Value) { _ASSERT( Value != NULL ); CComVariant default_node_name (cDefaultName); CComVariant bitmap ((LONG)m_bitmap); CComVariant name (cProjectItemName); CComVariant description (cProjectItemDescription); CComVariant description_ex (cProjectItemDescription_ex); CComVariant help_context (0); CComVariant help_context_file_name(_T("")); CComVariant help_topic (_T("")); CComVariant help_topic_file_name (_T("")); CComVariant is_alone (true); CComVariant is_required (false); CComVariant can_edit_name (false); CComVariant can_delete (true); CComVariant recorder_create_only (false); switch (PropID) { case pniDefaultNodeName: return VariantCopy(Value, &default_node_name); case pniBitmapReference: return VariantCopy(Value, &bitmap); case pniName: return VariantCopy(Value, &name); case pniDescription: return VariantCopy(Value, &description); case pniDescriptionEx: return VariantCopy(Value, &description_ex); case pniHelpContext: return VariantCopy(Value, &help_context); case pniHelpContextFileName: return VariantCopy(Value, &help_context_file_name); case pniHelpTopic: return VariantCopy(Value, &help_topic); case pniHelpTopicFileName: return VariantCopy(Value, &help_topic_file_name); case pniIsAlone: return VariantCopy(Value, &is_alone); case pniIsRequired: return VariantCopy(Value, &is_required); case pniCanEditName: return VariantCopy(Value, &can_edit_name); case pniCanDelete: return VariantCopy(Value, &can_delete); case pniRecorderCreateOnly: return VariantCopy(Value, &recorder_create_only); default: _ASSERT( false ); return ERROR_BAD_ARGUMENTS; } }
zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int by_ref) { php_com_dotnet_object *obj; struct php_com_iterator *I; IEnumVARIANT *iev = NULL; DISPPARAMS dp; VARIANT v; unsigned long n_fetched; zval ptr; if (by_ref) { zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } obj = CDNO_FETCH(object); if (V_VT(&obj->v) != VT_DISPATCH && !V_ISARRAY(&obj->v)) { php_error_docref(NULL, E_WARNING, "variant is not an object or array VT=%d", V_VT(&obj->v)); return NULL; } memset(&dp, 0, sizeof(dp)); VariantInit(&v); I = (struct php_com_iterator*)ecalloc(1, sizeof(*I)); zend_iterator_init(&I->iter); I->iter.funcs = &com_iter_funcs; Z_PTR(I->iter.data) = I; I->code_page = obj->code_page; ZVAL_UNDEF(&I->zdata); VariantInit(&I->safe_array); VariantInit(&I->v); if (V_ISARRAY(&obj->v)) { LONG bound; UINT dims; dims = SafeArrayGetDim(V_ARRAY(&obj->v)); if (dims != 1) { php_error_docref(NULL, E_WARNING, "Can only handle single dimension variant arrays (this array has %d)", dims); goto fail; } /* same semantics as foreach on a PHP array; * make a copy and enumerate that copy */ VariantCopy(&I->safe_array, &obj->v); /* determine the key value for the array */ SafeArrayGetLBound(V_ARRAY(&I->safe_array), 1, &bound); SafeArrayGetUBound(V_ARRAY(&I->safe_array), 1, &I->sa_max); /* pre-fetch the element */ if (php_com_safearray_get_elem(&I->safe_array, &I->v, bound)) { I->key = bound; ZVAL_NULL(&ptr); php_com_zval_from_variant(&ptr, &I->v, I->code_page); ZVAL_COPY_VALUE(&I->zdata, &ptr); } else { I->key = (ulong)-1; } } else { /* can we enumerate it? */ if (FAILED(IDispatch_Invoke(V_DISPATCH(&obj->v), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL))) { goto fail; } /* get something useful out of it */ if (V_VT(&v) == VT_UNKNOWN) { IUnknown_QueryInterface(V_UNKNOWN(&v), &IID_IEnumVARIANT, (void**)&iev); } else if (V_VT(&v) == VT_DISPATCH) { IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IEnumVARIANT, (void**)&iev); } VariantClear(&v); if (iev == NULL) { goto fail; } I->ev = iev; /* Get the first element now */ if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 0) { /* indicate that we have element 0 */ I->key = 0; ZVAL_NULL(&ptr); php_com_zval_from_variant(&ptr, &I->v, I->code_page); ZVAL_COPY_VALUE(&I->zdata, &ptr); } else { /* indicate that there are no more items */ I->key = (ulong)-1; } } return &I->iter; fail: if (I) { VariantClear(&I->safe_array); VariantClear(&I->v); efree(I); } return NULL; }
// AutoWrap() - Automation helper function... HRESULT OCVariant::AutoWrap(int autoType, VARIANT *pvResult, LPOLESTR ptName, OCVariant *argchain) { // bug ? comment (see old ole32core.cpp project) // execute at the first time to safety free argchain // Allocate memory for arguments... unsigned int size = argchain ? argchain->size() : 0; VARIANT *pArgs = new VARIANT[size]; OCVariant *p = argchain; for(unsigned int i = 0; p; i++, p = p->next){ // bug ? comment (see old ole32core.cpp project) // will be reallocated BSTR whein using VariantCopy() (see by debugger) VariantInit(&pArgs[i]); // It will be free before copy. VariantCopy(&pArgs[i], &p->v); } if(argchain) delete argchain; // bug ? comment (see old ole32core.cpp project) // unexpected free original BSTR HRESULT hr = NULL; if(!v.pdispVal){ checkOLEresult("Called with NULL IDispatch. AutoWrap"); return hr; } // Convert down to ANSI (for error message only) char szName[256]; WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, sizeof(szName), NULL, NULL); // Get DISPID for name passed... DISPID dispID; hr = v.pdispVal->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID); // or _SYSTEM_ ? if(FAILED(hr)){ ostringstream oss; oss << hr << " [" << szName << "] "; oss << "IDispatch::GetIDsOfNames AutoWrap"; checkOLEresult(oss.str()); return hr; } // Build DISPPARAMS DISPPARAMS dp = { NULL, NULL, 0, 0 }; dp.cArgs = size; dp.rgvarg = pArgs; // Handle special-case for property-puts! DISPID dispidNamed = DISPID_PROPERTYPUT; if(autoType & DISPATCH_PROPERTYPUT){ dp.cNamedArgs = 1; dp.rgdispidNamedArgs = &dispidNamed; } EXCEPINFO exceptInfo; // Make the call! hr = v.pdispVal->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, autoType, &dp, pvResult, &exceptInfo, NULL); // or _SYSTEM_ ? delete [] pArgs; if(FAILED(hr)){ // Convert down to ANSI (for error message only) char szErrSource[256]; int sourceLen = WideCharToMultiByte(CP_ACP, 0, exceptInfo.bstrSource, -1, szErrSource, sizeof(szErrSource), NULL, NULL); char szErrDescription[256]; int descLen = WideCharToMultiByte(CP_ACP, 0, exceptInfo.bstrDescription, -1, szErrDescription, sizeof(szErrDescription), NULL, NULL); szErrSource[sourceLen] = 0; szErrDescription[descLen] = 0; ostringstream oss; oss << hr << " [" << szName << "] = [" << dispID << "]\r\n"; oss << szErrSource << ": "; oss << szErrDescription << "\r\n"; oss << "(It always seems to be appeared at that time you mistake calling "; oss << "'obj.get { ocv->getProp() }' <-> 'obj.call { ocv->invoke() }'.) "; oss << "IDispatch::Invoke AutoWrap"; checkOLEresult(oss.str()); return hr; } return hr; }
static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar) { HRESULT hr = S_OK; if (((vt & ~VT_BYREF) == (VT_ARRAY | VT_UI1)) && RB_TYPE_P(val, T_STRING)) { long len = RSTRING_LEN(val); void *pdest = NULL; SAFEARRAY *p = NULL; SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, len); if (!psa) { rb_raise(rb_eRuntimeError, "fail to SafeArrayCreateVector"); } hr = SafeArrayAccessData(psa, &pdest); if (SUCCEEDED(hr)) { memcpy(pdest, RSTRING_PTR(val), len); SafeArrayUnaccessData(psa); V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF); p = V_ARRAY(&(pvar->realvar)); if (p != NULL) { SafeArrayDestroy(p); } V_ARRAY(&(pvar->realvar)) = psa; if (vt & VT_BYREF) { V_VT(&(pvar->var)) = vt; V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar))); } else { hr = VariantCopy(&(pvar->var), &(pvar->realvar)); } } else { if (psa) SafeArrayDestroy(psa); } } else if (vt & VT_ARRAY) { if (val == Qnil) { V_VT(&(pvar->var)) = vt; if (vt & VT_BYREF) { V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar))); } } else { hr = ole_val_ary2variant_ary(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF)); if (SUCCEEDED(hr)) { if (vt & VT_BYREF) { V_VT(&(pvar->var)) = vt; V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar))); } else { hr = VariantCopy(&(pvar->var), &(pvar->realvar)); } } } #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) } else if ( (vt & ~VT_BYREF) == VT_I8 || (vt & ~VT_BYREF) == VT_UI8) { ole_val2variant_ex(val, &(pvar->realvar), (vt & ~VT_BYREF)); ole_val2variant_ex(val, &(pvar->var), (vt & ~VT_BYREF)); V_VT(&(pvar->var)) = vt; if (vt & VT_BYREF) { ole_set_byref(&(pvar->realvar), &(pvar->var), vt); } #endif } else if ( (vt & ~VT_BYREF) == VT_ERROR) { ole_val2variant_err(val, &(pvar->realvar)); if (vt & VT_BYREF) { ole_set_byref(&(pvar->realvar), &(pvar->var), vt); } else { hr = VariantCopy(&(pvar->var), &(pvar->realvar)); } } else { if (val == Qnil) { V_VT(&(pvar->var)) = vt; if (vt == (VT_BYREF | VT_VARIANT)) { ole_set_byref(&(pvar->realvar), &(pvar->var), vt); } else { V_VT(&(pvar->realvar)) = vt & ~VT_BYREF; if (vt & VT_BYREF) { ole_set_byref(&(pvar->realvar), &(pvar->var), vt); } } } else { ole_val2variant_ex(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF)); if (vt == (VT_BYREF | VT_VARIANT)) { ole_set_byref(&(pvar->realvar), &(pvar->var), vt); } else if (vt & VT_BYREF) { if ( (vt & ~VT_BYREF) != V_VT(&(pvar->realvar))) { hr = VariantChangeTypeEx(&(pvar->realvar), &(pvar->realvar), cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF)); } if (SUCCEEDED(hr)) { ole_set_byref(&(pvar->realvar), &(pvar->var), vt); } } else { if (vt == V_VT(&(pvar->realvar))) { hr = VariantCopy(&(pvar->var), &(pvar->realvar)); } else { hr = VariantChangeTypeEx(&(pvar->var), &(pvar->realvar), cWIN32OLE_lcid, 0, vt); } } } } if (FAILED(hr)) { ole_raise(hr, eWIN32OLERuntimeError, "failed to change type"); } }
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); }
/************************************************************************* * SafeArrayPutElement (OLEAUT32.26) * * Put an item into a SafeArray. * * PARAMS * psa [I] SafeArray to insert into * rgIndices [I] Indices to insert at * pvData [I] Data to insert * * RETURNS * Success: S_OK. The item is inserted * Failure: An HRESULT error code indicating the error. * * NOTES * See SafeArray. */ HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData) { HRESULT hRet; TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData); if (!psa || !rgIndices) return E_INVALIDARG; hRet = SafeArrayLock(psa); if (SUCCEEDED(hRet)) { PVOID lpvDest; hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvDest); if (SUCCEEDED(hRet)) { if (psa->fFeatures & FADF_VARIANT) { VARIANT* lpVariant = pvData; VARIANT* lpDest = lpvDest; hRet = VariantCopy(lpDest, lpVariant); if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet); } else if (psa->fFeatures & FADF_BSTR) { BSTR lpBstr = (BSTR)pvData; BSTR* lpDest = lpvDest; SysFreeString(*lpDest); *lpDest = SysAllocStringByteLen((char*)lpBstr, SysStringByteLen(lpBstr)); if (!*lpDest) hRet = E_OUTOFMEMORY; } else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { IUnknown *lpUnknown = pvData; IUnknown **lpDest = lpvDest; if (lpUnknown) IUnknown_AddRef(lpUnknown); if (*lpDest) IUnknown_Release(*lpDest); *lpDest = lpUnknown; } else if (psa->fFeatures & FADF_RECORD) { IRecordInfo *record; SafeArrayGetRecordInfo(psa, &record); hRet = IRecordInfo_RecordCopy(record, pvData, lpvDest); IRecordInfo_Release(record); } else /* Copy the data over */ memcpy(lpvDest, pvData, psa->cbElements); } SafeArrayUnlock(psa); } return hRet; }
// ***************************************************************** // GenerateCategories() // ***************************************************************** vector<CategoriesData>* FieldClassification::GenerateCategories(CString fieldName, FieldType fieldType, vector<VARIANT*>& srcValues, tkClassificationType ClassificationType, long numClasses, long& errorCode) { CComVariant minValue, maxValue; minValue.vt = VT_EMPTY; maxValue.vt = VT_EMPTY; long numShapes = srcValues.size(); /* we won't define intervals for string values */ if (ClassificationType != ctUniqueValues && fieldType == STRING_FIELD) { errorCode = tkNOT_UNIQUE_CLASSIFICATION_FOR_STRINGS; return NULL; } if ((numClasses <= 0 || numClasses > 1000) && (ClassificationType != ctUniqueValues)) { errorCode = tkTOO_MANY_CATEGORIES; return NULL; } if (ClassificationType == ctStandardDeviation) { errorCode = tkINVALID_PARAMETER_VALUE; return NULL; } // natural breaks aren't designed to work otherwise if (numShapes < numClasses && ClassificationType == ctNaturalBreaks) { numClasses = numShapes; } // values in specified range should be classified bool useRange = minValue.vt != VT_EMPTY && maxValue.vt != VT_EMPTY && fieldType == DOUBLE_FIELD; if (useRange) //fieldType == DOUBLE_FIELD) { double max, min; dVal(minValue, min); dVal(maxValue, max); minValue.vt = VT_R8; maxValue.vt = VT_R8; minValue.dblVal = min; maxValue.dblVal = max; } //bool useRange = minValue.vt == VT_R8 && maxValue.vt == VT_R8 && fieldType != STRING_FIELD; std::vector<CategoriesData>* result = new std::vector<CategoriesData>; if (ClassificationType == ctUniqueValues) { std::set<CComVariant> dict; CComVariant val; for (long i = 0; i < numShapes; i++) { VariantCopy(&val, srcValues[i]); if (useRange && (val.dblVal < minValue.dblVal || val.dblVal > maxValue.dblVal)) continue; if (dict.find(val) == dict.end()) dict.insert(val); } /* creating categories */ std::vector<CComVariant> values; copy(dict.begin(), dict.end(), inserter(values, values.end())); for (int i = 0; i < (int)values.size(); i++) { CategoriesData data; data.minValue = values[i]; data.maxValue = values[i]; result->push_back(data); } dict.clear(); values.clear(); } else if (ClassificationType == ctEqualSumOfValues) { CComVariant val; // sorting the values std::vector<double> values; double totalSum = 0, dValue; for (int i = 0; i < numShapes; i++) { VariantCopy(&val, srcValues[i]); if (useRange && (val.dblVal < minValue.dblVal || val.dblVal > maxValue.dblVal)) continue; dVal(val, dValue); val.Clear(); values.push_back(dValue); totalSum += dValue; } sort(values.begin(), values.end()); double step = totalSum / (double)numClasses; int index = 1; double sum = 0; for (int i = 0; i < (int)values.size(); i++) { sum += values[i]; if (sum >= step * (double)index || i == numShapes - 1) { CategoriesData data; if (index == numClasses) data.maxValue = values[values.size() - 1]; else if (i != 0) data.maxValue = (values[i] + values[i - 1]) / 2; else data.maxValue = values[0]; if (index == 1) data.minValue = values[0]; else data.minValue = (*result)[result->size() - 1].maxValue; result->push_back(data); index++; } } } else if (ClassificationType == ctEqualIntervals) { CComVariant vMin, vMax; if (useRange) { vMin = minValue; vMax = maxValue; } else { GetMinValue(srcValues, vMin, true); GetMinValue(srcValues, vMax, false); } double dMin, dMax; dVal(vMin, dMin); dVal(vMax, dMax); vMin.Clear(); vMax.Clear(); /* creating classes */ double dStep = (dMax - dMin) / (double)numClasses; while (dMin < dMax) { CategoriesData data; data.minValue = dMin; data.maxValue = dMin + dStep; result->push_back(data); dMin += dStep; } } else if (ClassificationType == ctEqualCount) { CComVariant vMin, vMax; if (useRange) { vMin = minValue; vMax = maxValue; } else { GetMinValue(srcValues, vMin, true); GetMinValue(srcValues, vMax, false); } double dMin, dMax; dVal(vMin, dMin); dVal(vMax, dMax); vMin.Clear(); vMax.Clear(); // sorting the values std::vector<double> values; for (int i = 0; i < numShapes; i++) { VariantCopy(&vMin, srcValues[i]); dVal(vMin, dMin); vMin.Clear(); values.push_back(dMin); } sort(values.begin(), values.end()); /* creating classes */ int i = 0; int count = numShapes / numClasses; for (int i = 0; i < numShapes; i += count) { dMin = values[i]; if (i + count < numShapes) dMax = values[i + count]; else dMax = values[numShapes - 1]; CategoriesData data; data.minValue = dMin; data.maxValue = dMax; result->push_back(data); } values.clear(); } else if (ClassificationType == ctNaturalBreaks) { CComVariant vMin; double dMin; // sorting the values std::vector<double> values; for (int i = 0; i < numShapes; i++) { VariantCopy(&vMin, srcValues[i]); if (useRange && (vMin.dblVal < minValue.dblVal || vMin.dblVal > maxValue.dblVal)) continue; dVal(vMin, dMin); vMin.Clear(); values.push_back(dMin); } sort(values.begin(), values.end()); CJenksBreaks breaks(&values, numClasses); if (breaks.Initialized()) { breaks.Optimize(); std::vector<long>* startIndices = breaks.get_Results(); //std::vector<int>* startIndices = breaks.TestIt(&values, numClasses); if (startIndices) { for (unsigned int i = 0; i < startIndices->size(); i++) { CategoriesData data; data.minValue = values[(*startIndices)[i]]; if (i == startIndices->size() - 1) data.maxValue = values[values.size() - 1]; else data.maxValue = values[(*startIndices)[i + 1]]; result->push_back(data); } delete startIndices; } } } // TODO: implement this as well; then it can be used in table class //else if (ClassificationType == ctStandardDeviation) // ------------------------------------------------------ // generating text expressions // ------------------------------------------------------ if (ClassificationType == ctUniqueValues) { USES_CONVERSION; for (int i = 0; i < (int)result->size(); i++) { //CString strExpression; CString strValue; CComVariant* val = &(*result)[i].minValue; switch (val->vt) { case VT_BSTR: strValue = OLE2CA(val->bstrVal); (*result)[i].name = strValue; (*result)[i].expression = "[" + fieldName + "] = \"" + strValue + "\""; break; case VT_R8: strValue.Format("%g", val->dblVal); (*result)[i].name = strValue; (*result)[i].expression = "[" + fieldName + "] = " + strValue; break; case VT_I4: strValue.Format("%i", val->lVal); (*result)[i].name = strValue; (*result)[i].expression = "[" + fieldName + "] = " + strValue; break; } } } else //if (ClassificationType == ctEqualIntervals || ClassificationType == ctEqualCount) { // in case % is present, we need to put to double it for proper formatting fieldName.Replace("%", "%%"); for (int i = 0; i < (int)result->size(); i++) { CategoriesData* data = &((*result)[i]); CString strExpression, strName, sFormat; if (i == 0) { data->minValue.dblVal = floor(data->minValue.dblVal); } else if (i == result->size() - 1) { data->maxValue.dblVal = ceil(data->maxValue.dblVal); } CString upperBound = (i == result->size() - 1) ? "<=" : "<"; switch (data->minValue.vt) { case VT_R8: sFormat = "%g"; data->name = Utility::FormatNumber(data->minValue.dblVal, sFormat) + " - " + Utility::FormatNumber(data->maxValue.dblVal, sFormat); data->expression.Format("[" + fieldName + "] >= %f AND [" + fieldName + "] " + upperBound + " %f", data->minValue.dblVal, data->maxValue.dblVal); break; case VT_I4: sFormat = "%i"; data->name = Utility::FormatNumber(data->minValue.dblVal, sFormat) + " - " + Utility::FormatNumber(data->maxValue.dblVal, sFormat); data->expression.Format("[" + fieldName + "] >= %i AND [" + fieldName + "] " + upperBound + " %i", data->minValue.lVal, data->maxValue.lVal); break; } } } if (result->size() > 0) { return result; } else { delete result; return NULL; } }
STDMETHODIMP CProperties::putref_pVariant(VARIANT* newVal) { return VariantCopy(&m_variantVal, newVal); }
VARIANT* set( JNIEnv* env, jobject src ) { VARIANT* pv = new VARIANT(); VariantClear(pv); VariantCopy(pv, com4jVariantToVARIANT(env,src)); return pv; }
STDMETHODIMP CProperties::get_pVariant(VARIANT* pVal) { return VariantCopy(pVal, &m_variantVal); }
STDMETHODIMP CProperties::put_pVariant(VARIANT newVal) { if (newVal.vt != VARENUM::VT_DISPATCH){ return VariantCopy(&m_variantVal, &newVal); } }
STDMETHODIMP LightOPCGroup::Write(DWORD dwCount, OPCHANDLE *phServer, VARIANT *pItemValues, DWORD dwTransactionID, DWORD *pdwCancelID, HRESULT **ppErrors) { HRESULT hr = S_FALSE; HRESULT *errs = 0; loRequest *rq = 0; unsigned items_ok = 0; LO_CHECK_STATEz1("AsyncIO2:Write", ppErrors); UL_TRACE((LOG_GRH("AsyncIO2:Write(%u)..."), dwCount)); if (!phServer || !dwCount || !pdwCancelID || !pItemValues) { hr = E_INVALIDARG; goto Return; } *pdwCancelID = 0; if (owner->q_req.metric_overload) { hr = CONNECT_E_ADVISELIMIT; goto Return; } errs = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT)); rq = lo_req_alloc(dwCount, loUPL_AsyncWrite); if (!rq || !errs) { hr = E_OUTOFMEMORY; goto Return; } loTagPair_init(rq->upl.tagpair, dwCount); rq->operation = loRQ_OP_WRITE | loRQ_CONN_DATABACK | loRQ_DEVICE; rq->group_key = ServerHandle; rq->serv_key = owner->serv_key; rq->upl.transaction_id = dwTransactionID; rq->upl.rctx = owner->ctxt; lock_read(); rq->upl.rctx.cta.vc_lcid = grLCID; if (owner->access_mode & loAM_RDONLY_OP) { unsigned ii; for(ii = 0; ii < dwCount; ii++) errs[ii] = OPC_E_BADRIGHTS; goto Unlock; } if (0 == (advise_present & loRQ_CONN_DATABACK)/*conn_databack*/) hr = CONNECT_E_NOCONNECTION; else { unsigned ii; loTagPair *tpl = rq->upl.tagpair; // HRESULT *errors = rq->upl.errors; LightOPCItem *it; loTagEntry *tags = owner->se->tags; for(ii = 0; ii < dwCount; ii++, pItemValues++) if (!(it = by_index(phServer[ii]))) errs[ii] = OPC_E_INVALIDHANDLE; else { loTagEntry *te = &tags[it->tid]; #if 0 != LO_CHECK_RIGHTS if (!(OPC_WRITEABLE & te->attr.taRights)) errs[ii] = OPC_E_BADRIGHTS; else #endif if (VT_EMPTY == V_VT(pItemValues) || /*) *errors = OPC_E_BADTYPE; else if (*/S_OK == (errs[ii] = VariantCopy(&rq->upl.variant[ii], pItemValues))) { tpl->tpTi = te->attr.taTi; tpl->tpRt = te->attr.taRt; tpl->tpAP = it->AcPath; tpl++; rq->upl.opchandle[items_ok++] = it->hClient; errs[ii] = S_OK; } }/* end of for */ } Unlock: unlock(); if (items_ok) { rq->upl.used = items_ok; rq->upl.master_err = hr = items_ok == dwCount? S_OK: S_FALSE; if (0 == (*pdwCancelID = lo_req_put_async(&owner->q_req, rq))) hr = CONNECT_E_ADVISELIMIT; rq = 0; } Return: if (rq) lo_req_free(rq); if (SUCCEEDED(hr)) { if (ppErrors) *ppErrors = errs, errs = 0; UL_NOTICE((LOG_GRH("AsyncIO2:Write(%u) = %u -> %x Ok"), dwCount, items_ok, *pdwCancelID)); } else { UL_INFO((LOG_GRH("AsyncIO2:Write(%u) = %u /%s"), dwCount, items_ok, loStrError(hr))); } if (errs) loComFree(errs); LO_FINISH(); return hr; }
STDMETHODIMP LightOPCGroup::Write(DWORD dwCount, OPCHANDLE *phServer, VARIANT *pItemValues, HRESULT **ppErrors) { HRESULT hr = S_OK; HRESULT *err = 0; unsigned items_ok = 0; loRequest *rq; LO_CHECK_STATEz1("SyncIO:Write", ppErrors); UL_TRACE((LOG_GRH("SyncIO:Write(%u)..."), dwCount)); if (!phServer || !pItemValues || !dwCount) { hr = E_INVALIDARG; goto Return; } err = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT)); rq = lo_req_alloc(dwCount, loUPL_variant /*| loUPL_errors*/ | loUPL_tagpair); if (!rq || !err) { hr = E_OUTOFMEMORY; goto Return; } rq->operation = loRQ_OP_WRITE | loRQ_SYNC | loRQ_DEVICE; rq->group_key = ServerHandle; rq->serv_key = owner->serv_key; rq->com_allocated = rq->upl.errors = err; loTagPair_init(rq->upl.tagpair, dwCount); rq->upl.rctx = owner->ctxt; lock_read(); rq->upl.rctx.cta.vc_lcid = grLCID; if (owner->access_mode & loAM_RDONLY_OP) { unsigned ii; for(ii = 0; ii < dwCount; ii++) err[ii] = OPC_E_BADRIGHTS; } else { loService *se = owner->se; loTagEntry *tags = se->tags; loTagPair *tpl = rq->upl.tagpair; // HRESULT *errors = rq->upl.errors; VARIANT *variant = rq->upl.variant; LightOPCItem *it; unsigned ii; for(ii = 0; ii < dwCount; ii++, tpl++, pItemValues++) if (!(it = by_index(phServer[ii]))) err[ii] = OPC_E_INVALIDHANDLE; else { loTagEntry *te = &tags[it->tid]; #if 0 != LO_CHECK_RIGHTS if (!(OPC_WRITEABLE & te->attr.taRights)) err[ii] = OPC_E_BADRIGHTS; else #endif if (VT_EMPTY == V_VT(pItemValues) ||/*) *errors = OPC_E_BADTYPE; else if (*/ S_OK == (err[ii] = VariantCopy(&variant[ii], pItemValues))) { err[ii] = S_OK; tpl->tpTi = te->attr.taTi; tpl->tpRt = te->attr.taRt; tpl->tpAP = it->AcPath; items_ok++; } else UL_TRACE((LOG_GRH("SyncIO:Write(%u) [ %x / %x ] %s"), ii, V_VT(pItemValues), taVTYPE(&te->attr), loStrError(err[ii]))); } rq->upl.used = dwCount; } unlock(); // rq->upl.used = dwCount; if (0 == items_ok) { // memcpy(err, rq->upl.errors, dwCount * sizeof(*err)); rq->com_allocated = 0; lo_req_free(rq); hr = S_FALSE; } else { rq->upl.master_err = items_ok == dwCount? S_OK: S_FALSE; err = 0; if (rq = lo_req_put_sync(&owner->q_req, &owner->q_ret, rq)) { hr = rq->upl.master_err; // memcpy(err, rq->upl.errors, dwCount * sizeof(*err)); err = rq->upl.errors; rq->com_allocated = 0; lo_req_free(rq); } else hr = LO_E_SHUTDOWN; } Return: if (SUCCEEDED(hr)) { if (ppErrors) *ppErrors = err, err = 0; // if (items_ok != dwCount && hr == S_OK) hr = S_FALSE; UL_NOTICE((LOG_GRH("SyncIO:Write(%u) = %u Ok"), dwCount, items_ok)); } else { UL_INFO((LOG_GRH("SyncIO:Write(%u) = %u /%s"), dwCount, items_ok, loStrError(hr))); } if (err) loComFree(err); LO_FINISH(); return hr; }
STDMETHODIMP CPyCOMTest::GetSetVariant(VARIANT var, VARIANT *out) { VariantClear(out); // necessary? return VariantCopy(out, &var); }
lw_thrrettype loUpdatePipe(void *vse) { loService *se = (loService *)vse; if (!loIS_VALID(se)) { UL_ERROR((LOGID, "loUpdatePipe() prematurely terminated")); lw_RETURN; } UL_TRACE((LOGID, "loUpdatePipe() started...")); loThrControl_accept(&se->update_pipe); lw_mutex_lock(&se->update_pipe.lk); for(;; lw_conds_wait(&se->update_pipe.cond, &se->update_pipe.lk)) if (0 != se->update_pipe.tstate) { if (0 > se->update_pipe.tstate) break; /* terminate thread */ lw_mutex_unlock(&se->update_pipe.lk); lw_rw_wrlock(&se->lkPrim); lw_mutex_lock(&se->update_pipe.lk); if (0 > se->update_pipe.tstate) { lw_rw_unlock(&se->lkPrim); break; }/* terminate thread */ { /* do actual update here */ unsigned ii = se->lastused; loTagEntry *te = se->tags; loTagValue *ts = se->secondary; loTrid prim_changed = se->sec_trid; while(ii--) { te++; ts++; if (ts->tvTi) { if (ts->tvTi == loCH_TIMESTAMP) te->prim.tsTime = ts->tvState.tsTime; else { te->primChanged = prim_changed; te->prim = ts->tvState; #if LO_KEEP_OLD_CACHE { HRESULT hr; if (S_OK != (hr = VariantCopy(&te->primValue, &ts->tvValue))) { LO_E_BADTYPE_QUAL(hr, te->prim.tsError, te->prim.tsQuality); UL_WARNING((LOGID, "%!l loUpdatePipe(VariantCopy())", hr)); } } #else VariantClear(&te->primValue); te->primValue = ts->tvValue; VARIANTINIT(&ts->tvValue); #endif } ts->tvTi = 0; } } } se->prim_trid = se->sec_trid; #if 0 != LO_EV_TIMESTAMP if (se->ts_prim != se->ts_sec) { freeX(se->ts_prim); se->ts_prim = se->ts_sec; } memcpy(se->ts_prim, se->ts_prim + se->ts_size, se->ts_size * sizeof(FILETIME)); #endif lw_rw_unlock(&se->lkPrim); se->update_pipe.tstate = 0; lw_condb_broadcast(&se->lkTridWait); } loThrControl_finish(&se->update_pipe); lw_mutex_unlock(&se->update_pipe.lk); UL_NOTICE((LOGID, "loUpdatePipe() finished")); lw_RETURN; }
JNIEXPORT void JNICALL Java_com4j_Variant_set0(JNIEnv * env, jobject, jobject value, jobject image) { VARIANT *destVar = (VARIANT*)env->GetDirectBufferAddress(image); VARIANT *newVar = convertToVariant(env, value); VariantCopy(destVar, newVar); }
/* Copy data items from one array to another. Destination data is freed before copy. */ static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest) { HRESULT hr = S_OK; if (!psa->pvData) return S_OK; if (!dest->pvData || psa->fFeatures & FADF_DATADELETED) return E_INVALIDARG; else { ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); dest->fFeatures = (dest->fFeatures & FADF_CREATEVECTOR) | (psa->fFeatures & ~ignored_copy_features); if (psa->fFeatures & FADF_VARIANT) { VARIANT *src_var = psa->pvData; VARIANT *dest_var = dest->pvData; while(ulCellCount--) { HRESULT hRet; /* destination is cleared automatically */ hRet = VariantCopy(dest_var, src_var); if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%08x, element %u\n", hRet, ulCellCount); src_var++; dest_var++; } } else if (psa->fFeatures & FADF_BSTR) { BSTR *src_bstr = psa->pvData; BSTR *dest_bstr = dest->pvData; while(ulCellCount--) { SysFreeString(*dest_bstr); if (*src_bstr) { *dest_bstr = SysAllocStringByteLen((char*)*src_bstr, SysStringByteLen(*src_bstr)); if (!*dest_bstr) return E_OUTOFMEMORY; } else *dest_bstr = NULL; src_bstr++; dest_bstr++; } } else if (psa->fFeatures & FADF_RECORD) { BYTE *dest_data = dest->pvData; BYTE *src_data = psa->pvData; IRecordInfo *record; SafeArrayGetRecordInfo(psa, &record); while (ulCellCount--) { /* RecordCopy() clears destination record */ hr = IRecordInfo_RecordCopy(record, src_data, dest_data); if (FAILED(hr)) break; src_data += psa->cbElements; dest_data += psa->cbElements; } SafeArraySetRecordInfo(dest, record); /* This value is set to 32 bytes by default on descriptor creation, update with actual structure size. */ dest->cbElements = psa->cbElements; IRecordInfo_Release(record); } else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { IUnknown **dest_unk = dest->pvData; IUnknown **src_unk = psa->pvData; /* release old iface, addref new one */ while (ulCellCount--) { if (*dest_unk) IUnknown_Release(*dest_unk); *dest_unk = *src_unk; if (*dest_unk) IUnknown_AddRef(*dest_unk); src_unk++; dest_unk++; } } else { /* Copy the data over */ memcpy(dest->pvData, psa->pvData, ulCellCount * psa->cbElements); } if (psa->fFeatures & FADF_HAVEIID) { GUID guid; SafeArrayGetIID(psa, &guid); SafeArraySetIID(dest, &guid); } else if (psa->fFeatures & FADF_HAVEVARTYPE) { SAFEARRAY_SetHiddenDWORD(dest, SAFEARRAY_GetHiddenDWORD(psa)); } } return hr; }
STDMETHODIMP CBDictionary::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { if((dispIdMember & 0xff000000) != 0x65000000) return CBDispatch<IVariantDictionary>::g_typeinfo.Invoke((IVariantDictionary*)this, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); dispIdMember &= 0xffffff; CBLock l(&m_cs); if(dispIdMember < (int)m_posArray.GetCount()) { if((wFlags & (DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF)) && pDispParams->cArgs == 1) { VARIANT* pvar = pDispParams->rgvarg; while(pvar->vt == (VT_VARIANT | VT_BYREF)) pvar = pvar->pvarVal; if(!(wFlags & DISPATCH_PROPERTYPUTREF) && (pvar->vt == VT_UNKNOWN || pvar->vt == VT_DISPATCH)) { l.Unlock(); if(pvar->punkVal == NULL) return DISP_E_UNKNOWNINTERFACE; CBDispatchPtr pDisp; CComVariant var; HRESULT hr = pvar->punkVal->QueryInterface(&pDisp); if(FAILED(hr))return hr; hr = pDisp.GetProperty(0, &var); if(FAILED(hr))return hr; l.Lock(); if(dispIdMember < (int)m_posArray.GetCount()) { var.Detach(&m_posArray[dispIdMember]->m_value); return S_OK; }else return DISP_E_MEMBERNOTFOUND; }else return VariantCopyInd(&m_posArray[dispIdMember]->m_value, pvar); }else if(pDispParams->cArgs == 0) { if(pVarResult != NULL) return VariantCopy(pVarResult, &m_posArray[dispIdMember]->m_value); return S_OK; } VARIANT *pvar = &m_posArray[dispIdMember]->m_value; if(pvar->vt == VT_UNKNOWN || pvar->vt == VT_DISPATCH) { CBDispatchPtr pDisp; HRESULT hr = pvar->punkVal->QueryInterface(&pDisp); if(FAILED(hr)) return DISP_E_BADPARAMCOUNT; l.Unlock(); return pDisp->Invoke(0, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } return DISP_E_BADPARAMCOUNT; }else return DISP_E_MEMBERNOTFOUND; return S_OK; }
/************************************************************************* * SafeArrayGetElement (OLEAUT32.25) * * Get an item from a SafeArray. * * PARAMS * psa [I] SafeArray to get from * rgIndices [I] Indices to get from * pvData [O] Destination for data * * RETURNS * Success: S_OK. The item data is returned in pvData. * Failure: An HRESULT error code indicating the error. * * NOTES * See SafeArray. */ HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData) { HRESULT hRet; TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData); if (!psa || !rgIndices || !pvData) return E_INVALIDARG; hRet = SafeArrayLock(psa); if (SUCCEEDED(hRet)) { PVOID lpvSrc; hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvSrc); if (SUCCEEDED(hRet)) { if (psa->fFeatures & FADF_VARIANT) { VARIANT* lpVariant = lpvSrc; VARIANT* lpDest = pvData; /* The original content of pvData is ignored. */ V_VT(lpDest) = VT_EMPTY; hRet = VariantCopy(lpDest, lpVariant); if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet); } else if (psa->fFeatures & FADF_BSTR) { BSTR* lpBstr = lpvSrc; BSTR* lpDest = pvData; if (*lpBstr) { *lpDest = SysAllocStringByteLen((char*)*lpBstr, SysStringByteLen(*lpBstr)); if (!*lpBstr) hRet = E_OUTOFMEMORY; } else *lpDest = NULL; } else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { IUnknown **src_unk = lpvSrc; IUnknown **dest_unk = pvData; if (*src_unk) IUnknown_AddRef(*src_unk); *dest_unk = *src_unk; } else if (psa->fFeatures & FADF_RECORD) { IRecordInfo *record; SafeArrayGetRecordInfo(psa, &record); hRet = IRecordInfo_RecordCopy(record, lpvSrc, pvData); IRecordInfo_Release(record); } else /* Copy the data over */ memcpy(pvData, lpvSrc, psa->cbElements); } SafeArrayUnlock(psa); } return hRet; }
void *comget_variant( VARIANT *var, int *restype, BOOL fvariantret /* = FALSE*/ ) { // VARIANT型→HSPの型に変換する // int size; BSTR bstr; /* rev 43 mingw : warning : 定数へのポインタを非定数へのポインタに代入 に対処 */ void const *ptr; if ( fvariantret ) { VariantCopy( &comconv_var, var ); *restype = HSPVAR_FLAG_VARIANT; return &comconv_var; } VariantCopyInd( &comconv_var, var ); switch ( comconv_var.vt ) { case VT_R4: VariantChangeType( &comconv_var, &comconv_var, VARIANT_NOVALUEPROP, VT_R8 ); case VT_R8: *restype = HSPVAR_FLAG_DOUBLE; return &comconv_var.dblVal; case VT_BSTR: // 文字列全体を返すため、ANSI文字列をバイナリデータBSTRとして格納 ptr = comconv_var.bstrVal; if ( ptr == NULL ) ptr = L""; size = cnvsjis( NULL, (char *)ptr, 0 ); bstr = SysAllocStringByteLen( NULL, size ); if ( bstr == NULL ) throw HSPERR_OUT_OF_MEMORY; cnvsjis( (char *)bstr, (char *)ptr, size ); SysFreeString( comconv_var.bstrVal ); comconv_var.bstrVal = bstr; *restype = HSPVAR_FLAG_STR; return comconv_var.bstrVal; case VT_DISPATCH: case VT_UNKNOWN: *restype = HSPVAR_FLAG_COMSTRUCT; return &comconv_var.punkVal; case VT_I2: case VT_UI2: case VT_I1: case VT_UI1: case VT_I8: case VT_UI8: case VT_BOOL: VariantChangeType( &comconv_var, &comconv_var, VARIANT_NOVALUEPROP, VT_I4 ); case VT_I4: case VT_UI4: case VT_ERROR: case VT_INT: case VT_UINT: *restype = HSPVAR_FLAG_INT; return &comconv_var.lVal; default: if ( comconv_var.vt & VT_ARRAY ) { *restype = HSPVAR_FLAG_VARIANT; // SafeArray は Variant 型変数で扱う return &comconv_var; } throw HSPERR_INVALID_TYPE; } }
// The actual callback from the connection point arrives here STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid, LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { const char *eventMethodName = NULL; //Sourceforge report 1394001 JNIEnv *env = NULL; // map dispID to jmethodID for(int i=0;i<MethNum;i++) { if (MethID[i] == dispID) { USES_CONVERSION; eventMethodName = W2A((OLECHAR *)MethName[i]); } } // added 1.12 if (!eventMethodName) { // just bail if can't find signature. no need to attach // printf("Invoke: didn't find method name for dispatch id %d\n",dispID); return S_OK; } if (DISPATCH_METHOD & wFlags) { // attach to the current running thread //printf("Invoke: Attaching to current thread using JNI Version 1.2\n"); JavaVMAttachArgs attachmentArgs; attachmentArgs.version = JNI_VERSION_1_2; attachmentArgs.name = NULL; attachmentArgs.group = NULL; jvm->AttachCurrentThread((void **)&env, &attachmentArgs); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} if (!eventMethodName) { // could not find this signature in list // printf("Invoke: didn't find method name for dispatch id %d\n",dispID); // this probably leaves a native thread attached to the vm when we don't want it ThrowComFail(env, "Event method received was not defined as part of callback interface", -1); // should we detatch before returning?? We probably never get here if we ThrowComFail() // jvm->DetachCurrentThread(); return S_OK; } // find the class of the InvocationHandler jclass javaSinkClass = env->GetObjectClass(javaSinkObj); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} //printf("Invoke: Got sink class\n"); jmethodID invokeMethod; invokeMethod = env->GetMethodID(javaSinkClass, "invoke", "(Ljava/lang/String;[Lcom/jacob/com/Variant;)Lcom/jacob/com/Variant;"); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} jstring eventMethodNameAsString = env->NewStringUTF(eventMethodName); //printf("Invoke: Got method name\n"); // now do what we need for the variant jmethodID getVariantMethod = env->GetMethodID(javaSinkClass, "getVariant", "()Lcom/jacob/com/Variant;"); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} //printf("Invoke: Found way too getVariant\n"); jobject aVariantObj = env->CallObjectMethod(javaSinkObj, getVariantMethod); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} //printf("Invoke: Made Variant\n"); jclass variantClass = env->GetObjectClass(aVariantObj); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} // create the variant parameter array // how many params int numVariantParams = pDispParams->cArgs; // make an array of them jobjectArray varr = env->NewObjectArray(numVariantParams, variantClass, 0); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} //printf("Invoke: Created Array\n"); int i,j; for(i=numVariantParams-1,j=0;i>=0;i--,j++) { // construct a java variant holder jobject arg = env->CallObjectMethod(javaSinkObj, getVariantMethod); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} // get the empty variant from it VARIANT *va = extractVariant(env, arg); // copy the value VariantCopy(va, &pDispParams->rgvarg[i]); // put it in the array env->SetObjectArrayElement(varr, j, arg); env->DeleteLocalRef(arg); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} } //printf("Invoke: Filled Array\n"); // Set up the return value jobject ret; ret = env->CallObjectMethod(javaSinkObj, invokeMethod, eventMethodNameAsString, varr); //printf("Invoke: Invoked callback\n"); if (!env->ExceptionOccurred() && ret != NULL) { VariantCopy(pVarResult, extractVariant(env,ret)); } if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} // don't need the first variant we created to get the class // SF 1689061 change not accepted but put in as comment for later reminder //Java_com_jacob_com_Variant_release(env, aVariantObj); env->DeleteLocalRef(aVariantObj); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} // Begin code from Jiffie team that copies parameters back from java to COM for(i=numVariantParams-1,j=0;i>=0;i--,j++) { jobject arg = env->GetObjectArrayElement(varr, j); VARIANT *java = extractVariant(env, arg); VARIANT *com = &pDispParams->rgvarg[i]; convertJavaVariant(java, com); // SF 1689061 change not accepted but put in as comment for later reminder //Java_com_jacob_com_Variant_release(env, arg); zeroVariant(env, arg); env->DeleteLocalRef(arg); } // End code from Jiffie team that copies parameters back from java to COM // detach from thread //printf("Invoke: Detatching\n"); jvm->DetachCurrentThread(); //fflush(stdout); return S_OK; } return E_NOINTERFACE; }
STDMETHODIMP CBasic::get_prprefVariant(VARIANT* pVal) { HRESULT hr = S_OK; hr = VariantCopy(pVal, & m_var1); return hr; }
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { DispatchEx *This = impl_from_IDispatchEx(iface); IUnknown *unk; ITypeInfo *ti; dispex_data_t *data; UINT argerr=0; int min, max, n; HRESULT hres; TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(This->data->vtbl && This->data->vtbl->invoke) { hres = This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei); if (hres != DISP_E_UNKNOWNNAME) return hres; } if(wFlags == DISPATCH_CONSTRUCT) { FIXME("DISPATCH_CONSTRUCT not implemented\n"); return E_NOTIMPL; } if(is_dynamic_dispid(id)) { DWORD idx = id - DISPID_DYNPROP_0; VARIANT *var; if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx) return DISP_E_UNKNOWNNAME; var = &This->dynamic_data->props[idx].var; switch(wFlags) { case INVOKE_PROPERTYGET: V_VT(pvarRes) = VT_EMPTY; return VariantCopy(pvarRes, var); case INVOKE_PROPERTYPUT: VariantClear(var); return VariantCopy(var, pdp->rgvarg); default: FIXME("unhandled wFlags %x\n", wFlags); return E_NOTIMPL; } } data = get_dispex_data(This); if(!data) return E_FAIL; min = 0; max = data->func_cnt-1; while(min <= max) { n = (min+max)/2; if(data->funcs[n].id == id) break; if(data->funcs[n].id < id) min = n+1; else max = n-1; } if(min > max) { WARN("invalid id %x\n", id); return DISP_E_UNKNOWNNAME; } hres = get_typeinfo(data->funcs[n].tid, &ti); if(FAILED(hres)) { ERR("Could not get type info: %08x\n", hres); return hres; } hres = IUnknown_QueryInterface(This->outer, get_riid_from_tid(data->funcs[n].tid), (void**)&unk); if(FAILED(hres)) { ERR("Could not get iface: %08x\n", hres); ITypeInfo_Release(ti); return E_FAIL; } hres = ITypeInfo_Invoke(ti, unk, id, wFlags, pdp, pvarRes, pei, &argerr); ITypeInfo_Release(ti); IUnknown_Release(unk); return hres; }
STDMETHODIMP CInOutParams::mVariant(VARIANT a, VARIANT* b) { VariantClear( b); return VariantCopy ( b, &a); }
static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { HRESULT hres; switch(flags) { case DISPATCH_METHOD|DISPATCH_PROPERTYGET: if(!res) return E_INVALIDARG; /* fall through */ case DISPATCH_METHOD: if(This->dynamic_data && This->dynamic_data->func_disps && This->dynamic_data->func_disps[func->func_disp_idx].func_obj) { func_obj_entry_t *entry = This->dynamic_data->func_disps + func->func_disp_idx; if(V_VT(&entry->val) != VT_DISPATCH) { FIXME("calling %s not supported\n", debugstr_variant(&entry->val)); return E_NOTIMPL; } if((IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface != V_DISPATCH(&entry->val)) { if(!V_DISPATCH(&entry->val)) { FIXME("Calling null\n"); return E_FAIL; } hres = invoke_disp_value(This, V_DISPATCH(&entry->val), 0, flags, dp, res, ei, NULL); break; } } if(func->call_vtbl_off) hres = invoke_builtin_function(This, func, dp, res, caller); else hres = typeinfo_invoke(This, func, flags, dp, res, ei); break; case DISPATCH_PROPERTYGET: { func_obj_entry_t *entry; if(func->id == DISPID_VALUE) { BSTR ret; ret = SysAllocString(objectW); if(!ret) return E_OUTOFMEMORY; V_VT(res) = VT_BSTR; V_BSTR(res) = ret; return S_OK; } hres = get_func_obj_entry(This, func, &entry); if(FAILED(hres)) return hres; V_VT(res) = VT_EMPTY; return VariantCopy(res, &entry->val); } case DISPATCH_PROPERTYPUT: { func_obj_entry_t *entry; if(dp->cArgs != 1 || (dp->cNamedArgs == 1 && *dp->rgdispidNamedArgs != DISPID_PROPERTYPUT) || dp->cNamedArgs > 1) { FIXME("invalid args\n"); return E_INVALIDARG; } /* * NOTE: Although we have IDispatchEx tests showing, that it's not allowed to set * function property using InvokeEx, it's possible to do that from jscript. * Native probably uses some undocumented interface in this case, but it should * be fine for us to allow IDispatchEx handle that. */ hres = get_func_obj_entry(This, func, &entry); if(FAILED(hres)) return hres; return VariantCopy(&entry->val, dp->rgvarg); } default: FIXME("Unimplemented flags %x\n", flags); hres = E_NOTIMPL; } return hres; }
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { DispatchEx *This = DISPATCHEX_THIS(iface); HRESULT hres; TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(is_custom_dispid(id) && This->data->vtbl && This->data->vtbl->invoke) return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(wFlags == DISPATCH_CONSTRUCT) { if(id == DISPID_VALUE) { if(This->data->vtbl && This->data->vtbl->value) { return This->data->vtbl->value(This->outer, lcid, wFlags, pdp, pvarRes, pei, pspCaller); } FIXME("DISPATCH_CONSTRUCT flag but missing value function\n"); return E_FAIL; } FIXME("DISPATCH_CONSTRUCT flag without DISPID_VALUE\n"); return E_FAIL; } if(is_dynamic_dispid(id)) { DWORD idx = id - DISPID_DYNPROP_0; dynamic_prop_t *prop; if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx) return DISP_E_UNKNOWNNAME; prop = This->dynamic_data->props+idx; switch(wFlags) { case DISPATCH_METHOD|DISPATCH_PROPERTYGET: if(!pvarRes) return E_INVALIDARG; case DISPATCH_METHOD: { DISPID named_arg = DISPID_THIS; DISPPARAMS dp = {NULL, &named_arg, 0, 1}; IDispatchEx *dispex; if(V_VT(&prop->var) != VT_DISPATCH) { FIXME("invoke %s\n", debugstr_variant(&prop->var)); return E_NOTIMPL; } if(pdp->cNamedArgs) { FIXME("named args not supported\n"); return E_NOTIMPL; } dp.rgvarg = heap_alloc((pdp->cArgs+1)*sizeof(VARIANTARG)); if(!dp.rgvarg) return E_OUTOFMEMORY; dp.cArgs = pdp->cArgs+1; memcpy(dp.rgvarg+1, pdp->rgvarg, pdp->cArgs*sizeof(VARIANTARG)); V_VT(dp.rgvarg) = VT_DISPATCH; V_DISPATCH(dp.rgvarg) = (IDispatch*)DISPATCHEX(This); hres = IDispatch_QueryInterface(V_DISPATCH(&prop->var), &IID_IDispatchEx, (void**)&dispex); TRACE("%s call\n", debugstr_w(This->dynamic_data->props[idx].name)); if(SUCCEEDED(hres)) { hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, wFlags, &dp, pvarRes, pei, pspCaller); IDispatchEx_Release(dispex); }else { ULONG err = 0; hres = IDispatch_Invoke(V_DISPATCH(&prop->var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err); } TRACE("%s ret %08x\n", debugstr_w(This->dynamic_data->props[idx].name), hres); heap_free(dp.rgvarg); return hres; } case DISPATCH_PROPERTYGET: if(prop->flags & DYNPROP_DELETED) return DISP_E_UNKNOWNNAME; return VariantCopy(pvarRes, &prop->var); case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: case DISPATCH_PROPERTYPUT: if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT) || pdp->cNamedArgs > 1) { FIXME("invalid args\n"); return E_INVALIDARG; } TRACE("put %s\n", debugstr_variant(pdp->rgvarg)); VariantClear(&prop->var); hres = VariantCopy(&prop->var, pdp->rgvarg); if(FAILED(hres)) return hres; prop->flags &= ~DYNPROP_DELETED; return S_OK; default: FIXME("unhandled wFlags %x\n", wFlags); return E_NOTIMPL; } } return invoke_builtin_prop(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); }
STDMETHODIMP CPoint::RoundTrip(VARIANT s1, /*[out, retval]*/ VARIANT *s2) { VariantCopy(s2, &s1); return S_OK; }
loTrid loCacheUpdate(loService *se, unsigned count, loTagValue taglist[], FILETIME *timestamp) { unsigned ii; loTagValue *ts; #if 0 != LO_FILL_TIMESTAMP FILETIME ft; #endif // UL_DEBUG((LOGID, "loCacheUpdate(%p %u %p)", se, count, taglist)); if (!loSERVICE_OK(se)) return 0;//EBADF; /*ERROR:EARG*/ if (!timestamp && (0 >= count || !taglist)) return 0; #if 0 != LO_FILL_TIMESTAMP #if 1 == LO_FILL_TIMESTAMP se->driver.ldCurrentTime(&se->cactx, &ft); #else if (timestamp) ft = *timestamp; else memset(&ft, 0, sizeof(ft)); #endif #endif if (!(ts = loCacheLock(se))) { UL_INFO((LOGID, "loCacheUpdate() lock failed")); return 0;//-1; /*ERROR:out-of-service*/ } for(ii = 0; ii < count; ii++, taglist++) { loTagId ti; if (0 == (ti = taglist->tvTi)) continue; else if (ti < 1 || ti > se->lastused/*tag_count*/) { /*rv = -1;*//*ERROR:BAD ti*/ UL_INFO((LOGID, "loCacheUpdate(BAD ti:%u)", ii)); continue; } else { HRESULT hr; loTagValue *tv = &ts[ti]; tv->tvState = taglist->tvState; #if 0 != LO_FILL_TIMESTAMP if (!IsFILETIME(tv->tvState.tsTime)) tv->tvState.tsTime = ft; #endif /* hr = (V_ISBYREF(&taglist->tvValue)? VariantCopyInd(&tv->tvValue, &taglist->tvValue): VariantCopy(&tv->tvValue, &taglist->tvValue)); */ hr = VariantCopy(&tv->tvValue, &taglist->tvValue); if (S_OK != hr) { LO_E_BADTYPE_QUAL(hr, tv->tvState.tsError, tv->tvState.tsQuality); /*rv = -1;*//*ERROR:BAD VALUE*/ UL_WARNING((LOGID, "%!l loCacheUpdate(VariantCopy())", hr)); } tv->tvTi = ti; } } return loCacheUnlock(se, timestamp); /* return rv; */ }
SCODE CCmdTarget::SetStandardProp(const AFX_DISPMAP_ENTRY* pEntry, DISPPARAMS* pDispParams, UINT* puArgErr) { ASSERT(pEntry != NULL); ASSERT(*puArgErr != 0); // it is a DISPATCH_PROPERTYSET (for standard, non-function property) SCODE sc = S_OK; VARIANT va; AfxVariantInit(&va); VARIANT* pArg = &pDispParams->rgvarg[0]; if (pEntry->vt != VT_VARIANT && pArg->vt != pEntry->vt) { // argument is not of appropriate type, attempt to coerce it sc = VariantChangeType(&va, pArg, 0, pEntry->vt); if (FAILED(sc)) { TRACE0("Warning: automation property coercion failed.\n"); *puArgErr = 0; return sc; } ASSERT(va.vt == pEntry->vt); pArg = &va; } void* pProp = (BYTE*)this + pEntry->nPropOffset; switch (pEntry->vt) { case VT_I1: *(BYTE*)pProp = pArg->bVal; break; case VT_I2: *(short*)pProp = pArg->iVal; break; case VT_I4: *(long*)pProp = pArg->lVal; break; case VT_R4: *(float*)pProp = pArg->fltVal; break; case VT_R8: *(double*)pProp = pArg->dblVal; break; case VT_DATE: *(double*)pProp = pArg->date; break; case VT_CY: *(CY*)pProp = pArg->cyVal; break; case VT_BSTR: AfxBSTR2CString((CString*)pProp, pArg->bstrVal); break; case VT_ERROR: *(SCODE*)pProp = pArg->scode; break; case VT_BOOL: *(BOOL*)pProp = (V_BOOL(pArg) != 0); break; case VT_VARIANT: if (VariantCopy((LPVARIANT)pProp, pArg) != S_OK) *puArgErr = 0; break; case VT_DISPATCH: case VT_UNKNOWN: if (pArg->punkVal != NULL) pArg->punkVal->AddRef(); _AfxRelease((LPUNKNOWN*)pProp); *(LPUNKNOWN*)pProp = pArg->punkVal; break; default: *puArgErr = 0; sc = DISP_E_BADVARTYPE; } VariantClear(&va); // if property was a DISP_PROPERTY_NOTIFY type, call pfnSet after setting if (!FAILED(sc) && pEntry->pfnSet != NULL) { AFX_MANAGE_STATE(m_pModuleState); (this->*pEntry->pfnSet)(); } return sc; }
HRESULT STDMETHODCALLTYPE C[!output Safe_root]::RefreshLicense( DWORD dwCookie, VARIANT_BOOL fLocal, BSTR bstrURL, WMPStreamingType type, ULONG contentID, BSTR bstrRefreshReason, VARIANT *pReasonContext) { REFRESH_LICENSE_CONTEXT* pRefrLicCtx = NULL; BOOL postResult = 0; HRESULT hr = S_OK; if(NULL == bstrURL || NULL == bstrRefreshReason || NULL == pReasonContext) { hr = E_INVALIDARG; goto cleanup; } // If the refresh-license thread has not already been started, // start it now. if(0 == m_refreshLicenseThreadHandle) { hr = this->StartContentPartnerThread(ThreadTypeRefreshLicense); if(FAILED(hr)) { ATLTRACE2("%x: RefreshLicense: StartContentPartnerThread failed. %x\n", GetCurrentThreadId(), hr); goto cleanup; } ATLTRACE2("%x: RefreshLicense: StartContentPartnerThread succeeded.\n", GetCurrentThreadId()); } // At this point, we khow the refresh-license thread started, but // we don't know whether it is still active. // When we post a refresh-license message, we must provide // all the information we were passed in the seven parameters // of this method. So we copy the seven parameters into a // REFRESH_LICENSE_CONTEXT structure. pRefrLicCtx = new REFRESH_LICENSE_CONTEXT(); // This memory is freed in HandleMessageForRefreshLicenseThread. if(NULL == pRefrLicCtx) { ATLTRACE2("%x: RefreshLicense: Failed to create new REFRESH_LICENSE_CONTEXT.\n", GetCurrentThreadId()); hr = E_OUTOFMEMORY; goto cleanup; } ZeroMemory(pRefrLicCtx, sizeof(REFRESH_LICENSE_CONTEXT)); pRefrLicCtx->dwCookie = dwCookie; pRefrLicCtx->fLocal = fLocal; pRefrLicCtx->bstrURL = SysAllocString(bstrURL); // This memory is freed in HandleMessageForRefreshLicenseThread. pRefrLicCtx->type = type; pRefrLicCtx->contentID = contentID; pRefrLicCtx->bstrRefreshReason = SysAllocString(bstrRefreshReason); // This memory is freed in HandleMessageForRefreshLicenseThread. VariantInit(pRefrLicCtx->pReasonContext); VariantCopy(pRefrLicCtx->pReasonContext, pReasonContext); // This memory is freed in HandleMessageForRefreshLicenseThread. // If the refresh-license thread is not active, the following // call to PostThreadMessage will fail. postResult = PostThreadMessage( m_refreshLicenseThreadId, m_msgRefreshLicense, 0, reinterpret_cast<LPARAM>(pRefrLicCtx) ); if(0 == postResult) { hr = HRESULT_FROM_WIN32(GetLastError()); ATLTRACE2("%x: RefreshLicense: PostThreadMessage failed. %x\n", GetCurrentThreadId(), hr); goto cleanup; } ATLTRACE2("%x: RefreshLicense: PostThreadMessage succeeded.\n", GetCurrentThreadId()); // We successfully posted the message to the refresh-license thread. // We have no more need for the pointer to the refresh-license context. pRefrLicCtx = NULL; // The refresh-license thread must free the memory // that pRefrLicCtx pointed to previously. cleanup: if(pRefrLicCtx) { // We failed to post a message to the refresh-license thread. // The refresh-license thread will not be able to free the memory // pointed to by pRefrLicCtx. So we free it here. SysFreeString(pRefrLicCtx->bstrURL); SysFreeString(pRefrLicCtx->bstrRefreshReason); VariantClear(pRefrLicCtx->pReasonContext); delete pRefrLicCtx; pRefrLicCtx = NULL; } // If pRefrLicCtx is NULL, refresh-license thread will free the memory // pointed to by pRefrLicCtx. return hr; }