oleaut32: Improved implementation of ICreateTypeInfo2_fnAddImplType.

This commit is contained in:
Piotr Caban 2010-02-22 23:15:42 +01:00 committed by Alexandre Julliard
parent 32803c0489
commit 9e02ef54e1
2 changed files with 80 additions and 23 deletions

View File

@ -155,6 +155,7 @@ typedef struct tagMSFT_TypeInfoBase {
INT datatype2; /* if 0x8000, entry above is valid */ INT datatype2; /* if 0x8000, entry above is valid */
/* actually dunno */ /* actually dunno */
/* else it is zero? */ /* else it is zero? */
/* if interface: inheritance level | no of inherited funcs */
INT res18; /* always? 0 */ INT res18; /* always? 0 */
/*060*/ INT res19; /* always? -1 */ /*060*/ INT res19; /* always? -1 */
} MSFT_TypeInfoBase; } MSFT_TypeInfoBase;

View File

@ -1326,7 +1326,8 @@ static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
if (!ref) { if (!ref) {
if (This->typelib) { if (This->typelib) {
ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)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. */ /* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
@ -1791,18 +1792,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
} else if ((This->typeinfo->typekind & 15) == TKIND_DISPATCH) { } else if ((This->typeinfo->typekind & 15) == TKIND_DISPATCH) {
FIXME("dispatch case unhandled.\n"); FIXME("dispatch case unhandled.\n");
} else if ((This->typeinfo->typekind & 15) == TKIND_INTERFACE) { } else if ((This->typeinfo->typekind & 15) == TKIND_INTERFACE) {
if (This->typeinfo->cImplTypes) { if (This->typeinfo->cImplTypes && index==1)
return (index == 1)? TYPE_E_BADMODULEKIND: TYPE_E_ELEMENTNOTFOUND; return TYPE_E_BADMODULEKIND;
}
if (index != 0) return TYPE_E_ELEMENTNOTFOUND; if( index != 0) return TYPE_E_ELEMENTNOTFOUND;
This->typeinfo->cImplTypes++; This->typeinfo->datatype1 = hRefType;
This->typeinfo->cImplTypes++;
/* 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; /* ? */
} else { } else {
FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15); FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -2251,29 +2247,87 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
{ {
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
CyclicList *iter, *iter2, **typedata; CyclicList *iter, *iter2, **typedata;
HREFTYPE hreftype;
HRESULT hres;
int i; int i;
TRACE("(%p)\n", iface); 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) if(!This->typedata)
return S_OK; return S_OK;
typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*This->typeinfo->cElement); typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff));
if(!typedata) if(!typedata)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
/* Assign IDs and VTBL entries */ /* Assign IDs and VTBL entries */
i = 0; i = 0;
This->typeinfo->cbSizeVft = 0;
for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) { for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
/* Assign MEMBERID if MEMBERID_NIL was specified */ /* Assign MEMBERID if MEMBERID_NIL was specified */
if(iter->indice == MEMBERID_NIL) { 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) { for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
if(iter == iter2) continue; if(iter == iter2) continue;
if(iter2->indice == iter->indice) { 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) { for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
if(iter == iter2) continue; if(iter == iter2) continue;
@ -2313,7 +2367,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
i++; 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) { if(typedata[i]->u.data[4]>>16 > i) {
int inv; int inv;
@ -3757,14 +3811,16 @@ static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
HRESULT hres; HRESULT hres;
for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
typeinfo->typeinfo->memoffset = filesize; typeinfo->typeinfo->memoffset = filesize;
if (typeinfo->typedata) {
hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
if(FAILED(hres))
return hres;
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; return S_OK;