HRESULT __RPC_STUB ITypeInfo_GetVarDesc_Stub( ITypeInfo* This, UINT index, LPVARDESC* ppVarDesc, CLEANLOCALSTORAGE* pDummy) { HRESULT hr; TRACE("(%p, %d, %p)\n", This, index, ppVarDesc); hr = ITypeInfo_GetVarDesc(This, index, ppVarDesc); if(hr != S_OK) return hr; pDummy->flags = CLS_VARDESC; ITypeInfo_AddRef(This); pDummy->pInterface = (IUnknown*)This; pDummy->pStorage = ppVarDesc; return hr; }
/* Given a type-library, merge it into the current engine state */ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepage TSRMLS_DC) { int i, j, interfaces; TYPEKIND pTKind; ITypeInfo *TypeInfo; VARDESC *pVarDesc; UINT NameCount; BSTR bstr_ids; zend_constant c; zval *exists, results, value; char *const_name; int len; if (TL == NULL) { return FAILURE; } interfaces = ITypeLib_GetTypeInfoCount(TL); for (i = 0; i < interfaces; i++) { ITypeLib_GetTypeInfoType(TL, i, &pTKind); if (pTKind == TKIND_ENUM) { ITypeLib_GetTypeInfo(TL, i, &TypeInfo); for (j = 0; ; j++) { if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) { break; } ITypeInfo_GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount); if (NameCount != 1) { ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); continue; } const_name = php_com_olestring_to_string(bstr_ids, &len, codepage TSRMLS_CC); c.name = STR_INIT(const_name, len, 1); // TODO: avoid reallocation??? efree(const_name); if(c.name == NULL) { ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); continue; } //??? c.name_len++; /* include NUL */ SysFreeString(bstr_ids); /* sanity check for the case where the constant is already defined */ if ((exists = zend_get_constant(c.name TSRMLS_CC)) != NULL) { if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, exists TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library constant %s is already defined", c.name); } STR_RELEASE(c.name); ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); continue; } /* register the constant */ php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage TSRMLS_CC); if (Z_TYPE(value) == IS_INT) { c.flags = mode; ZVAL_INT(&c.value, Z_IVAL(value)); c.module_number = 0; zend_register_constant(&c TSRMLS_CC); } ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); } ITypeInfo_Release(TypeInfo); } } return SUCCESS; }
/****************************************************************************** * GetRecordInfoFromTypeInfo [OLEAUT32.332] */ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo) { HRESULT hres; TYPEATTR *typeattr; IRecordInfoImpl *ret; ITypeInfo *pTypeInfo; int i; GUID guid; TRACE("(%p %p)\n", pTI, ppRecInfo); if(!pTI || !ppRecInfo) return E_INVALIDARG; hres = ITypeInfo_GetTypeAttr(pTI, &typeattr); if(FAILED(hres) || !typeattr) { WARN("GetTypeAttr failed: %08x\n", hres); return hres; } if(typeattr->typekind == TKIND_ALIAS) { hres = ITypeInfo_GetRefTypeInfo(pTI, typeattr->tdescAlias.u.hreftype, &pTypeInfo); guid = typeattr->guid; ITypeInfo_ReleaseTypeAttr(pTI, typeattr); if(FAILED(hres)) { WARN("GetRefTypeInfo failed: %08x\n", hres); return hres; } ITypeInfo_GetTypeAttr(pTypeInfo, &typeattr); }else { pTypeInfo = pTI; ITypeInfo_AddRef(pTypeInfo); guid = typeattr->guid; } if(typeattr->typekind != TKIND_RECORD) { WARN("typekind != TKIND_RECORD\n"); ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr); ITypeInfo_Release(pTypeInfo); return E_INVALIDARG; } ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret)); ret->IRecordInfo_iface.lpVtbl = &IRecordInfoImplVtbl; ret->ref = 1; ret->pTypeInfo = pTypeInfo; ret->n_vars = typeattr->cVars; ret->size = typeattr->cbSizeInstance; ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr); ret->guid = guid; /* NOTE: Windows implementation calls ITypeInfo::GetCantainingTypeLib and * ITypeLib::GetLibAttr, but we currently don't need this. */ hres = ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, &ret->name, NULL, NULL, NULL); if(FAILED(hres)) { WARN("ITypeInfo::GetDocumentation failed\n"); ret->name = NULL; } ret->fields = HeapAlloc(GetProcessHeap(), 0, ret->n_vars*sizeof(fieldstr)); for(i = 0; i<ret->n_vars; i++) { VARDESC *vardesc; hres = ITypeInfo_GetVarDesc(pTypeInfo, i, &vardesc); if(FAILED(hres)) { WARN("GetVarDesc failed\n"); continue; } ret->fields[i].vt = vardesc->elemdescVar.tdesc.vt; ret->fields[i].varkind = vardesc->varkind; ret->fields[i].offset = vardesc->u.oInst; hres = ITypeInfo_GetDocumentation(pTypeInfo, vardesc->memid, &ret->fields[i].name, NULL, NULL, NULL); if(FAILED(hres)) WARN("GetDocumentation failed: %08x\n", hres); ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc); } *ppRecInfo = &ret->IRecordInfo_iface; return S_OK; }