Commit 6868fe86 authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

oleaut32: Implement ITypeInfo2::GetFuncDesc.

parent 3788a080
......@@ -1073,6 +1073,7 @@ static void test_CreateTypeLib(void) {
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};
......@@ -1093,8 +1094,8 @@ static void test_CreateTypeLib(void) {
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;
......@@ -1226,6 +1227,8 @@ static void test_CreateTypeLib(void) {
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;
......@@ -1242,6 +1245,32 @@ static void test_CreateTypeLib(void) {
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);
......@@ -1277,6 +1306,30 @@ static void test_CreateTypeLib(void) {
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);
......@@ -1295,6 +1348,26 @@ static void test_CreateTypeLib(void) {
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);
......@@ -1321,6 +1394,37 @@ static void test_CreateTypeLib(void) {
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;
......@@ -1332,6 +1436,42 @@ static void test_CreateTypeLib(void) {
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 = &paramdescex;
elemdesc[1].tdesc.vt = VT_INT;
......@@ -1347,6 +1487,50 @@ static void test_CreateTypeLib(void) {
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");
......@@ -1383,6 +1567,7 @@ static void test_CreateTypeLib(void) {
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);
......
......@@ -1310,6 +1310,31 @@ static int ctl2_encode_typedesc(
}
/****************************************************************************
* 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
*
* Finds a reference by index into the linked list of reference records.
......@@ -3144,8 +3169,101 @@ static HRESULT WINAPI ITypeInfo2_fnGetFuncDesc(
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;
}
/******************************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment