Module: wine Branch: master Commit: b85cb1b865c6004f672c483133b7bbc349cd85d7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b85cb1b865c6004f672c483133...
Author: Andrew Eikum aeikum@codeweavers.com Date: Fri Aug 20 14:59:33 2010 -0500
oleaut32: Implement decoding for complex typedescs.
---
dlls/oleaut32/tests/typelib.c | 99 ++++++++++++++++++++++++++++++++++++++++- dlls/oleaut32/typelib2.c | 56 ++++++++++++++++++++++- 2 files changed, 151 insertions(+), 4 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index a201550..e801160 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -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); diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c index 90cee43..eccc72b 100644 --- a/dlls/oleaut32/typelib2.c +++ b/dlls/oleaut32/typelib2.c @@ -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; + } }
/****************************************************************************