static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { HRESULT hres; switch(flags) { case DISPATCH_METHOD|DISPATCH_PROPERTYGET: if(!res) return E_INVALIDARG; /* fall through */ case DISPATCH_METHOD: if(This->dynamic_data && This->dynamic_data->func_disps && This->dynamic_data->func_disps[func->func_disp_idx].func_obj) { func_obj_entry_t *entry = This->dynamic_data->func_disps + func->func_disp_idx; if(V_VT(&entry->val) != VT_DISPATCH) { FIXME("calling %s not supported\n", debugstr_variant(&entry->val)); return E_NOTIMPL; } if((IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface != V_DISPATCH(&entry->val)) { if(!V_DISPATCH(&entry->val)) { FIXME("Calling null\n"); return E_FAIL; } hres = invoke_disp_value(This, V_DISPATCH(&entry->val), 0, flags, dp, res, ei, NULL); break; } } if(func->call_vtbl_off) hres = invoke_builtin_function(This, func, dp, res, caller); else hres = typeinfo_invoke(This, func, flags, dp, res, ei); break; case DISPATCH_PROPERTYGET: { func_obj_entry_t *entry; if(func->id == DISPID_VALUE) { BSTR ret; ret = SysAllocString(objectW); if(!ret) return E_OUTOFMEMORY; V_VT(res) = VT_BSTR; V_BSTR(res) = ret; return S_OK; } hres = get_func_obj_entry(This, func, &entry); if(FAILED(hres)) return hres; V_VT(res) = VT_EMPTY; return VariantCopy(res, &entry->val); } case DISPATCH_PROPERTYPUT: { func_obj_entry_t *entry; if(dp->cArgs != 1 || (dp->cNamedArgs == 1 && *dp->rgdispidNamedArgs != DISPID_PROPERTYPUT) || dp->cNamedArgs > 1) { FIXME("invalid args\n"); return E_INVALIDARG; } /* * NOTE: Although we have IDispatchEx tests showing, that it's not allowed to set * function property using InvokeEx, it's possible to do that from jscript. * Native probably uses some undocumented interface in this case, but it should * be fine for us to allow IDispatchEx handle that. */ hres = get_func_obj_entry(This, func, &entry); if(FAILED(hres)) return hres; return VariantCopy(&entry->val, dp->rgvarg); } default: FIXME("Unimplemented flags %x\n", flags); hres = E_NOTIMPL; } return hres; }
static HRESULT selection_get_item(IUnknown *iface, LONG index, VARIANT* item) { V_VT(item) = VT_DISPATCH; return IXMLDOMSelection_get_item((IXMLDOMSelection*)iface, index, (IXMLDOMNode**)&V_DISPATCH(item)); }
//+------------------------------------------------------------------------ // // Member: Item // // Synopsis: collection object model // // we handle the following parameter cases: // 0 params : by index = 0 // 1 params bstr : by name, index = 0 // 1 params # : by index // 2 params bstr, # : by name, index // 2 params #, bstr : by index, ignoring bstr // //------------------------------------------------------------------------- HRESULT CCollectionCache::Item(long lCollection, VARIANTARG var1, VARIANTARG var2, IDispatch** ppResult) { VARIANT* pvarName = NULL; VARIANT* pvarOne = NULL; VARIANT* pvarIndex = NULL; long lIndex = 0; HRESULT hr=E_INVALIDARG; if(!ppResult) { goto Cleanup; } *ppResult = NULL; pvarOne = (V_VT(&var1) == (VT_BYREF|VT_VARIANT)) ? V_VARIANTREF(&var1) : &var1; if((V_VT(pvarOne)==VT_BSTR) || V_VT(pvarOne)==(VT_BYREF|VT_BSTR)) { pvarName = (V_VT(pvarOne)&VT_BYREF) ? V_VARIANTREF(pvarOne) : pvarOne; if((V_VT(&var2)!=VT_ERROR) && (V_VT(&var2)!=VT_EMPTY)) { pvarIndex = &var2; } } else if((V_VT(&var1)!=VT_ERROR )&& (V_VT(&var1)!=VT_EMPTY)) { pvarIndex = &var1; } if(pvarIndex) { VARIANT varNum; VariantInit(&varNum); hr = VariantChangeTypeSpecial(&varNum, pvarIndex, VT_I4); if(hr) { goto Cleanup; } lIndex = V_I4(&varNum); } // Make sure our collection is up-to-date. hr = EnsureAry(lCollection); if(hr) { goto Cleanup; } // Get a collection or element of the specified object. if(pvarName) { BSTR Name = V_BSTR(pvarName); if(pvarIndex) { hr = GetDisp( lCollection, Name, lIndex, ppResult, FALSE); // BUBUG rgardner - shouldn't ignore case if(hr) { goto Cleanup; } } else { hr = GetDisp( lCollection, Name, CacheType_Named, ppResult, FALSE); // BUBUG rgardner - shouldn't ignore case if(FAILED(hr)) { HRESULT hrSave = hr; // save error code, and see if it a cell range hr = GetDisp( lCollection, Name, CacheType_CellRange, ppResult, FALSE); // BUBUG rgardner - shouldn't ignore case if(hr) { hr = hrSave; // restore error code goto Cleanup; } } } } else { hr = GetDisp(lCollection, lIndex, ppResult); if(hr) { goto Cleanup; } } Cleanup: // If we didn't find anything, make sure to just return NULL. if(hr == DISP_E_MEMBERNOTFOUND) { hr = S_OK; } RRETURN(hr); }
static HRESULT WINAPI xmlelem_getAttribute(IXMLElement *iface, BSTR name, VARIANT *value) { static const WCHAR xmllangW[] = { 'x','m','l',':','l','a','n','g',0 }; xmlelem *This = impl_from_IXMLElement(iface); xmlChar *val = NULL; TRACE("(%p, %s, %p)\n", iface, debugstr_w(name), value); if (!value) return E_INVALIDARG; VariantInit(value); V_BSTR(value) = NULL; if (!name) return E_INVALIDARG; /* case for xml:lang attribute */ if (!lstrcmpiW(name, xmllangW)) { xmlNsPtr ns; ns = xmlSearchNs(This->node->doc, This->node, (xmlChar*)"xml"); val = xmlGetNsProp(This->node, (xmlChar*)"lang", ns->href); } else { xmlAttrPtr attr; xmlChar *xml_name; xml_name = xmlChar_from_wchar(name); attr = This->node->properties; while (attr) { BSTR attr_name; attr_name = bstr_from_xmlChar(attr->name); if (!lstrcmpiW(name, attr_name)) { val = xmlNodeListGetString(attr->doc, attr->children, 1); SysFreeString(attr_name); break; } attr = attr->next; SysFreeString(attr_name); } heap_free(xml_name); } if (val) { V_VT(value) = VT_BSTR; V_BSTR(value) = bstr_from_xmlChar(val); } xmlFree(val); TRACE("returning %s\n", debugstr_w(V_BSTR(value))); return (val) ? S_OK : S_FALSE; }
/* ECMA-262 3rd Edition 9.9 */ HRESULT to_object(script_ctx_t *ctx, jsval_t val, IDispatch **disp) { jsdisp_t *dispex; HRESULT hres; switch(jsval_type(val)) { case JSV_STRING: hres = create_string(ctx, get_string(val), &dispex); if(FAILED(hres)) return hres; *disp = to_disp(dispex); break; case JSV_NUMBER: hres = create_number(ctx, get_number(val), &dispex); if(FAILED(hres)) return hres; *disp = to_disp(dispex); break; case JSV_OBJECT: if(get_object(val)) { *disp = get_object(val); IDispatch_AddRef(*disp); }else { jsdisp_t *obj; hres = create_object(ctx, NULL, &obj); if(FAILED(hres)) return hres; *disp = to_disp(obj); } break; case JSV_BOOL: hres = create_bool(ctx, get_bool(val), &dispex); if(FAILED(hres)) return hres; *disp = to_disp(dispex); break; case JSV_UNDEFINED: case JSV_NULL: WARN("object expected\n"); return throw_type_error(ctx, JS_E_OBJECT_EXPECTED, NULL); case JSV_VARIANT: switch(V_VT(get_variant(val))) { case VT_ARRAY|VT_VARIANT: hres = create_vbarray(ctx, V_ARRAY(get_variant(val)), &dispex); if(FAILED(hres)) return hres; *disp = to_disp(dispex); break; default: FIXME("Unsupported %s\n", debugstr_variant(get_variant(val))); return E_NOTIMPL; } break; } return S_OK; }
PHP_COM_DOTNET_API int php_com_copy_variant(VARIANT *dstvar, VARIANT *srcvar) { int ret = SUCCESS; switch (V_VT(dstvar) & ~VT_BYREF) { case VT_EMPTY: case VT_NULL: case VT_VOID: /* should not be possible */ break; case VT_UI1: if (V_VT(dstvar) & VT_BYREF) { *V_UI1REF(dstvar) = V_UI1(srcvar); } else { V_UI1(dstvar) = V_UI1(srcvar); } break; case VT_I1: if (V_VT(dstvar) & VT_BYREF) { *V_I1REF(dstvar) = V_I1(srcvar); } else { V_I1(dstvar) = V_I1(srcvar); } break; case VT_UI2: if (V_VT(dstvar) & VT_BYREF) { *V_UI2REF(dstvar) = V_UI2(srcvar); } else { V_UI2(dstvar) = V_UI2(srcvar); } break; case VT_I2: if (V_VT(dstvar) & VT_BYREF) { *V_I2REF(dstvar) = V_I2(srcvar); } else { V_I2(dstvar) = V_I2(srcvar); } break; case VT_UI4: if (V_VT(dstvar) & VT_BYREF) { *V_UI4REF(dstvar) = V_UI4(srcvar); } else { V_UI4(dstvar) = V_UI4(srcvar); } break; case VT_I4: if (V_VT(dstvar) & VT_BYREF) { *V_I4REF(dstvar) = V_I4(srcvar); } else { V_I4(dstvar) = V_I4(srcvar); } break; #if SIZEOF_ZEND_LONG == 8 case VT_UI8: if (V_VT(dstvar) & VT_BYREF) { *V_UI8REF(dstvar) = V_UI8(srcvar); } else { V_UI8(dstvar) = V_UI8(srcvar); } break; case VT_I8: if (V_VT(dstvar) & VT_BYREF) { *V_I8REF(dstvar) = V_I8(srcvar); } else { V_I8(dstvar) = V_I8(srcvar); } break; #endif case VT_INT: if (V_VT(dstvar) & VT_BYREF) { *V_INTREF(dstvar) = V_INT(srcvar); } else { V_INT(dstvar) = V_INT(srcvar); } break; case VT_UINT: if (V_VT(dstvar) & VT_BYREF) { *V_UINTREF(dstvar) = V_UINT(srcvar); } else { V_UINT(dstvar) = V_UINT(srcvar); } break; case VT_R4: if (V_VT(dstvar) & VT_BYREF) { *V_R4REF(dstvar) = V_R4(srcvar); } else { V_R4(dstvar) = V_R4(srcvar); } break; case VT_R8: if (V_VT(dstvar) & VT_BYREF) { *V_R8REF(dstvar) = V_R8(srcvar); } else { V_R8(dstvar) = V_R8(srcvar); } break; case VT_BOOL: if (V_VT(dstvar) & VT_BYREF) { *V_BOOLREF(dstvar) = V_BOOL(srcvar); } else { V_BOOL(dstvar) = V_BOOL(srcvar); } break; case VT_BSTR: if (V_VT(dstvar) & VT_BYREF) { *V_BSTRREF(dstvar) = V_BSTR(srcvar); } else { V_BSTR(dstvar) = V_BSTR(srcvar); } break; case VT_UNKNOWN: if (V_VT(dstvar) & VT_BYREF) { *V_UNKNOWNREF(dstvar) = V_UNKNOWN(srcvar); } else { V_UNKNOWN(dstvar) = V_UNKNOWN(srcvar); } break; case VT_DISPATCH: if (V_VT(dstvar) & VT_BYREF) { *V_DISPATCHREF(dstvar) = V_DISPATCH(srcvar); } else { V_DISPATCH(dstvar) = V_DISPATCH(srcvar); } break; case VT_VARIANT: return php_com_copy_variant(V_VARIANTREF(dstvar), srcvar); default: php_error_docref(NULL, E_WARNING, "variant->variant: failed to copy from 0x%x to 0x%x", V_VT(dstvar), V_VT(srcvar)); ret = FAILURE; } return ret; }
PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codepage) { OLECHAR *olestring; php_com_dotnet_object *obj; zend_uchar ztype = IS_NULL; if (z) { ZVAL_DEREF(z); ztype = Z_TYPE_P(z); } switch (ztype) { case IS_NULL: V_VT(v) = VT_NULL; break; case IS_FALSE: V_VT(v) = VT_BOOL; V_BOOL(v) = VARIANT_FALSE; break; case IS_TRUE: V_VT(v) = VT_BOOL; V_BOOL(v) = VARIANT_TRUE; break; case IS_OBJECT: if (php_com_is_valid_object(z)) { obj = CDNO_FETCH(z); if (V_VT(&obj->v) == VT_DISPATCH) { /* pass the underlying object */ V_VT(v) = VT_DISPATCH; if (V_DISPATCH(&obj->v)) { IDispatch_AddRef(V_DISPATCH(&obj->v)); } V_DISPATCH(v) = V_DISPATCH(&obj->v); } else { /* pass the variant by reference */ V_VT(v) = VT_VARIANT | VT_BYREF; V_VARIANTREF(v) = &obj->v; } } else { /* export the PHP object using our COM wrapper */ V_VT(v) = VT_DISPATCH; V_DISPATCH(v) = php_com_wrapper_export(z); } break; case IS_ARRAY: /* map as safe array */ safe_array_from_zval(v, z, codepage); break; case IS_LONG: #if SIZEOF_ZEND_LONG == 4 V_VT(v) = VT_I4; V_I4(v) = Z_LVAL_P(z); #else V_VT(v) = VT_I8; V_I8(v) = Z_LVAL_P(z); #endif break; case IS_DOUBLE: V_VT(v) = VT_R8; V_R8(v) = Z_DVAL_P(z); break; case IS_STRING: V_VT(v) = VT_BSTR; olestring = php_com_string_to_olestring(Z_STRVAL_P(z), Z_STRLEN_P(z), codepage); if (CP_UTF8 == codepage) { V_BSTR(v) = SysAllocStringByteLen((char*)olestring, (UINT)(wcslen(olestring) * sizeof(OLECHAR))); } else { V_BSTR(v) = SysAllocStringByteLen((char*)olestring, (UINT)(Z_STRLEN_P(z) * sizeof(OLECHAR))); } efree(olestring); break; case IS_RESOURCE: case IS_CONSTANT_AST: default: V_VT(v) = VT_NULL; break; } }
static BOOL is_optional_argument(const VARIANT *arg) { return V_VT(arg) == VT_ERROR && V_ERROR(arg) == DISP_E_PARAMNOTFOUND; }
static void call_event_handlers(HTMLDocumentNode *doc, IHTMLEventObj *event_obj, event_target_t *event_target, ConnectionPointContainer *cp_container, eventid_t eid, IDispatch *this_obj) { handler_vector_t *handler_vector = NULL; int i; HRESULT hres; if(event_target) handler_vector = event_target->event_table[eid]; if(handler_vector && handler_vector->handler_prop) { DISPID named_arg = DISPID_THIS; VARIANTARG arg; DISPPARAMS dp = {&arg, &named_arg, 1, 1}; V_VT(&arg) = VT_DISPATCH; V_DISPATCH(&arg) = this_obj; TRACE("%s >>>\n", debugstr_w(event_info[eid].name)); hres = call_disp_func(handler_vector->handler_prop, &dp); if(hres == S_OK) TRACE("%s <<<\n", debugstr_w(event_info[eid].name)); else WARN("%s <<< %08x\n", debugstr_w(event_info[eid].name), hres); } if(handler_vector && handler_vector->handler_cnt) { VARIANTARG arg; DISPPARAMS dp = {&arg, NULL, 1, 0}; V_VT(&arg) = VT_DISPATCH; V_DISPATCH(&arg) = (IDispatch*)event_obj; i = handler_vector->handler_cnt; while(i--) { if(handler_vector->handlers[i]) { TRACE("%s [%d] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_disp_func(handler_vector->handlers[i], &dp); if(hres == S_OK) TRACE("%s [%d] <<<\n", debugstr_w(event_info[eid].name), i); else WARN("%s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres); } } } if(cp_container) { ConnectionPoint *cp; if(cp_container->forward_container) cp_container = cp_container->forward_container; for(cp = cp_container->cp_list; cp; cp = cp->next) { if(cp->sinks_size && is_cp_event(cp->data, event_info[eid].dispid)) { for(i=0; i < cp->sinks_size; i++) { if(!cp->sinks[i].disp) continue; TRACE("cp %s [%d] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_cp_func(cp->sinks[i].disp, event_info[eid].dispid); if(hres == S_OK) TRACE("cp %s [%d] <<<\n", debugstr_w(event_info[eid].name), i); else WARN("cp %s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres); } } } } }
static HRESULT WINAPI HTMLElementCollection_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp) { HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface); HRESULT hres = S_OK; TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp); *pdisp = NULL; switch(V_VT(&name)) { case VT_I4: if(V_I4(&name) < 0) return E_INVALIDARG; hres = get_item_idx(This, V_I4(&name), pdisp); break; case VT_UINT: hres = get_item_idx(This, V_UINT(&name), pdisp); break; case VT_BSTR: { DWORD i; if(V_VT(&index) == VT_I4) { LONG idx = V_I4(&index); if(idx < 0) return E_INVALIDARG; for(i=0; i<This->len; i++) { if(is_elem_name(This->elems[i], V_BSTR(&name)) && !idx--) break; } if(i != This->len) { *pdisp = (IDispatch*)&This->elems[i]->IHTMLElement_iface; IDispatch_AddRef(*pdisp); } }else { elem_vector_t buf = {NULL, 0, 8}; buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*)); for(i=0; i<This->len; i++) { if(is_elem_name(This->elems[i], V_BSTR(&name))) { node_addref(&This->elems[i]->node); elem_vector_add(&buf, This->elems[i]); } } if(buf.len > 1) { elem_vector_normalize(&buf); *pdisp = (IDispatch*)HTMLElementCollection_Create(buf.buf, buf.len); }else { if(buf.len == 1) { /* Already AddRef-ed */ *pdisp = (IDispatch*)&buf.buf[0]->IHTMLElement_iface; } heap_free(buf.buf); } } break; } default: FIXME("Unsupported name %s\n", debugstr_variant(&name)); hres = E_NOTIMPL; } if(SUCCEEDED(hres)) TRACE("returning %p\n", *pdisp); return hres; }
static HRESULT WINAPI DocObjectService_FireBeforeNavigate2( IDocObjectService* iface, IDispatch *pDispatch, LPCWSTR lpszUrl, DWORD dwFlags, LPCWSTR lpszFrameName, BYTE *pPostData, DWORD cbPostData, LPCWSTR lpszHeaders, BOOL fPlayNavSound, BOOL *pfCancel) { ShellBrowser *This = impl_from_IDocObjectService(iface); VARIANT var_url, var_flags, var_frame_name, var_post_data, var_post_data2, var_headers; VARIANTARG params[7]; DISPPARAMS dp = {params, NULL, 7, 0}; VARIANT_BOOL cancel = VARIANT_FALSE; SAFEARRAY *post_data; TRACE("%p %p %s %x %s %p %d %s %d %p\n", This, pDispatch, debugstr_w(lpszUrl), dwFlags, debugstr_w(lpszFrameName), pPostData, cbPostData, debugstr_w(lpszHeaders), fPlayNavSound, pfCancel); if(cbPostData) { post_data = SafeArrayCreateVector(VT_UI1, 0, cbPostData); if(!post_data) return E_OUTOFMEMORY; memcpy(post_data->pvData, pPostData, cbPostData); }else { post_data = NULL; } V_VT(params) = VT_BOOL|VT_BYREF; V_BOOLREF(params) = &cancel; V_VT(params+1) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+1) = &var_headers; V_VT(&var_headers) = VT_BSTR; V_BSTR(&var_headers) = lpszHeaders ? SysAllocString(lpszHeaders) : NULL; V_VT(params+2) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+2) = &var_post_data2; V_VT(&var_post_data2) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(&var_post_data2) = &var_post_data; if(post_data) { V_VT(&var_post_data) = VT_UI1|VT_ARRAY; V_ARRAY(&var_post_data) = post_data; }else { V_VT(&var_post_data) = VT_EMPTY; } V_VT(params+3) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+3) = &var_frame_name; V_VT(&var_frame_name) = VT_BSTR; V_BSTR(&var_frame_name) = NULL; V_VT(params+4) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+4) = &var_flags; V_VT(&var_flags) = VT_I4; V_I4(&var_flags) = 0; V_VT(params+5) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+5) = &var_url; V_VT(&var_url) = VT_BSTR; V_BSTR(&var_url) = SysAllocString(lpszUrl); V_VT(params+6) = (VT_DISPATCH); V_DISPATCH(params+6) = (IDispatch*)This->doc_host->wb; TRACE(">>>\n"); call_sink(This->doc_host->cps.wbe2, DISPID_BEFORENAVIGATE2, &dp); TRACE("<<<\n"); SysFreeString(V_BSTR(&var_url)); SysFreeString(V_BSTR(&var_headers)); SafeArrayDestroy(post_data); *pfCancel = !!cancel; return S_OK; }
/* The real invoke mechanism that handles all the details. */ SEXP R_COM_Invoke(SEXP obj, SEXP methodName, SEXP args, WORD callType, WORD doReturn, SEXP ids) { IDispatch* disp; SEXP ans = R_NilValue; int numNamedArgs = 0, *namedArgPositions = NULL, i; HRESULT hr; // callGC(); disp = (IDispatch *) getRDCOMReference(obj); #ifdef ANNOUNCE_COM_CALLS fprintf(stderr, "<COM> %s %d %p\n", CHAR(STRING_ELT(methodName, 0)), (int) callType, disp);fflush(stderr); #endif DISPID *methodIds; const char *pmname = CHAR(STRING_ELT(methodName, 0)); BSTR *comNames = NULL; SEXP names = GET_NAMES(args); int numNames = Rf_length(names) + 1; SetErrorInfo(0L, NULL); methodIds = (DISPID *) S_alloc(numNames, sizeof(DISPID)); namedArgPositions = (int*) S_alloc(numNames, sizeof(int)); // we may not use all of these, but we allocate them if(Rf_length(ids) == 0) { comNames = (BSTR*) S_alloc(numNames, sizeof(BSTR)); comNames[0] = AsBstr(pmname); for(i = 0; i < Rf_length(names); i++) { const char *str = CHAR(STRING_ELT(names, i)); if(str && str[0]) { comNames[numNamedArgs+1] = AsBstr(str); namedArgPositions[numNamedArgs] = i; numNamedArgs++; } } numNames = numNamedArgs + 1; hr = disp->GetIDsOfNames(IID_NULL, comNames, numNames, LOCALE_USER_DEFAULT, methodIds); if(FAILED(hr) || hr == DISP_E_UNKNOWNNAME /* || DISPID mid == DISPID_UNKNOWN */) { PROBLEM "Cannot locate %d name(s) %s in COM object (status = %d)", numNamedArgs, pmname, (int) hr ERROR; } } else { for(i = 0; i < Rf_length(ids); i++) { methodIds[i] = (MEMBERID) NUMERIC_DATA(ids)[i]; //XXX What about namedArgPositions here. } } DISPPARAMS params = {NULL, NULL, 0, 0}; if(args != NULL && Rf_length(args) > 0) { hr = R_getCOMArgs(args, ¶ms, methodIds, numNamedArgs, namedArgPositions); if(FAILED(hr)) { clearVariants(¶ms); freeSysStrings(comNames, numNames); PROBLEM "Failed in converting arguments to DCOM call" ERROR; } if(callType & DISPATCH_PROPERTYPUT) { params.rgdispidNamedArgs = (DISPID*) S_alloc(1, sizeof(DISPID)); params.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT; params.cNamedArgs = 1; } } VARIANT varResult, *res = NULL; if(doReturn && callType != DISPATCH_PROPERTYPUT) VariantInit(res = &varResult); EXCEPINFO exceptionInfo; memset(&exceptionInfo, 0, sizeof(exceptionInfo)); unsigned int nargErr = 100; #ifdef RDCOM_VERBOSE if(params.cNamedArgs) { errorLog("# of named arguments to %d: %d\n", (int) methodIds[0], (int) params.cNamedArgs); for(int p = params.cNamedArgs; p > 0; p--) errorLog("%d) id %d, type %d\n", p, (int) params.rgdispidNamedArgs[p-1], (int) V_VT(&(params.rgvarg[p-1]))); } #endif hr = disp->Invoke(methodIds[0], IID_NULL, LOCALE_USER_DEFAULT, callType, ¶ms, res, &exceptionInfo, &nargErr); if(FAILED(hr)) { if(hr == DISP_E_MEMBERNOTFOUND) { errorLog("Error because member not found %d\n", nargErr); } #ifdef RDCOM_VERBOSE errorLog("Error (%d): <in argument %d>, call type = %d, call = \n", (int) hr, (int)nargErr, (int) callType, pmname); #endif clearVariants(¶ms); freeSysStrings(comNames, numNames); if(checkErrorInfo(disp, hr, NULL) != S_OK) { fprintf(stderr, "checkErrorInfo %d\n", (int) hr);fflush(stderr); COMError(hr); } } if(res) { ans = R_convertDCOMObjectToR(&varResult); VariantClear(&varResult); } clearVariants(¶ms); freeSysStrings(comNames, numNames); #ifdef ANNOUNCE_COM_CALLS fprintf(stderr, "</COM>\n", (int) callType);fflush(stderr); #endif return(ans); }
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { DispatchEx *This = impl_from_IDispatchEx(iface); HRESULT hres; TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(wFlags == (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF)) wFlags = DISPATCH_PROPERTYPUT; switch(get_dispid_type(id)) { case DISPEXPROP_CUSTOM: if(!This->data->vtbl || !This->data->vtbl->invoke) return DISP_E_UNKNOWNNAME; return This->data->vtbl->invoke(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); case DISPEXPROP_DYNAMIC: { DWORD idx = id - DISPID_DYNPROP_0; dynamic_prop_t *prop; if(!get_dynamic_data(This) || This->dynamic_data->prop_cnt <= idx) return DISP_E_UNKNOWNNAME; prop = This->dynamic_data->props+idx; switch(wFlags) { case DISPATCH_METHOD|DISPATCH_PROPERTYGET: if(!pvarRes) return E_INVALIDARG; /* fall through */ case DISPATCH_METHOD: if(V_VT(&prop->var) != VT_DISPATCH) { FIXME("invoke %s\n", debugstr_variant(&prop->var)); return E_NOTIMPL; } return invoke_disp_value(This, V_DISPATCH(&prop->var), lcid, wFlags, pdp, pvarRes, pei, pspCaller); case DISPATCH_PROPERTYGET: if(prop->flags & DYNPROP_DELETED) return DISP_E_UNKNOWNNAME; V_VT(pvarRes) = VT_EMPTY; return variant_copy(pvarRes, &prop->var); case DISPATCH_PROPERTYPUT: if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT) || pdp->cNamedArgs > 1) { FIXME("invalid args\n"); return E_INVALIDARG; } TRACE("put %s\n", debugstr_variant(pdp->rgvarg)); VariantClear(&prop->var); hres = variant_copy(&prop->var, pdp->rgvarg); if(FAILED(hres)) return hres; prop->flags &= ~DYNPROP_DELETED; return S_OK; default: FIXME("unhandled wFlags %x\n", wFlags); return E_NOTIMPL; } } case DISPEXPROP_BUILTIN: if(wFlags == DISPATCH_CONSTRUCT) { if(id == DISPID_VALUE) { if(This->data->vtbl && This->data->vtbl->value) { return This->data->vtbl->value(This, lcid, wFlags, pdp, pvarRes, pei, pspCaller); } FIXME("DISPATCH_CONSTRUCT flag but missing value function\n"); return E_FAIL; } FIXME("DISPATCH_CONSTRUCT flag without DISPID_VALUE\n"); return E_FAIL; } return invoke_builtin_prop(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); default: assert(0); return E_FAIL; } }
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success) { switch(get_dispid_type(id)) { case DISPEXPROP_CUSTOM: FIXME("DISPEXPROP_CUSTOM not supported\n"); return E_NOTIMPL; case DISPEXPROP_DYNAMIC: { DWORD idx = id - DISPID_DYNPROP_0; dynamic_prop_t *prop; prop = This->dynamic_data->props+idx; VariantClear(&prop->var); prop->flags |= DYNPROP_DELETED; *success = VARIANT_TRUE; return S_OK; } case DISPEXPROP_BUILTIN: { VARIANT var; DISPPARAMS dp = {&var,NULL,1,0}; dispex_data_t *data; func_info_t *func; HRESULT hres; data = get_dispex_data(This); if(!data) return E_FAIL; hres = get_builtin_func(data, id, &func); if(FAILED(hres)) return hres; /* For builtin functions, we set their value to the original function. */ if(func->func_disp_idx != -1) { func_obj_entry_t *entry; if(!This->dynamic_data || !This->dynamic_data->func_disps || !This->dynamic_data->func_disps[func->func_disp_idx].func_obj) { *success = VARIANT_FALSE; return S_OK; } entry = This->dynamic_data->func_disps + func->func_disp_idx; if(V_VT(&entry->val) == VT_DISPATCH && V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface) { *success = VARIANT_FALSE; return S_OK; } VariantClear(&entry->val); V_VT(&entry->val) = VT_DISPATCH; V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface; IDispatch_AddRef(V_DISPATCH(&entry->val)); *success = VARIANT_TRUE; return S_OK; } V_VT(&var) = VT_EMPTY; hres = builtin_propput(This, func, &dp, NULL); if(FAILED(hres)) return hres; *success = VARIANT_TRUE; return S_OK; } default: assert(0); return E_FAIL; } }
RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t cbBuf) { AssertPtrReturn(pszBuf, VERR_INVALID_POINTER); AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER); *pszBuf = '\0'; AssertReturn(enmString > RTSYSDMISTR_INVALID && enmString < RTSYSDMISTR_END, VERR_INVALID_PARAMETER); /* * Figure the property name before we start. */ const char *pszPropName; switch (enmString) { case RTSYSDMISTR_PRODUCT_NAME: pszPropName = "Name"; break; case RTSYSDMISTR_PRODUCT_VERSION: pszPropName = "Version"; break; case RTSYSDMISTR_PRODUCT_UUID: pszPropName = "UUID"; break; case RTSYSDMISTR_PRODUCT_SERIAL: pszPropName = "IdentifyingNumber"; break; case RTSYSDMISTR_MANUFACTURER: pszPropName = "Vendor"; break; default: return VERR_NOT_SUPPORTED; } /* * Before we do anything with COM, we have to initialize it. */ bool fUninit = true; HRESULT hrc = rtSystemDmiWinInitialize(); if (hrc == RPC_E_CHANGED_MODE) fUninit = false; /* don't fail if already initialized */ else if (FAILED(hrc)) return VERR_NOT_SUPPORTED; int rc = VERR_NOT_SUPPORTED; BSTR pBstrPropName = rtSystemWinBstrFromUtf8(pszPropName); if (pBstrPropName) { /* * Instantiate the IWbemLocator, whatever that is and connect to the * DMI serve. */ IWbemLocator *pLoc; hrc = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc); if (SUCCEEDED(hrc)) { IWbemServices *pServices; hrc = rtSystemDmiWinConnectToServer(pLoc, "ROOT\\CIMV2", &pServices); if (SUCCEEDED(hrc)) { /* * Enumerate whatever it is we're looking at and try get * the desired property. */ BSTR pBstrFilter = rtSystemWinBstrFromUtf8("Win32_ComputerSystemProduct"); if (pBstrFilter) { IEnumWbemClassObject *pEnum; hrc = pServices->CreateInstanceEnum(pBstrFilter, 0, NULL, &pEnum); if (SUCCEEDED(hrc)) { do { IWbemClassObject *pObj; ULONG cObjRet; hrc = pEnum->Next(WBEM_INFINITE, 1, &pObj, &cObjRet); if ( SUCCEEDED(hrc) && cObjRet >= 1) { VARIANT Var; VariantInit(&Var); hrc = pObj->Get(pBstrPropName, 0, &Var, 0, 0); if ( SUCCEEDED(hrc) && V_VT(&Var) == VT_BSTR) { /* * Convert the BSTR to UTF-8 and copy it * into the return buffer. */ char *pszValue; rc = RTUtf16ToUtf8(Var.bstrVal, &pszValue); if (RT_SUCCESS(rc)) { rc = RTStrCopy(pszBuf, cbBuf, pszValue); RTStrFree(pszValue); hrc = WBEM_S_FALSE; } } VariantClear(&Var); pObj->Release(); } } while (hrc != WBEM_S_FALSE); pEnum->Release(); } SysFreeString(pBstrFilter); } else hrc = E_OUTOFMEMORY; pServices->Release(); } pLoc->Release(); } SysFreeString(pBstrPropName); } else hrc = E_OUTOFMEMORY; if (fUninit) rtSystemDmiWinTerminate(); if (FAILED(hrc) && rc == VERR_NOT_SUPPORTED) rc = VERR_NOT_SUPPORTED; return rc; }
TRACE("(%p)->(%p %p)\n", This, in, out); if(in) { if(V_VT(in) == VT_I4) { nsICommandParams *nsparam = create_nscommand_params(); char color_str[10]; sprintf(color_str, "#%02x%02x%02x", V_I4(in)&0xff, (V_I4(in)>>8)&0xff, (V_I4(in)>>16)&0xff); nsICommandParams_SetCStringValue(nsparam, NSSTATE_ATTRIBUTE, color_str); do_ns_command(This, NSCMD_FONTCOLOR, nsparam); nsICommandParams_Release(nsparam); }else { FIXME("unsupported in vt=%d\n", V_VT(in)); } update_doc(This, UPDATE_UI); } if(out) { FIXME("unsupported out\n"); return E_NOTIMPL; } return S_OK; } static HRESULT exec_fontsize(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out) {
PHP_COM_DOTNET_API int php_com_zval_from_variant(zval *z, VARIANT *v, int codepage) { OLECHAR *olestring = NULL; int ret = SUCCESS; switch (V_VT(v)) { case VT_EMPTY: case VT_NULL: case VT_VOID: ZVAL_NULL(z); break; case VT_UI1: ZVAL_LONG(z, (zend_long)V_UI1(v)); break; case VT_I1: ZVAL_LONG(z, (zend_long)V_I1(v)); break; case VT_UI2: ZVAL_LONG(z, (zend_long)V_UI2(v)); break; case VT_I2: ZVAL_LONG(z, (zend_long)V_I2(v)); break; case VT_UI4: /* TODO: promote to double if large? */ ZVAL_LONG(z, (long)V_UI4(v)); break; case VT_I4: ZVAL_LONG(z, (long)V_I4(v)); break; #if SIZEOF_ZEND_LONG == 8 case VT_UI8: ZVAL_LONG(z, (zend_long)V_UI8(v)); break; case VT_I8: ZVAL_LONG(z, (zend_long)V_I8(v)); break; #endif case VT_INT: ZVAL_LONG(z, V_INT(v)); break; case VT_UINT: /* TODO: promote to double if large? */ ZVAL_LONG(z, (zend_long)V_UINT(v)); break; case VT_R4: ZVAL_DOUBLE(z, (double)V_R4(v)); break; case VT_R8: ZVAL_DOUBLE(z, V_R8(v)); break; case VT_BOOL: ZVAL_BOOL(z, V_BOOL(v) ? 1 : 0); break; case VT_BSTR: olestring = V_BSTR(v); if (olestring) { size_t len; char *str = php_com_olestring_to_string(olestring, &len, codepage); ZVAL_STRINGL(z, str, len); // TODO: avoid reallocation??? efree(str); olestring = NULL; } break; case VT_UNKNOWN: if (V_UNKNOWN(v) != NULL) { IDispatch *disp; if (SUCCEEDED(IUnknown_QueryInterface(V_UNKNOWN(v), &IID_IDispatch, &disp))) { php_com_wrap_dispatch(z, disp, codepage); IDispatch_Release(disp); } else { ret = FAILURE; } } break; case VT_DISPATCH: if (V_DISPATCH(v) != NULL) { php_com_wrap_dispatch(z, V_DISPATCH(v), codepage); } break; case VT_VARIANT: /* points to another variant */ return php_com_zval_from_variant(z, V_VARIANTREF(v), codepage); default: php_com_wrap_variant(z, v, codepage); } if (olestring) { efree(olestring); } if (ret == FAILURE) { php_error_docref(NULL, E_WARNING, "variant->zval: conversion from 0x%x ret=%d", V_VT(v), ret); } return ret; }
static void test_Invoke(void) { IPictureDisp *picdisp; HRESULT hr; VARIANTARG vararg; DISPPARAMS dispparams; VARIANT varresult; IStream *stream; HGLOBAL hglob; void *data; hglob = GlobalAlloc (0, sizeof(gifimage)); data = GlobalLock(hglob); memcpy(data, gifimage, sizeof(gifimage)); GlobalUnlock(hglob); hr = CreateStreamOnHGlobal (hglob, FALSE, &stream); ok_ole_success(hr, "CreateStreamOnHGlobal"); hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp); IStream_Release(stream); GlobalFree(hglob); ok_ole_success(hr, "OleLoadPicture"); V_VT(&vararg) = VT_BOOL; V_BOOL(&vararg) = VARIANT_FALSE; dispparams.cNamedArgs = 0; dispparams.rgdispidNamedArgs = NULL; dispparams.cArgs = 1; dispparams.rgvarg = &vararg; hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IPictureDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr); hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr); dispparams.cArgs = 0; dispparams.rgvarg = NULL; hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr); hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL); ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr); hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL); ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr); hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL); ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr); hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL); ok_ole_success(hr, "IPictureDisp_Invoke"); ok(V_VT(&varresult) == VT_I4, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult)); hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL); ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr); hr = IPictureDisp_Invoke(picdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL); ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr); dispparams.cArgs = 1; dispparams.rgvarg = &vararg; hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL); ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr); dispparams.cArgs = 1; dispparams.rgvarg = &vararg; hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL); ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr); IPictureDisp_Release(picdisp); }
/* create an automation SafeArray from a PHP array. * Only creates a single-dimensional array of variants. * The keys of the PHP hash MUST be numeric. If the array * is sparse, then the gaps will be filled with NULL variants */ static void safe_array_from_zval(VARIANT *v, zval *z, int codepage) { SAFEARRAY *sa = NULL; SAFEARRAYBOUND bound; HashPosition pos; int keytype; zend_string *strindex; zend_ulong intindex = 0; VARIANT *va; zval *item; /* find the largest array index, and assert that all keys are integers */ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(z), &pos); for (;; zend_hash_move_forward_ex(Z_ARRVAL_P(z), &pos)) { keytype = zend_hash_get_current_key_ex(Z_ARRVAL_P(z), &strindex, &intindex, &pos); if (HASH_KEY_IS_STRING == keytype) { goto bogus; } else if (HASH_KEY_NON_EXISTENT == keytype) { break; } else if (intindex > UINT_MAX) { php_error_docref(NULL, E_WARNING, "COM: max number %u of elements in safe array exceeded", UINT_MAX); break; } } /* allocate the structure */ bound.lLbound = 0; bound.cElements = zend_hash_num_elements(Z_ARRVAL_P(z)); sa = SafeArrayCreate(VT_VARIANT, 1, &bound); /* get a lock on the array itself */ SafeArrayAccessData(sa, &va); va = (VARIANT*)sa->pvData; /* now fill it in */ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(z), &pos); for (;; zend_hash_move_forward_ex(Z_ARRVAL_P(z), &pos)) { if (NULL == (item = zend_hash_get_current_data_ex(Z_ARRVAL_P(z), &pos))) { break; } zend_hash_get_current_key_ex(Z_ARRVAL_P(z), &strindex, &intindex, &pos); php_com_variant_from_zval(&va[intindex], item, codepage); } /* Unlock it and stuff it into our variant */ SafeArrayUnaccessData(sa); V_VT(v) = VT_ARRAY|VT_VARIANT; V_ARRAY(v) = sa; return; bogus: php_error_docref(NULL, E_WARNING, "COM: converting from PHP array to VARIANT array; only arrays with numeric keys are allowed"); V_VT(v) = VT_NULL; if (sa) { SafeArrayUnlock(sa); SafeArrayDestroy(sa); } }
static void test_VarFormat(void) { static const WCHAR szTesting[] = { 't','e','s','t','i','n','g','\0' }; static const WCHAR szNum[] = { '3','9','6','9','7','.','1','1','\0' }; size_t i; WCHAR buffW[256]; char buff[256]; VARIANT in; VARIANT_BOOL bTrue = VARIANT_TRUE, bFalse = VARIANT_FALSE; int fd = 0, fw = 0; ULONG flags = 0; BSTR bstrin, out = NULL; HRESULT hres; CHECKPTR(VarFormat); if (PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())) != LANG_ENGLISH) { skip("Skipping VarFormat tests for non english language\n"); return; } GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char)); if (buff[0] != '.' || buff[1]) { skip("Skipping VarFormat tests as decimal separator is '%s'\n", buff); return; } GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDIGITS, buff, sizeof(buff)/sizeof(char)); if (buff[0] != '2' || buff[1]) { skip("Skipping VarFormat tests as decimal places is '%s'\n", buff); return; } VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"True/False",S_OK,"True"); VARFMT(VT_BOOL,V_BOOL,VARIANT_FALSE,"True/False",S_OK,"False"); VNUMFMT(VT_I1,V_I1); VNUMFMT(VT_I2,V_I2); VNUMFMT(VT_I4,V_I4); if (HAVE_OLEAUT32_I8) { VNUMFMT(VT_I8,V_I8); } VNUMFMT(VT_INT,V_INT); VNUMFMT(VT_UI1,V_UI1); VNUMFMT(VT_UI2,V_UI2); VNUMFMT(VT_UI4,V_UI4); if (HAVE_OLEAUT32_I8) { VNUMFMT(VT_UI8,V_UI8); } VNUMFMT(VT_UINT,V_UINT); VNUMFMT(VT_R4,V_R4); VNUMFMT(VT_R8,V_R8); /* Reference types are dereferenced */ VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bTrue,"True/False",S_OK,"True"); VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bFalse,"True/False",S_OK,"False"); /* Dates */ for (i = 0; i < sizeof(VarFormat_date_results)/sizeof(FMTDATERES); i++) { if (i < 7) fd = i + 1; /* Test first day */ else fd = 0; VARFMT(VT_DATE,V_DATE,VarFormat_date_results[i].val, VarFormat_date_results[i].fmt,S_OK, VarFormat_date_results[i].res); } /* Strings */ bstrin = SysAllocString(szTesting); VARFMT(VT_BSTR,V_BSTR,bstrin,"",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"@",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"&",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x@\\x@",S_OK,"xtxesting"); VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x&\\x&",S_OK,"xtxesting"); VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x",S_OK,"txesting"); VARFMT(VT_BSTR,V_BSTR,bstrin,"@@@@@@@@",S_OK," testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x@@@@@@@",S_OK," xtesting"); VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&&",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"!&&&&&&&",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&!",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,">&&",S_OK,"TESTING"); VARFMT(VT_BSTR,V_BSTR,bstrin,"<&&",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"<&>&",S_OK,"testing"); SysFreeString(bstrin); bstrin = SysAllocString(szNum); todo_wine VARFMT(VT_BSTR,V_BSTR,bstrin,"hh:mm",S_OK,"02:38"); todo_wine VARFMT(VT_BSTR,V_BSTR,bstrin,"mm-dd-yy",S_OK,"09-06-08"); SysFreeString(bstrin); /* Numeric values are converted to strings then output */ VARFMT(VT_I1,V_I1,1,"<&>&",S_OK,"1"); /* Number formats */ VARFMT(VT_I4,V_I4,1,"#00000000",S_OK,"00000001"); VARFMT(VT_I4,V_I4,1,"000###",S_OK,"000001"); VARFMT(VT_I4,V_I4,1,"#00##00#0",S_OK,"00000001"); VARFMT(VT_I4,V_I4,1,"1#####0000",S_OK,"10001"); VARFMT(VT_I4,V_I4,100000,"#,###,###,###",S_OK,"100,000"); VARFMT(VT_I4,V_I4,1,"0,000,000,000",S_OK,"0,000,000,001"); VARFMT(VT_I4,V_I4,123456789,"#,#.#",S_OK,"123,456,789."); VARFMT(VT_I4,V_I4,123456789,"###, ###, ###",S_OK,"123, 456, 789"); VARFMT(VT_I4,V_I4,1,"#;-#",S_OK,"1"); VARFMT(VT_I4,V_I4,-1,"#;-#",S_OK,"-1"); VARFMT(VT_R8,V_R8,1.23456789,"0#.0#0#0#0#0",S_OK,"01.234567890"); VARFMT(VT_R8,V_R8,1.2,"0#.0#0#0#0#0",S_OK,"01.200000000"); VARFMT(VT_R8,V_R8,9.87654321,"#0.#0#0#0#0#",S_OK,"9.87654321"); VARFMT(VT_R8,V_R8,9.8,"#0.#0#0#0#0#",S_OK,"9.80000000"); VARFMT(VT_R8,V_R8,0.00000008,"#0.#0#0#0#0#0",S_OK,"0.0000000800"); VARFMT(VT_R8,V_R8,0.00010705,"#0.##########",S_OK,"0.00010705"); VARFMT(VT_I4,V_I4,17,"#0",S_OK,"17"); VARFMT(VT_I4,V_I4,4711,"#0",S_OK,"4711"); VARFMT(VT_I4,V_I4,17,"#00",S_OK,"17"); VARFMT(VT_I4,V_I4,100,"0##",S_OK,"100"); VARFMT(VT_I4,V_I4,17,"#000",S_OK,"017"); VARFMT(VT_I4,V_I4,17,"#0.00",S_OK,"17.00"); VARFMT(VT_I4,V_I4,17,"#0000.00",S_OK,"0017.00"); VARFMT(VT_I4,V_I4,17,"#.00",S_OK,"17.00"); VARFMT(VT_R8,V_R8,1.7,"#.00",S_OK,"1.70"); VARFMT(VT_R8,V_R8,.17,"#.00",S_OK,".17"); VARFMT(VT_I4,V_I4,17,"#3",S_OK,"173"); VARFMT(VT_I4,V_I4,17,"#33",S_OK,"1733"); VARFMT(VT_I4,V_I4,17,"#3.33",S_OK,"173.33"); VARFMT(VT_I4,V_I4,17,"#3333.33",S_OK,"173333.33"); VARFMT(VT_I4,V_I4,17,"#.33",S_OK,"17.33"); VARFMT(VT_R8,V_R8,.17,"#.33",S_OK,".33"); VARFMT(VT_R8,V_R8,1.7,"0.0000E-000",S_OK,"1.7000E000"); VARFMT(VT_R8,V_R8,1.7,"0.0000e-1",S_OK,"1.7000e01"); VARFMT(VT_R8,V_R8,86.936849,"#0.000000000000e-000",S_OK,"86.936849000000e000"); VARFMT(VT_R8,V_R8,1.7,"#0",S_OK,"2"); VARFMT(VT_R8,V_R8,1.7,"#.33",S_OK,"2.33"); VARFMT(VT_R8,V_R8,1.7,"#3",S_OK,"23"); VARFMT(VT_R8,V_R8,1.73245,"0.0000E+000",S_OK,"1.7325E+000"); VARFMT(VT_R8,V_R8,9.9999999,"#0.000000",S_OK,"10.000000"); VARFMT(VT_R8,V_R8,1.7,"0.0000e+0#",S_OK,"1.7000e+0"); VARFMT(VT_R8,V_R8,100.0001e+0,"0.0000E+0",S_OK,"1.0000E+2"); VARFMT(VT_R8,V_R8,1000001,"0.0000e+1",S_OK,"1.0000e+61"); VARFMT(VT_R8,V_R8,100.0001e+25,"0.0000e+0",S_OK,"1.0000e+27"); VARFMT(VT_R8,V_R8,450.0001e+43,"#000.0000e+0",S_OK,"4500.0010e+42"); VARFMT(VT_R8,V_R8,0.0001e-11,"##00.0000e-0",S_OK,"1000.0000e-18"); VARFMT(VT_R8,V_R8,0.0317e-11,"0000.0000e-0",S_OK,"3170.0000e-16"); VARFMT(VT_R8,V_R8,0.0021e-11,"00##.0000e-0",S_OK,"2100.0000e-17"); VARFMT(VT_R8,V_R8,1.0001e-27,"##00.0000e-0",S_OK,"1000.1000e-30"); VARFMT(VT_R8,V_R8,47.11,".0000E+0",S_OK,".4711E+2"); VARFMT(VT_R8,V_R8,3.0401e-13,"#####.####e-0%",S_OK,"30401.e-15%"); VARFMT(VT_R8,V_R8,1.57,"0.00",S_OK,"1.57"); VARFMT(VT_R8,V_R8,-1.57,"0.00",S_OK,"-1.57"); VARFMT(VT_R8,V_R8,-1.57,"#.##",S_OK,"-1.57"); VARFMT(VT_R8,V_R8,-0.1,".#",S_OK,"-.1"); VARFMT(VT_R8,V_R8,0.099,"#.#",S_OK,".1"); VARFMT(VT_R8,V_R8,0.0999,"#.##",S_OK,".1"); VARFMT(VT_R8,V_R8,0.099,"#.##",S_OK,".1"); VARFMT(VT_R8,V_R8,0.0099,"#.##",S_OK,".01"); VARFMT(VT_R8,V_R8,0.0049,"#.##",S_OK,"."); VARFMT(VT_R8,V_R8,0.0094,"#.##",S_OK,".01"); VARFMT(VT_R8,V_R8,0.00099,"#.##",S_OK,"."); VARFMT(VT_R8,V_R8,0.0995,"#.##",S_OK,".1"); VARFMT(VT_R8,V_R8,8.0995,"#.##",S_OK,"8.1"); VARFMT(VT_R8,V_R8,0.0994,"#.##",S_OK,".1"); VARFMT(VT_R8,V_R8,1.00,"#,##0.00",S_OK,"1.00"); VARFMT(VT_R8,V_R8,0.0995,"#.###",S_OK,".1"); /* 'out' is not cleared */ out = (BSTR)0x1; hres = pVarFormat(&in,NULL,fd,fw,flags,&out); /* Would crash if out is cleared */ ok(hres == S_OK, "got %08x\n", hres); SysFreeString(out); out = NULL; /* VT_NULL */ V_VT(&in) = VT_NULL; hres = pVarFormat(&in,NULL,fd,fw,0,&out); ok(hres == S_OK, "VarFormat failed with 0x%08x\n", hres); ok(out == NULL, "expected NULL formatted string\n"); /* Invalid args */ hres = pVarFormat(&in,NULL,fd,fw,flags,NULL); ok(hres == E_INVALIDARG, "Null out: expected E_INVALIDARG, got 0x%08x\n", hres); hres = pVarFormat(NULL,NULL,fd,fw,flags,&out); ok(hres == E_INVALIDARG, "Null in: expected E_INVALIDARG, got 0x%08x\n", hres); fd = -1; VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); fd = 8; VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); fd = 0; fw = -1; VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); fw = 4; VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); }
HRESULT DoTheWork (INetSharingManager * pNSM) { // add a port mapping to every firewalled or shared connection INetSharingEveryConnectionCollection * pNSECC = NULL; HRESULT hr = pNSM->get_EnumEveryConnection (&pNSECC); int LastErrorCode = 0; if (!pNSECC) return ICS_Error_FailGetEvery; else { // enumerate connections IEnumVARIANT * pEV = NULL; IUnknown * pUnk = NULL; hr = pNSECC->get__NewEnum (&pUnk); if (pUnk) { hr = pUnk->QueryInterface (__uuidof(IEnumVARIANT), (void**)&pEV); pUnk->Release(); }else{ return ICS_Error_FailGetNewEnum; } if (pEV) { VARIANT v; VariantInit (&v); while (S_OK == pEV->Next (1, &v, NULL)) { if (V_VT (&v) == VT_UNKNOWN) { INetConnection * pNC = NULL; V_UNKNOWN (&v)->QueryInterface (__uuidof(INetConnection), (void**)&pNC); if (pNC) { INetConnectionProps * pNCP = NULL; pNSM->get_NetConnectionProps (pNC, &pNCP); if (!pNCP) wprintf (L"failed to get NetConnectionProps!\r\n"); else { // check properties for firewalled or shared connection NETCON_MEDIATYPE MediaType; pNCP->get_MediaType(&MediaType); NETCON_STATUS Status; pNCP->get_Status(&Status); BSTR DevName; pNCP->get_DeviceName(&DevName); if (MediaType & (NCM_LAN | NCM_SHAREDACCESSHOST_LAN | NCM_PHONE) && Status == NCS_CONNECTED && QString(_com_util::ConvertBSTRToString(DevName)).indexOf("hosted network", 0, Qt::CaseInsensitive)==-1 && QString(_com_util::ConvertBSTRToString(DevName)).indexOf("virtual", 0, Qt::CaseInsensitive)==-1 && QString(_com_util::ConvertBSTRToString(DevName)).indexOf("teamviewer", 0, Qt::CaseInsensitive)==-1) { // got a shared/firewalled connection INetSharingConfiguration * pNSC = NULL; hr = pNSM->get_INetSharingConfigurationForINetConnection (pNC, &pNSC); if (!pNSC) wprintf (L"can't make INetSharingConfiguration object!\r\n"); else { hr = pNSC->EnableSharing(ICSSHARINGTYPE_PRIVATE); if(hr!=S_OK){ LastErrorCode = ICS_Error_EnableSharing; }else{ BSTR Name; pNCP->get_Name(&Name); QMessageBox msg; msg.setText(QString("Network: %1 %2 %3").arg(_com_util::ConvertBSTRToString(Name)).arg(_com_util::ConvertBSTRToString(DevName)).arg(Status)); msg.exec(); return 0; } pNSC->Release(); } } pNCP->Release(); } pNC->Release(); } } VariantClear (&v); } pEV->Release(); }else{ return ICS_Error_FailGetEnumVariant; } pNSECC->Release(); } if(LastErrorCode!=0) return LastErrorCode; return hr; }
static void on_before_navigate2(DocHost *This, LPCWSTR url, SAFEARRAY *post_data, LPWSTR headers, VARIANT_BOOL *cancel) { VARIANT var_url, var_flags, var_frame_name, var_post_data, var_post_data2, var_headers; DISPPARAMS dispparams; VARIANTARG params[7]; dispparams.cArgs = 7; dispparams.cNamedArgs = 0; dispparams.rgdispidNamedArgs = NULL; dispparams.rgvarg = params; This->busy = VARIANT_TRUE; V_VT(params) = VT_BOOL|VT_BYREF; V_BOOLREF(params) = cancel; V_VT(params+1) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+1) = &var_headers; V_VT(&var_headers) = VT_BSTR; V_BSTR(&var_headers) = headers; V_VT(params+2) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+2) = &var_post_data2; V_VT(&var_post_data2) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(&var_post_data2) = &var_post_data; if(post_data) { V_VT(&var_post_data) = VT_UI1|VT_ARRAY; V_ARRAY(&var_post_data) = post_data; }else { V_VT(&var_post_data) = VT_EMPTY; } V_VT(params+3) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+3) = &var_frame_name; V_VT(&var_frame_name) = VT_BSTR; V_BSTR(&var_frame_name) = NULL; V_VT(params+4) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+4) = &var_flags; V_VT(&var_flags) = VT_I4; V_I4(&var_flags) = 0; V_VT(params+5) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+5) = &var_url; V_VT(&var_url) = VT_BSTR; V_BSTR(&var_url) = SysAllocString(url); V_VT(params+6) = (VT_DISPATCH); V_DISPATCH(params+6) = This->disp; call_sink(This->cps.wbe2, DISPID_BEFORENAVIGATE2, &dispparams); SysFreeString(V_BSTR(&var_url)); }
static HRESULT set_dbpropset(BSTR name, BSTR value, DBPROPSET **propset) { VARIANT src, dest; int min, max, n; HRESULT hr; min = 0; max = sizeof(dbproperties)/sizeof(struct dbproperty) - 1; while (min <= max) { int r; n = (min+max)/2; r = strcmpiW(dbproperties[n].name, name); if (!r) break; if (r < 0) min = n+1; else max = n-1; } if (min > max) { *propset = NULL; FIXME("unsupported property %s\n", debugstr_w(name)); return E_FAIL; } VariantInit(&dest); V_VT(&src) = VT_BSTR; V_BSTR(&src) = value; hr = VariantChangeType(&dest, &src, 0, dbproperties[n].type); if (FAILED(hr)) { ERR("failed to init property %s value as type %d\n", debugstr_w(name), dbproperties[n].type); return hr; } *propset = CoTaskMemAlloc(sizeof(DBPROPSET)); if (!*propset) { VariantClear(&dest); return E_OUTOFMEMORY; } (*propset)->rgProperties = CoTaskMemAlloc(sizeof(DBPROP)); if (!(*propset)->rgProperties) { VariantClear(&dest); CoTaskMemFree(*propset); return E_OUTOFMEMORY; } (*propset)->cProperties = 1; (*propset)->guidPropertySet = DBPROPSET_DBINIT; (*propset)->rgProperties[0].dwPropertyID = dbproperties[n].id; (*propset)->rgProperties[0].dwOptions = dbproperties[n].options; (*propset)->rgProperties[0].dwStatus = 0; memset(&(*propset)->rgProperties[0].colid, 0, sizeof(DBID)); (*propset)->rgProperties[0].vValue = dest; return S_OK; }
HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags, const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers) { PBYTE post_data = NULL; ULONG post_data_len = 0; LPWSTR headers = NULL; HRESULT hres = S_OK; TRACE("navigating to %s\n", debugstr_w(url)); if((Flags && V_VT(Flags) != VT_EMPTY) || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY)) FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n", Flags, Flags ? V_VT(Flags) : -1, TargetFrameName, TargetFrameName ? V_VT(TargetFrameName) : -1); if(PostData && V_VT(PostData) == (VT_ARRAY | VT_UI1) && V_ARRAY(PostData)) { SafeArrayAccessData(V_ARRAY(PostData), (void**)&post_data); post_data_len = V_ARRAY(PostData)->rgsabound[0].cElements; } if(Headers && V_VT(Headers) == VT_BSTR) { headers = V_BSTR(Headers); TRACE("Headers: %s\n", debugstr_w(headers)); } set_doc_state(This, READYSTATE_LOADING); This->ready_state = READYSTATE_LOADING; if(This->doc_navigate) { WCHAR new_url[INTERNET_MAX_URL_LENGTH]; if(PathIsURLW(url)) { new_url[0] = 0; }else { DWORD size; size = sizeof(new_url)/sizeof(WCHAR); hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT); if(FAILED(hres)) { WARN("UrlApplyScheme failed: %08x\n", hres); new_url[0] = 0; } } hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data, post_data_len, TRUE); }else { task_navigate_bsc_t *task; task = heap_alloc(sizeof(*task)); task->bsc = create_callback(This, url, post_data, post_data_len, headers); push_dochost_task(This, &task->header, navigate_bsc_proc, navigate_bsc_task_destr, This->url == NULL); } if(post_data) SafeArrayUnaccessData(V_ARRAY(PostData)); return hres; }
HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTYPE vt) { jsval_t val; HRESULT hres; clear_ei(ctx); hres = variant_to_jsval(src, &val); if(FAILED(hres)) return hres; switch(vt) { case VT_I2: case VT_I4: { INT i; hres = to_int32(ctx, val, &i); if(SUCCEEDED(hres)) { if(vt == VT_I4) V_I4(dst) = i; else V_I2(dst) = i; } break; } case VT_R8: { double n; hres = to_number(ctx, val, &n); if(SUCCEEDED(hres)) V_R8(dst) = n; break; } case VT_R4: { double n; hres = to_number(ctx, val, &n); if(SUCCEEDED(hres)) V_R4(dst) = n; break; } case VT_BOOL: { BOOL b; hres = to_boolean(val, &b); if(SUCCEEDED(hres)) V_BOOL(dst) = b ? VARIANT_TRUE : VARIANT_FALSE; break; } case VT_BSTR: { jsstr_t *str; hres = to_string(ctx, val, &str); if(FAILED(hres)) break; if(str->length_flags & JSSTR_FLAG_NULLBSTR) { V_BSTR(dst) = NULL; break; } V_BSTR(dst) = SysAllocStringLen(str->str, jsstr_length(str)); if(!V_BSTR(dst)) hres = E_OUTOFMEMORY; break; } case VT_EMPTY: hres = V_VT(src) == VT_EMPTY ? S_OK : E_NOTIMPL; break; case VT_NULL: hres = V_VT(src) == VT_NULL ? S_OK : E_NOTIMPL; break; default: FIXME("vt %d not implemented\n", vt); hres = E_NOTIMPL; } jsval_release(val); if(FAILED(hres)) return hres; V_VT(dst) = vt; return S_OK; }
//------------------------------------------------------------------------------- // Name: Exec // Desc: Обрабатывает Стандыртные События для Exec'a... //------------------------------------------------------------------------------- STDMETHODIMP COfsDhtmlEditCtrl::Exec(const GUID *pguidCmdGroup, DWORD nCmdID , DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { HRESULT hr = S_OK; if ( pguidCmdGroup == NULL ) { USES_CONVERSION; switch (nCmdID) { case OLECMDID_SAVE: // We don't support any save stuff! hr = OLECMDERR_E_NOTSUPPORTED; break; case OLECMDID_SETPROGRESSTEXT: if ( pvaIn && V_VT(pvaIn) == VT_BSTR ) { // CFrameWnd* pFrame = GetTopLevelFrame(); // if ( pFrame != NULL ) // { // pFrame->SetMessageText( OLE2T(V_BSTR(pvaIn)) ); // } } else { hr = OLECMDERR_E_NOTSUPPORTED; } break; case OLECMDID_UPDATECOMMANDS: // MFC updates all other commands in it's idle so we don't bother forcing the update here { ///////////////////////////////////////////// /// Посылать Сообщение предку на Обновление ///////////////////////////////////////////// if(dwInfoMessage) GetParent()->SendMessage(dwInfoMessage); //SetFontState(); } break; case OLECMDID_SETTITLE: if (pvaIn && V_VT(pvaIn) == VT_BSTR) { // CCEditDoc* pDoc = GetDocument(); // ASSERT_VALID(pDoc); // pDoc->SetTitle(OLE2T(V_BSTR(pvaIn))); } else { hr = OLECMDERR_E_NOTSUPPORTED; } break; default: hr = OLECMDERR_E_NOTSUPPORTED; break; } } else { hr = OLECMDERR_E_UNKNOWNGROUP; } return (hr); }
static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *func) { HRESULT hres; func->code_off = ctx->instr_cnt; ctx->while_end_label = 0; ctx->for_end_label = 0; ctx->sub_end_label = 0; ctx->func_end_label = 0; ctx->prop_end_label = 0; switch(func->type) { case FUNC_FUNCTION: ctx->func_end_label = alloc_label(ctx); if(!ctx->func_end_label) return E_OUTOFMEMORY; break; case FUNC_SUB: ctx->sub_end_label = alloc_label(ctx); if(!ctx->sub_end_label) return E_OUTOFMEMORY; break; case FUNC_PROPGET: case FUNC_PROPLET: case FUNC_PROPSET: case FUNC_DEFGET: ctx->prop_end_label = alloc_label(ctx); if(!ctx->prop_end_label) return E_OUTOFMEMORY; break; case FUNC_GLOBAL: break; } ctx->func = func; ctx->dim_decls = NULL; ctx->const_decls = NULL; hres = compile_statement(ctx, stat); ctx->func = NULL; if(FAILED(hres)) return hres; assert(!ctx->while_end_label); assert(!ctx->for_end_label); if(ctx->sub_end_label) label_set_addr(ctx, ctx->sub_end_label); if(ctx->func_end_label) label_set_addr(ctx, ctx->func_end_label); if(ctx->prop_end_label) label_set_addr(ctx, ctx->prop_end_label); if(!push_instr(ctx, OP_ret)) return E_OUTOFMEMORY; resolve_labels(ctx, func->code_off); if(func->var_cnt) { dim_decl_t *dim_decl; if(func->type == FUNC_GLOBAL) { dynamic_var_t *new_var; func->var_cnt = 0; for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) { new_var = compiler_alloc(ctx->code, sizeof(*new_var)); if(!new_var) return E_OUTOFMEMORY; new_var->name = compiler_alloc_string(ctx->code, dim_decl->name); if(!new_var->name) return E_OUTOFMEMORY; V_VT(&new_var->v) = VT_EMPTY; new_var->is_const = FALSE; new_var->next = ctx->global_vars; ctx->global_vars = new_var; } }else { unsigned i; func->vars = compiler_alloc(ctx->code, func->var_cnt * sizeof(var_desc_t)); if(!func->vars) return E_OUTOFMEMORY; for(dim_decl = ctx->dim_decls, i=0; dim_decl; dim_decl = dim_decl->next, i++) { func->vars[i].name = compiler_alloc_string(ctx->code, dim_decl->name); if(!func->vars[i].name) return E_OUTOFMEMORY; } assert(i == func->var_cnt); } } return S_OK; }
int Extension::foreachCmd ( ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { if (objc != 4) { Tcl_WrongNumArgs( interp, 1, objv, "varList collectionHandle script"); return TCL_ERROR; } Tcl_Obj *pVarList = objv[1]; Tcl_Obj *pBody = objv[3]; Reference *pCollection = referenceHandles.find(interp, objv[2]); if (pCollection == 0) { const char *arg = Tcl_GetStringFromObj(objv[2], 0); Tcl_AppendResult( interp, "invalid interface pointer handle ", arg, 0); return TCL_ERROR; } // Collections should implement a _NewEnum method which returns an object // that enumerates the elements. HRESULT hr; PositionalArguments arguments; _variant_t varResult; hr = pCollection->invoke( DISPID_NEWENUM, DISPATCH_METHOD | DISPATCH_PROPERTYGET, arguments, &varResult); if (FAILED(hr) || V_VT(&varResult) != VT_UNKNOWN) { Tcl_AppendResult(interp, "object is not a collection", NULL); return TCL_ERROR; } IUnknownPtr pUnk(V_UNKNOWN(&varResult)); // Get a specific kind of enumeration. IEnumVARIANTPtr pEnumVARIANT; IEnumUnknownPtr pEnumUnknown; enum EnumKind { ENUM_VARIANT, ENUM_UNKNOWN }; EnumKind enumKind; hr = pUnk->QueryInterface( IID_IEnumVARIANT, reinterpret_cast<void **>(&pEnumVARIANT)); if (SUCCEEDED(hr)) { enumKind = ENUM_VARIANT; } else { hr = pUnk->QueryInterface( IID_IEnumUnknown, reinterpret_cast<void **>(&pEnumUnknown)); if (SUCCEEDED(hr)) { enumKind = ENUM_UNKNOWN; } } if (FAILED(hr)) { Tcl_AppendResult(interp, "Unknown enumerator type: not IEnumVARIANT or IEnumUnknown", NULL); return TCL_ERROR; } int completionCode; int varc; // number of loop variables completionCode = Tcl_ListObjLength(interp, pVarList, &varc); if (completionCode != TCL_OK) { return TCL_ERROR; } if (varc < 1) { Tcl_AppendResult(interp, "foreach varlist is empty", NULL); return TCL_ERROR; } while (true) { // If the variable list has been converted to another kind of Tcl // object, convert it back to a list and refetch the pointer to its // element array. Tcl_Obj **varv; completionCode = Tcl_ListObjGetElements(interp, pVarList, &varc, &varv); if (completionCode != TCL_OK) { return TCL_ERROR; } // Assign values to all loop variables. int v = 0; for (; v < varc; ++v) { TclObject value; ULONG count; switch (enumKind) { case ENUM_VARIANT: { _variant_t elementVar; hr = pEnumVARIANT->Next(1, &elementVar, &count); if (hr == S_OK && count > 0) { value = TclObject(&elementVar, Type::variant(), interp, 0); } } break; case ENUM_UNKNOWN: { IUnknown *pElement; hr = pEnumUnknown->Next(1, &pElement, &count); if (hr == S_OK && count > 0) { value = referenceHandles.newObj( interp, Reference::newReference(pElement)); } } break; } if (FAILED(hr)) { _com_issue_error(hr); } if (hr != S_OK || count == 0) { break; } Tcl_Obj *varValuePtr = Tcl_ObjSetVar2( interp, varv[v], NULL, value, TCL_LEAVE_ERR_MSG); if (varValuePtr == NULL) { return TCL_ERROR; } } if (v == 0) { completionCode = TCL_OK; break; } if (v < varc) { TclObject empty; for (; v < varc; ++v) { Tcl_Obj *varValuePtr = Tcl_ObjSetVar2( interp, varv[v], NULL, empty, TCL_LEAVE_ERR_MSG); if (varValuePtr == NULL) { return TCL_ERROR; } } } // Execute the script body. completionCode = #if TCL_MINOR_VERSION >= 1 Tcl_EvalObjEx(interp, pBody, 0); #else Tcl_EvalObj(interp, pBody); #endif if (completionCode == TCL_CONTINUE) { // do nothing } else if (completionCode == TCL_BREAK) { completionCode = TCL_OK; break; } else if (completionCode == TCL_ERROR) { std::ostringstream oss; oss << "\n (\"foreach\" body line %d)" << interp->errorLine; Tcl_AddObjErrorInfo( interp, const_cast<char *>(oss.str().c_str()), -1); break; } else if (completionCode != TCL_OK) { break; } } if (completionCode == TCL_OK) { Tcl_ResetResult(interp); } return completionCode; }
/*********************************************************************** * AtlAxCreateControlEx [ATL.@] * * REMARKS * See http://www.codeproject.com/com/cwebpage.asp for some background * */ HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd, IStream *pStream, IUnknown **ppUnkContainer, IUnknown **ppUnkControl, REFIID iidSink, IUnknown *punkSink) { CLSID controlId; HRESULT hRes; IOleObject *pControl; IUnknown *pUnkControl; IPersistStreamInit *pPSInit; IUnknown *pContainer; enum {IsGUID=0,IsHTML=1,IsURL=2} content; TRACE("(%s %p %p %p %p %p %p)\n", debugstr_w(lpszName), hWnd, pStream, ppUnkContainer, ppUnkControl, iidSink, punkSink); hRes = CLSIDFromString( lpszName, &controlId ); if ( FAILED(hRes) ) hRes = CLSIDFromProgID( lpszName, &controlId ); if ( SUCCEEDED( hRes ) ) content = IsGUID; else { /* FIXME - check for MSHTML: prefix! */ content = IsURL; controlId = CLSID_WebBrowser; } hRes = CoCreateInstance( &controlId, 0, CLSCTX_ALL, &IID_IOleObject, (void**) &pControl ); if ( FAILED( hRes ) ) { WARN( "cannot create ActiveX control %s instance - error 0x%08x\n", debugstr_guid( &controlId ), hRes ); return hRes; } hRes = IOleObject_QueryInterface( pControl, &IID_IPersistStreamInit, (void**) &pPSInit ); if ( SUCCEEDED( hRes ) ) { if (!pStream) IPersistStreamInit_InitNew( pPSInit ); else IPersistStreamInit_Load( pPSInit, pStream ); IPersistStreamInit_Release( pPSInit ); } else WARN("cannot get IID_IPersistStreamInit out of control\n"); IOleObject_QueryInterface( pControl, &IID_IUnknown, (void**) &pUnkControl ); IOleObject_Release( pControl ); hRes = AtlAxAttachControl( pUnkControl, hWnd, &pContainer ); if ( FAILED( hRes ) ) WARN("cannot attach control to window\n"); if ( content == IsURL ) { IWebBrowser2 *browser; hRes = IOleObject_QueryInterface( pControl, &IID_IWebBrowser2, (void**) &browser ); if ( !browser ) WARN( "Cannot query IWebBrowser2 interface: %08x\n", hRes ); else { VARIANT url; IWebBrowser2_put_Visible( browser, VARIANT_TRUE ); /* it seems that native does this on URL (but do not on MSHTML:! why? */ V_VT(&url) = VT_BSTR; V_BSTR(&url) = SysAllocString( lpszName ); hRes = IWebBrowser2_Navigate2( browser, &url, NULL, NULL, NULL, NULL ); if ( FAILED( hRes ) ) WARN( "IWebBrowser2::Navigate2 failed: %08x\n", hRes ); SysFreeString( V_BSTR(&url) ); IWebBrowser2_Release( browser ); } } if (ppUnkContainer) { *ppUnkContainer = pContainer; if ( pContainer ) IUnknown_AddRef( pContainer ); } if (ppUnkControl) { *ppUnkControl = pUnkControl; if ( pUnkControl ) IUnknown_AddRef( pUnkControl ); } if ( pUnkControl ) IUnknown_Release( pUnkControl ); if ( pContainer ) IUnknown_Release( pContainer ); return S_OK; }
static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, VARIANT *res, IServiceProvider *caller) { VARIANT arg_buf[MAX_ARGS], *arg_ptrs[MAX_ARGS], *arg, retv, ret_ref, vhres; unsigned i, nconv = 0; IUnknown *iface; HRESULT hres; if(dp->cNamedArgs) { FIXME("Named arguments not supported\n"); return E_NOTIMPL; } if(dp->cArgs != func->argc) { FIXME("Invalid argument count (expected %u, got %u)\n", func->argc, dp->cArgs); return E_INVALIDARG; } hres = IUnknown_QueryInterface(This->outer, tid_ids[func->tid], (void**)&iface); if(FAILED(hres)) return hres; for(i=0; i < func->argc; i++) { arg = dp->rgvarg+dp->cArgs-i-1; if(func->arg_types[i] == V_VT(arg)) { arg_ptrs[i] = arg; } else { hres = change_type(arg_buf+nconv, arg, func->arg_types[i], caller); if(FAILED(hres)) break; arg_ptrs[i] = arg_buf + nconv++; } } if(SUCCEEDED(hres)) { if(func->prop_vt == VT_VOID) { V_VT(&retv) = VT_EMPTY; } else { V_VT(&retv) = func->prop_vt; arg_ptrs[func->argc] = &ret_ref; V_VT(&ret_ref) = VT_BYREF|func->prop_vt; switch(func->prop_vt) { #define CASE_VT(vt,type,access) \ case vt: \ V_BYREF(&ret_ref) = &access(&retv); \ break BUILTIN_TYPES_SWITCH; #undef CASE_VT default: assert(0); } } V_VT(&vhres) = VT_ERROR; hres = DispCallFunc(iface, func->call_vtbl_off*sizeof(void*), CC_STDCALL, VT_ERROR, func->argc + (func->prop_vt == VT_VOID ? 0 : 1), func->arg_types, arg_ptrs, &vhres); } while(nconv--) VariantClear(arg_buf+nconv); IUnknown_Release(iface); if(FAILED(hres)) return hres; if(FAILED(V_ERROR(&vhres))) return V_ERROR(&vhres); if(res) *res = retv; else VariantClear(&retv); return V_ERROR(&vhres); }