static OLECHAR dualW[] = {'d','u','a','l',0};
static OLECHAR coclassW[] = {'c','o','c','l','a','s','s',0};
static WCHAR defaultW[] = {'d','e','f','a','u','l','t',0x3213,0};
+ static WCHAR defaultQW[] = {'d','e','f','a','u','l','t','?',0};
static OLECHAR func1W[] = {'f','u','n','c','1',0};
static OLECHAR func2W[] = {'f','u','n','c','2',0};
static OLECHAR prop1W[] = {'P','r','o','p','1',0};
ITypeLib *tl, *stdole;
ITypeInfo *interface1, *interface2, *dual, *unknown, *dispatch, *ti;
ITypeInfo2 *ti2;
- FUNCDESC funcdesc;
- ELEMDESC elemdesc[5];
+ FUNCDESC funcdesc, *pfuncdesc;
+ ELEMDESC elemdesc[5], *edesc;
PARAMDESCEX paramdescex;
TYPEDESC typedesc1, typedesc2;
TYPEATTR *typeattr;
hres = ITypeInfo_GetRefTypeOfImplType(interface1, -1, &hreftype);
ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+ ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo2, (void**)&ti2);
+
memset(&funcdesc, 0, sizeof(FUNCDESC));
funcdesc.funckind = FUNC_PUREVIRTUAL;
funcdesc.invkind = INVOKE_PROPERTYGET;
hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 0, NULL);
+ ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
+ hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
+ ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+
+ hres = ITypeInfo2_GetFuncDesc(ti2, 0, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_PROPERTYGET, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 12 ||
+ broken(pfuncdesc->oVft == 24) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_BSTR, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
hres = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0xabcdefab);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 1, propname, 2);
ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_PROPERTYPUT, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 16 ||
+ broken(pfuncdesc->oVft == 28) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
+ ok(edesc->idldesc.wIDLFlags == IDLFLAG_FIN, "got: %x\n", edesc->idldesc.wIDLFlags);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
funcdesc.invkind = INVOKE_PROPERTYPUTREF;
hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 1, "got %d\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 16 ||
+ broken(pfuncdesc->oVft == 28), /* xp64 */
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
funcdesc.memid = MEMBERID_NIL;
hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x60010003, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 24 ||
+ broken(pfuncdesc->oVft == 36) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
+ ok(edesc->paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", edesc->paramdesc.wParamFlags);
+ ok(edesc->paramdesc.pparamdescex != NULL, "got: %p\n", edesc->paramdesc.pparamdescex);
+ ok(edesc->paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
+ edesc->paramdesc.pparamdescex->cBytes);
+ ok(V_VT(&edesc->paramdesc.pparamdescex->varDefaultValue) == VT_I4, "got: %d\n",
+ V_VT(&edesc->paramdesc.pparamdescex->varDefaultValue));
+ ok(V_I4(&edesc->paramdesc.pparamdescex->varDefaultValue) == 0x123, "got: 0x%x\n",
+ V_I4(&edesc->paramdesc.pparamdescex->varDefaultValue));
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
U(elemdesc[0]).idldesc.dwReserved = 0;
U(elemdesc[0]).idldesc.wIDLFlags = IDLFLAG_FIN;
elemdesc[1].tdesc.vt = VT_UI2;
hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x60010009, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 24 ||
+ broken(pfuncdesc->oVft == 36) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
+ ok(edesc->paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", edesc->paramdesc.wParamFlags);
+ ok(edesc->paramdesc.pparamdescex == NULL, "got: %p\n", edesc->paramdesc.pparamdescex);
+
+ edesc = pfuncdesc->lprgelemdescParam + 1;
+ ok(edesc->tdesc.vt == VT_UI2, "got: %d\n", edesc->tdesc.vt);
+ ok(edesc->paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", edesc->paramdesc.wParamFlags);
+ ok(edesc->paramdesc.pparamdescex != NULL, "got: %p\n", edesc->paramdesc.pparamdescex);
+ ok(edesc->paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
+ edesc->paramdesc.pparamdescex->cBytes);
+ ok(V_VT(&edesc->paramdesc.pparamdescex->varDefaultValue) == VT_UI2, "got: %d\n",
+ V_VT(&edesc->paramdesc.pparamdescex->varDefaultValue));
+ ok(V_UI2(&edesc->paramdesc.pparamdescex->varDefaultValue) == 0xFFFF, "got: 0x%x\n",
+ V_UI2(&edesc->paramdesc.pparamdescex->varDefaultValue));
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
U(elemdesc[0]).paramdesc.pparamdescex = ¶mdescex;
elemdesc[1].tdesc.vt = VT_INT;
hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x6001000b, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 24 ||
+ broken(pfuncdesc->oVft == 36) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
+ ok(edesc->paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", edesc->paramdesc.wParamFlags);
+ ok(edesc->paramdesc.pparamdescex != NULL, "got: %p\n", edesc->paramdesc.pparamdescex);
+ ok(edesc->paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
+ edesc->paramdesc.pparamdescex->cBytes);
+ ok(V_VT(&edesc->paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
+ V_VT(&edesc->paramdesc.pparamdescex->varDefaultValue));
+ ok(!lstrcmpW(V_BSTR(&edesc->paramdesc.pparamdescex->varDefaultValue), defaultQW),
+ "got: %s\n",
+ wine_dbgstr_w(V_BSTR(&edesc->paramdesc.pparamdescex->varDefaultValue)));
+
+ edesc = pfuncdesc->lprgelemdescParam + 1;
+ ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
+ ok(edesc->paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", edesc->paramdesc.wParamFlags);
+ ok(edesc->paramdesc.pparamdescex != NULL, "got: %p\n", edesc->paramdesc.pparamdescex);
+ ok(edesc->paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
+ edesc->paramdesc.pparamdescex->cBytes);
+ ok(V_VT(&edesc->paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
+ V_VT(&edesc->paramdesc.pparamdescex->varDefaultValue));
+ ok(!lstrcmpW(V_BSTR(&edesc->paramdesc.pparamdescex->varDefaultValue), defaultQW),
+ "got: %s\n",
+ wine_dbgstr_w(V_BSTR(&edesc->paramdesc.pparamdescex->varDefaultValue)));
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
hres = ITypeInfo_GetDocumentation(interface1, 0, &name, &docstring, &helpcontext, &helpfile);
ok(hres == S_OK, "got %08x\n", hres);
ok(name == NULL, "name != NULL\n");
hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 3, names1, 3);
ok(hres == TYPE_E_AMBIGUOUSNAME, "got %08x\n", hres);
+ ITypeInfo2_Release(ti2);
ICreateTypeInfo_Release(createti);
hres = ICreateTypeLib_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
return 0;
}
+/****************************************************************************
+ * ctl2_decode_typedesc
+ *
+ * Decodes a type description from an ICreateTypeLib2Impl.
+ *
+ * RETURNS
+ *
+ * Success: S_OK.
+ * Failure: HRESULT error code.
+ */
+static HRESULT ctl2_decode_typedesc(
+ ICreateTypeLib2Impl *This, /* [I] The type library from which to decode the TYPEDESC. */
+ int encoded_tdesc, /* [I] The encoded type description. */
+ TYPEDESC *tdesc) /* [O] The decoded type description. */
+{
+ if (encoded_tdesc & 0x80000000) {
+ tdesc->vt = encoded_tdesc & VT_TYPEMASK;
+ tdesc->u.lptdesc = NULL;
+ return S_OK;
+ }
+
+ FIXME("unable to decode typedesc: %08x\n", encoded_tdesc);
+ return E_NOTIMPL;
+}
+
/****************************************************************************
* ctl2_find_nth_reference
*
UINT index,
FUNCDESC** ppFuncDesc)
{
- FIXME("(%p,%d,%p), stub!\n", iface, index, ppFuncDesc);
- return E_OUTOFMEMORY;
+ ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+ int i, *typedata, num_defaults = 0, hdr_len, tail, has_defaults;
+ CyclicList *desc;
+ HRESULT hres;
+
+ TRACE("(%p,%d,%p), semi-stub\n", iface, index, ppFuncDesc);
+
+ if (!ppFuncDesc)
+ return E_INVALIDARG;
+
+ if (index >= This->typeinfo->cElement)
+ return TYPE_E_ELEMENTNOTFOUND;
+
+ hres = ICreateTypeInfo2_LayOut((ICreateTypeInfo2*)This);
+ if (FAILED(hres))
+ return hres;
+
+ desc = This->typedata->next;
+ for (i = index; i >= 0; ) {
+ desc = desc->next;
+ if (desc->type == CyclicListFunc)
+ --i;
+ }
+
+ typedata = desc->u.data;
+
+ *ppFuncDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FUNCDESC));
+ if (!*ppFuncDesc)
+ return E_OUTOFMEMORY;
+
+ (*ppFuncDesc)->memid = desc->indice;
+ (*ppFuncDesc)->lprgscode = NULL; /* FIXME: Unimplemented */
+ (*ppFuncDesc)->funckind = typedata[4] & 0x7;
+ (*ppFuncDesc)->invkind = (typedata[4] >> 3) & 0xF;
+ (*ppFuncDesc)->callconv = (typedata[4] >> 8) & 0xF;
+ (*ppFuncDesc)->cParams = typedata[5];
+ (*ppFuncDesc)->cParamsOpt = 0; /* FIXME: Unimplemented*/
+ (*ppFuncDesc)->oVft = typedata[3] & 0xFFFF;
+ if ((*ppFuncDesc)->oVft)
+ --(*ppFuncDesc)->oVft;
+ (*ppFuncDesc)->cScodes = 0; /* FIXME: Unimplemented*/
+ hres = ctl2_decode_typedesc(This->typelib, typedata[1],
+ &(*ppFuncDesc)->elemdescFunc.tdesc);
+ if (FAILED(hres)) {
+ HeapFree(GetProcessHeap(), 0, *ppFuncDesc);
+ return hres;
+ }
+ (*ppFuncDesc)->wFuncFlags = typedata[2];
+
+ has_defaults = typedata[4] & 0x1000;
+ tail = typedata[5] * (has_defaults ? 16 : 12);
+ hdr_len = ((typedata[0] & 0xFFFF) - tail) / sizeof(int);
+
+ if ((*ppFuncDesc)->cParams > 0) {
+ (*ppFuncDesc)->lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (*ppFuncDesc)->cParams * sizeof(ELEMDESC));
+ if (!(*ppFuncDesc)->lprgelemdescParam) {
+ HeapFree(GetProcessHeap(), 0, *ppFuncDesc);
+ return E_OUTOFMEMORY;
+ }
+ if (has_defaults) {
+ num_defaults = (*ppFuncDesc)->cParams;
+
+ for (i = 0; i < num_defaults; ++i) {
+ if (typedata[hdr_len + i] != 0xFFFFFFFF) {
+ (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags |= PARAMFLAG_FHASDEFAULT;
+
+ (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex = HeapAlloc(GetProcessHeap(), 0, sizeof(PARAMDESCEX));
+ if (!(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex) {
+ ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
+ return E_OUTOFMEMORY;
+ }
+
+ (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->cBytes = sizeof(PARAMDESCEX);
+ hres = ctl2_decode_variant(This->typelib, typedata[hdr_len + i],
+ &(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
+ if (FAILED(hres)) {
+ ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
+ return hres;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < (*ppFuncDesc)->cParams; ++i) {
+ hres = ctl2_decode_typedesc(This->typelib, typedata[hdr_len + num_defaults + (i * 3)],
+ &((*ppFuncDesc)->lprgelemdescParam + i)->tdesc);
+ if (FAILED(hres)) {
+ ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
+ return hres;
+ }
+ (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags = typedata[hdr_len + num_defaults + (i * 3) + 2];
+ }
+ }
+
+ return S_OK;
}
/******************************************************************************