Piotr Caban : oleaut32: Improved implementation of ICreateTypeInfo2_fnAddImplType.

Alexandre Julliard julliard at winehq.org
Tue Feb 23 11:17:22 CST 2010


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Feb 22 23:15:42 2010 +0100

oleaut32: Improved implementation of ICreateTypeInfo2_fnAddImplType.

---

 dlls/oleaut32/typelib.h  |    1 +
 dlls/oleaut32/typelib2.c |  102 +++++++++++++++++++++++++++++++++++----------
 2 files changed, 80 insertions(+), 23 deletions(-)

diff --git a/dlls/oleaut32/typelib.h b/dlls/oleaut32/typelib.h
index b1c85ed..058c6a2 100644
--- a/dlls/oleaut32/typelib.h
+++ b/dlls/oleaut32/typelib.h
@@ -155,6 +155,7 @@ typedef struct tagMSFT_TypeInfoBase {
         INT     datatype2;      /* if 0x8000, entry above is valid */
                                 /* actually dunno */
                                 /* else it is zero? */
+                                /* if interface: inheritance level | no of inherited funcs */
         INT     res18;          /* always? 0 */
 /*060*/ INT     res19;          /* always? -1 */
 } MSFT_TypeInfoBase;
diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c
index a5eebea..71e8e81 100644
--- a/dlls/oleaut32/typelib2.c
+++ b/dlls/oleaut32/typelib2.c
@@ -1326,7 +1326,8 @@ static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
     if (!ref) {
 	if (This->typelib) {
 	    ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib);
-	    This->typelib = NULL;
+            /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */
+            /* This->typelib = NULL; */
 	}
 
 	/* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
@@ -1791,18 +1792,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
     } else if ((This->typeinfo->typekind & 15) == TKIND_DISPATCH) {
 	FIXME("dispatch case unhandled.\n");
     } else if ((This->typeinfo->typekind & 15) == TKIND_INTERFACE) {
-	if (This->typeinfo->cImplTypes) {
-	    return (index == 1)? TYPE_E_BADMODULEKIND: TYPE_E_ELEMENTNOTFOUND;
-	}
-
-	if (index != 0)  return TYPE_E_ELEMENTNOTFOUND;
+        if (This->typeinfo->cImplTypes && index==1)
+            return TYPE_E_BADMODULEKIND;
 
-	This->typeinfo->cImplTypes++;
+        if( index != 0)  return TYPE_E_ELEMENTNOTFOUND;
 
-	/* hacked values for IDispatch only, and maybe only for stdole. */
-	This->typeinfo->cbSizeVft += 0x0c; /* hack */
-	This->typeinfo->datatype1 = hRefType;
-	This->typeinfo->datatype2 = (3 << 16) | 1; /* ? */
+        This->typeinfo->datatype1 = hRefType;
+        This->typeinfo->cImplTypes++;
     } else {
 	FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15);
 	return E_OUTOFMEMORY;
@@ -2251,29 +2247,87 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
 {
     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
     CyclicList *iter, *iter2, **typedata;
+    HREFTYPE hreftype;
+    HRESULT hres;
     int i;
 
     TRACE("(%p)\n", iface);
 
+    /* Validate inheritance */
+    This->typeinfo->datatype2 = 0;
+    hreftype = This->typeinfo->datatype1;
+
+    /* Process internally defined interfaces */
+    for(i=0; i<This->typelib->typelib_header.nrtypeinfos; i++) {
+        MSFT_TypeInfoBase *header;
+
+        if(hreftype&1)
+            break;
+
+        header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]);
+        This->typeinfo->datatype2 += (header->cElement<<16) + 1;
+        hreftype = header->datatype1;
+    }
+    if(i == This->typelib->typelib_header.nrtypeinfos)
+        return TYPE_E_CIRCULARTYPE;
+
+    /* Process externally defined interfaces */
+    if(hreftype != -1) {
+        ITypeInfo *cur, *next;
+        TYPEATTR *typeattr;
+
+        hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next);
+        if(FAILED(hres))
+            return hres;
+
+        hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur);
+        if(FAILED(hres))
+            return hres;
+
+        ITypeInfo_Release(next);
+
+        while(1) {
+            hres = ITypeInfo_GetTypeAttr(cur, &typeattr);
+            if(FAILED(hres))
+                return hres;
+
+            This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1;
+            ITypeInfo_ReleaseTypeAttr(cur, typeattr);
+
+            hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype);
+            if(hres == TYPE_E_ELEMENTNOTFOUND)
+                break;
+            if(FAILED(hres))
+                return hres;
+
+            hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next);
+            if(FAILED(hres))
+                return hres;
+
+            ITypeInfo_Release(cur);
+            cur = next;
+        }
+    }
+
+    This->typeinfo->cbSizeVft = (This->typeinfo->datatype2>>16) * 4;
     if(!This->typedata)
         return S_OK;
 
-    typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*This->typeinfo->cElement);
+    typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff));
     if(!typedata)
         return E_OUTOFMEMORY;
 
     /* Assign IDs and VTBL entries */
     i = 0;
-    This->typeinfo->cbSizeVft = 0;
     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) {
-            iter->indice = 0x60000000 + i;
+            iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16);
 
             for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
                 if(iter == iter2) continue;
                 if(iter2->indice == iter->indice) {
-                    iter->indice = 0x5fffffff + This->typeinfo->cElement + i;
+                    iter->indice = 0x5fffffff + This->typeinfo->cElement + i + (This->typeinfo->datatype2<<16);
 
                     for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
                         if(iter == iter2) continue;
@@ -2313,7 +2367,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
         i++;
     }
 
-    for(i=0; i<This->typeinfo->cElement; i++) {
+    for(i=0; i<(This->typeinfo->cElement&0xffff); i++) {
         if(typedata[i]->u.data[4]>>16 > i) {
             int inv;
 
@@ -3757,14 +3811,16 @@ static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
     HRESULT hres;
 
     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
-	typeinfo->typeinfo->memoffset = filesize;
-	if (typeinfo->typedata) {
-	    hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
-            if(FAILED(hres))
-                return hres;
+        typeinfo->typeinfo->memoffset = filesize;
 
-	    filesize += typeinfo->typedata->next->u.val + ((typeinfo->typeinfo->cElement >> 16) * 12) + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
-	}
+        hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
+        if(FAILED(hres))
+            return hres;
+
+	if (typeinfo->typedata)
+	    filesize += typeinfo->typedata->next->u.val
+                + ((typeinfo->typeinfo->cElement >> 16) * 12)
+                + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
     }
 
     return S_OK;




More information about the wine-cvs mailing list