Commit b85cb1b8 authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

oleaut32: Implement decoding for complex typedescs.

parent 6868fe86
...@@ -1380,12 +1380,68 @@ static void test_CreateTypeLib(void) { ...@@ -1380,12 +1380,68 @@ static void test_CreateTypeLib(void) {
hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc); hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres); ok(hres == S_OK, "got %08x\n", hres);
hres = ITypeInfo2_GetFuncDesc(ti2, 4, &pfuncdesc);
ok(hres == S_OK, "got %08x\n", hres);
ok(pfuncdesc->memid == 0x60010004, "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 == 28 ||
broken(pfuncdesc->oVft == 40) /* 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_PTR, "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);
ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
ok(U(edesc->tdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
U(elemdesc[0].tdesc).lptdesc = &typedesc2; U(elemdesc[0].tdesc).lptdesc = &typedesc2;
typedesc2.vt = VT_PTR; typedesc2.vt = VT_PTR;
U(typedesc2).lptdesc = &typedesc1; U(typedesc2).lptdesc = &typedesc1;
hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc); hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres); ok(hres == S_OK, "got %08x\n", hres);
hres = ITypeInfo2_GetFuncDesc(ti2, 4, &pfuncdesc);
ok(hres == S_OK, "got %08x\n", hres);
ok(pfuncdesc->memid == 0x60010007, "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 == 28 ||
broken(pfuncdesc->oVft == 40) /* 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_PTR, "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);
ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
ok(U(edesc->tdesc).lptdesc->vt == VT_PTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
ok(U(edesc->tdesc).lptdesc->lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc->lptdesc);
ok(U(edesc->tdesc).lptdesc->lptdesc->vt == VT_BSTR, "got: %d\n", U(edesc->tdesc).lptdesc->lptdesc->vt);
ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
elemdesc[0].tdesc.vt = VT_INT; elemdesc[0].tdesc.vt = VT_INT;
U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT; U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
U(elemdesc[0]).paramdesc.pparamdescex = &paramdescex; U(elemdesc[0]).paramdesc.pparamdescex = &paramdescex;
...@@ -1531,6 +1587,45 @@ static void test_CreateTypeLib(void) { ...@@ -1531,6 +1587,45 @@ static void test_CreateTypeLib(void) {
ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc); ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
elemdesc[0].tdesc.vt = VT_USERDEFINED;
elemdesc[0].tdesc.hreftype = hreftype;
U(elemdesc[0]).paramdesc.pparamdescex = NULL;
U(elemdesc[0]).paramdesc.wParamFlags = 0;
funcdesc.lprgelemdescParam = elemdesc;
funcdesc.invkind = INVOKE_FUNC;
funcdesc.cParams = 1;
funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
hres = ICreateTypeInfo_AddFuncDesc(createti, 5, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
hres = ITypeInfo2_GetFuncDesc(ti2, 5, &pfuncdesc);
ok(hres == S_OK, "got %08x\n", hres);
ok(pfuncdesc->memid == 0x60010005, "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 == 32 ||
broken(pfuncdesc->oVft == 44), /* 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->paramdesc.pparamdescex == NULL, "got: %p\n", edesc->paramdesc.pparamdescex);
ok(edesc->paramdesc.wParamFlags == 0, "got: 0x%x\n", edesc->paramdesc.wParamFlags);
ok(edesc->tdesc.vt == VT_USERDEFINED, "got: %d\n", edesc->tdesc.vt);
ok(edesc->tdesc.hreftype == hreftype, "got: 0x%x\n", edesc->tdesc.hreftype);
ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
hres = ITypeInfo_GetDocumentation(interface1, 0, &name, &docstring, &helpcontext, &helpfile); hres = ITypeInfo_GetDocumentation(interface1, 0, &name, &docstring, &helpcontext, &helpfile);
ok(hres == S_OK, "got %08x\n", hres); ok(hres == S_OK, "got %08x\n", hres);
ok(name == NULL, "name != NULL\n"); ok(name == NULL, "name != NULL\n");
...@@ -1840,10 +1935,10 @@ static void test_CreateTypeLib(void) { ...@@ -1840,10 +1935,10 @@ static void test_CreateTypeLib(void) {
ok(hres == S_OK, "got %08x\n", hres); ok(hres == S_OK, "got %08x\n", hres);
ok(typeattr->cbSizeInstance == 4, "cbSizeInstance = %d\n", typeattr->cbSizeInstance); ok(typeattr->cbSizeInstance == 4, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
ok(typeattr->typekind == 3, "typekind = %d\n", typeattr->typekind); ok(typeattr->typekind == 3, "typekind = %d\n", typeattr->typekind);
ok(typeattr->cFuncs == 11, "cFuncs = %d\n", typeattr->cFuncs); ok(typeattr->cFuncs == 12, "cFuncs = %d\n", typeattr->cFuncs);
ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars); ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes); ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
ok(typeattr->cbSizeVft == 56 || broken(typeattr->cbSizeVft == 3 * sizeof(void *) + 44), /* xp64 */ ok(typeattr->cbSizeVft == 60 || broken(typeattr->cbSizeVft == 3 * sizeof(void *) + 48), /* xp64 */
"cbSizeVft = %d\n", typeattr->cbSizeVft); "cbSizeVft = %d\n", typeattr->cbSizeVft);
ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment); ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags); ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
......
...@@ -1324,14 +1324,66 @@ static HRESULT ctl2_decode_typedesc( ...@@ -1324,14 +1324,66 @@ static HRESULT ctl2_decode_typedesc(
int encoded_tdesc, /* [I] The encoded type description. */ int encoded_tdesc, /* [I] The encoded type description. */
TYPEDESC *tdesc) /* [O] The decoded type description. */ TYPEDESC *tdesc) /* [O] The decoded type description. */
{ {
int *typedata, i;
HRESULT hres;
if (encoded_tdesc & 0x80000000) { if (encoded_tdesc & 0x80000000) {
tdesc->vt = encoded_tdesc & VT_TYPEMASK; tdesc->vt = encoded_tdesc & VT_TYPEMASK;
tdesc->u.lptdesc = NULL; tdesc->u.lptdesc = NULL;
return S_OK; return S_OK;
} }
FIXME("unable to decode typedesc: %08x\n", encoded_tdesc); typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][encoded_tdesc];
return E_NOTIMPL;
tdesc->vt = typedata[0] & 0xFFFF;
switch(tdesc->vt) {
case VT_PTR:
case VT_SAFEARRAY:
tdesc->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEDESC));
if (!tdesc->u.lptdesc)
return E_OUTOFMEMORY;
hres = ctl2_decode_typedesc(This, typedata[1], tdesc->u.lptdesc);
if (FAILED(hres)) {
HeapFree(GetProcessHeap(), 0, tdesc->u.lptdesc);
return hres;
}
return S_OK;
case VT_CARRAY: {
int arrayoffset, *arraydata, num_dims;
arrayoffset = typedata[1];
arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
num_dims = arraydata[1] & 0xFFFF;
tdesc->u.lpadesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(ARRAYDESC) + sizeof(SAFEARRAYBOUND) * (num_dims - 1));
if (!tdesc->u.lpadesc)
return E_OUTOFMEMORY;
hres = ctl2_decode_typedesc(This, arraydata[0], &tdesc->u.lpadesc->tdescElem);
if (FAILED(hres)) {
HeapFree(GetProcessHeap(), 0, tdesc->u.lpadesc);
return E_OUTOFMEMORY;
}
for (i = 0; i < num_dims; ++i) {
tdesc->u.lpadesc->rgbounds[i].cElements = arraydata[2 + i * 2];
tdesc->u.lpadesc->rgbounds[i].lLbound = arraydata[3 + i * 2];
}
return S_OK;
}
case VT_USERDEFINED:
tdesc->u.hreftype = typedata[1];
return S_OK;
default:
FIXME("unable to decode typedesc (%08x): unknown VT: %d\n", encoded_tdesc, tdesc->vt);
return E_NOTIMPL;
}
} }
/**************************************************************************** /****************************************************************************
......
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