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;
	}
}
Beispiel #2
0
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;
}
Beispiel #4
0
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");
    }
}
Beispiel #5
0
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);
}
Beispiel #6
0
/*************************************************************************
 *		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;
	}
}
Beispiel #8
0
STDMETHODIMP CProperties::putref_pVariant(VARIANT* newVal)
{
    return VariantCopy(&m_variantVal, newVal);
}
Beispiel #9
0
	VARIANT* set( JNIEnv* env, jobject src ) {
		VARIANT* pv = new VARIANT();
		VariantClear(pv);
		VariantCopy(pv, com4jVariantToVARIANT(env,src));
		return pv;
	}
Beispiel #10
0
STDMETHODIMP CProperties::get_pVariant(VARIANT* pVal)
{
	return VariantCopy(pVal, &m_variantVal);
}
Beispiel #11
0
STDMETHODIMP CProperties::put_pVariant(VARIANT newVal)
{
    if (newVal.vt != VARENUM::VT_DISPATCH){
        return VariantCopy(&m_variantVal, &newVal);
    }
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
STDMETHODIMP CPyCOMTest::GetSetVariant(VARIANT var, VARIANT *out)
{
	VariantClear(out); // necessary?
	return VariantCopy(out, &var);
}
Beispiel #15
0
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;
}
Beispiel #16
0
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);
}
Beispiel #17
0
/* 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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
/*************************************************************************
 *		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;
}
Beispiel #20
0
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;
	}
}
Beispiel #21
0
// 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;
}
Beispiel #22
0
STDMETHODIMP CBasic::get_prprefVariant(VARIANT* pVal)
{
	HRESULT hr = S_OK;
	hr = VariantCopy(pVal, & m_var1);
	return hr;
}
Beispiel #23
0
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;
}
Beispiel #24
0
STDMETHODIMP CInOutParams::mVariant(VARIANT a, VARIANT* b)
{
	VariantClear( b);
	return VariantCopy ( b, &a);
}
Beispiel #25
0
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;
}
Beispiel #26
0
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);
}
Beispiel #27
0
STDMETHODIMP CPoint::RoundTrip(VARIANT s1, /*[out, retval]*/ VARIANT *s2) {
  VariantCopy(s2, &s1);
  return S_OK;
}
Beispiel #28
0
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; */
}
Beispiel #29
0
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;
}