Ejemplo n.º 1
0
HRESULT CBDictionary::putItem(VARIANT* pvarKey, VARIANT* pvar)
{
	if(pvarKey->vt == VT_ERROR)return DISP_E_PARAMNOTOPTIONAL;
	if(pvarKey->vt & VT_ARRAY)return E_INVALIDARG;

	if(pvarKey->vt == VT_BSTR)
	{
		if(pvarKey->bstrVal == NULL)
			return DISP_E_TYPEMISMATCH;

		UINT len = SysStringByteLen(pvarKey->bstrVal);

		if(len & 1)
			return DISP_E_TYPEMISMATCH;

		for(UINT i = 0; i < len / 2; i ++)
			if(pvarKey->bstrVal[i] == 0)
				return DISP_E_TYPEMISMATCH;
	}

	if(pvar->vt == VT_ERROR)
		return DISP_E_PARAMNOTOPTIONAL;

	m_cs.Enter();
	if(m_bArrayMode && (pvarKey->vt == VT_I4 || pvarKey->vt == VT_I2))
	{
		long i = varGetNumber(*pvarKey);

		if(i >=0 && i < (int)m_posArray.GetCount())
		{
			VariantCopyInd(&m_posArray[i]->m_value, pvar);
			m_cs.Leave();
			return S_OK;
		}
	}

	CRBMap<CBVariant, CComVariant>::CPair* pPair = m_mapItems.Lookup(*(CBVariant*)pvarKey);

	if(pPair == NULL)
	{
		static VARIANT varTemp;

		pPair = (CRBMap<CBVariant, CComVariant>::CPair*)m_mapItems.SetAt(*(CBVariant*)pvarKey, varTemp);
		m_posArray.Add(pPair);
	}

	VariantCopyInd(&pPair->m_value, pvar);

	m_cs.Leave();

	return S_OK;
}
Ejemplo n.º 2
0
////////////////////////////////////////////////////////////////////////
// put_Value
//
HRESULT CDocProperty::put_Value(VARIANT *pvValue)
{
	VARIANT vtTmp; vtTmp.vt = VT_EMPTY;

	ODS(_T("CDocProperty::put_Value\n"));
	CHECK_NULL_RETURN(pvValue, E_POINTER);
	CHECK_FLAG_RETURN((m_fDeadObj || m_fRemovedItem), E_INVALIDOBJECT);

	// We don't support arrays (in this sample at least)...
	if ((pvValue->vt) & VT_ARRAY)
		return E_INVALIDARG;

	// Sanity check of VARTYPE (if it is not one we can save, don't bother)...
	switch (((pvValue->vt) & VT_TYPEMASK))
	{
	case VT_I2:
	case VT_I4:
	case VT_R4:
	case VT_R8:
	case VT_DATE:
	case VT_BSTR:
	case VT_BOOL:
		break;
	default:
		return E_INVALIDARG;
	}

	// Swap out the variant value and set the dirty flag. We make independent
	// copy of the VARIANT (performs indirection as needed)...
	m_fModified = TRUE;
	VariantClear(&m_vValue);
	return VariantCopyInd(&m_vValue, pvValue);
}
Ejemplo n.º 3
0
static HRESULT invoke_variant_prop(script_ctx_t *ctx, VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
{
    HRESULT hres;

    switch(flags) {
    case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
    case DISPATCH_PROPERTYGET:
        if(dp->cArgs) {
            WARN("called with arguments\n");
            return DISP_E_MEMBERNOTFOUND; /* That's what tests show */
        }

        hres = VariantCopyInd(res, v);
        break;

    case DISPATCH_PROPERTYPUT:
    case DISPATCH_PROPERTYPUTREF:
    case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: {
        VARIANT put_val;
        BOOL own_val;

        hres = get_propput_arg(ctx, dp, flags, &put_val, &own_val);
        if(FAILED(hres))
            return hres;

        if(arg_cnt(dp)) {
            FIXME("Arguments not supported\n");
            return E_NOTIMPL;
        }

        if(res)
            V_VT(res) = VT_EMPTY;

        if(own_val)
            *v = put_val;
        else
            hres = VariantCopyInd(v, &put_val);
        break;
    }

    default:
        FIXME("unimplemented flags %x\n", flags);
        return E_NOTIMPL;
    }

    return hres;
}
Ejemplo n.º 4
0
static HRESULT add_keyitem_pair(dictionary *dict, VARIANT *key, VARIANT *item)
{
    struct keyitem_pair *pair;
    struct list *head;
    VARIANT hash;
    HRESULT hr;

    hr = IDictionary_get_HashVal(&dict->IDictionary_iface, key, &hash);
    if (FAILED(hr))
        return hr;

    pair = heap_alloc(sizeof(*pair));
    if (!pair)
        return E_OUTOFMEMORY;

    pair->hash = V_I4(&hash);
    VariantInit(&pair->key);
    VariantInit(&pair->item);

    hr = VariantCopyInd(&pair->key, key);
    if (FAILED(hr))
        goto failed;

    hr = VariantCopyInd(&pair->item, item);
    if (FAILED(hr))
        goto failed;

    head = get_bucket_head(dict, pair->hash);
    if (!head->next)
        /* this only happens once per bucket */
        list_init(head);

    /* link to bucket list and to full list */
    list_add_tail(head, &pair->bucket);
    list_add_tail(&dict->pairs, &pair->entry);
    dict->count++;
    return S_OK;

failed:
    VariantClear(&pair->key);
    VariantClear(&pair->item);
    heap_free(pair);
    return hr;
}
Ejemplo n.º 5
0
static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
{
    HRESULT hres;

    switch(flags) {
    case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
    case DISPATCH_PROPERTYGET:
        if(dp->cArgs) {
            WARN("called with arguments\n");
            return DISP_E_MEMBERNOTFOUND; /* That's what tests show */
        }

        hres = VariantCopyInd(res, v);
        break;

    case DISPATCH_PROPERTYPUT: {
        VARIANT *put_val;

        put_val = get_propput_arg(dp);
        if(!put_val) {
            WARN("no value to set\n");
            return DISP_E_PARAMNOTOPTIONAL;
        }

        if(arg_cnt(dp)) {
            FIXME("Arguments not supported\n");
            return E_NOTIMPL;
        }

        if(res)
            V_VT(res) = VT_EMPTY;

        hres = VariantCopyInd(v, put_val);
        break;
    }

    default:
        FIXME("unimplemented flags %x\n", flags);
        return E_NOTIMPL;
    }

    return hres;
}
Ejemplo n.º 6
0
STDMETHODIMP CBQueue::AddTail(VARIANT var)
{
	VARIANT varTemp = {VT_EMPTY};

	VariantCopyInd(&varTemp, &var);

	m_cs.Enter();
	m_listItems.AddTail(varTemp);
	m_cs.Leave();

	return S_OK;
}
Ejemplo n.º 7
0
SEXP
createRVariantObject(VARIANT *var,  VARTYPE kind)
{
  const char *className;
  SEXP klass, ans, tmp;
  VARIANT *dupvar;  
  switch(kind) {
    case VT_DATE:
      className = "DateVARIANT";
      break;
    case VT_CY:
      className = "CurrencyVARIANT";
      break;

    default:
      className = "VARIANT";
  }

  PROTECT(klass = MAKE_CLASS(className));
  if(klass == NULL || klass == R_NilValue) {
     PROBLEM  "Can't locate S4 class definition %s", className
     ERROR;
  }
  
  dupvar = (VARIANT *) malloc(sizeof(VARIANT));
  VariantCopyInd(dupvar, var);
  
  PROTECT(ans = NEW(klass));
  PROTECT(tmp = R_MakeExternalPtr(dupvar, Rf_install(className), R_NilValue));
  R_RegisterCFinalizer(tmp, R_Variant_finalizer);
  SET_SLOT(ans, Rf_install("ref"), tmp);
  UNPROTECT(1);

  PROTECT(tmp = NEW_INTEGER(1));
  INTEGER(tmp)[0] = kind;
  SET_SLOT(ans, Rf_install("kind"), tmp);
  
  UNPROTECT(3);
  return(ans);
}
Ejemplo n.º 8
0
zend_object* php_com_object_clone(zval *object)
{
	php_com_dotnet_object *cloneobj, *origobject;

	origobject = (php_com_dotnet_object*)Z_OBJ_P(object);
	cloneobj = (php_com_dotnet_object*)emalloc(sizeof(php_com_dotnet_object));

	memcpy(cloneobj, origobject, sizeof(*cloneobj));

	/* VariantCopy will perform VariantClear; we don't want to clobber
	 * the IDispatch that we memcpy'd, so we init a new variant in the
	 * clone structure */
	VariantInit(&cloneobj->v);
	/* We use the Indirection-following version of the API since we
	 * want to clone as much as possible */
	VariantCopyInd(&cloneobj->v, &origobject->v);

	if (cloneobj->typeinfo) {
		ITypeInfo_AddRef(cloneobj->typeinfo);
	}

	return (zend_object*)cloneobj;
}
Ejemplo n.º 9
0
PHP_COM_DOTNET_API void php_com_wrap_variant(zval *z, VARIANT *v,
        int codepage)
{
    php_com_dotnet_object *obj;

    obj = emalloc(sizeof(*obj));
    memset(obj, 0, sizeof(*obj));
    obj->code_page = codepage;
    obj->ce = php_com_variant_class_entry;
    obj->zo.ce = php_com_variant_class_entry;

    VariantInit(&obj->v);
    VariantCopyInd(&obj->v, v);
    obj->modified = 0;

    if ((V_VT(&obj->v) == VT_DISPATCH) && (V_DISPATCH(&obj->v) != NULL)) {
        IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
    }

    zend_object_std_init(&obj->zo, php_com_variant_class_entry);
    obj->zo.handlers = &php_com_object_handlers;
    ZVAL_OBJ(z, &obj->zo);
}
Ejemplo n.º 10
0
STDMETHODIMP CAvatarProfileObject::AddKey(BSTR bstrKey, VARIANT varKeyVal, VARIANT varStrGraphic, VARIANT varAccess, VARIANT varOwner)
{
	HRESULT hr = S_OK;
	CComVariant varTemp;
	long psbits = 0;
	IThing* pUser = NULL;
	IThing* pCaller = NULL;
	IThing* pOwner = NULL;
	IAvatarProfileData* pProfileData = NULL;
	VARIANT_BOOL bShouldExecute = VARIANT_TRUE;
	VARIANT_BOOL bShouldRemote = VARIANT_FALSE;
	VARIANT_BOOL bShouldNotify = VARIANT_FALSE;

	// REVIEW: should really create an AddKeyExt method which takes the real datatypes

	hr = VariantCopyInd(&varTemp, &varKeyVal);
	if (FAILED(hr))
		goto ERROR_ENCOUNTERED;

	if (m_pWorld)
	{
		hr = m_pWorld->ValidateProperty(varTemp);
		if (FAILED(hr))
			goto ERROR_ENCOUNTERED;
	}

	GetMarshallingFlags(&bShouldExecute, &bShouldRemote, &bShouldNotify);

	if (bShouldRemote == VARIANT_TRUE)
		GetMarshallingBits(&psbits, &bShouldExecute, &bShouldRemote, &bShouldNotify);

#ifdef _DEBUG
	VWTRACE(m_pWorld, "VWPROPERTY", VWT_METHOD, "CAvatarProfileObject::AddKey\n");
#endif

	if (bShouldExecute == VARIANT_TRUE)
	{
		VARIANT_BOOL bValid = VARIANT_FALSE;
		CComBSTR bstrGraphic;
		short sAccess = 0;

		if (m_pParent)
		{
			if (FAILED(m_pParent->CheckPropertySecurityExt(m_bstrPropertyName, PS_WRITE)))
			{
				VWTRACE(m_pWorld, "VWOBJECT", VWT_ERROR, "CAvatarProfileObject::AddKey: security violation (PS_WRITE)\n");
				hr = VWOBJECT_E_PERMISSION_DENIED;
				goto ERROR_ENCOUNTERED;
			}
		}

		if (m_pKeys == NULL)
		{
			VWTRACE(m_pWorld, "VWPROPERTY", VWT_ERROR, "CAvatarProfileObject::AddKey: invalid key map\n");
			hr = VWAVATARPROFILE_E_INVALIDKEYMAP;
			goto ERROR_ENCOUNTERED;
		}

		if (m_pBannedObjects == NULL)
		{
			VWTRACE(m_pWorld, "VWPROPERTY", VWT_ERROR, "CAvatarProfileObject::AddKey: invalid banned object list\n");
			hr = VWAVATARPROFILE_E_INVALIDBANNEDOBJECTLIST;
			goto ERROR_ENCOUNTERED;
		}

		// if user isn't avatar
		if (bShouldRemote == VARIANT_TRUE)
		{
			hr = m_pWorld->get_User(&pUser);
			if (FAILED(hr))
				goto ERROR_ENCOUNTERED;

			// we are the originator - check protocol
			if (pUser && m_pAvatar && (pUser != m_pAvatar))
			{
				long lIndex = -1;

				/* hr = */ m_pBannedObjects->Find(CComVariant(pUser), &lIndex);

				// if user is banned object, fail
				if (lIndex != -1)
				{
					VWTRACE(m_pWorld, "VWPROPERTY", VWT_ERROR, "CAvatarProfileObject::AddKey: user is banned object, failed to add key\n");
					hr = VWAVATARPROFILE_E_BANNEDOBJECT;
					goto ERROR_ENCOUNTERED;
				}
			}
		}

		// if key already exists, fail
		hr = m_pKeys->IsValid(bstrKey, &bValid);
		if (FAILED(hr))
			goto ERROR_ENCOUNTERED;

		if (bValid == VARIANT_TRUE)
		{
#ifdef _DEBUG
			VWTRACE(m_pWorld, "VWPROPERTY", VWT_IMPORTANT, "CAvatarProfileObject::AddKey: key (%s) already exists, failed to add key\n", CString(bstrKey));
#endif
			hr = VWAVATARPROFILE_E_KEYEXISTS;
			goto ERROR_ENCOUNTERED;
		}

		// add the property..
		pProfileData = new CComAvatarProfileData;
		if (pProfileData == NULL)
			goto ERROR_ENCOUNTERED;

		pProfileData->AddRef();

		/* hr = */ pProfileData->put_World(m_pWorld);

		// now, create the optional data items
		if (varStrGraphic.vt == VT_BSTR)
			bstrGraphic = varStrGraphic.bstrVal;
		
		if ((varAccess.vt == VT_EMPTY) || (varAccess.vt == VT_ERROR))
			sAccess = kKeyPublic;
		else
		{
			CComVariant varI2;

			::VariantChangeType(&varI2, &varAccess, 0, VT_I2);
			ASSERT(varI2.vt == VT_I2);

			sAccess = (short)varI2.iVal;
		}

		if (varOwner.vt == VT_DISPATCH)
		{
			pOwner = (IThing *)varOwner.pdispVal;
			SAFEADDREF(pOwner);
		}
		else
		{
			// if no owner passed in, set owner to be avatar
			pOwner = m_pAvatar;
			SAFEADDREF(pOwner);
		}

		// can only set the owner to the user
		if (bShouldRemote == VARIANT_TRUE)
		{
			// REVIEW: why are we resetting the owner?

			hr = m_pWorld->get_Caller(&pCaller);
			if (FAILED(hr))
				goto ERROR_ENCOUNTERED;

			// check protocol:
			// otherwise, make sure passed in owner is either user or caller
			if ((pOwner != NULL) && (pUser != NULL) && (pCaller != NULL) && (pOwner != pUser) && (pOwner != pCaller))
			{
#ifdef _DEBUG
				CComBSTR bstrUser("n/a"), bstrCaller("n/a"), bstrOwner("n/a");

				/* hr = */ pUser->get_Name(&bstrUser.m_str);
				/* hr = */ pCaller->get_Name(&bstrCaller.m_str);
				/* hr = */ pOwner->get_Name(&bstrOwner.m_str);

				VWTRACE(m_pWorld, "VWPROPERTY", VWT_ERROR, "CAvatarProfileObject::AddKey: invalid owner (not user or caller), user (%s), caller (%s), owner (%s)\n", 
					CString(bstrUser), CString(bstrCaller), CString(bstrOwner));
#endif

				hr = VWAVATARPROFILE_E_INVALIDOWNER;
				goto ERROR_ENCOUNTERED;
			}
		}

		/* hr = */ pProfileData->put_Value(varTemp);
		/* hr = */ pProfileData->put_Owner(pOwner);
		/* hr = */ pProfileData->put_Graphic(bstrGraphic);
		/* hr = */ pProfileData->put_Access(sAccess);

		hr = m_pKeys->put_ObjectProperty(bstrKey, pProfileData);
		if (FAILED(hr))
			goto ERROR_ENCOUNTERED;
	}

	// remote
	if (bShouldRemote == VARIANT_TRUE)
	{
		DISPPARAMS dispparams;

		// package up args into DISPPARAMS struct
		hr = InitializeDISPPARAMS(&dispparams, 5);
		if (FAILED(hr))
			goto ERROR_ENCOUNTERED;

		dispparams.rgvarg[4].vt = VT_BSTR;
		dispparams.rgvarg[4].bstrVal = bstrKey;
		dispparams.rgvarg[3] = varTemp;
		dispparams.rgvarg[2] = varStrGraphic;
		dispparams.rgvarg[1] = varAccess;
		dispparams.rgvarg[0] = varOwner;

		hr = SendObjectPropertyCommand(psbits, DISPID_AVATARPROFILE_ADDKEY, DISPATCH_METHOD, &dispparams);

		TerminateDISPPARAMS(VARIANT_FALSE, &dispparams);

		if (FAILED(hr))
			goto ERROR_ENCOUNTERED;
	}

	// Notify
	if (bShouldNotify == VARIANT_TRUE)
	{
		// notify client/server and world of property change
		if (m_pParent)
		{
			hr = m_pParent->NotifyObjectPropertyChanged(this, profileAddKey, CComVariant(bstrKey));
			if (FAILED(hr))
				goto ERROR_ENCOUNTERED;
		}
	}
	
ERROR_ENCOUNTERED:
	SAFERELEASE(pOwner);
	SAFERELEASE(pUser);
	SAFERELEASE(pCaller);
	SAFERELEASE(pProfileData);
	
	return hr;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
	}
}
Ejemplo n.º 13
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;
}