Piotr Caban : oleaut32: Improved ICreateTypeInfo AddFuncDesc implementation .

Alexandre Julliard julliard at winehq.org
Tue Mar 16 11:49:17 CDT 2010


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Mar 15 23:40:15 2010 +0100

oleaut32: Improved ICreateTypeInfo AddFuncDesc implementation.

---

 dlls/oleaut32/tests/typelib.c |   12 ++++++++++--
 dlls/oleaut32/typelib2.c      |   25 ++++++++++++++++++++++---
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index b31466e..797ac02 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -1265,6 +1265,14 @@ static void test_CreateTypeLib(void) {
     hres = ITypeInfo_GetImplTypeFlags(interface2, 1, &impltypeflags);
     ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
 
+    funcdesc.oVft = 0xaaac;
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
+    ok(hres == S_OK, "got %08x\n", hres);
+    funcdesc.oVft = 0xaaa8;
+    hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
+    ok(hres == S_OK, "got %08x\n", hres);
+    funcdesc.oVft = 0;
+
     ICreateTypeInfo_Release(createti);
 
     hres = ICreateTypeLib_CreateTypeInfo(createtl, coclassW, TKIND_COCLASS, &createti);
@@ -1412,10 +1420,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 == 0, "cFuncs = %d\n", typeattr->cFuncs);
+    ok(typeattr->cFuncs == 2, "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, "cbSizeVft = %d\n", typeattr->cbSizeVft);
+    ok(typeattr->cbSizeVft == 43696, "cbSizeVft = %d\n", typeattr->cbSizeVft);
     ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
     ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
     ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c
index 59f431e..3a92bad 100644
--- a/dlls/oleaut32/typelib2.c
+++ b/dlls/oleaut32/typelib2.c
@@ -1674,7 +1674,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
 
     TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);
 
-    if(!pFuncDesc)
+    if(!pFuncDesc || pFuncDesc->oVft&3)
         return E_INVALIDARG;
 
     TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid,
@@ -1683,6 +1683,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
             pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes,
             pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
 
+    if(pFuncDesc->cParamsOpt || pFuncDesc->cScodes)
+        FIXME("Unimplemented parameter - created typelib will be incorrect\n");
+
     switch(This->typekind) {
     case TKIND_MODULE:
         if(pFuncDesc->funckind != FUNC_STATIC)
@@ -1736,7 +1739,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
     typedata[0] = 0x18 + pFuncDesc->cParams*(num_defaults?16: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[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | (unsigned short)(pFuncDesc->oVft?pFuncDesc->oVft+1:0);
     typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind;
     if(num_defaults) typedata[4] |= 0x1000;
     typedata[5] = pFuncDesc->cParams;
@@ -2352,6 +2355,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
     CyclicList *iter, *iter2, **typedata;
     HREFTYPE hreftype;
     HRESULT hres;
+    unsigned user_vft = 0;
     int i;
 
     TRACE("(%p)\n", iface);
@@ -2435,6 +2439,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
 
     /* Assign IDs and VTBL entries */
     i = 0;
+    if(This->typedata->u.data[3]&1)
+        user_vft = This->typedata->u.data[3]&0xffff;
+
     for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
         /* Assign MEMBERID if MEMBERID_NIL was specified */
         if(iter->indice == MEMBERID_NIL) {
@@ -2460,7 +2467,16 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
 
         iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16);
 
-        if(This->typekind != TKIND_MODULE) {
+        if((iter->u.data[3]&1) != (user_vft&1))
+            return TYPE_E_INVALIDID;
+
+        if(user_vft&1) {
+            if(user_vft < (iter->u.data[3]&0xffff))
+                user_vft = (iter->u.data[3]&0xffff);
+
+            if((iter->u.data[3]&0xffff) < This->typeinfo->cbSizeVft)
+                return TYPE_E_INVALIDID;
+        } else if(This->typekind != TKIND_MODULE) {
             iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft;
             This->typeinfo->cbSizeVft += 4;
         }
@@ -2483,6 +2499,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
         i++;
     }
 
+    if(user_vft)
+        This->typeinfo->cbSizeVft = user_vft+3;
+
     for(i=0; i<(This->typeinfo->cElement&0xffff); i++) {
         if(typedata[i]->u.data[4]>>16 > i) {
             int inv;




More information about the wine-cvs mailing list