Andrew Eikum : oleaut32: Implement decoding for complex typedescs.
Alexandre Julliard
julliard at winehq.org
Mon Aug 23 10:50:14 CDT 2010
Module: wine
Branch: master
Commit: b85cb1b865c6004f672c483133b7bbc349cd85d7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b85cb1b865c6004f672c483133b7bbc349cd85d7
Author: Andrew Eikum <aeikum at 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;
+ }
}
/****************************************************************************
More information about the wine-cvs
mailing list