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 = &paramdescex;
@@ -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