Piotr Caban : oleaut32: Improved ICreateTypeInfo2_fnAddFuncDesc implementation.

Alexandre Julliard julliard at winehq.org
Mon Feb 22 08:46:50 CST 2010


Module: wine
Branch: master
Commit: 1dda40deb2ae1dac4852f1bd7547a92694a25cb7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1dda40deb2ae1dac4852f1bd7547a92694a25cb7

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Feb 22 10:24:17 2010 +0100

oleaut32: Improved ICreateTypeInfo2_fnAddFuncDesc implementation.

---

 dlls/oleaut32/tests/typelib.c |   53 ++++++++++++++++++++++++
 dlls/oleaut32/typelib2.c      |   89 +++++++++++++++++++++++++----------------
 2 files changed, 107 insertions(+), 35 deletions(-)

diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index ff85320..2a04ae9 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -976,6 +976,8 @@ static void test_CreateTypeLib(void) {
     ICreateTypeLib2 *createtl;
     ICreateTypeInfo *createti;
     ITypeLib *tl;
+    FUNCDESC funcdesc;
+    ELEMDESC elemdesc;
     HRESULT hres;
 
     trace("CreateTypeLib tests\n");
@@ -988,6 +990,57 @@ static void test_CreateTypeLib(void) {
 
     hres = ICreateTypeLib_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
     ok(hres == S_OK, "got %08x\n", hres);
+
+    hres = ICreateTypeInfo_LayOut(createti);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    memset(&funcdesc, 0, sizeof(FUNCDESC));
+    funcdesc.funckind = FUNC_PUREVIRTUAL;
+    funcdesc.invkind = INVOKE_PROPERTYGET;
+    funcdesc.callconv = CC_STDCALL;
+    funcdesc.elemdescFunc.tdesc.vt = VT_BSTR;
+    funcdesc.elemdescFunc.idldesc.wIDLFlags = IDLFLAG_NONE;
+
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 0, NULL);
+    ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
+    ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    funcdesc.invkind = INVOKE_PROPERTYPUT;
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
+    ok(hres == TYPE_E_INCONSISTENTPROPFUNCS, "got %08x\n", hres);
+
+    funcdesc.invkind = INVOKE_PROPERTYPUTREF;
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
+    ok(hres == TYPE_E_INCONSISTENTPROPFUNCS, "got %08x\n", hres);
+
+    elemdesc.tdesc.vt = VT_BSTR;
+    elemdesc.idldesc.dwReserved = 0;
+    elemdesc.idldesc.wIDLFlags = IDLFLAG_FIN;
+
+    funcdesc.lprgelemdescParam = &elemdesc;
+    funcdesc.invkind = INVOKE_PROPERTYPUT;
+    funcdesc.cParams = 1;
+    funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
+
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    funcdesc.invkind = INVOKE_PROPERTYPUTREF;
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    funcdesc.memid = 1;
+    funcdesc.lprgelemdescParam = NULL;
+    funcdesc.invkind = INVOKE_FUNC;
+    funcdesc.cParams = 0;
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
+    ok(hres == S_OK, "got %08x\n", hres);
+
     ICreateTypeInfo_Release(createti);
 
     hres = ICreateTypeLib_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c
index 0f5d57f..66edc37 100644
--- a/dlls/oleaut32/typelib2.c
+++ b/dlls/oleaut32/typelib2.c
@@ -514,7 +514,7 @@ static int ctl2_alloc_typeinfo(
     typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16;
     typeinfo->memoffset = -1; /* should be EOF if no elements */
     typeinfo->res2 = 0;
-    typeinfo->res3 = -1;
+    typeinfo->res3 = 0;
     typeinfo->res4 = 3;
     typeinfo->res5 = 0;
     typeinfo->cElement = 0;
@@ -1382,16 +1382,43 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
 {
     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
 
-    CyclicList *insert;
+    CyclicList *iter, *insert;
     int *typedata;
     int i;
     int decoded_size;
 
-    FIXME("(%p,%d,%p), stub!\n", iface, index, pFuncDesc);
-    FIXME("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
-/*     FIXME("{%d, %d}\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt, pFuncDesc->lprgelemdescParam[1].tdesc.vt); */
-/*     return E_OUTOFMEMORY; */
-    
+    TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);
+
+    if(!pFuncDesc || (pFuncDesc->memid>0x7fffffff && pFuncDesc->memid!=MEMBERID_NIL))
+        return E_INVALIDARG;
+
+    TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid,
+            pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind,
+            pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams,
+            pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes,
+            pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
+
+    switch(This->typeinfo->typekind&0xf) {
+    case TKIND_MODULE:
+        if(pFuncDesc->funckind != FUNC_STATIC)
+            return TYPE_E_BADMODULEKIND;
+        break;
+    case TKIND_DISPATCH:
+        if(pFuncDesc->funckind != FUNC_DISPATCH)
+            return TYPE_E_BADMODULEKIND;
+        break;
+    default:
+        if(pFuncDesc->funckind != FUNC_PUREVIRTUAL)
+            return TYPE_E_BADMODULEKIND;
+    }
+
+    if(This->typeinfo->cElement<index)
+        return TYPE_E_ELEMENTNOTFOUND;
+
+    if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) &&
+        !pFuncDesc->cParams)
+        return TYPE_E_INCONSISTENTPROPFUNCS;
+
     if (!This->typedata) {
 	This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
         if(!This->typedata)
@@ -1411,19 +1438,30 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
         return E_OUTOFMEMORY;
     }
 
-    insert->next = This->typedata->next;
-    This->typedata->next = insert;
-    This->typedata = insert;
+    /* insert type data to list */
+    if(index == This->typeinfo->cElement) {
+        insert->next = This->typedata->next;
+        This->typedata->next = insert;
+        This->typedata = insert;
+    } else {
+        iter = This->typedata->next;
+        for(i=0; i<index; i++)
+            iter = iter->next;
+
+        insert->next = iter->next;
+        iter->next = insert;
+    }
 
+    /* update type data size */
     This->typedata->next->u.val += 0x18 + (pFuncDesc->cParams * 12);
-    typedata = This->typedata->u.data;
 
     /* fill out the basic type information */
-    typedata[0] = (0x18 + (pFuncDesc->cParams * 12)) | (index << 16);
+    typedata = insert->u.data;
+    typedata[0] = 0x18 + pFuncDesc->cParams * 12;
     ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size);
     typedata[2] = pFuncDesc->wFuncFlags;
     typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | This->typeinfo->cbSizeVft;
-    typedata[4] = (index << 16) | (pFuncDesc->callconv << 8) | 9;
+    typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind;
     typedata[5] = pFuncDesc->cParams;
 
     /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */
@@ -1436,33 +1474,14 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
 	typedata[8+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
 	typedata[3] += decoded_size << 16;
 
-#if 0
-	/* FIXME: Doesn't work. Doesn't even come up with usable VTs for varDefaultValue. */
-	if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
-	    ctl2_alloc_custdata(This->typelib, &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
-	}
-#endif
+        if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
+            FIXME("default values not implemented\n");
     }
 
     /* update the index data */
-    insert->indice = ((0x6000 | This->typeinfo->cImplTypes) << 16) | index;
+    insert->indice = (This->typeinfo->cImplTypes << 16) | pFuncDesc->memid;
     insert->name = -1;
 
-    /* ??? */
-    if (!This->typeinfo->res2) This->typeinfo->res2 = 0x20;
-    This->typeinfo->res2 <<= 1;
-
-    /* ??? */
-    if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0;
-    This->typeinfo->res3 += 0x38;
-
-    /* ??? */
-    if (index < 2) This->typeinfo->res2 += pFuncDesc->cParams << 4;
-    This->typeinfo->res3 += pFuncDesc->cParams << 4;
-
-    /* adjust size of VTBL */
-    This->typeinfo->cbSizeVft += 4;
-
     /* Increment the number of function elements */
     This->typeinfo->cElement += 1;
 




More information about the wine-cvs mailing list