Esempio n. 1
0
/************************************************************************
 *		SafeArrayCopy (OLEAUT32.27)
 *
 * Make a duplicate of a SafeArray.
 *
 * PARAMS
 *  psa     [I] Source for copy
 *  ppsaOut [O] Destination for new copy
 *
 * RETURNS
 *  Success: S_OK. ppsaOut contains a copy of the array.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut)
{
  HRESULT hRet;

  TRACE("(%p,%p)\n", psa, ppsaOut);

  if (!ppsaOut)
    return E_INVALIDARG;

  *ppsaOut = NULL;

  if (!psa)
    return S_OK; /* Handles copying of NULL arrays */

  if (!psa->cbElements)
    return E_INVALIDARG;

  if (psa->fFeatures & (FADF_RECORD|FADF_HAVEIID|FADF_HAVEVARTYPE))
  {
    VARTYPE vt;

    hRet = SafeArrayGetVartype(psa, &vt);
    if (SUCCEEDED(hRet))
      hRet = SafeArrayAllocDescriptorEx(vt, psa->cDims, ppsaOut);
  }
  else
  {
    hRet = SafeArrayAllocDescriptor(psa->cDims, ppsaOut);
    if (SUCCEEDED(hRet))
    {
      (*ppsaOut)->fFeatures = psa->fFeatures & ~ignored_copy_features;
      (*ppsaOut)->cbElements = psa->cbElements;
    }
  }

  if (SUCCEEDED(hRet))
  {
    /* Copy dimension bounds */
    memcpy((*ppsaOut)->rgsabound, psa->rgsabound, psa->cDims * sizeof(SAFEARRAYBOUND));

    (*ppsaOut)->pvData = SAFEARRAY_Malloc(SAFEARRAY_GetCellCount(psa) * psa->cbElements);
    if (!(*ppsaOut)->pvData)
    {
      SafeArrayDestroyDescriptor(*ppsaOut);
      *ppsaOut = NULL;
      return E_OUTOFMEMORY;
    }

    hRet = SAFEARRAY_CopyData(psa, *ppsaOut);
    if (FAILED(hRet))
    {
      SAFEARRAY_Free((*ppsaOut)->pvData);
      SafeArrayDestroyDescriptor(*ppsaOut);
      *ppsaOut = NULL;
      return hRet;
    }
  }

  return hRet;
}
Esempio n. 2
0
STDMETHODIMP Profile::put_Languages(SAFEARRAY * newVal)
{
	try {
		VARTYPE vt = VT_UNKNOWN;
		SafeArrayGetVartype(newVal, & vt);
		UINT uiDim = SafeArrayGetDim(newVal);
		if((uiDim != 1) || (vt != VT_BSTR)) {
			return AtlReportError(GetObjectCLSID(), L"Array of languages must be single dimension array of strings", GUID_NULL, E_INVALIDARG);
		}

		HRESULT hr = SafeArrayLock(newVal);
		if(FAILED(hr)) {
			return AtlReportError(GetObjectCLSID(), L"Unable to lock array", GUID_NULL, E_FAIL);
		}

		BSTR * pItems = (BSTR *) newVal->pvData;
		wstring wstrItems;
		for(ULONG l = 0; l < newVal->rgsabound[0].cElements; l++) {
			if(l > 0) wstrItems += L" ";
			wstrItems += pItems[l];
		}

		SafeArrayUnlock(newVal);
		gSkypeQueue.SetProperty(L"PROFILE", L"", L"LANGUAGES", wstrItems.c_str());
		return S_OK;
	} catch (const WCHAR * err) {
		return AtlReportError(GetObjectCLSID(), err, GUID_NULL, E_FAIL);
	}
}
Esempio n. 3
0
static zval* saproxy_iter_get_data(zend_object_iterator *iter)
{
	php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data);
	VARIANT v;
	VARTYPE vt;
	SAFEARRAY *sa;

	I->indices[I->proxy->dimensions-1] = I->key;

	sa = V_ARRAY(&I->proxy->obj->v);

	if (FAILED(SafeArrayGetVartype(sa, &vt)) || vt == VT_EMPTY) {
		vt = V_VT(&I->proxy->obj->v) & ~VT_ARRAY;
	}

	VariantInit(&v);
	if (vt == VT_VARIANT) {
		SafeArrayGetElement(sa, I->indices, &v);
	} else {
		V_VT(&v) = vt;
		SafeArrayGetElement(sa, I->indices, &v.lVal);
	}

	ZVAL_NULL(&I->data);
	php_com_wrap_variant(&I->data, &v, I->proxy->obj->code_page);
	VariantClear(&v);

	return &I->data;
}
Esempio n. 4
0
STDMETHODIMP CMTDoubleVector::setValueVector(SAFEARRAY * pValues)
{

	VARTYPE varType;
	if( FAILED(SafeArrayGetVartype(pValues, &varType)) )
	{
		return Error( _T("setValueVector: Invalid result array") , __uuidof( IMTDoubleVector ), E_FAIL  );				
	}
	
	if( varType != VT_R8 )
	{
		return Error( _T("setValueVector: Invalid result array type.  Must be double") , __uuidof( IMTDoubleVector ), E_FAIL  );				
	}

	if( (pValues)->cDims != 1 )
	{
		return Error( _T("setValueVector: The array must have only one dimension") , __uuidof( IMTDoubleVector ), E_FAIL  );				
	}

	clear();	
	m_nbValues = pValues->rgsabound[0].cElements;	
	m_pValues = new double[m_nbValues];
	CopyMemory(m_pValues, pValues->pvData, sizeof(double)*m_nbValues);	
	
	updateListeners();
	return S_OK;
}
Esempio n. 5
0
static void com_write_dimension(zval *object, zval *offset, zval *value)
{
	php_com_dotnet_object *obj;
	zval args[2];
	VARIANT v;
	HRESULT res;

	obj = CDNO_FETCH(object);

	if (V_VT(&obj->v) == VT_DISPATCH) {
		ZVAL_COPY_VALUE(&args[0], offset);
		ZVAL_COPY_VALUE(&args[1], value);

		VariantInit(&v);

		if (SUCCESS == php_com_do_invoke_by_id(obj, DISPID_VALUE,
				DISPATCH_METHOD|DISPATCH_PROPERTYPUT, &v, 2, args, 0, 0)) {
			VariantClear(&v);
		}
	} else if (V_ISARRAY(&obj->v)) {
		LONG indices = 0;
		VARTYPE vt;

		if (SafeArrayGetDim(V_ARRAY(&obj->v)) == 1) {
			if (FAILED(SafeArrayGetVartype(V_ARRAY(&obj->v), &vt)) || vt == VT_EMPTY) {
				vt = V_VT(&obj->v) & ~VT_ARRAY;
			}

			convert_to_long(offset);
			indices = (LONG)Z_LVAL_P(offset);

			VariantInit(&v);
			php_com_variant_from_zval(&v, value, obj->code_page);

			if (V_VT(&v) != vt) {
				VariantChangeType(&v, &v, 0, vt);
			}

			if (vt == VT_VARIANT) {
				res = SafeArrayPutElement(V_ARRAY(&obj->v), &indices, &v);
			} else {
				res = SafeArrayPutElement(V_ARRAY(&obj->v), &indices, &v.lVal);
			}

			VariantClear(&v);

			if (FAILED(res)) {
				php_com_throw_exception(res, NULL);
			}

		} else {
			php_com_throw_exception(DISP_E_BADINDEX, "this variant has multiple dimensions; you can't set a new value without specifying *all* dimensions");
		}

	} else {
		php_com_throw_exception(E_INVALIDARG, "this variant is not an array type");
	}
}
Esempio n. 6
0
//==============================================================================
// 1D array of ints, dim unspecified, allow Nx1 or 1xN arrays
int g_CheckVariantArray( int * pnDim1, VARIANT vMtx, int ** ppiMtx ){
  SAFEARRAY * psaMtx;
  int nDims;
  long iDim1, iDim2;
  VARTYPE tSaType;

  psaMtx = vMtx.parray;
  *pnDim1 = 0;

  if( vMtx.vt != (VT_ARRAY|VT_I4)){
    CP_printf("\ng_CheckVariantArray(): wrong VARIANT type, expecting array of ints!\n");
    return 1;
  }

  SafeArrayGetVartype( psaMtx, &tSaType );
  if( tSaType != VT_I4 ){
    CP_printf("\ng_CheckVariantArray(): wrong array type, expecting array of ints!\n");
    return 1;
  }

  nDims = SafeArrayGetDim( psaMtx );
  if( nDims !=2 && nDims !=1 ) {    // Allow Nx1 or 1xN arrays
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting 1xN, or Nx1 array!\n");
    return 1;
  }
  SafeArrayGetLBound( psaMtx, 1, &iDim1 );
  if( iDim1 != 0) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting 1xN, or Nx1 array!\n");
    return 1;
  }
  SafeArrayGetUBound( psaMtx, 1, &iDim1 );

  if( nDims == 2 ) {
    SafeArrayGetLBound( psaMtx, 2, &iDim2 );
    if( iDim2 != 0) {
      CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting 1xN, or Nx1 array!\n");
      return 1;
    }
    SafeArrayGetUBound( psaMtx, 2, &iDim2 );
  }
  else 
    iDim2 = 0;

  // stupid Matlab hack allowing any 2D array with one redundant dim
  if( (iDim2 != 0) && (iDim1 != 0)) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting 1xN, or Nx1 array!\n");
    return 1;
  }

  *pnDim1 = iDim1 + iDim2 + 1;  // if we get here, one size is always zero
  SafeArrayAccessData(psaMtx, (void **) ppiMtx);  // Get data pointer

  return 0;
}
Esempio n. 7
0
//==============================================================================
// 2D array of doubles 
int g_CheckVariantArray( int nDim1, int nDim2, VARIANT vMtx, double ** ppdMtx ){
  SAFEARRAY * psaMtx;
  int nDims;
  long iDim;
  VARTYPE tSaType;

  psaMtx = vMtx.parray;

  if( vMtx.vt != (VT_ARRAY|VT_R8)){
    CP_printf("\ng_CheckVariantArray(): wrong VARIANT type, expecting array of doubles!\n");
    return 1;
  }

  SafeArrayGetVartype( psaMtx, &tSaType );
  if( tSaType != VT_R8 ){
    CP_printf("\ng_CheckVariantArray(): wrong array type, expecting array of doubles!\n");
    return 1;
  }

  nDims = SafeArrayGetDim( psaMtx );
  if( nDims !=2 ) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting %dx%d array!\n", 
                                                            nDim1, nDim2 );
    return 1;
  }
  SafeArrayGetLBound( psaMtx, 1, &iDim );
  if( iDim != 0) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting %dx%d array!\n", 
                                                            nDim1, nDim2 );
    return 1;
  }
  SafeArrayGetUBound( psaMtx, 1, &iDim );
  if( iDim+1 != nDim1) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting %dx%d array!\n",
                                                            nDim1, nDim2 );
    return 1;
  }
  SafeArrayGetLBound( psaMtx, 2, &iDim );
  if( iDim != 0) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting %dx%d array!\n", 
                                                            nDim1, nDim2 );
    return 1;
  }
  SafeArrayGetUBound( psaMtx, 2, &iDim );
  if( iDim+1 != nDim2) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting %dx%d array!\n",
                                                            nDim1, nDim2 );
    return 1;
  }
  SafeArrayAccessData(psaMtx, (void **) ppdMtx);  // Get data pointer

  return 0;
}
Esempio n. 8
0
/* this is a convenience function for fetching a particular
 * element from a (possibly multi-dimensional) safe array */
PHP_COM_DOTNET_API int php_com_safearray_get_elem(VARIANT *array, VARIANT *dest, LONG dim1)
{
    UINT dims;
    LONG lbound, ubound;
    LONG indices[1];
    VARTYPE vt;

    if (!V_ISARRAY(array)) {
        return 0;
    }

    dims = SafeArrayGetDim(V_ARRAY(array));

    if (dims != 1) {
        php_error_docref(NULL, E_WARNING,
                         "Can only handle single dimension variant arrays (this array has %d)", dims);
        return 0;
    }

    if (FAILED(SafeArrayGetVartype(V_ARRAY(array), &vt)) || vt == VT_EMPTY) {
        vt = V_VT(array) & ~VT_ARRAY;
    }

    /* determine the bounds */
    SafeArrayGetLBound(V_ARRAY(array), 1, &lbound);
    SafeArrayGetUBound(V_ARRAY(array), 1, &ubound);

    /* check bounds */
    if (dim1 < lbound || dim1 > ubound) {
        php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds");
        return 0;
    }

    /* now fetch that element */
    VariantInit(dest);

    indices[0] = dim1;

    if (vt == VT_VARIANT) {
        SafeArrayGetElement(V_ARRAY(array), indices, dest);
    } else {
        V_VT(dest) = vt;
        /* store the value into "lVal" member of the variant.
         * This works because it is a union; since we know the variant
         * type, we end up with a working variant */
        SafeArrayGetElement(V_ARRAY(array), indices, &dest->lVal);
    }

    return 1;
}
Esempio n. 9
0
//==============================================================================
// 2D array of ints, both dims unspecified 
int g_CheckVariantArray( int * pnDim1, int * pnDim2, VARIANT vMtx, int ** ppiMtx ){
  SAFEARRAY * psaMtx;
  int nDims;
  long iDim;
  VARTYPE tSaType;

  psaMtx = vMtx.parray;
  *pnDim1 = 0;
  *pnDim2 = 0;

  if( vMtx.vt != (VT_ARRAY|VT_I4)){
    CP_printf("\ng_CheckVariantArray(): wrong VARIANT type, expecting array of ints!\n");
    return 1;
  }

  SafeArrayGetVartype( psaMtx, &tSaType );
  if( tSaType != VT_I4 ){
    CP_printf("\ng_CheckVariantArray(): wrong array type, expecting array of 4-byte integers!\n");
    return 1;
  }

  nDims = SafeArrayGetDim( psaMtx );
  if( nDims !=2 ) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions\n" );
    return 1;
  }
  SafeArrayGetLBound( psaMtx, 1, &iDim );
  if( iDim != 0) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions!\n" );
    return 1;
  }
  SafeArrayGetLBound( psaMtx, 2, &iDim );
  if( iDim != 0) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions\n" );
    return 1;
  }
  SafeArrayGetUBound( psaMtx, 1, &iDim );
  iDim++;   // we return the size, which is upperbound +1
  * pnDim1 = iDim; 
  SafeArrayGetUBound( psaMtx, 2, &iDim );
  iDim++;   // we return the size, which is upperbound +1
  * pnDim2 = iDim; 
  SafeArrayAccessData(psaMtx, (void **) ppiMtx);  // Get data pointer

  return 0;
}
Esempio n. 10
0
	JNIEXPORT void JNICALL Java_com_tangram_Variant_putVariantSafeArray(JNIEnv *env, jobject _this, jobject sa)
	{
		SAFEARRAY *psa = extractSA(env, sa);
		if (psa)
		{
			VARIANT *v = extractVariant(env, _this);
			if (v) {
				VARTYPE vt;
				SafeArrayGetVartype(psa, &vt);
				V_VT(v) = VT_ARRAY | vt;
				V_ARRAY(v) = copySA(psa);
				return;
			}
			ThrowComFail(env, "Can't get variant pointer", -1);
			return;
		}
		ThrowComFail(env, "Can't get sa pointer", -1);
		return;
	}
Esempio n. 11
0
//==============================================================================
// 2D array of doubles, second dim unspecified 
int g_CheckVariantArray( int nDim1, int * pnDim2, VARIANT vMtx, double ** ppdMtx ){
  SAFEARRAY * psaMtx;
  int nDims;
  long iDim;
  VARTYPE tSaType;

  psaMtx = vMtx.parray;
  *pnDim2 = 0;

  SafeArrayGetVartype( psaMtx, &tSaType );
  if( tSaType != VT_R8 ){
    CP_printf("\ng_CheckVariantArray(): wrong array type, expecting array of doubles!\n");
    return 1;
  }

  nDims = SafeArrayGetDim( psaMtx );
  if( nDims !=2 ) {
    CP_printf("\ng_CheckVariantArray(): wrong number of dimensions, expecting 2D array!\n" );
    return 1;
  }
  SafeArrayGetLBound( psaMtx, 1, &iDim );
  if( iDim != 0) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting %dxN array!\n", nDim1 );
    return 1;
  }
  SafeArrayGetUBound( psaMtx, 1, &iDim );
  if( iDim+1 != nDim1) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting %dxN array!\n", nDim1 );
    return 1;
  }
  SafeArrayGetLBound( psaMtx, 2, &iDim );
  if( iDim != 0) {
    CP_printf("\ng_CheckVariantArray(): wrong array dimensions, expecting %dxN array!\n", nDim1 );
    return 1;
  }
  SafeArrayGetUBound( psaMtx, 2, &iDim );
  iDim++;   // we return the size, which is upperbound +1
  * pnDim2 = iDim; 
  SafeArrayAccessData(psaMtx, (void **) ppdMtx);  // Get data pointer

  return 0;
}
Esempio n. 12
0
static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa)
{
    VARTYPE vt;
    HRESULT hr;

    hr = SafeArrayGetVartype(psa, &vt);
    if (FAILED(hr))
        RpcRaiseException(hr);

    if (psa->fFeatures & FADF_HAVEIID)
        return SF_HAVEIID;

    switch (vt)
    {
    case VT_I1:
    case VT_UI1:      return SF_I1;
    case VT_BOOL:
    case VT_I2:
    case VT_UI2:      return SF_I2;
    case VT_INT:
    case VT_UINT:
    case VT_I4:
    case VT_UI4:
    case VT_R4:       return SF_I4;
    case VT_DATE:
    case VT_CY:
    case VT_R8:
    case VT_I8:
    case VT_UI8:      return SF_I8;
    case VT_INT_PTR:
    case VT_UINT_PTR: return (sizeof(UINT_PTR) == 4 ? SF_I4 : SF_I8);
    case VT_BSTR:     return SF_BSTR;
    case VT_DISPATCH: return SF_DISPATCH;
    case VT_VARIANT:  return SF_VARIANT;
    case VT_UNKNOWN:  return SF_UNKNOWN;
    /* Note: Return a non-zero size to indicate vt is valid. The actual size
     * of a UDT is taken from the result of IRecordInfo_GetSize().
     */
    case VT_RECORD:   return SF_RECORD;
    default:          return SF_ERROR;
    }
}
Esempio n. 13
0
HRESULT _SetArrayHelper(VARTYPE expectedType, SAFEARRAY *vals, int *resultSize)
{
	VARTYPE gotType;
	HRESULT hr = SafeArrayGetVartype(vals, &gotType);
	if (FAILED(hr)) {
		return hr;
	}
	if (gotType != expectedType) {
		return E_UNEXPECTED;
	}
	UINT cDims = SafeArrayGetDim(vals);
	*resultSize = 0;
	long ub=0, lb=0;
	if (cDims) {
		SafeArrayGetUBound(vals, 1, &ub);
		SafeArrayGetLBound(vals, 1, &lb);
		*resultSize = ub - lb + 1;
	}
	return S_OK;
}
Esempio n. 14
0
	JNIEXPORT void JNICALL Java_com_tangram_Variant_putVariantSafeArrayRef(JNIEnv *env, jobject _this, jobject sa)
	{
		SAFEARRAY *psa = extractSA(env, sa);
		if (psa)
		{
			VARIANT *v = extractVariant(env, _this);
			if (v) {
				VARTYPE vt;
				SAFEARRAY **sa = (SAFEARRAY **)CoTaskMemAlloc(sizeof(SAFEARRAY*));
				*sa = psa;
				SafeArrayGetVartype(psa, &vt);
				V_VT(v) = VT_ARRAY | vt | VT_BYREF;
				V_ARRAYREF(v) = sa;
				return;
			}
			ThrowComFail(env, "Can't get variant pointer", -1);
			return;
		}
		ThrowComFail(env, "Can't get sa pointer", -1);
		return;
	}
Esempio n. 15
0
STDMETHODIMP Profile::put_ForwardingRules(SAFEARRAY * newVal)
{
	try {
		VARTYPE vt = VT_UNKNOWN;
		SafeArrayGetVartype(newVal, & vt);
		UINT uiDim = SafeArrayGetDim(newVal);
		if((uiDim != 1) || (vt != VT_RECORD)) {
			return AtlReportError(GetObjectCLSID(), L"Array of rules must be single dimension array of strings", GUID_NULL, E_INVALIDARG);
		}

		HRESULT hr = SafeArrayLock(newVal);
		if(FAILED(hr)) {
			return AtlReportError(GetObjectCLSID(), L"Unable to lock array", GUID_NULL, E_FAIL);
		}

		wstring wstrItems;
		ForwardingRule * pItems = (ForwardingRule *) newVal->pvData;
		for(ULONG l = 0; l < newVal->rgsabound[0].cElements; l++) {
			WCHAR start[32], end[32];
			_ltow_s(pItems[l].StartTime, start, sizeof(start)/sizeof(start[0]), 10);
			_ltow_s(pItems[l].EndTime, end, sizeof(end)/sizeof(end[0]), 10);
			if(l > 0) {
				wstrItems += L" ";
			}
			wstrItems += start;
			wstrItems += L",";
			wstrItems += end;
			wstrItems += L",";
			wstrItems += pItems[l].Handle;
		}

		SafeArrayUnlock(newVal);
		gSkypeQueue.SetProperty(L"PROFILE", L"", L"CALL_FORWARD_RULES", wstrItems.c_str());
		return S_OK;
	} catch (const WCHAR * err) {
		return AtlReportError(GetObjectCLSID(), err, GUID_NULL, E_FAIL);
	}
}
Esempio n. 16
0
WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant)
{
    VariantInit(&oleVariant);
    if (variant.IsNull())
    {
        oleVariant.vt = VT_NULL;
        return true;
    }

    wxString type(variant.GetType());

    if (type == wxT("errorcode"))
    {
        wxVariantDataErrorCode* const
            ec = wxStaticCastVariantData(variant.GetData(),
                                         wxVariantDataErrorCode);
        oleVariant.vt = VT_ERROR;
        oleVariant.scode = ec->GetValue();
    }
    else if (type == wxT("currency"))
    {
        wxVariantDataCurrency* const
            c = wxStaticCastVariantData(variant.GetData(),
                                        wxVariantDataCurrency);
        oleVariant.vt = VT_CY;
        oleVariant.cyVal = c->GetValue();
    }
    else if (type == wxT("safearray"))
    {
        wxVariantDataSafeArray* const
            vsa = wxStaticCastVariantData(variant.GetData(),
                                          wxVariantDataSafeArray);
        SAFEARRAY* psa = vsa->GetValue();
        VARTYPE vt;

        wxCHECK(psa, false);
        HRESULT hr = SafeArrayGetVartype(psa, &vt);
        if ( FAILED(hr) )
        {
            wxLogApiError(wxS("SafeArrayGetVartype()"), hr);
            SafeArrayDestroy(psa);
            return false;
        }
        oleVariant.vt = vt | VT_ARRAY;
        oleVariant.parray = psa;
    }
    else if (type == wxT("long"))
    {
        oleVariant.vt = VT_I4;
        oleVariant.lVal = variant.GetLong() ;
    }
    // Original VC6 came with SDK too old to contain VARIANT::llVal declaration
    // and there doesn't seem to be any way to test for it as Microsoft simply
    // added it to the later version of oaidl.h without changing anything else.
    // So assume it's not present for VC6, even though it might be if an
    // updated SDK is used. In this case the user would need to disable this
    // check himself.
#if wxUSE_LONGLONG && !defined(__VISUALC6__)
    else if (type == wxT("longlong"))
    {
        oleVariant.vt = VT_I8;
        oleVariant.llVal = variant.GetLongLong().GetValue();
    }
#endif
    else if (type == wxT("char"))
    {
        oleVariant.vt=VT_I1;            // Signed Char
        oleVariant.cVal=variant.GetChar();
    }
    else if (type == wxT("double"))
    {
        oleVariant.vt = VT_R8;
        oleVariant.dblVal = variant.GetDouble();
    }
    else if (type == wxT("bool"))
    {
        oleVariant.vt = VT_BOOL;
        oleVariant.boolVal = variant.GetBool() ? VARIANT_TRUE : VARIANT_FALSE;
    }
    else if (type == wxT("string"))
    {
        wxString str( variant.GetString() );
        oleVariant.vt = VT_BSTR;
        oleVariant.bstrVal = wxConvertStringToOle(str);
    }
#if wxUSE_DATETIME
    else if (type == wxT("datetime"))
    {
        wxDateTime date( variant.GetDateTime() );
        oleVariant.vt = VT_DATE;

        SYSTEMTIME st;
        date.GetAsMSWSysTime(&st);

        SystemTimeToVariantTime(&st, &oleVariant.date);
    }
#endif
    else if (type == wxT("void*"))
    {
        oleVariant.vt = VT_DISPATCH;
        oleVariant.pdispVal = (IDispatch*) variant.GetVoidPtr();
    }
    else if (type == wxT("list"))
    {
        wxSafeArray<VT_VARIANT> safeArray;
        if (!safeArray.CreateFromListVariant(variant))
            return false;

        oleVariant.vt = VT_VARIANT | VT_ARRAY;
        oleVariant.parray = safeArray.Detach();
    }
    else if (type == wxT("arrstring"))
    {
        wxSafeArray<VT_BSTR> safeArray;

        if (!safeArray.CreateFromArrayString(variant.GetArrayString()))
            return false;

        oleVariant.vt = VT_BSTR | VT_ARRAY;
        oleVariant.parray = safeArray.Detach();
    }
    else
    {
        oleVariant.vt = VT_NULL;
        return false;
    }
    return true;
}
Esempio n. 17
0
unsigned char * WINAPI LPSAFEARRAY_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa)
{
    HRESULT hr;

    TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", Buffer, *ppsa);

    ALIGN_POINTER(Buffer, 3);
    *(ULONG_PTR *)Buffer = *ppsa ? TRUE : FALSE;
    Buffer += sizeof(ULONG_PTR);
    if (*ppsa)
    {
        VARTYPE vt;
        SAFEARRAY *psa = *ppsa;
        ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
        wireSAFEARRAY wiresa;
        SF_TYPE sftype;
        GUID guid;

        *(ULONG *)Buffer = psa->cDims;
        Buffer += sizeof(ULONG);
        wiresa = (wireSAFEARRAY)Buffer;
        wiresa->cDims = psa->cDims;
        wiresa->fFeatures = psa->fFeatures;
        wiresa->cbElements = psa->cbElements;

        hr = SafeArrayGetVartype(psa, &vt);
        if (FAILED(hr))
            RpcRaiseException(hr);
        wiresa->cLocks = (USHORT)psa->cLocks | (vt << 16);

        Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);

        sftype = SAFEARRAY_GetUnionType(psa);
        *(ULONG *)Buffer = sftype;
        Buffer += sizeof(ULONG);

        *(ULONG *)Buffer = ulCellCount;
        Buffer += sizeof(ULONG);
        *(ULONG_PTR *)Buffer = (ULONG_PTR)psa->pvData;
        Buffer += sizeof(ULONG_PTR);
        if (sftype == SF_HAVEIID)
        {
            SafeArrayGetIID(psa, &guid);
            memcpy(Buffer, &guid, sizeof(guid));
            Buffer += sizeof(guid);
        }

        memcpy(Buffer, psa->rgsabound, sizeof(psa->rgsabound[0]) * psa->cDims);
        Buffer += sizeof(psa->rgsabound[0]) * psa->cDims;

        *(ULONG *)Buffer = ulCellCount;
        Buffer += sizeof(ULONG);

        if (psa->pvData)
        {
            switch (sftype)
            {
                case SF_BSTR:
                {
                    BSTR* lpBstr;

                    for (lpBstr = (BSTR*)psa->pvData; ulCellCount; ulCellCount--, lpBstr++)
                        Buffer = BSTR_UserMarshal(pFlags, Buffer, lpBstr);

                    break;
                }
                case SF_DISPATCH:
                case SF_UNKNOWN:
                case SF_HAVEIID:
                    FIXME("marshal interfaces\n");
                    break;
                case SF_VARIANT:
                {
                    VARIANT* lpVariant;

                    for (lpVariant = (VARIANT*)psa->pvData; ulCellCount; ulCellCount--, lpVariant++)
                        Buffer = VARIANT_UserMarshal(pFlags, Buffer, lpVariant);

                    break;
                }
                case SF_RECORD:
                {
                    IRecordInfo* pRecInfo = NULL;

                    hr = SafeArrayGetRecordInfo(psa, &pRecInfo);
                    if (FAILED(hr))
                        RpcRaiseException(hr);

                    if (pRecInfo)
                    {
                        FIXME("write record info %p\n", pRecInfo);

                        IRecordInfo_Release(pRecInfo);
                    }
                    break;
                }

                case SF_I8:
                    ALIGN_POINTER(Buffer, 7);
                    /* fallthrough */
                case SF_I1:
                case SF_I2:
                case SF_I4:
                    /* Just copy the data over */
                    memcpy(Buffer, psa->pvData, ulCellCount * psa->cbElements);
                    Buffer += ulCellCount * psa->cbElements;
                    break;
                default:
                    break;
            }
        }

    }
    return Buffer;
}
Esempio n. 18
0
NDArray *roper::getData()
{
    NDArray *pArray = NULL;
    VARIANT varData, varResult;
    short result;
    SAFEARRAY *pData;
    int dim;
    LONG lbound, ubound;
    size_t dims[ND_ARRAY_MAX_DIMS];
    int nDims;
    VARTYPE varType;
    NDDataType_t dataType;
    int docDataType;
    NDArrayInfo arrayInfo;
    void HUGEP *pVarData;
    bool typeMismatch;
    const char *functionName = "getData";
        
    VariantInit(&varData);
    VariantInit(&varResult);
    try {
        this->pDocFile->GetFrame(1, &varData);
        varResult = this->pDocFile->GetParam(DM_DATATYPE, &result);
        docDataType = varResult.lVal;
        pData = varData.parray;
        nDims = SafeArrayGetDim(pData);
        for (dim=0; dim<nDims; dim++) {
            SafeArrayGetLBound(pData, dim+1, &lbound);
            SafeArrayGetUBound(pData, dim+1, &ubound);
            dims[dim] = ubound - lbound + 1;
        }
        SafeArrayGetVartype(pData, &varType);
        typeMismatch = TRUE;
        switch (docDataType) {
            case X_BYTE:
                dataType = NDUInt8;
                typeMismatch = (varType != VT_UI1);
                break;
            case X_SHORT:
                dataType = NDInt16;
                typeMismatch = (varType != VT_I2);
                break;
            case X_UINT16:
                dataType = NDUInt16;
                typeMismatch = (varType != VT_I2);
                break;
            case X_LONG:
                dataType = NDInt32;
                typeMismatch = (varType != VT_I4);
                break;
            case X_ULONG:
                dataType = NDUInt32;
                typeMismatch = (varType != VT_I4);
                break;
            case X_FLOAT:
                dataType = NDFloat32;
                typeMismatch = (varType != VT_R4);
                break;
            case X_DOUBLE:
                dataType = NDFloat64;
                typeMismatch = (varType != VT_R8);
                break;
            default:
                asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
                    "%s:%s: unknown data type = %d\n", 
                    driverName, functionName, docDataType);
                return(NULL);
        }
        if (typeMismatch) {
            asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
                "%s:%s: data type mismatch: docDataType=%d, varType=%d\n", 
                driverName, functionName, docDataType, varType);
            return(NULL);
        }
        pArray = this->pNDArrayPool->alloc(nDims, dims, dataType, 0, NULL);
        pArray->getInfo(&arrayInfo);
        SafeArrayAccessData(pData, &pVarData);
        memcpy(pArray->pData, pVarData, arrayInfo.totalBytes);
        SafeArrayUnaccessData(pData);
        SafeArrayDestroy(pData);
        setIntegerParam(NDArraySize, arrayInfo.totalBytes);
        setIntegerParam(NDArraySizeX, (int)dims[0]);
        setIntegerParam(NDArraySizeY, (int)dims[1]);
        setIntegerParam(NDDataType, dataType);
    }
    catch(CException *pEx) {
        pEx->GetErrorMessage(this->errorMessage, sizeof(this->errorMessage));
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
            "%s:%s: exception = %s\n", 
            driverName, functionName, this->errorMessage);
        pEx->Delete();
        return(NULL);
    }
        
    return(pArray);
}
Esempio n. 19
0
static void saproxy_write_dimension(zend_object *object, zval *offset, zval *value)
{
	php_com_saproxy *proxy = (php_com_saproxy*) object;
	UINT dims, i;
	HRESULT res;
	VARIANT v;

	if (V_VT(&proxy->obj->v) == VT_DISPATCH) {
		/* We do a prop-set using the first dimension as the property name,
		 * all subsequent dimensions and offset as parameters, with value as
		 * the final value */
		zval *args = safe_emalloc(proxy->dimensions + 2, sizeof(zval), 0);

		for (i = 1; i < (UINT) proxy->dimensions; i++) {
			ZVAL_COPY_VALUE(&args[i-1], &proxy->indices[i]);
		}
		ZVAL_COPY_VALUE(&args[i-1], offset);
		ZVAL_COPY_VALUE(&args[i], value);

		convert_to_string(&proxy->indices[0]);
		VariantInit(&v);
		if (SUCCESS == php_com_do_invoke(proxy->obj, Z_STRVAL(proxy->indices[0]),
					Z_STRLEN(proxy->indices[0]), DISPATCH_PROPERTYPUT, &v, proxy->dimensions + 1,
					args, 0)) {
			VariantClear(&v);
		}

		efree(args);

	} else if (V_ISARRAY(&proxy->obj->v)) {
		LONG *indices;
		VARTYPE vt;

		dims = SafeArrayGetDim(V_ARRAY(&proxy->obj->v));
		indices = safe_emalloc(dims, sizeof(LONG), 0);
		/* copy indices from proxy */
		for (i = 0; i < dims; i++) {
			convert_to_long(&proxy->indices[i]);
			indices[i] = (LONG)Z_LVAL(proxy->indices[i]);
		}

		/* add user-supplied index */
		convert_to_long(offset);
		indices[dims-1] = (LONG)Z_LVAL_P(offset);

		if (FAILED(SafeArrayGetVartype(V_ARRAY(&proxy->obj->v), &vt)) || vt == VT_EMPTY) {
			vt = V_VT(&proxy->obj->v) & ~VT_ARRAY;
		}

		VariantInit(&v);
		php_com_variant_from_zval(&v, value, proxy->obj->code_page);

		if (V_VT(&v) != vt) {
			VariantChangeType(&v, &v, 0, vt);
		}

		if (vt == VT_VARIANT) {
			res = SafeArrayPutElement(V_ARRAY(&proxy->obj->v), indices, &v);
		} else {
			res = SafeArrayPutElement(V_ARRAY(&proxy->obj->v), indices, &v.lVal);
		}

		efree(indices);
		VariantClear(&v);

		if (FAILED(res)) {
			php_com_throw_exception(res, NULL);
		}
	} else {
		php_com_throw_exception(E_NOTIMPL, "invalid write to com proxy object");
	}
}
Esempio n. 20
0
int main()
{
    CoInitializeEx(0, COINIT_MULTITHREADED);

    HRESULT hr = S_OK;
    //GUID guid;
    //hr = CLSIDFromString(L"MyNamespace.MyClass", &guid);
    //hr = CLSIDFromString(L"{7884998B-0504-4CBE-9FF9-6BBAA9776188}", &guid);
    //hr = CoCreateInstance(guid, NULL, CLSCTX_ALL, IID_IUnknown, reinterpret_cast<void**>(&p));

    NetCom::IMyClassPtr ptr;
    hr = ptr.CreateInstance(__uuidof(NetCom::Class1));
    long l;
    hr = ptr->GetData(&l);

	SAFEARRAY *ppData = NULL;
    hr = ptr->GetStructs(&ppData);
    if (SUCCEEDED(hr) && ppData)
    {
        #pragma region Validate received datatype 

        VARTYPE vt;
        hr = SafeArrayGetVartype(ppData, &vt);
        if (SUCCEEDED(hr) && (vt != VT_RECORD))
        {
            //Not a sturcture
            hr = E_POINTER;
        }

        if (SUCCEEDED(hr))
        {
            IRecordInfoPtr spIRecordInfo = NULL;
            hr = SafeArrayGetRecordInfo(ppData, &spIRecordInfo);
            if (SUCCEEDED(hr) && spIRecordInfo)
            {
                GUID guid;
                hr = spIRecordInfo->GetGuid(&guid);
                if (guid != __uuidof(NetCom::TICKSTRUCT))
                {
                    //Invalid record type
                    hr = E_POINTER;
                }
            }
        }
        #pragma endregion

        NetCom::TICKSTRUCT *pVals = NULL;
        hr = SafeArrayAccessData(ppData, (void**)&pVals);
        if (SUCCEEDED(hr))
        {
            long lowerBound, upperBound;  // get array bounds
            SafeArrayGetLBound(ppData, 1, &lowerBound);
            SafeArrayGetUBound(ppData, 1, &upperBound);

            long count = upperBound - lowerBound + 1;
            for (int i = 0; i < count; ++i)  // iterate through returned values
            {
                printf("[%d] Date: %f Price: %f Volume: %d\n", i, pVals->Date, pVals->Price, pVals->Volume);
                pVals++;
            }
            hr = SafeArrayUnaccessData(ppData);
        }
        hr = SafeArrayDestroy(ppData);
    }

	//Control safearray lifetime by _variant_t wrapper
	_variant_t vt;
	if (SUCCEEDED(ptr->GetStructs(&vt.parray)))
	{
		vt.vt = VT_ARRAY | VT_RECORD;
		SAFEARRAY* ppData2 = vt.parray;
		//ppData2 can be used in same way as ppData above with exception:
		//1. Do not call SafeArrayDestroy. array will be destroyed by VariantClear function
		//2. Make sure ppData2 is not locked (SafeArrayAccessData) before vt.Clear or ~vt will be called.
		//		In this case VariantClear will not able to clean locked data
	}

    return 0;
}
Esempio n. 21
0
static zval *saproxy_read_dimension(zend_object *object, zval *offset, int type, zval *rv)
{
	php_com_saproxy *proxy = (php_com_saproxy*) object;
	UINT dims, i;
	SAFEARRAY *sa;
	LONG ubound, lbound;
	HRESULT res;

	ZVAL_NULL(rv);

	if (V_VT(&proxy->obj->v) == VT_DISPATCH) {
		VARIANT v;
		zval *args;

		/* prop-get using first dimension as the property name,
		 * all subsequent dimensions and the offset as parameters */

		args = safe_emalloc(proxy->dimensions + 1, sizeof(zval), 0);

		for (i = 1; i < (UINT) proxy->dimensions; i++) {
			args[i-1] = proxy->indices[i];
		}
		ZVAL_COPY_VALUE(&args[i-1], offset);

		convert_to_string(&proxy->indices[0]);
		VariantInit(&v);

		res = php_com_do_invoke(proxy->obj, Z_STRVAL(proxy->indices[0]),
			   	Z_STRLEN(proxy->indices[0]), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v,
			   	proxy->dimensions, args, 0);

		if (res == SUCCESS) {
			php_com_zval_from_variant(rv, &v, proxy->obj->code_page);
			VariantClear(&v);
		} else if (res == DISP_E_BADPARAMCOUNT) {
			/* return another proxy */
			php_com_saproxy_create(object, rv, offset);
		}

		return rv;

	} else if (!V_ISARRAY(&proxy->obj->v)) {
		php_com_throw_exception(E_INVALIDARG, "invalid read from com proxy object");
		return rv;
	}

	/* the SafeArray case */

	/* offset/index must be an integer */
	convert_to_long(offset);

	sa = V_ARRAY(&proxy->obj->v);
	dims = SafeArrayGetDim(sa);

	if ((UINT) proxy->dimensions >= dims) {
		/* too many dimensions */
		php_com_throw_exception(E_INVALIDARG, "too many dimensions!");
		return rv;
	}

	/* bounds check */
	SafeArrayGetLBound(sa, proxy->dimensions, &lbound);
	SafeArrayGetUBound(sa, proxy->dimensions, &ubound);

	if (Z_LVAL_P(offset) < lbound || Z_LVAL_P(offset) > ubound) {
		php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds");
		return rv;
	}

	if (dims - 1 == proxy->dimensions) {
		LONG *indices;
		VARTYPE vt;
		VARIANT v;

		VariantInit(&v);

		/* we can return a real value */
		indices = safe_emalloc(dims, sizeof(LONG), 0);

		/* copy indices from proxy */
		for (i = 0; i < dims; i++) {
			convert_to_long(&proxy->indices[i]);
			indices[i] = (LONG)Z_LVAL(proxy->indices[i]);
		}

		/* add user-supplied index */
		indices[dims-1] = (LONG)Z_LVAL_P(offset);

		/* now fetch the value */
		if (FAILED(SafeArrayGetVartype(sa, &vt)) || vt == VT_EMPTY) {
			vt = V_VT(&proxy->obj->v) & ~VT_ARRAY;
		}

		if (vt == VT_VARIANT) {
			res = SafeArrayGetElement(sa, indices, &v);
		} else {
			V_VT(&v) = vt;
			res = SafeArrayGetElement(sa, indices, &v.lVal);
		}

		efree(indices);

		if (SUCCEEDED(res)) {
			php_com_wrap_variant(rv, &v, proxy->obj->code_page);
		} else {
			php_com_throw_exception(res, NULL);
		}

		VariantClear(&v);

	} else {
		/* return another proxy */
		php_com_saproxy_create(object, rv, offset);
	}

	return rv;
}
Esempio n. 22
0
/*!
 * @brief Convert a variant type to a string and write it to the given buffer.
 * @param v The variant to convert.
 * @param buffer Pointer to the buffer to write the value to.
 * @param bufferSize size of the buffer.
 * @returns Pointer to the next location in the buffer.
 * @remarks This attempts to "flatten" a variant, including array types. The implementation is
 *          not 100% complete, but is good enough for the sake of this requirement. Only arrays
 *          of BSTR are currenty supported, more types can be added later if needed. Arbitrary
 *          array depth has been attempted, but no tests have yet found a nested array in the
 *          result set. There's probably bugs in that bit.
 */
char* variant_to_string(_variant_t& v, char* buffer, DWORD bufferSize)
{
	dprintf("[WMI] preparing to parse variant of type %u (%x), buffer size %u", v.vt, v.vt, bufferSize);

	switch (v.vt)
	{
	case VT_EMPTY:
		strncpy_s(buffer, bufferSize, "(EMPTY)", bufferSize - 1);
		break;
	case VT_NULL:
		strncpy_s(buffer, bufferSize, "(NULL)", bufferSize - 1);
		break;
	case VT_BOOL:
		strncpy_s(buffer, bufferSize, v.boolVal == VARIANT_TRUE ? "true" : "false", bufferSize - 1);
		break;
	case VT_I1:
		_snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRId8, (CHAR)v);
		break;
	case VT_I2:
		_snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRId16, (SHORT)v);
		break;
	case VT_INT:
	case VT_I4:
		_snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRId32, (INT)v);
		break;
	case VT_INT_PTR:
	case VT_I8:
		_snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRId64, (INT_PTR)v);
		break;
	case VT_UI1:
		_snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRIu8, (BYTE)v);
		break;
	case VT_UI2:
		_snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRIu16, (SHORT)v);
		break;
	case VT_UINT:
	case VT_UI4:
		_snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRIu32, (UINT)v);
		break;
	case VT_UINT_PTR:
	case VT_UI8:
		_snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRIu64, (UINT_PTR)v);
		break;
	case VT_BSTR:
	case VT_LPSTR:
	case VT_LPWSTR:
		// not sure if this is correct
		strncpy_s(buffer, bufferSize, (char*)(_bstr_t)v.bstrVal, bufferSize - 1);
		break;
		// TODO more types, such as floats, dates, etc.
	default:
		if ((v.vt & VT_ARRAY) == VT_ARRAY)
		{
			// nested array type, great.
			dprintf("[WMI] array type found!");
			LPSAFEARRAY array = v.parray;
			HRESULT hResult;

			if (FAILED(hResult = SafeArrayLock(array)))
			{
				dprintf("[WMI] Failed to get array dimension: %x", hResult);
				break;
			}
			dprintf("[WMI] Field name array locked.");

			LONG* indices = NULL;
			LONG* bounds = NULL;
			do
			{
				VARTYPE varType;
				SafeArrayGetVartype(array, &varType);
				dprintf("[WMI] Array type %u (%x)", (ULONG)varType, (ULONG)varType);
				dprintf("[WMI] Array dimensions: %u", SafeArrayGetDim(array));

				LONG iterations = 1;
				LONG dim = SafeArrayGetDim(array);
				indices = (LONG*)malloc(dim * sizeof(LONG));
				bounds = (LONG*)malloc(dim * sizeof(LONG) * 2);
				memset(indices, 0, dim * sizeof(LONG));
				memset(bounds, 0, dim * sizeof(LONG) * 2);

				for (LONG i = 0; i < dim; ++i)
				{
					LONG* lBound = bounds + i * 2;
					LONG* uBound = lBound + 1;
					if (FAILED(hResult = SafeArrayGetLBound(array, i + 1, lBound))
						|| FAILED(hResult = SafeArrayGetUBound(array, i + 1, uBound)))
					{
						dprintf("[WMI] Failed to get array dimensions: %x", hResult);
						break;
					}
					dprintf("[WMI] Array bounds: %u to %u", *lBound, *uBound);

					iterations *= *uBound - *lBound;
					indices[i] = *lBound;
				}
				dprintf("[WMI] Array requires %u iterations", iterations);

				// we're going to wrap our array elements in brackets, and separate with pipes
				// because we need some kind of array visualisation and this is the best I could
				// come up with at this time of night. Each dimension nests in a new set of brackets
				while (iterations-- > 0)
				{
					for (LONG i = 0; i < dim; ++i)
					{
						if (indices[i] == 0)
						{
							// save space for the closing bracket as well
							bufferSize -= 2;
							*buffer++ = '{';
							dprintf("[WMI] opening bracket for dimension %u", i);
						}
						else if(*(buffer - 1) != '|')
						{
							--bufferSize;
							*buffer++ = '|';
						}
					}

					dprintf("[WMI] extracting value for iteration %u", iterations);
					switch (varType)
					{
					case VT_BSTR:
						BSTR val;
						if (SUCCEEDED(SafeArrayGetElement(array, indices, (void*)&val)))
						{
							dprintf("[WMI] Value extracted for iteration %u", iterations);
							char* newBuf = variant_to_string(_variant_t(val), buffer, bufferSize);
							bufferSize -= (LONG)(newBuf - buffer + 1);
							buffer = newBuf;
							dprintf("[WMI] Value added", iterations);
						}
						break;
					default:
						dprintf("[WMI] Unsupported nested array type %u", (LONG)varType);
						break;
					}

					++indices[dim - 1];
					for (LONG i = dim - 1; i >= 0; --i)
					{
						if (indices[i] == bounds[i * 2 + 1])
						{
							dprintf("[WMI] closing bracket for dimension %u", i);
							*buffer++ = '}';
							indices[i] = bounds[i * 2];
							if (i > 0)
							{
								++indices[i - 1];
							}
						}
					}
				}
			} while (0);

			if (indices)
			{
				free(indices);
			}
			if (bounds)
			{
				free(bounds);
			}

			SafeArrayUnlock(array);
		}
		else
		{
			dprintf("[WMI] Unhandled type: %u (%x)", v.vt, v.vt);
		}
		// ignore the buffer for other types
		break;
	}

	// return wherever we go to.
	return buffer + strlen(buffer);
}
Esempio n. 23
0
STDMETHODIMP CGraphElement::Plot(VARIANT newXVals, VARIANT newYVals)
{
    LONG lXBound, uXBound, lYBound, uYBound;
    SAFEARRAY* psaXVals, *psaYVals;
    HRESULT hr;

    //usually from VBScript the arrays are coming packed in by ref variants
    hr = GetArrayFromVariant(&newXVals, &psaXVals);
    if(FAILED(hr))
    {
        return hr;
    }
    hr = GetArrayFromVariant(&newYVals, &psaYVals);
    if(FAILED(hr))
    {
        return hr;
    }

    hr = SafeArrayGetLBound(psaXVals, 1, &lXBound);
    if(FAILED(hr))
    {
        return hr;
    }
    hr = SafeArrayGetUBound(psaYVals, 1, &uXBound);
    if(FAILED(hr))
    {
        return hr;
    }
    hr = SafeArrayGetLBound(psaXVals, 1, &lYBound);
    if(FAILED(hr))
    {
        return hr;
    }
    hr = SafeArrayGetUBound(psaYVals, 1, &uYBound);
    if(FAILED(hr))
    {
        return hr;
    }
    if(uXBound - lXBound != uYBound - lYBound)
    {
        return AtlReportError(GUID_NULL, L"Array with same size expected", IID_NULL, E_INVALIDARG);
    }

    int i, nCount;

    min = max = CElementPoint(0,0);

    nCount = m_PointList.GetSize();

    EnterCriticalSection(&m_CritSectionForPlot);
    m_PointList.RemoveAll();
    LeaveCriticalSection(&m_CritSectionForPlot);

    if(m_pCtrl && nCount)
    {
        m_pCtrl->OnPlotDeleted();    //current element does not have any points anymore
    }

    nCount = uXBound - lXBound + 1;

    VARTYPE typeX, typeY;
    SafeArrayGetVartype(psaXVals, &typeX);
    SafeArrayGetVartype(psaYVals, &typeY);

    for(i=0; i< nCount; i++)
    {
        double x ,y;
        hr = GetDoubleElement(typeX, psaXVals, i, &x);
        if(FAILED(hr))
        {
            break;
        }
        hr = GetDoubleElement(typeY, psaYVals, i, &y);
        if(FAILED(hr))
        {
            break;
        }

        CElementPoint point(x, y);
        m_PointList.Add(point);

        if(min.x > point.x)
        {
            min.x = point.x ;
        }
        if(min.y > point.y)
        {
            min.y = point.y ;
        }
        if(max.x < point.x)
        {
            max.x = point.x ;
        }
        if(max.y < point.y)
        {
            max.y = point.y ;
        }

        if(m_pCtrl)
        {
            m_pCtrl->UpdateAutoRange(x, y,
                                     i == 0);    //TRUE only for first added point
        }
    }
    if(m_pCtrl) //redraw once for all added points
    {
        m_pCtrl->Refresh(FALSE);
    }

    return hr;
}
Esempio n. 24
0
static void test_registry(void)
{
    static const WCHAR keypathW[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',
        'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','T','e','s','t','\\',0};
    static const WCHAR regsz2W[] = {'r','e','g','s','z','2',0};
    static const WCHAR regszW[] = {'r','e','g','s','z',0};
    static const WCHAR regdwordW[] = {'r','e','g','d','w','o','r','d',0};
    static const WCHAR regbinaryW[] = {'r','e','g','b','i','n','a','r','y',0};
    static const WCHAR regmultiszW[] = {'r','e','g','m','u','l','t','i','s','z',0};

    static const WCHAR regsz1W[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',
        'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','T','e','s','t','\\','r','e','g','s','z','1',0};
    static const WCHAR foobarW[] = {'f','o','o','b','a','r',0};
    static const WCHAR fooW[] = {'f','o','o',0};
    static const WCHAR brokenW[] = {'H','K','E','Y','_','b','r','o','k','e','n','_','k','e','y',0};
    static const WCHAR broken2W[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','a',0};
    WCHAR pathW[MAX_PATH];
    DWORD dwvalue, type;
    VARIANT value, v;
    IWshShell3 *sh3;
    VARTYPE vartype;
    LONG bound;
    HRESULT hr;
    BSTR name;
    HKEY root;
    LONG ret;
    UINT dim;

    hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
            &IID_IWshShell3, (void**)&sh3);
    ok(hr == S_OK, "got 0x%08x\n", hr);

    /* RegRead() */
    V_VT(&value) = VT_I2;
    hr = IWshShell3_RegRead(sh3, NULL, &value);
    ok(hr == E_POINTER, "got 0x%08x\n", hr);
    ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value));

    name = SysAllocString(brokenW);
    hr = IWshShell3_RegRead(sh3, name, NULL);
    ok(hr == E_POINTER, "got 0x%08x\n", hr);
    V_VT(&value) = VT_I2;
    hr = IWshShell3_RegRead(sh3, name, &value);
    ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "got 0x%08x\n", hr);
    ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value));
    SysFreeString(name);

    name = SysAllocString(broken2W);
    V_VT(&value) = VT_I2;
    hr = IWshShell3_RegRead(sh3, name, &value);
    ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "got 0x%08x\n", hr);
    ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value));
    SysFreeString(name);

    ret = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &root);
    ok(ret == 0, "got %d\n", ret);

    ret = RegSetValueExA(root, "regsz", 0, REG_SZ, (const BYTE*)"foobar", 7);
    ok(ret == 0, "got %d\n", ret);

    ret = RegSetValueExA(root, "regsz2", 0, REG_SZ, (const BYTE*)"foobar\0f", 9);
    ok(ret == 0, "got %d\n", ret);

    ret = RegSetValueExA(root, "regmultisz", 0, REG_MULTI_SZ, (const BYTE*)"foo\0bar\0", 9);
    ok(ret == 0, "got %d\n", ret);

    dwvalue = 10;
    ret = RegSetValueExA(root, "regdword", 0, REG_DWORD, (const BYTE*)&dwvalue, sizeof(dwvalue));
    ok(ret == 0, "got %d\n", ret);

    dwvalue = 11;
    ret = RegSetValueExA(root, "regbinary", 0, REG_BINARY, (const BYTE*)&dwvalue, sizeof(dwvalue));
    ok(ret == 0, "got %d\n", ret);

    /* REG_SZ */
    lstrcpyW(pathW, keypathW);
    lstrcatW(pathW, regszW);
    name = SysAllocString(pathW);
    VariantInit(&value);
    hr = IWshShell3_RegRead(sh3, name, &value);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
    ok(!lstrcmpW(V_BSTR(&value), foobarW), "got %s\n", wine_dbgstr_w(V_BSTR(&value)));
    VariantClear(&value);
    SysFreeString(name);

    /* REG_SZ with embedded NULL */
    lstrcpyW(pathW, keypathW);
    lstrcatW(pathW, regsz2W);
    name = SysAllocString(pathW);
    VariantInit(&value);
    hr = IWshShell3_RegRead(sh3, name, &value);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
    ok(SysStringLen(V_BSTR(&value)) == 6, "len %d\n", SysStringLen(V_BSTR(&value)));
    VariantClear(&value);
    SysFreeString(name);

    /* REG_DWORD */
    lstrcpyW(pathW, keypathW);
    lstrcatW(pathW, regdwordW);
    name = SysAllocString(pathW);
    VariantInit(&value);
    hr = IWshShell3_RegRead(sh3, name, &value);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(V_VT(&value) == VT_I4, "got %d\n", V_VT(&value));
    ok(V_I4(&value) == 10, "got %d\n", V_I4(&value));
    SysFreeString(name);

    /* REG_BINARY */
    lstrcpyW(pathW, keypathW);
    lstrcatW(pathW, regbinaryW);
    name = SysAllocString(pathW);
    VariantInit(&value);
    hr = IWshShell3_RegRead(sh3, name, &value);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(V_VT(&value) == (VT_ARRAY|VT_VARIANT), "got 0x%x\n", V_VT(&value));
    dim = SafeArrayGetDim(V_ARRAY(&value));
    ok(dim == 1, "got %u\n", dim);

    hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &bound);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(bound == 0, "got %u\n", bound);

    hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &bound);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(bound == 3, "got %u\n", bound);

    hr = SafeArrayGetVartype(V_ARRAY(&value), &vartype);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(vartype == VT_VARIANT, "got %d\n", vartype);

    bound = 0;
    hr = SafeArrayGetElement(V_ARRAY(&value), &bound, &v);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(V_VT(&v) == VT_UI1, "got %d\n", V_VT(&v));
    ok(V_UI1(&v) == 11, "got %u\n", V_UI1(&v));
    VariantClear(&v);
    VariantClear(&value);
    SysFreeString(name);

    /* REG_MULTI_SZ */
    lstrcpyW(pathW, keypathW);
    lstrcatW(pathW, regmultiszW);
    name = SysAllocString(pathW);
    VariantInit(&value);
    hr = IWshShell3_RegRead(sh3, name, &value);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(V_VT(&value) == (VT_ARRAY|VT_VARIANT), "got 0x%x\n", V_VT(&value));
    SysFreeString(name);

    dim = SafeArrayGetDim(V_ARRAY(&value));
    ok(dim == 1, "got %u\n", dim);

    hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &bound);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(bound == 0, "got %u\n", bound);

    hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &bound);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(bound == 1, "got %u\n", bound);

    hr = SafeArrayGetVartype(V_ARRAY(&value), &vartype);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(vartype == VT_VARIANT, "got %d\n", vartype);

    bound = 0;
    hr = SafeArrayGetElement(V_ARRAY(&value), &bound, &v);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
    ok(!lstrcmpW(V_BSTR(&v), fooW), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
    VariantClear(&v);
    VariantClear(&value);

    name = SysAllocString(regsz1W);
    V_VT(&value) = VT_I2;
    hr = IWshShell3_RegRead(sh3, name, &value);
    ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
    ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value));
    VariantClear(&value);
    SysFreeString(name);

    delete_key(root);

    /* RegWrite() */
    ret = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &root);
    ok(ret == 0, "got %d\n", ret);

    hr = IWshShell3_RegWrite(sh3, NULL, NULL, NULL);
    ok(hr == E_POINTER, "got 0x%08x\n", hr);

    lstrcpyW(pathW, keypathW);
    lstrcatW(pathW, regszW);
    name = SysAllocString(pathW);

    hr = IWshShell3_RegWrite(sh3, name, NULL, NULL);
    ok(hr == E_POINTER, "got 0x%08x\n", hr);

    VariantInit(&value);
    hr = IWshShell3_RegWrite(sh3, name, &value, NULL);
    ok(hr == E_POINTER, "got 0x%08x\n", hr);

    hr = IWshShell3_RegWrite(sh3, name, &value, &value);
    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);

    /* type is optional */
    V_VT(&v) = VT_ERROR;
    V_ERROR(&v) = DISP_E_PARAMNOTFOUND;
    hr = IWshShell3_RegWrite(sh3, name, &value, &v);
    ok(hr == S_OK, "got 0x%08x\n", hr);

    /* default type is REG_SZ */
    V_VT(&value) = VT_I4;
    V_I4(&value) = 12;
    hr = IWshShell3_RegWrite(sh3, name, &value, &v);
    ok(hr == S_OK, "got 0x%08x\n", hr);

    type = REG_NONE;
    ret = RegGetValueA(root, NULL, "regsz", RRF_RT_ANY, &type, NULL, NULL);
    ok(ret == ERROR_SUCCESS, "got %d\n", ret);
    ok(type == REG_SZ, "got %d\n", type);

    ret = RegDeleteValueA(root, "regsz");
    ok(ret == ERROR_SUCCESS, "got %d\n", ret);
    V_VT(&value) = VT_BSTR;
    V_BSTR(&value) = SysAllocString(regszW);
    hr = IWshShell3_RegWrite(sh3, name, &value, &v);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    VariantClear(&value);

    type = REG_NONE;
    ret = RegGetValueA(root, NULL, "regsz", RRF_RT_ANY, &type, NULL, NULL);
    ok(ret == ERROR_SUCCESS, "got %d\n", ret);
    ok(type == REG_SZ, "got %d\n", type);

    ret = RegDeleteValueA(root, "regsz");
    ok(ret == ERROR_SUCCESS, "got %d\n", ret);
    V_VT(&value) = VT_R4;
    V_R4(&value) = 1.2;
    hr = IWshShell3_RegWrite(sh3, name, &value, &v);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    VariantClear(&value);

    type = REG_NONE;
    ret = RegGetValueA(root, NULL, "regsz", RRF_RT_ANY, &type, NULL, NULL);
    ok(ret == ERROR_SUCCESS, "got %d\n", ret);
    ok(type == REG_SZ, "got %d\n", type);

    ret = RegDeleteValueA(root, "regsz");
    ok(ret == ERROR_SUCCESS, "got %d\n", ret);
    V_VT(&value) = VT_R4;
    V_R4(&value) = 1.2;
    V_VT(&v) = VT_I2;
    V_I2(&v) = 1;
    hr = IWshShell3_RegWrite(sh3, name, &value, &v);
    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
    VariantClear(&value);

    SysFreeString(name);

    delete_key(root);
    IWshShell3_Release(sh3);
}
Esempio n. 25
0
int __declspec(dllexport) __stdcall
vbSafeArrayToPtr( VARIANT *vArray, GDALDataType *peDataType,
                  int *pnXSize, int *pnYSize )

{
    char **papszResult = NULL;
    SAFEARRAY *psSA;
    long nLBound, nUBound;
    VARTYPE eVartype;

/* -------------------------------------------------------------------- */
/*      Get and verify info about safe array.                           */
/* -------------------------------------------------------------------- */
    if( vArray == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "VARIANT is NULL in SafeArrayToPtr()." );
        return NULL;
    }

    if( (vArray->vt & (VT_ARRAY | VT_BYREF)) == (VT_ARRAY | VT_BYREF) )
        psSA = *(vArray->pparray);
    else if( (vArray->vt & VT_ARRAY) == VT_ARRAY )
        psSA = vArray->parray;
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "VARIANT is wrong type (%x).",
                  vArray->vt );
        return NULL;
    }

    if( SafeArrayGetDim(psSA) < 1 || SafeArrayGetDim(psSA) > 2 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Wrong dimension in array (%d)",
                  SafeArrayGetDim(psSA) );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Get XSize                                                       */
/* -------------------------------------------------------------------- */
    if( FAILED(SafeArrayGetLBound( psSA, 1, &nLBound ))
        || FAILED(SafeArrayGetUBound( psSA, 1, &nUBound)) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "SafeARrayGet{L,U}Bound() failed." );
        return NULL;
    }

    if( nUBound <= nLBound )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Crazy L/U Bound (L=%d, U=%d)",
                  nLBound, nUBound );
        return NULL;
    }

    *pnXSize = nUBound - nLBound + 1;

/* -------------------------------------------------------------------- */
/*      Get YSize                                                       */
/* -------------------------------------------------------------------- */
    if( SafeArrayGetDim(psSA) == 1 )
        *pnYSize = 1;
    else
    {
        if( FAILED(SafeArrayGetLBound( psSA, 1, &nLBound ))
            || FAILED(SafeArrayGetUBound( psSA, 1, &nUBound)) )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "SafeARrayGet{L,U}Bound() failed." );
            return NULL;
        }

        if( nUBound <= nLBound )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Crazy L/U Bound (L=%d, U=%d)",
                      nLBound, nUBound );
            return NULL;
        }

        *pnYSize = nUBound - nLBound + 1;
    }

/* -------------------------------------------------------------------- */
/*      Translate the type.                                             */
/* -------------------------------------------------------------------- */
    SafeArrayGetVartype(psSA, &eVartype );
    if( eVartype == VT_UI1 )
        *peDataType = GDT_Byte;
    else if( eVartype == VT_UI2 )
        *peDataType = GDT_UInt16;
    else if( eVartype == VT_I2 )
        *peDataType = GDT_Int16;
    else if( eVartype == VT_I4 || eVartype == VT_INT )
        *peDataType = GDT_Int32;
    else if( eVartype == VT_UI4 || eVartype == VT_UINT )
        *peDataType = GDT_UInt32;
    else if( eVartype == VT_R4 )
        *peDataType = GDT_Float32;
    else if( eVartype == VT_R8 )
        *peDataType = GDT_Float64;
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "SafeArray contains type %d which is not supported.",
                  eVartype );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Return the raw data pointer cast to an int.                     */
/* -------------------------------------------------------------------- */
    return (int) psSA->pvData;
}
Esempio n. 26
0
char __declspec(dllexport) ** __stdcall
vbVariantToCSL( VARIANT *vList )

{
    char **papszResult = NULL;
    SAFEARRAY *psSA;
    long nLBound, nUBound;
    VARTYPE eVartype;

/* -------------------------------------------------------------------- */
/*      Get and verify info about safe array.                           */
/* -------------------------------------------------------------------- */
    if( vList == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "VARIANT is NULL in VariantToCSL()." );
        return NULL;
    }

    if( vList->vt == (VT_BSTR | VT_ARRAY | VT_BYREF) )
        psSA = *(vList->pparray);
    else if( vList->vt == (VT_BSTR | VT_ARRAY) )
        psSA = vList->parray;
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "VARIANT is wrong type (%x).",
                  vList->vt );
        return NULL;
    }

    if( SafeArrayGetDim(psSA) != 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Wrong dimension in array (%d)",
                  SafeArrayGetDim(psSA) );
        return NULL;
    }

    if( FAILED(SafeArrayGetLBound( psSA, 1, &nLBound ))
        || FAILED(SafeArrayGetUBound( psSA, 1, &nUBound)) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "SafeARrayGet{L,U}Bound() failed." );
        return NULL;
    }

    if( nUBound < nLBound )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Crazy L/U Bound (L=%d, U=%d)",
                  nLBound, nUBound );
        return NULL;
    }

    SafeArrayGetVartype(psSA, &eVartype );
    if( eVartype != VT_BSTR )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "SafeArray contains type %d instead of VT_BSTR.",
                  eVartype );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create string list from safe array BSTRings.                    */
/* -------------------------------------------------------------------- */
    papszResult = (char **) CPLCalloc(sizeof(char *),(nUBound-nLBound+2));

    for( long iElement = nLBound; iElement <= nUBound; iElement++ )
    {
        BSTR bstrValue;
        char szValue[5000];

        if( FAILED(SafeArrayGetElement(psSA, &iElement, &bstrValue)) )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "SafeArrayGetElement(%d) failed.",
                      iElement );
            CSLDestroy( papszResult );
            return NULL;
        }

        sprintf( szValue, "%S", bstrValue );
        papszResult[iElement - nLBound] = CPLStrdup( szValue );
    }

    return papszResult;
}
Esempio n. 27
0
static int cmdfunc_ctrlcmd( int cmd )
{
	//		cmdfunc : TYPE_DLLCTRL
	//		(拡張DLLコントロールコマンド)
	//
	code_next();							// 次のコードを取得(最初に必ず必要です)

	if ( cmd >= TYPE_OFFSET_COMOBJ ) {
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		// COM インターフェースメソッドの呼び出し
		STRUCTDAT *st;
		st = GetPRM( cmd - TYPE_OFFSET_COMOBJ );
		hspctx->stat = code_expand_and_call( st );
		return RUNMODE_RUN;
#endif
	}

	switch( cmd ) {							// サブコマンドごとの分岐


	case 0x00:								// newcom
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		IUnknown **ppunkNew, *punkDef;
		CLSID clsid;
		char *clsid_name;
		const IID *piid, *piid2;
		void *iptr;
		LIBDAT *lib;
		STRUCTDAT *st;
		int inimode;

		// 第1パラメータ:新しいインターフェースポインタを格納する変数
		// (変数にNULLポインタを格納)
		aptr = code_getva( &pval );
		iptr = NULL;
		code_setva( pval, aptr, TYPE_COMOBJ, &iptr );
		ppunkNew = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );

		// CLSID / IID 情報を取得
		if ( !code_getexflg() && *type == TYPE_DLLCTRL ) {
			// 第2パラメータ:#usecom 登録情報
			st = code_getcomst();
			if ( st->otindex != -1 ) throw HSPERR_TYPE_MISMATCH;
			lib = &hspctx->mem_linfo[ st->index ];
			if ( lib->clsid == -1 ) throw HSPERR_INVALID_PARAMETER;
			clsid_name = strp(lib->clsid);
			piid  = (IID *)strp( lib->nameidx );
			piid2 = NULL;
		} else {
			// 第2パラメータ:文字列 CLSID
			// (IID はデフォルトで IID_IDispatch, サポートされていなければ IID_IUnknown )
			clsid_name = code_getds("");
			piid  = &IID_IDispatch;
			piid2 = &IID_IUnknown;
		}
		inimode = code_getdi(0);				// 初期化モード
		punkDef = (IUnknown *)code_getdi(0);	// デフォルトオブジェクト

		// 新規CLSIDからインスタンスを作成
		hspctx->stat = 0;
		switch ( inimode ) {
		 case 0:
			// 新規にロード
			if ( clsid_name[0]!='\0' ) {
				if ( GetIIDFromString(&clsid,clsid_name,true) != FALSE &&
					 SUCCEEDED( CoCreateInstance( clsid, NULL, CLSCTX_SERVER, *piid, (void**)ppunkNew )) &&
					 *ppunkNew != NULL )
				{
					break;
				}
				if ( piid2 != NULL &&
					 SUCCEEDED( CoCreateInstance( clsid, NULL, CLSCTX_SERVER, *piid2, (void**)ppunkNew )) &&
					 *ppunkNew != NULL )
				{
					break;
				}
				hspctx->stat = 1;
			}
			break;
		 case -2:
			// オブジェクトを明示的に指定する場合 ( AddRef() あり)
			if ( punkDef != NULL ) punkDef->AddRef();
		 case -1:
			// オブジェクトを明示的に指定する場合 ( AddRef() なし)
			*ppunkNew = punkDef;
			break;
		 default:
			throw HSPERR_UNSUPPORTED_FUNCTION;
		}
	#ifdef HSP_COMOBJ_DEBUG
		COM_DBG_MSG( "newcom : pObj=%p : &pObj=%p\n", *ppunkNew, ppunkNew);
	#endif
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x01:								// querycom
#ifdef HSP_COM_UNSUPPORTED
		throw HSPERR_UNSUPPORTED_FUNCTION;
#else
		{
		PVal *pval, *pvalNew;
		APTR aptr, aptrNew;
		IUnknown **ppunkDst, **ppunkSrc;
		IID iid;
		const IID *piid;
		void *iptr;
		STRUCTDAT *st;
		LIBDAT *lib;

		// 第1パラメータ:新しいインターフェースポインタを格納する変数
		aptrNew = code_getva( &pvalNew );

		// 第2パラメータ:既存のCOMオブジェクト
		aptr = code_getva( &pval );
		if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH );
		ppunkSrc = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );
		if ( ! IsVaridComPtr(ppunkSrc) ) throw ( HSPERR_COMDLL_ERROR );

		// IID 情報を取得
		if ( *type == TYPE_DLLCTRL ) {
			// 第3パラメータ:#usecom 登録情報
			st = code_getcomst();
			if ( st->otindex != -1 ) throw ( HSPERR_TYPE_MISMATCH );
			lib = &hspctx->mem_linfo[ st->index ];
			piid = (IID *)strp( lib->nameidx );
		} else {
			// 第3パラメータ:文字列 IID
			GetIIDFromString( &iid, code_gets() );
			piid = &iid;
		}

		if ( pvalNew->flag != TYPE_COMOBJ ) {
			// 代入により型変換
			iptr = NULL;
			code_setva( pvalNew, aptrNew, TYPE_COMOBJ, &iptr );
		}
		ppunkDst = (IUnknown **)HspVarCorePtrAPTR( pvalNew, aptrNew );

		// query によりインスタンスを得る
		QueryComPtr( ppunkDst, *ppunkSrc, piid );
		if ( IsVaridComPtr(ppunkSrc) )
			hspctx->stat = 0;
		else
			hspctx->stat = 1;
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x02:								// delcom
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		IUnknown **ppunk;
		VARIANT *var;
		void *ptr;

		// 第1パラメータ:解放するCOMオブジェクト変数
		aptr = code_getva( &pval );
		ptr = HspVarCorePtrAPTR( pval, aptr );
		switch ( pval->flag ) {
		case TYPE_COMOBJ:
			ppunk = (IUnknown **)ptr;
			ReleaseComPtr( ppunk );
			break;
		case TYPE_VARIANT:
			var = (VARIANT *)ptr;
			VariantClear( var );
			break;
		default:
			throw HSPERR_TYPE_MISMATCH;
		}

		// このタイミングで一時オブジェクトも削除しちゃう
		if ( comconv_var.vt != VT_EMPTY ) VariantClear( &comconv_var );
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x03:								// 	cnvstow
		{
		PVal *pval;
		char *ptr;
		char *ps;
		int size;
		ptr = code_getvptr( &pval, &size );
		ps = code_gets();
		cnvwstr( ptr, ps, size/2 );
		break;
		}

	case 0x04:								// 	comres
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		if ( code_getexflg() ) {
			comres_pval = NULL;
			comres_aptr = 0;
		} else {
			comres_aptr = code_getva( &comres_pval );
		}
		break;
#endif	// HSP_COM_UNSUPPORTED

	case 0x05:								// 	axobj
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		const IID *piid;
		void *iptr;
		BMSCR *bm;
		HWND hwnd;
		int id,sx,sy;
		char clsid_name[1024];
		IUnknown **ppunk, *punkObj, *punkObj2;
		STRUCTDAT *st;
		LIBDAT *lib;
		HRESULT hr;

		bm = GetBMSCR();

		// 第1パラメータ:新しいインターフェースポインタを格納する変数
		// (あらかじめ変数にNULLを格納)
		aptr = code_getva( &pval );
		iptr = NULL;
		code_setva( pval, aptr, TYPE_COMOBJ, &iptr );
		ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );

		// オブジェクトの CLSID, ProgID, etc.
		if ( *type == TYPE_DLLCTRL ) {
			// 第2パラメータ:#usecom 登録情報から取得
			st = code_getcomst();
			if ( st->otindex != -1 ) throw ( HSPERR_TYPE_MISMATCH );
			lib = &hspctx->mem_linfo[ st->index ];
			piid = (IID *)strp( lib->nameidx );
			if ( lib->clsid == -1 ) throw ( HSPERR_INVALID_PARAMETER );
			strncpy( clsid_name, strp(lib->clsid), sizeof(clsid_name)-1 );
		} else {
			// 第2パラメータ:文字列 CLSID or ProgID を取得 (IID は IDispatch)
			piid = &IID_IDispatch;
			strncpy( clsid_name, code_gets(), sizeof(clsid_name)-1 );
		}

		// コントロールのサイズ
		sx = code_getdi( bm->sx );
		sy = code_getdi( bm->sy );

		//		ActiveXとしてロード
		//
		if ( fn_atxinit == NULL ) throw ( HSPERR_UNSUPPORTED_FUNCTION );
		hwnd = CreateWindow( atxwndclass, clsid_name,
				WS_CHILD, 			// 最初は WS_VISIBLE なし (後で ShowWindow() )
				bm->cx, bm->cy, sx, sy,
				bm->hwnd, (HMENU)0, (HINSTANCE)hspctx->instance, NULL );

		punkObj2 = NULL;
		if ( hwnd ) {
			punkObj = NULL;
			fn_atxgetctrl( hwnd, (void**)&punkObj );
			if ( punkObj ) {
				// 指定 IID が存在するかどうか
				hr = punkObj->QueryInterface( *piid, (void**)&punkObj2 );
				punkObj->Release();
			}
		}
		if ( punkObj2 == NULL ) {
			// 目的オブジェクトではないときコントロールを削除
			if (hwnd) { DestroyWindow( hwnd ); }
			hspctx->stat = -1;
			break;
		}
		// COM 型変数に格納
		*ppunk = punkObj2;

		// HSPのウインドゥオブジェクトとして登録する
		ShowWindow( hwnd, SW_SHOW );
		id = AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, sy );
#ifdef HSP_COMOBJ_DEBUG
		Alertf( "axobj : pObj=%p : &pObj=%p\n", *ppunk, ppunk);
	#endif
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x06:								// 	winobj
		{
#ifdef HSPDISH
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		char clsname[1024];
		char winname[1024];
		HWND hwnd;
		char *ps;
		BMSCR *bm;
		int i;
		int prm[6];

		ps = code_gets(); strncpy( clsname, ps, 1023 );
		ps = code_gets(); strncpy( winname, ps, 1023 );

		bm = GetBMSCR();
		for(i=0;i<6;i++) {
			prm[i] = code_getdi(0);
		}
		if ( prm[2] <= 0 ) prm[2] = bm->ox;
		if ( prm[3] <= 0 ) prm[3] = bm->oy;

		hwnd = CreateWindowEx(
		    (DWORD) prm[0],			// 拡張ウィンドウスタイル
		    clsname,				// ウィンドウクラス名
		    winname,				// ウィンドウ名
		    (DWORD) prm[1],			// ウィンドウスタイル
			bm->cx, bm->cy, prm[2], prm[3],		// X,Y,SIZEX,SIZEY
			bm->hwnd,				// 親ウィンドウのハンドル
		    (HMENU) prm[4],			// メニューハンドルまたは子ウィンドウID
			bm->hInst,				// インスタンスハンドル
		    (PVOID) prm[5]			// ウィンドウ作成データ
			);

		// AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, prm[3], NULL, 0 );			// HSPのウインドゥオブジェクトとして登録する
		AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, prm[3] );
		break;
#endif	// HSPDISH
		}

	case 0x07:								// 	sendmsg
		{
		int hw,p1,p2,p3,p4,fl,sz;
		char *vptr;
		hw = code_getdi(0);
		p1 = code_getdi(0);

		vptr = code_getsptr( &fl );
		if ( fl == TYPE_STRING ) {
			p2 = (int)code_stmpstr( vptr );
		} else {
			p2 = *(int *)vptr;
		}

		vptr = code_getsptr( &fl );
		if ( fl == TYPE_STRING ) {
			p3 = (int)vptr;
		} else {
			p3 = *(int *)vptr;
		}

		//Alertf( "SEND[%x][%x][%x]",p1,p2,p3 );
		hspctx->stat = (int)SendMessage( (HWND)hw, p1, p2, p3 );
		break;
		}

	case 0x08:								// 	comevent
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		void* iptr;
		char *ps;
		IID iid, *piid;
		unsigned short *subr;
		IUnknown **ppunk, **ppunkEvent;

		// 第1パラメータ:イベントハンドラオブジェクト (IEventHandler) を格納する変数
		// (あらかじめ NULL で初期化)
		aptr = code_getva( &pval );
		iptr = NULL;
		code_setva( pval, aptr, TYPE_COMOBJ, &iptr );
		ppunkEvent = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );

		// 第2パラメータ:COMオブジェクトを格納した変数
		aptr = code_getva( &pval );
		if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH );
		ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );
		if ( ! IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR );

		// 第3パラメータ:コネクションポイントIID (文字列形式)
		ps = code_getds("");
		if ( ps[0] != '\0' ) {
			piid = &iid;
			GetIIDFromString( piid, ps );
		} else {
			piid = NULL;	// NULL のときデフォルトIID が自動的に取得される
		}

		// 第4パラメータ:コールバック用のサブルーチンラベル
		subr = code_getlb2();

		// イベントハンドラ作成・接続
		SetComEvent( ppunkEvent, ppunk, piid, subr );
	#ifdef HSP_COMOBJ_DEBUG
		COM_DBG_MSG( "comevent : pEvent=%p : pObj=%p\n", *ppunkEvent, *ppunk);
	#endif
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x09:								// 	comevarg
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval, *pval2;
		APTR aptr, aptr2;
		VARIANT *v;
		void *ptr;
		int p1,p2;
		int res;
		IUnknown **ppunk;
		VARIANT varTemp;

		// 第1パラメータ:イベントのパラメータを格納する変数
		aptr = code_getva( &pval );

		// 第2パラメータ:イベントハンドラオブジェクト変数
		aptr2 = code_getva( &pval2 );
		if ( pval2->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH );
		ppunk = (IUnknown **)HspVarCorePtrAPTR( pval2, aptr2 );
		if ( ! IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR );

		// 第3パラメータ:パラメータインデックス
		p1 = code_getdi(0);

		// 第4パラメータ:文字列変換フラグ
		p2 = code_getdi(0);

		// イベントのパラメータ取得
		v = GetEventArg( *ppunk, p1 );
		if ( v == NULL ) throw ( HSPERR_ILLEGAL_FUNCTION );
		switch ( p2 ) {
		case 0:
			VariantInit( &varTemp );
			VariantCopyInd( &varTemp, v );
			ptr = comget_variant( &varTemp, &res );
			VariantClear( &varTemp );
			break;
		case 1:
			VariantInit( &varTemp );
			if FAILED( VariantChangeType( &varTemp, v, VARIANT_ALPHABOOL, VT_BSTR ) )
				throw ( HSPERR_TYPE_INITALIZATION_FAILED );
			ptr = comget_variant( &varTemp, &res );
			VariantClear( &varTemp );
			break;
		case 2:
			ptr = v;
			res = HSPVAR_FLAG_VARIANT;
			break;
		default:
			throw ( HSPERR_ILLEGAL_FUNCTION );
		}
		code_setva( pval, aptr, res, ptr );
		hspctx->stat = res;
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x0a:								// 	sarrayconv
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval1, *pval2;
		APTR aptr1, aptr2;
		int convdir, size;
		VARIANT *variant, varTemp;
		VARTYPE vt;
		SAFEARRAY *psa;
		long lbound, ubound;
		HRESULT hr;

		aptr1 = code_getva( &pval1 );
		aptr2 = code_getva( &pval2 );
		convdir = code_getdi(0);
		size = code_getdi(0);

		switch ( convdir ) {
		case 0:
		case 2:
		case 4:
			// 配列変数から SafeArray に変換
			VariantInit( &varTemp );
			code_setva( pval1, aptr1, HSPVAR_FLAG_VARIANT, &varTemp );
			variant = (VARIANT *)HspVarCorePtrAPTR( pval1, aptr1 );
			VariantClear( variant );		// 一応
			if ( convdir == 2 ) {
				// バイナリデータ(一次元のみ)
				void *ptr = HspVarCorePtrAPTR( pval2, aptr2 );
				psa = CreateBinarySafeArray( ptr, size, &vt );
			} else {
				BOOL bVariant = ( convdir == 4 );
				psa = ConvVar2SafeArray( pval2, bVariant, &vt );
			}
			variant->vt = vt | VT_ARRAY;
			variant->parray = psa;
			break;
		case 1:
		case 3:
			// SafeArray から配列変数に変換
			if ( pval2->flag != HSPVAR_FLAG_VARIANT ) throw HSPERR_INVALID_TYPE;
			variant = (VARIANT *)HspVarCorePtrAPTR( pval2, aptr2 );
			if ( (variant->vt & VT_ARRAY) == 0 ) throw HSPERR_INVALID_TYPE;
			psa = variant->parray;
			if ( psa == NULL ) throw HSPERR_ARRAY_OVERFLOW;
			vt = variant->vt & VT_TYPEMASK;
			if ( vt == VT_EMPTY ) {
				hr = SafeArrayGetVartype( psa, &vt );
				if ( FAILED(hr) || vt == VT_EMPTY ) throw HSPERR_INVALID_ARRAYSTORE;
			}
			if ( convdir == 1 ) {
				ConvSafeArray2Var( pval1, psa, vt );
			} else {
				// バイナリデータ(一次元のみ)
				int varsize;
				void *ptr = HspVarCorePtrAPTR( pval1, aptr1 );				if ( vt != VT_UI1 && vt != VT_I1 ) throw HSPERR_INVALID_TYPE;
				SafeArrayGetLBound( psa, 1, &lbound );
				hr = SafeArrayGetUBound( psa, 1, &ubound );
				if ( FAILED(hr) ) throw HSPERR_ARRAY_OVERFLOW;
				size = ubound - lbound + 1;
				HspVarCoreGetBlockSize( pval1, (PDAT*)ptr, &varsize );
				if ( varsize < size ) throw HSPERR_BUFFER_OVERFLOW;
				GetBinarySafeArray( ptr, size, psa );
			}
			break;
		default:
			throw ( HSPERR_UNSUPPORTED_FUNCTION );
		}
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	default:
		throw ( HSPERR_SYNTAX );
	}
	return RUNMODE_RUN;
}
Esempio n. 28
0
WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant)
{
    VariantInit(&oleVariant);
    if (variant.IsNull())
    {
        oleVariant.vt = VT_NULL;
        return true;
    }

    wxString type(variant.GetType());

    if (type == wxT("errorcode"))
    {
        wxVariantDataErrorCode* const
            ec = wxStaticCastVariantData(variant.GetData(),
                                         wxVariantDataErrorCode);
        oleVariant.vt = VT_ERROR;
        oleVariant.scode = ec->GetValue();
    }
    else if (type == wxT("currency"))
    {
        wxVariantDataCurrency* const
            c = wxStaticCastVariantData(variant.GetData(),
                                        wxVariantDataCurrency);
        oleVariant.vt = VT_CY;
        oleVariant.cyVal = c->GetValue();
    }
    else if (type == wxT("safearray"))
    {
        wxVariantDataSafeArray* const
            vsa = wxStaticCastVariantData(variant.GetData(),
                                          wxVariantDataSafeArray);
        SAFEARRAY* psa = vsa->GetValue();
        VARTYPE vt;

        wxCHECK(psa, false);
        HRESULT hr = SafeArrayGetVartype(psa, &vt);
        if ( FAILED(hr) )
        {
            wxLogApiError(wxS("SafeArrayGetVartype()"), hr);
            SafeArrayDestroy(psa);
            return false;
        }
        oleVariant.vt = vt | VT_ARRAY;
        oleVariant.parray = psa;
    }
    else if (type == wxT("long"))
    {
        oleVariant.vt = VT_I4;
        oleVariant.lVal = variant.GetLong() ;
    }
#if wxUSE_LONGLONG
    else if (type == wxT("longlong"))
    {
        oleVariant.vt = VT_I8;
        oleVariant.llVal = variant.GetLongLong().GetValue();
    }
#endif
    else if (type == wxT("char"))
    {
        oleVariant.vt=VT_I1;            // Signed Char
        oleVariant.cVal=variant.GetChar();
    }
    else if (type == wxT("double"))
    {
        oleVariant.vt = VT_R8;
        oleVariant.dblVal = variant.GetDouble();
    }
    else if (type == wxT("bool"))
    {
        oleVariant.vt = VT_BOOL;
        oleVariant.boolVal = variant.GetBool() ? VARIANT_TRUE : VARIANT_FALSE;
    }
    else if (type == wxT("string"))
    {
        wxString str( variant.GetString() );
        oleVariant.vt = VT_BSTR;
        oleVariant.bstrVal = wxConvertStringToOle(str);
    }
#if wxUSE_DATETIME
    else if (type == wxT("datetime"))
    {
        wxDateTime date( variant.GetDateTime() );
        oleVariant.vt = VT_DATE;

        SYSTEMTIME st;
        date.GetAsMSWSysTime(&st);

        SystemTimeToVariantTime(&st, &oleVariant.date);
    }
#endif
    else if (type == wxT("void*"))
    {
        oleVariant.vt = VT_DISPATCH;
        oleVariant.pdispVal = (IDispatch*) variant.GetVoidPtr();
    }
    else if (type == wxT("list"))
    {
        wxSafeArray<VT_VARIANT> safeArray;
        if (!safeArray.CreateFromListVariant(variant))
            return false;

        oleVariant.vt = VT_VARIANT | VT_ARRAY;
        oleVariant.parray = safeArray.Detach();
    }
    else if (type == wxT("arrstring"))
    {
        wxSafeArray<VT_BSTR> safeArray;

        if (!safeArray.CreateFromArrayString(variant.GetArrayString()))
            return false;

        oleVariant.vt = VT_BSTR | VT_ARRAY;
        oleVariant.parray = safeArray.Detach();
    }
    else
    {
        oleVariant.vt = VT_NULL;
        return false;
    }
    return true;
}
JSBool XPCDispConvert::COMArrayToJSArray(XPCCallContext& ccx,
                                         const VARIANT & src,
                                         jsval & dest, nsresult& err)
{
    err = NS_OK;
    // We only support one dimensional arrays for now
    if(SafeArrayGetDim(src.parray) != 1)
    {
        err = NS_ERROR_FAILURE;
        return JS_FALSE;
    }
    // Get the upper bound;
    long ubound;
    if(FAILED(SafeArrayGetUBound(src.parray, 1, &ubound)))
    {
        err = NS_ERROR_FAILURE;
        return JS_FALSE;
    }
    // Get the lower bound
    long lbound;
    if(FAILED(SafeArrayGetLBound(src.parray, 1, &lbound)))
    {
        err = NS_ERROR_FAILURE;
        return JS_FALSE;
    }
    // Create the JS Array
    JSObject * array = JS_NewArrayObject(ccx, ubound - lbound + 1, nsnull);
    if(!array)
    {
        err = NS_ERROR_OUT_OF_MEMORY;
        return JS_FALSE;
    }
    AUTO_MARK_JSVAL(ccx, OBJECT_TO_JSVAL(array));
    // Divine the type of our array
    VARTYPE vartype;
    if((src.vt & VT_ARRAY) != 0)
    {
        vartype = src.vt & ~VT_ARRAY;
    }
    else // This was maybe a VT_SAFEARRAY
    {
#ifndef WINCE
        if(FAILED(SafeArrayGetVartype(src.parray, &vartype)))
            return JS_FALSE;
#else
        return JS_FALSE;
#endif
    }
    jsval val = JSVAL_NULL;
    AUTO_MARK_JSVAL(ccx, &val);
    for(long index = lbound; index <= ubound; ++index)
    {
        HRESULT hr;
        _variant_t var;
        if(vartype == VT_VARIANT)
        {
            hr = SafeArrayGetElement(src.parray, &index, &var);
        }
        else
        {
            var.vt = vartype;
            hr = SafeArrayGetElement(src.parray, &index, &var.byref);
        }
        if(FAILED(hr))
        {
            err = NS_ERROR_FAILURE;
            return JS_FALSE;
        }
        if(!COMToJS(ccx, var, val, err))
            return JS_FALSE;
        JS_SetElement(ccx, array, index, &val);
    }
    dest = OBJECT_TO_JSVAL(array);
    return JS_TRUE;
}