Beispiel #1
0
const char *debugstr_variant(const VARIANT *v)
{
    if(!v)
        return "(null)";

    if(V_ISBYREF(v))
        return wine_dbg_sprintf("{V_BYREF -> %s}", debugstr_variant(V_BYREF(v)));

    switch(V_VT(v)) {
    case VT_EMPTY:
        return "{VT_EMPTY}";
    case VT_NULL:
        return "{VT_NULL}";
    case VT_I2:
        return wine_dbg_sprintf("{VT_I2: %d}", V_I2(v));
    case VT_I4:
        return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v));
    case VT_UI4:
        return wine_dbg_sprintf("{VT_UI4: %u}", V_UI4(v));
    case VT_R8:
        return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v));
    case VT_BSTR:
        return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v)));
    case VT_DISPATCH:
        return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v));
    case VT_BOOL:
        return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v));
    default:
        return wine_dbg_sprintf("{vt %d}", V_VT(v));
    }
}
Beispiel #2
0
static const char *vt2a(VARIANT *v)
{
    if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
        static char buf[64];
        sprintf(buf, "%s*", vt2a(V_BYREF(v)));
        return buf;
    }

    switch(V_VT(v)) {
    case VT_EMPTY:
        return "VT_EMPTY";
    case VT_NULL:
        return "VT_NULL";
    case VT_I2:
        return "VT_I2";
    case VT_I4:
        return "VT_I4";
    case VT_R8:
        return "VT_R8";
    case VT_BSTR:
        return "VT_BSTR";
    case VT_DISPATCH:
        return "VT_DISPATCH";
    case VT_BOOL:
        return "VT_BOOL";
    case VT_ARRAY|VT_VARIANT:
        return "VT_ARRAY|VT_VARIANT";
    default:
        ok(0, "unknown vt %d\n", V_VT(v));
        return NULL;
    }
}
Beispiel #3
0
static void notif_complete(DocHost *This, DISPID dispid)
{
    DISPPARAMS dispparams;
    VARIANTARG params[2];
    VARIANT url;

    dispparams.cArgs = 2;
    dispparams.cNamedArgs = 0;
    dispparams.rgdispidNamedArgs = NULL;
    dispparams.rgvarg = params;

    V_VT(params) = (VT_BYREF|VT_VARIANT);
    V_BYREF(params) = &url;

    V_VT(params+1) = VT_DISPATCH;
    V_DISPATCH(params+1) = This->disp;

    V_VT(&url) = VT_BSTR;
    V_BSTR(&url) = SysAllocString(This->url);

    TRACE("%d >>>\n", dispid);
    call_sink(This->cps.wbe2, dispid, &dispparams);
    TRACE("%d <<<\n", dispid);

    SysFreeString(V_BSTR(&url));
    This->busy = VARIANT_FALSE;
}
Beispiel #4
0
static void navigate_complete(DocHost *This)
{
    IDispatch *disp = NULL;
    DISPPARAMS dispparams;
    VARIANTARG params[2];
    VARIANT url;
    HRESULT hres;

    hres = IUnknown_QueryInterface(This->document, &IID_IDispatch, (void**)&disp);
    if(FAILED(hres))
        FIXME("Could not get IDispatch interface\n");

    dispparams.cArgs = 2;
    dispparams.cNamedArgs = 0;
    dispparams.rgdispidNamedArgs = NULL;
    dispparams.rgvarg = params;

    V_VT(params) = (VT_BYREF|VT_VARIANT);
    V_BYREF(params) = &url;

    V_VT(params+1) = VT_DISPATCH;
    V_DISPATCH(params+1) = disp;

    V_VT(&url) = VT_BSTR;
    V_BSTR(&url) = SysAllocString(This->url);

    call_sink(This->cps.wbe2, DISPID_NAVIGATECOMPLETE2, &dispparams);
    call_sink(This->cps.wbe2, DISPID_DOCUMENTCOMPLETE, &dispparams);

    SysFreeString(V_BSTR(&url));
    if(disp)
        IDispatch_Release(disp);
    This->busy = VARIANT_FALSE;
}
Beispiel #5
0
/*
 *  call-seq:
 *     WIN32OLE_VARIANT[i,j,...] #=> element of OLE array.
 *
 *  Returns the element of WIN32OLE_VARIANT object(OLE array).
 *  This method is available only when the variant type of
 *  WIN32OLE_VARIANT object is VT_ARRAY.
 *
 *  REMARK:
 *     The all indices should be 0 or natural number and
 *     lower than or equal to max indices.
 *     (This point is different with Ruby Array indices.)
 *
 *     obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
 *     p obj[0,0] # => 1
 *     p obj[1,0] # => 4
 *     p obj[2,0] # => WIN32OLERuntimeError
 *     p obj[0, -1] # => WIN32OLERuntimeError
 *
 */
static VALUE
folevariant_ary_aref(int argc, VALUE *argv, VALUE self)
{
    struct olevariantdata *pvar;
    SAFEARRAY *psa;
    VALUE val = Qnil;
    VARIANT variant;
    LONG *pid;
    HRESULT hr;

    TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar);
    if (!V_ISARRAY(&(pvar->var))) {
        rb_raise(eWIN32OLERuntimeError,
                 "`[]' is not available for this variant type object");
    }
    psa = get_locked_safe_array(self);
    if (psa == NULL) {
        return val;
    }

    pid = ary2safe_array_index(argc, argv, psa);

    VariantInit(&variant);
    V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF;
    hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex");
    }
    val = ole_variant2val(&variant);

    unlock_safe_array(psa);
    if (pid) free(pid);
    return val;
}
Beispiel #6
0
//+---------------------------------------------------------------------------
//
//  Function:   CVarToVARIANTARG
//
//  Synopsis:   Converts a C-language variable to a VARIANT.
//
//  Arguments:  [pv]    -- Pointer to C-language variable.
//              [vt]    -- Type of C-language variable.
//              [pvarg] -- Resulting VARIANT.  Must be initialized by caller.
//                         Any contents will be freed.
//
//  Modifies:   [pvarg]
//
//  History:    2-23-94   adams   Created
//
//  Notes:      Supports all variant pointer types, VT_UI2, VT_I2, VT_UI4,
//              VT_I4, VT_R4, VT_R8, VT_ERROR.
//
//----------------------------------------------------------------------------
void CVarToVARIANTARG(void* pv, VARTYPE vt, VARIANTARG* pvarg)
{
    Assert(pv);
    Assert(pvarg);

    VariantClear(pvarg);

    V_VT(pvarg) = vt;
    if(V_ISBYREF(pvarg))
    {
        // Use a supported pointer type for derefencing.
        vt = VT_UNKNOWN;
    }

    switch(vt)
    {
    case VT_BOOL:
        // convert TRUE to VT_TRUE
        Assert(*(BOOL*)pv==1 || *(BOOL*)pv==0);
        V_BOOL(pvarg) = VARIANT_BOOL(-*(BOOL*)pv);
        break;

    case VT_I2:
        V_I2(pvarg) = *(short*)pv;
        break;

    case VT_ERROR:
    case VT_I4:
        V_I4(pvarg) = *(long*)pv;
        break;

    case VT_R4:
        V_R4(pvarg) = *(float*)pv;
        break;

    case VT_R8:
        V_R8(pvarg) = *(double*)pv;
        break;

    case VT_CY:
        V_CY(pvarg) = *(CY*)pv;
        break;

        // All Pointer types.
    case VT_PTR:
    case VT_BSTR:
    case VT_LPSTR:
    case VT_LPWSTR:
    case VT_DISPATCH:
    case VT_UNKNOWN:
        V_BYREF(pvarg) = *(void**)pv;
        break;

    default:
        Assert(FALSE && "Unknown type.");
        break;
    }
}
Beispiel #7
0
static HRESULT WINAPI DocObjectService_FireNavigateComplete2(
        IDocObjectService* iface,
        IHTMLWindow2 *pHTMLWindow2,
        DWORD dwFlags)
{
    ShellBrowser *This = impl_from_IDocObjectService(iface);
    IHTMLPrivateWindow *priv_window;
    VARIANTARG params[2];
    DISPPARAMS dp = {params, NULL, 2, 0};
    VARIANT url_var;
    BSTR url;
    HRESULT hres;

    TRACE("%p %p %x\n", This, pHTMLWindow2, dwFlags);

    hres = IHTMLWindow2_QueryInterface(pHTMLWindow2, &IID_IHTMLPrivateWindow, (void**)&priv_window);
    if(FAILED(hres))
        return hres;

    hres = IHTMLPrivateWindow_GetAddressBarUrl(priv_window, &url);
    IHTMLPrivateWindow_Release(priv_window);
    if(FAILED(hres))
        return hres;

    TRACE("got URL %s\n", debugstr_w(url));
    set_dochost_url(This->doc_host, url);

    V_VT(params) = (VT_BYREF|VT_VARIANT);
    V_BYREF(params) = &url;

    V_VT(params+1) = VT_DISPATCH;
    V_DISPATCH(params+1) = This->doc_host->disp;

    V_VT(&url_var) = VT_BSTR;
    V_BSTR(&url_var) = url;

    TRACE(">>>\n");
    call_sink(This->doc_host->cps.wbe2, DISPID_NAVIGATECOMPLETE2, &dp);
    TRACE("<<<\n");

    SysFreeString(url);

    This->doc_host->busy = VARIANT_FALSE;
    return S_OK;
}
HRESULT CMaxMaterialCollection::GetXMLImpExp(IVIZPointerClient** ppClient)
{
#ifdef XXX
	//Begin temporary
	// temporary impl: Create an XMLMaterial COM object and ask it to import
	//TODO (JH 7/25/02 Done By CC) implement this differently, CoCreate is slow
	HRESULT hr = CoCreateInstance(CLSID_XmlMaterial, NULL, CLSCTX_INPROC_SERVER,
		__uuidof(IVIZPointerClient), (void**)ppClient);
	if(!SUCCEEDED(hr) || *ppClient == NULL)
	{
		//TODO (JH 7/25/02 Done By CC)Remove the message box 
		MessageBox(NULL, _T("Failed to create XML Material importer, is it registered?"), NULL, MB_OK | MB_TASKMODAL);
		return E_FAIL;
	}
	VARIANT vIp, vImpIp;
	vIp.vt = vImpIp.vt = VT_BYREF;
	vIp.byref = GetCOREInterface();
	vImpIp.byref = GetCOREInterface();//this is a HACK
	return (*ppClient)->InitPointers(vIp, vImpIp);
#else
	*ppClient = NULL;
	Interface *ip = GetCOREInterface();
	TSTR plugletModuleName(ip->GetDir(APP_MAX_SYS_ROOT_DIR));
	plugletModuleName.Append(sXmlMaterialModuleName);
	HRESULT hr = CreatePluglet(CLSID_XmlMaterial, __uuidof(IVIZPointerClient), (void**)ppClient, plugletModuleName.data());
	if(SUCCEEDED(hr) && *ppClient)
	{
		VARIANT vIp, vImpIp;
		VariantInit(&vIp);
		VariantInit(&vImpIp);
		V_VT(&vIp) = VT_BYREF;
		V_BYREF(&vIp) = ip;
		// We don't have access to an import interface ptr here.
		HRESULT hr = (*ppClient)->InitPointers(vIp, vImpIp);
	}
	return hr;
#endif
}
Beispiel #9
0
static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData,
                            LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
{
    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
    int i;

    TRACE("(%p)->(%p %s %p %p)\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray);

    if(!pvData || !szFieldName || !pvarField)
        return E_INVALIDARG;

    for(i=0; i<This->n_vars; i++)
        if(!strcmpW(This->fields[i].name, szFieldName))
            break;
    if(i == This->n_vars)
        return TYPE_E_FIELDNOTFOUND;

    VariantClear(pvarField);
    V_VT(pvarField) = VT_BYREF|This->fields[i].vt;
    V_BYREF(pvarField) = ((PBYTE)pvData)+This->fields[i].offset;
    *ppvDataCArray = NULL;
    return S_OK;
}
Beispiel #10
0
static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
    switch(id) {
    case DISPID_GLOBAL_OK: {
        VARIANT *b;

        ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
        ok(pdp != NULL, "pdp == NULL\n");
        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
        if(wFlags & INVOKE_PROPERTYGET)
            ok(pvarRes != NULL, "pvarRes == NULL\n");
        else
            ok(!pvarRes, "pvarRes != NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));

        b = pdp->rgvarg+1;
        if(V_VT(b) == (VT_BYREF|VT_VARIANT))
            b = V_BYREF(b);

        ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));

        ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
        return S_OK;
    }

     case DISPID_GLOBAL_TRACE:
        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
        ok(pdp != NULL, "pdp == NULL\n");
        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
        ok(!pvarRes, "pvarRes != NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
        if(V_VT(pdp->rgvarg) == VT_BSTR)
            trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));

        return S_OK;

    case DISPID_GLOBAL_REPORTSUCCESS:
        CHECK_EXPECT(global_success_i);

        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
        ok(pdp != NULL, "pdp == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
        ok(!pvarRes, "pvarRes != NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        return S_OK;

    case DISPID_GLOBAL_GETVT:
        ok(pdp != NULL, "pdp == NULL\n");
        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
        ok(pvarRes != NULL, "pvarRes == NULL\n");
        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
        ok(pei != NULL, "pei == NULL\n");

        V_VT(pvarRes) = VT_BSTR;
        V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg));
        return S_OK;

    case DISPID_GLOBAL_ISENGLANG:
        ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
        ok(pdp != NULL, "pdp == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
        ok(pvarRes != NULL, "pvarRes == NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        V_VT(pvarRes) = VT_BOOL;
        if(is_lang_english()) {
            V_BOOL(pvarRes) = VARIANT_TRUE;
        }else {
            skip("Skipping some tests in non-English UIs\n");
            V_BOOL(pvarRes) = VARIANT_FALSE;
        }
        return S_OK;

    case DISPID_GLOBAL_VBVAR:
        CHECK_EXPECT(global_vbvar_i);

        ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
        ok(pdp != NULL, "pdp == NULL\n");
        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
        ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
        ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
        ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
        ok(!pvarRes, "pvarRes != NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
        ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
        return S_OK;

    case DISPID_GLOBAL_TESTOBJ:
        ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);

        ok(pdp != NULL, "pdp == NULL\n");
        ok(!pdp->rgvarg, "rgvarg == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
        ok(pvarRes != NULL, "pvarRes == NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        V_VT(pvarRes) = VT_DISPATCH;
        V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
        return S_OK;

    case DISPID_GLOBAL_ISNULLDISP: {
        VARIANT *v;

        ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
        ok(pdp != NULL, "pdp == NULL\n");
        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
        ok(pvarRes != NULL, "pvarRes == NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        v = pdp->rgvarg;
        if(V_VT(v) == (VT_VARIANT|VT_BYREF))
            v = V_VARIANTREF(v);

        ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
        V_VT(pvarRes) = VT_BOOL;
        V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE;
        return S_OK;
    }

    case DISPID_GLOBAL_TESTDISP:
        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
        ok(pdp != NULL, "pdp == NULL\n");
        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
        ok(!pvarRes, "pvarRes != NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
        test_disp(V_DISPATCH(pdp->rgvarg));
        return S_OK;
    }

    ok(0, "unexpected call %d\n", id);
    return DISP_E_MEMBERNOTFOUND;
}
Beispiel #11
0
HRESULT __RPC_STUB IDispatch_Invoke_Stub(
    IDispatch* This,
    DISPID dispIdMember,
    REFIID riid,
    LCID lcid,
    DWORD dwFlags,
    DISPPARAMS* pDispParams,
    VARIANT* pVarResult,
    EXCEPINFO* pExcepInfo,
    UINT* pArgErr,
    UINT cVarRef,
    UINT* rgVarRefIdx,
    VARIANTARG* rgVarRef)
{
  HRESULT hr = S_OK;
  VARIANTARG *rgvarg, *arg;
  UINT u;

  /* initialize out parameters, so that they can be marshalled
   * in case the real Invoke doesn't initialize them */
  VariantInit(pVarResult);
  memset(pExcepInfo, 0, sizeof(*pExcepInfo));
  *pArgErr = 0;

  /* let the real Invoke operate on a copy of the in parameters,
   * so we don't risk losing pointers to allocated memory */
  rgvarg = pDispParams->rgvarg;
  arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs);
  if (!arg) return E_OUTOFMEMORY;

  /* init all args so we can call VariantClear on all the args if the copy
   * below fails */
  for (u = 0; u < pDispParams->cArgs; u++)
    VariantInit(&arg[u]);

  for (u = 0; u < pDispParams->cArgs; u++) {
    hr = VariantCopy(&arg[u], &rgvarg[u]);
    if (FAILED(hr))
        break;
  }

  if (SUCCEEDED(hr)) {
    pDispParams->rgvarg = arg;

    hr = IDispatch_Invoke(This,
			  dispIdMember,
			  riid,
			  lcid,
			  dwFlags,
			  pDispParams,
			  pVarResult,
			  pExcepInfo,
			  pArgErr);

    /* copy ref args to out list */
    for (u=0; u<cVarRef; u++) {
      unsigned i = rgVarRefIdx[u];
      VariantInit(&rgVarRef[u]);
      VariantCopy(&rgVarRef[u], &arg[i]);
      /* clear original if equal, to avoid double-free */
      if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
        VariantClear(&rgvarg[i]);
    }
  }

  /* clear the duplicate argument list */
  for (u=0; u<pDispParams->cArgs; u++)
    VariantClear(&arg[u]);

  pDispParams->rgvarg = rgvarg;
  CoTaskMemFree(arg);

  return hr;
}
Beispiel #12
0
//+---------------------------------------------------------------------------
//
//  Function:   VARIANTARGToCVar
//
//  Synopsis:   Converts a VARIANT to a C-language variable.
//
//  Arguments:  [pvarg]         -- Variant to convert.
//              [pfAlloc]       -- BSTR allocated during conversion caller is
//                                 now owner of this BSTR or IUnknown or IDispatch
//                                 object allocated needs to be released.
//              [vt]            -- Type to convert to.
//              [pv]            -- Location to place C-language variable.
//
//  Modifies:   [pv].
//
//  Returns:    HRESULT.
//
//  History:    2-23-94   adams   Created
//
//  Notes:      Supports all variant pointer types, VT_I2, VT_I4, VT_R4,
//              VT_R8, VT_ERROR.
//----------------------------------------------------------------------------
HRESULT VARIANTARGToCVar(VARIANT* pvarg, BOOL* pfAlloc, VARTYPE vt, void* pv, IServiceProvider* pSrvProvider, WORD wMaxstrlen)
{
    HRESULT     hr = S_OK;
    VARIANTARG* pVArgCopy = pvarg;
    VARIANTARG  vargNew; // variant of new type
    BOOL        fAlloc;

    Assert(pvarg);
    Assert(pv);

    if(!pfAlloc)
    {
        pfAlloc = &fAlloc;
    }

    Assert((vt&~VT_TYPEMASK) == 0 || (vt&~VT_TYPEMASK)==VT_BYREF);

    // Assume no allocations yet.
    *pfAlloc = FALSE;

    if(vt & VT_BYREF)
    {
        // If the parameter is a variant pointer then everything is acceptable.
        if((vt&VT_TYPEMASK) == VT_VARIANT)
        {
            switch(V_VT(pvarg))
            {
            case VT_VARIANT|VT_BYREF:
                hr = ClipVarString(pvarg->pvarVal, *(VARIANT**)pv, pfAlloc, wMaxstrlen);
                break;
            default:
                hr = ClipVarString(pvarg, *(VARIANT**)pv, pfAlloc, wMaxstrlen);
                break;
            }
            if(hr == S_FALSE)
            {
                hr = S_OK;
                *(PVOID*)pv = (PVOID)pvarg;
            }

            goto Cleanup;
        }

        if((V_VT(pvarg)&VT_TYPEMASK) != (vt&VT_TYPEMASK))
        {
            hr = DISP_E_TYPEMISMATCH;
            goto Cleanup;
        }

        // Type of both original and destination or same type (however, original
        // may not be a byref only the original.
        if(V_ISBYREF(pvarg))
        {
            // Destination and original are byref and same type just copy pointer.
            *(PVOID*)pv = V_BYREF(pvarg);
        }
        else
        {
            // Convert original to byref.
            switch(vt & VT_TYPEMASK)
            {
            case VT_BOOL:
                *(PVOID*)pv = (PVOID)&V_BOOL(pvarg);
                break;

            case VT_I2:
                *(PVOID*)pv = (PVOID)&V_I2(pvarg);
                break;

            case VT_ERROR:
            case VT_I4:
                *(PVOID*)pv = (PVOID)&V_I4(pvarg);
                break;

            case VT_R4:
                *(PVOID*)pv = (PVOID)&V_R4(pvarg);
                break;

            case VT_R8:
                *(PVOID*)pv = (PVOID)&V_R8(pvarg);
                break;

            case VT_CY:
                *(PVOID*)pv = (PVOID)&V_CY(pvarg);
                break;

                // All pointer types.
            case VT_PTR:
            case VT_BSTR:
            case VT_LPSTR:
            case VT_LPWSTR:
            case VT_DISPATCH:
            case VT_UNKNOWN:
                *(PVOID*)pv = (PVOID)&V_UNKNOWN(pvarg);
                break;

            case VT_VARIANT:
                Assert("Dead code: shudn't have gotten here!");
                *(PVOID*)pv = (PVOID)pvarg;
                break;

            default:
                Assert(!"Unknown type in BYREF VARIANTARGToCVar().\n");
                hr = DISP_E_TYPEMISMATCH;
                goto Cleanup;
            }
        }

        goto Cleanup;
    }
    // If the c style parameter is the same type as the VARIANT then we'll just
    // move the data.  Also if the c style type is a VARIANT then there's
    // nothing to convert just copy the variant to the C parameter.
    else if((V_VT(pvarg)&(VT_TYPEMASK|VT_BYREF))!=vt && (vt!=VT_VARIANT))
    {
        // If the request type isn't the same as the variant passed in then we
        // need to convert.
        VariantInit(&vargNew);
        pVArgCopy = &vargNew;

        hr = VariantChangeTypeSpecial(pVArgCopy, pvarg, vt,pSrvProvider);

        if(hr)
        {
            goto Cleanup;
        }

        *pfAlloc = (vt==VT_BSTR) || (vt==VT_UNKNOWN) || (vt==VT_DISPATCH);
    }

    // Move the variant data to C style data.
    switch(vt)
    {
    case VT_BOOL:
        // convert VT_TRUE and any other non-zero values to TRUE
        *(VARIANT_BOOL*)pv = V_BOOL(pVArgCopy);
        break;

    case VT_I2:
        *(short*)pv = V_I2(pVArgCopy);
        break;

    case VT_ERROR:
    case VT_I4:
        *(long*)pv = V_I4(pVArgCopy);
        break;

    case VT_R4:
        *(float*)pv = V_R4(pVArgCopy);
        break;

    case VT_R8:
        *(double*)pv = V_R8(pVArgCopy);
        break;

    case VT_CY:
        *(CY*)pv = V_CY(pVArgCopy);
        break;

        // All Pointer types.
    case VT_BSTR:
        if(wMaxstrlen && FormsStringLen(V_BSTR(pVArgCopy))>wMaxstrlen)
        {
            hr = FormsAllocStringLen(V_BSTR(pVArgCopy), wMaxstrlen, (BSTR*)pv);
            if(hr)
            {
                goto Cleanup;
            }

            if(*pfAlloc)
            {
                VariantClear(&vargNew);
            }
            else
            {
                *pfAlloc = TRUE;
            }

            goto Cleanup;
        }
    case VT_PTR:
    case VT_LPSTR:
    case VT_LPWSTR:
    case VT_DISPATCH:
    case VT_UNKNOWN:
        *(void**)pv = V_BYREF(pVArgCopy);
        break;

    case VT_VARIANT:
        hr = ClipVarString(pVArgCopy, (VARIANT*)pv, pfAlloc, wMaxstrlen);
        if(hr == S_FALSE)
        {
            hr = S_OK;
            // Copy entire variant to output parameter.
            *(VARIANT*)pv = *pVArgCopy;
        }

        break;

    default:
        Assert(FALSE && "Unknown type in VARIANTARGToCVar().\n");
        hr = DISP_E_TYPEMISMATCH;
        break;
    }

Cleanup:
    RRETURN(hr);
}
HRESULT ModifyContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved) 
{
	ASSERT((ppt != NULL) && (pcmdtReserved != NULL));
	if ((ppt == NULL) || (pcmdtReserved == NULL))
		return S_OK;

    //#define IDR_BROWSE_CONTEXT_MENU  24641
    //#define IDR_FORM_CONTEXT_MENU    24640
    #define SHDVID_GETMIMECSETMENU   27
    #define SHDVID_ADDMENUEXTENSIONS 53

    HRESULT hr;
    HINSTANCE hinstSHDOCLC;
    HWND hwnd;
    HMENU hMenu;
    IOleCommandTarget *spCT;
    IOleWindow *spWnd;
    MENUITEMINFO mii = {0};
    VARIANT var, var1, var2;

    hr = pcmdtReserved->QueryInterface(IID_IOleCommandTarget, (void**)&spCT);
    hr = pcmdtReserved->QueryInterface(IID_IOleWindow, (void**)&spWnd);
    hr = spWnd->GetWindow(&hwnd);

    hinstSHDOCLC = LoadLibrary(TEXT("SHDOCLC.DLL"));

    hMenu = LoadMenu(hinstSHDOCLC,
                     MAKEINTRESOURCE(IDR_BROWSE_CONTEXT_MENU));

    hMenu = GetSubMenu(hMenu, dwID);

    // Get the language submenu
    hr = spCT->Exec(&CGID_ShellDocView, SHDVID_GETMIMECSETMENU, 0, NULL, &var);

    mii.cbSize = sizeof(mii);
    mii.fMask  = MIIM_SUBMENU;
    mii.hSubMenu = (HMENU) var.byref;

    // Add language submenu to Encoding context item
    SetMenuItemInfo(hMenu, IDM_LANGUAGE, FALSE, &mii);

    // Insert Shortcut Menu Extensions from registry
    V_VT(&var1) = VT_PTR;
    V_BYREF(&var1) = hMenu;

    V_VT(&var2) = VT_I4;
    V_I4(&var2) = dwID;

    hr = spCT->Exec(&CGID_ShellDocView, SHDVID_ADDMENUEXTENSIONS, 0, &var1, &var2);

    // Remove View Source
    ::DeleteMenu(hMenu, IDM_VIEWSOURCE, MF_BYCOMMAND);
	// Remove the item that produces the exta separator
	::DeleteMenu(hMenu, IDM_EXTRA_ITEM, MF_BYCOMMAND);

    // Show shortcut menu
    int iSelection = ::TrackPopupMenu(hMenu,
                                      TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
                                      ppt->x,
                                      ppt->y,
                                      0,
                                      hwnd,
                                      (RECT*)NULL);

    // Send selected shortcut menu item command to shell
	if (iSelection != 0)
		LRESULT lr = ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL);

    FreeLibrary(hinstSHDOCLC);
    return S_OK;
}
Beispiel #14
0
TclObject::TclObject (VARIANT *pSrc, const Type &type, Tcl_Interp *interp, int bytes)
{
    if (V_ISARRAY(pSrc)) {
        SAFEARRAY *psa = V_ISBYREF(pSrc) ? *V_ARRAYREF(pSrc) : V_ARRAY(pSrc);
        VARTYPE elementType = V_VT(pSrc) & VT_TYPEMASK;
        unsigned numDimensions = SafeArrayGetDim(psa);
        std::vector<long> indices(numDimensions);

        m_pObj = convertFromSafeArray( psa, elementType, 1, &indices[0], type, interp, bytes);

    } else if (vtMissing == pSrc) {
        m_pObj = Extension::newNaObj();

    } else {
        switch (V_VT(pSrc)) {
        case VT_BOOL:
            m_pObj = Tcl_NewBooleanObj(V_BOOL(pSrc));
            break;

        case VT_ERROR:
            m_pObj = Tcl_NewLongObj(V_ERROR(pSrc));
            break;

        case VT_I1:
        case VT_UI1:
            m_pObj = Tcl_NewLongObj(V_I1(pSrc));
            break;

        case VT_I2:
        case VT_UI2:
            m_pObj = Tcl_NewLongObj(V_I2(pSrc));
            break;

        case VT_I4:
        case VT_UI4:
        case VT_INT:
        case VT_UINT:
            m_pObj = Tcl_NewLongObj(V_I4(pSrc));
            break;

#ifdef V_I8
        case VT_I8:
        case VT_UI8:
            m_pObj = Tcl_NewWideIntObj(V_I8(pSrc));
            break;
#endif

        case VT_R4:
            m_pObj = Tcl_NewDoubleObj(V_R4(pSrc));
            break;

        case VT_DATE:
        case VT_R8:
            m_pObj = Tcl_NewDoubleObj(V_R8(pSrc));
            break;

        case VT_DISPATCH:
            m_pObj = convertFromUnknown(V_DISPATCH(pSrc), type.iid(), interp);
            break;

        case VT_DISPATCH | VT_BYREF:
            m_pObj = convertFromUnknown(
                (V_DISPATCHREF(pSrc) != 0) ? *V_DISPATCHREF(pSrc) : 0,
                type.iid(),
                interp);
            break;

        case VT_UNKNOWN:
            m_pObj = convertFromUnknown(V_UNKNOWN(pSrc), type.iid(), interp);
            break;

        case VT_UNKNOWN | VT_BYREF:
            m_pObj = convertFromUnknown(
                (V_UNKNOWNREF(pSrc) != 0) ? *V_UNKNOWNREF(pSrc) : 0,
                type.iid(),
                interp);
            break;

        case VT_NULL:
            m_pObj = Extension::newNullObj();
            break;

        case VT_LPSTR:
            m_pObj = Tcl_NewStringObj(V_I1REF(pSrc), -1);
            break;

        case VT_LPWSTR:
            {
#if TCL_MINOR_VERSION >= 2
                // Uses Unicode function introduced in Tcl 8.2.
                m_pObj = newUnicodeObj(V_UI2REF(pSrc), -1);
#else
		const wchar_t *pWide = V_UI2REF(pSrc);
                _bstr_t str(pWide);
                m_pObj = Tcl_NewStringObj(str, -1);
#endif
            }
            break;

        default:
            if (V_VT(pSrc) == VT_USERDEFINED && type.name() == "GUID") {
                Uuid uuid(*static_cast<UUID *>(V_BYREF(pSrc)));
                m_pObj = Tcl_NewStringObj(
                    const_cast<char *>(uuid.toString().c_str()), -1);
            } else {
                if (V_VT(pSrc) == (VT_VARIANT | VT_BYREF)) {
                    pSrc = V_VARIANTREF(pSrc);
                }

                _bstr_t str(pSrc);
#if TCL_MINOR_VERSION >= 2
                // Uses Unicode function introduced in Tcl 8.2.
		wchar_t *pWide = str;
                m_pObj = newUnicodeObj(
                    reinterpret_cast<Tcl_UniChar *>(pWide), str.length());
#else
                m_pObj = Tcl_NewStringObj(str, -1);
#endif
            }
        }
    }

    Tcl_IncrRefCount(m_pObj);
}