mirror of
https://github.com/reactos/wine.git
synced 2025-02-21 21:32:01 +00:00
oleaut32: Implement ITypeInfo2::GetFuncDesc.
This commit is contained in:
parent
3788a080cf
commit
6868fe8643
@ -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 = ¶mdescex;
|
||||
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);
|
||||
|
@ -1309,6 +1309,31 @@ static int ctl2_encode_typedesc(
|
||||
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
|
||||
*
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user