oleaut32: Implement decoding for complex typedescs.
This commit is contained in:
parent
6868fe8643
commit
b85cb1b865
|
@ -1380,12 +1380,68 @@ static void test_CreateTypeLib(void) {
|
|||
hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
|
||||
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;
|
||||
typedesc2.vt = VT_PTR;
|
||||
U(typedesc2).lptdesc = &typedesc1;
|
||||
hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
|
||||
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;
|
||||
U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
|
||||
U(elemdesc[0]).paramdesc.pparamdescex = ¶mdescex;
|
||||
|
@ -1531,6 +1587,45 @@ static void test_CreateTypeLib(void) {
|
|||
|
||||
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);
|
||||
ok(hres == S_OK, "got %08x\n", hres);
|
||||
ok(name == NULL, "name != NULL\n");
|
||||
|
@ -1840,10 +1935,10 @@ static void test_CreateTypeLib(void) {
|
|||
ok(hres == S_OK, "got %08x\n", hres);
|
||||
ok(typeattr->cbSizeInstance == 4, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
|
||||
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->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);
|
||||
ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
|
||||
ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
|
||||
|
|
|
@ -1324,14 +1324,66 @@ static HRESULT ctl2_decode_typedesc(
|
|||
int encoded_tdesc, /* [I] The encoded type description. */
|
||||
TYPEDESC *tdesc) /* [O] The decoded type description. */
|
||||
{
|
||||
int *typedata, i;
|
||||
HRESULT hres;
|
||||
|
||||
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;
|
||||
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][encoded_tdesc];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
Loading…
Reference in New Issue