From 1436e51e2af30f1f0c476613deae5bed998eaf38 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 21 Mar 2010 13:04:42 +0000 Subject: [PATCH] [OLEAUT32] sync oleaut32 with wine 1.1.41 svn path=/trunk/; revision=46296 --- reactos/dll/win32/oleaut32/typelib.c | 30 ++- reactos/dll/win32/oleaut32/typelib2.c | 352 ++++++++++++++++++-------- 2 files changed, 275 insertions(+), 107 deletions(-) diff --git a/reactos/dll/win32/oleaut32/typelib.c b/reactos/dll/win32/oleaut32/typelib.c index 445eac5c51e..b09f7ab64d1 100644 --- a/reactos/dll/win32/oleaut32/typelib.c +++ b/reactos/dll/win32/oleaut32/typelib.c @@ -4722,6 +4722,7 @@ static HRESULT WINAPI ITypeLibComp_fnBind( { ITypeLibImpl *This = impl_from_ITypeComp(iface); ITypeInfoImpl *pTypeInfo; + int typemismatch=0; TRACE("(%s, 0x%x, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr); @@ -4761,6 +4762,8 @@ static HRESULT WINAPI ITypeLibComp_fnBind( TRACE("found in module or in enum: %s\n", debugstr_w(szName)); return S_OK; } + else if (hr == TYPE_E_TYPEMISMATCH) + typemismatch = 1; } if ((pTypeInfo->TypeAttr.typekind == TKIND_COCLASS) && @@ -4833,11 +4836,21 @@ static HRESULT WINAPI ITypeLibComp_fnBind( ITypeInfo_AddRef(*ppTInfo); return S_OK; } + else if (hr == TYPE_E_TYPEMISMATCH) + typemismatch = 1; } } - TRACE("name not found %s\n", debugstr_w(szName)); - return S_OK; + if (typemismatch) + { + TRACE("type mismatch %s\n", debugstr_w(szName)); + return TYPE_E_TYPEMISMATCH; + } + else + { + TRACE("name not found %s\n", debugstr_w(szName)); + return S_OK; + } } static HRESULT WINAPI ITypeLibComp_fnBindType( @@ -5568,6 +5581,11 @@ static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface, return S_OK; } *pImplTypeFlags=0; + + if(This->TypeAttr.typekind==TKIND_DISPATCH && !index) + return S_OK; + + WARN("ImplType %d not found\n", index); return TYPE_E_ELEMENTNOTFOUND; } @@ -6052,9 +6070,6 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( hres = DISP_E_PARAMNOTFOUND; goto func_fail; } - /* ignore the DISPID_PROPERTYPUT named argument from now on */ - cNamedArgs--; - rgdispidNamedArgs++; } if (func_desc->cParamsOpt < 0 && cNamedArgs) @@ -6092,7 +6107,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( USHORT j; src_arg = NULL; for (j = 0; j < cNamedArgs; j++) - if (rgdispidNamedArgs[j] == i) + if (rgdispidNamedArgs[j] == i || (i == func_desc->cParams-1 && rgdispidNamedArgs[j] == DISPID_PROPERTYPUT)) { src_arg = &pDispParams->rgvarg[j]; break; @@ -6859,7 +6874,8 @@ static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid, BSTR *pBstrMops) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - FIXME("(%p) stub!\n", This); + FIXME("(%p %d) stub!\n", This, memid); + *pBstrMops = NULL; return S_OK; } diff --git a/reactos/dll/win32/oleaut32/typelib2.c b/reactos/dll/win32/oleaut32/typelib2.c index 4544317a512..6b1aea062ba 100644 --- a/reactos/dll/win32/oleaut32/typelib2.c +++ b/reactos/dll/win32/oleaut32/typelib2.c @@ -199,9 +199,11 @@ typedef struct tagICreateTypeInfo2Impl struct tagCyclicList *typedata; /* tail of cyclic list */ + TYPEKIND typekind; int datawidth; struct tagICreateTypeInfo2Impl *next_typeinfo; + struct tagICreateTypeInfo2Impl *dual; } ICreateTypeInfo2Impl; static inline ICreateTypeInfo2Impl *impl_from_ITypeInfo2( ITypeInfo2 *iface ) @@ -1177,6 +1179,7 @@ static HRESULT ctl2_add_default_value( { VARIANT v; HRESULT hres; + int mask = 0; TRACE("%p %d %d\n", This, V_VT(value), arg_type); @@ -1194,7 +1197,6 @@ static HRESULT ctl2_add_default_value( /* Check if default value can be stored in encoded_value */ switch(arg_type) { - int mask = 0; case VT_I4: case VT_UI4: mask = 0x3ffffff; @@ -1313,7 +1315,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface( if(*ppvObject) { - ICreateTypeLib2_AddRef(iface); + ICreateTypeInfo2_AddRef(iface); TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); return S_OK; } @@ -1333,6 +1335,9 @@ static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface) TRACE("(%p)->ref was %u\n",This, ref - 1); + if(ref==1 && This->typelib) + ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This->typelib); + return ref; } @@ -1406,43 +1411,63 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U TRACE("(%p,0x%x)\n", iface, uTypeFlags); - This->typeinfo->flags = uTypeFlags; + if(uTypeFlags & TYPEFLAG_FDUAL) { + This->typeinfo->typekind |= 0x10; + This->typeinfo->typekind &= ~0x0f; + This->typeinfo->typekind |= TKIND_DISPATCH; + + if(!This->dual) { + This->dual = HeapAlloc(GetProcessHeap(), 0, sizeof(ICreateTypeInfo2Impl)); + if(!This->dual) + return E_OUTOFMEMORY; + + memcpy(This->dual, This, sizeof(ICreateTypeInfo2Impl)); + This->dual->ref = 0; + This->dual->typekind = This->typekind==TKIND_DISPATCH ? + TKIND_INTERFACE : TKIND_DISPATCH; + This->dual->dual = This; + } + + /* Make sure dispatch is in typeinfos queue */ + if(This->typekind != TKIND_DISPATCH) { + if(This->typelib->last_typeinfo == This) + This->typelib->last_typeinfo = This->dual; + + if(This->typelib->typeinfos == This) + This->typelib->typeinfos = This->dual; + else { + ICreateTypeInfo2Impl *iter; + + for(iter=This->typelib->typeinfos; iter->next_typeinfo!=This; iter=iter->next_typeinfo); + iter->next_typeinfo = This->dual; + } + } else + iface = (ICreateTypeInfo2*)&This->dual->lpVtbl; + } + + if (uTypeFlags & (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL)) { + static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 }; + ITypeLib *stdole; + ITypeInfo *dispatch; + HREFTYPE hreftype; + HRESULT hres; + + hres = LoadTypeLib(stdole2tlb, &stdole); + if(FAILED(hres)) + return hres; + + hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch); + ITypeLib_Release(stdole); + if(FAILED(hres)) + return hres; - if (uTypeFlags & TYPEFLAG_FDISPATCHABLE) { - MSFT_GuidEntry foo; - int guidoffset; - int fileoffset; - MSFT_ImpInfo impinfo; - static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 }; - - foo.guid = IID_StdOle; - foo.hreftype = 2; - foo.next_hash = -1; - guidoffset = ctl2_alloc_guid(This->typelib, &foo); - if (guidoffset == -1) return E_OUTOFMEMORY; - - fileoffset = ctl2_alloc_importfile(This->typelib, guidoffset, - This->typelib->typelib_header.lcid2, 2, 0, stdole2tlb); - if (fileoffset == -1) return E_OUTOFMEMORY; - - foo.guid = IID_IDispatch; - foo.hreftype = 1; - foo.next_hash = -1; - guidoffset = ctl2_alloc_guid(This->typelib, &foo); - if (guidoffset == -1) return E_OUTOFMEMORY; - - impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID; - impinfo.oImpFile = fileoffset; - impinfo.oGuid = guidoffset; - ctl2_alloc_importinfo(This->typelib, &impinfo); - - This->typelib->typelib_header.dispatchpos = 1; - - This->typeinfo->typekind |= 0x10; - This->typeinfo->typekind &= ~0x0f; - This->typeinfo->typekind |= TKIND_DISPATCH; + hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype); + ITypeInfo_Release(dispatch); + if(FAILED(hres)) + return hres; } + This->typeinfo->flags = uTypeFlags; return S_OK; } @@ -1541,25 +1566,21 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( /* Process locally defined TypeInfo */ *phRefType = This->typelib->typelib_typeinfo_offsets[index]; } else { - static const WCHAR regkey[] = {'T','y','p','e','L','i','b','\\','{', - '%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%', - '0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x', - '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x', - '}','\\','%','d','.','%','d','\\','0','\\','w','i','n','3','2',0}; - - WCHAR name[MAX_PATH], *p; + BSTR name; TLIBATTR *tlibattr; TYPEATTR *typeattr; + TYPEKIND typekind; MSFT_GuidEntry guid, *check_guid; MSFT_ImpInfo impinfo; int guid_offset, import_offset; - DWORD len; HRESULT hres; /* Allocate container GUID */ hres = ITypeLib_GetLibAttr(container, &tlibattr); - if(FAILED(hres)) + if(FAILED(hres)) { + ITypeLib_Release(container); return hres; + } guid.guid = tlibattr->guid; guid.hreftype = This->typelib->typelib_guids*12+2; @@ -1568,6 +1589,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( guid_offset = ctl2_alloc_guid(This->typelib, &guid); if(guid_offset == -1) { ITypeLib_ReleaseTLibAttr(container, tlibattr); + ITypeLib_Release(container); return E_OUTOFMEMORY; } @@ -1576,50 +1598,50 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( This->typelib->typelib_guids++; /* Get import file name */ - /* Check HKEY_CLASSES_ROOT\TypeLib\{GUID}\{Ver}\0\win32 */ - len = MAX_PATH; - sprintfW(name, regkey, guid.guid.Data1, guid.guid.Data2, - guid.guid.Data3, guid.guid.Data4[0], guid.guid.Data4[1], - guid.guid.Data4[2], guid.guid.Data4[3], guid.guid.Data4[4], - guid.guid.Data4[5], guid.guid.Data4[6], guid.guid.Data4[7], - tlibattr->wMajorVerNum, tlibattr->wMinorVerNum); - - if(RegGetValueW(HKEY_CLASSES_ROOT, name, NULL, RRF_RT_REG_SZ, NULL, name, &len)!=ERROR_SUCCESS - || (p=strrchrW(name, '\\'))==NULL) { - ERR("Error guessing typelib filename\n"); + hres = QueryPathOfRegTypeLib(&guid.guid, tlibattr->wMajorVerNum, + tlibattr->wMinorVerNum, tlibattr->lcid, &name); + if(FAILED(hres)) { ITypeLib_ReleaseTLibAttr(container, tlibattr); - return E_NOTIMPL; + ITypeLib_Release(container); + return hres; } - memmove(name, p+1, strlenW(p)*sizeof(WCHAR)); /* Import file */ - import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, - tlibattr->lcid, tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, name); + import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, tlibattr->lcid, + tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, strrchrW(name, '\\')+1); ITypeLib_ReleaseTLibAttr(container, tlibattr); + SysFreeString(name); - if(import_offset == -1) + if(import_offset == -1) { + ITypeLib_Release(container); return E_OUTOFMEMORY; + } /* Allocate referenced guid */ hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr); - if(FAILED(hres)) + if(FAILED(hres)) { + ITypeLib_Release(container); return hres; + } guid.guid = typeattr->guid; guid.hreftype = This->typelib->typeinfo_guids*12+1; guid.next_hash = -1; + typekind = typeattr->typekind; ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr); guid_offset = ctl2_alloc_guid(This->typelib, &guid); - if(guid_offset == -1) + if(guid_offset == -1) { + ITypeLib_Release(container); return E_OUTOFMEMORY; + } check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset]; if(check_guid->hreftype == guid.hreftype) This->typelib->typeinfo_guids++; /* Allocate importinfo */ - impinfo.flags = ((This->typeinfo->typekind&0xf)<<24) | MSFT_IMPINFO_OFFSET_IS_GUID; + impinfo.flags = (typekind<<24) | MSFT_IMPINFO_OFFSET_IS_GUID; impinfo.oImpFile = import_offset; impinfo.oGuid = guid_offset; *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1; @@ -1652,7 +1674,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc); - if(!pFuncDesc || (pFuncDesc->memid>0x7fffffff && pFuncDesc->memid!=MEMBERID_NIL)) + if(!pFuncDesc || pFuncDesc->oVft&3) return E_INVALIDARG; TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, @@ -1661,7 +1683,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags); - switch(This->typeinfo->typekind&0xf) { + 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) return TYPE_E_BADMODULEKIND; @@ -1688,12 +1713,15 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( num_defaults++; if (!This->typedata) { - This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); if(!This->typedata) return E_OUTOFMEMORY; This->typedata->next = This->typedata; - This->typedata->u.val = 0; + This->typedata->u.val = 0; + + if(This->dual) + This->dual->typedata = This->typedata; } /* allocate type data space for us */ @@ -1711,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; @@ -1758,6 +1786,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( insert->next = This->typedata->next; This->typedata->next = insert; This->typedata = insert; + + if(This->dual) + This->dual->typedata = This->typedata; } else { iter = This->typedata->next; for(i=0; itypeinfo->typekind & 15) == TKIND_COCLASS) { + if (This->typekind == TKIND_COCLASS) { int offset; MSFT_RefRecord *ref; @@ -1822,21 +1853,26 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType( ref->flags = 0; ref->oCustData = -1; ref->onext = -1; - } else if ((This->typeinfo->typekind & 15) == TKIND_DISPATCH) { - FIXME("dispatch case unhandled.\n"); - } else if ((This->typeinfo->typekind & 15) == TKIND_INTERFACE) { + This->typeinfo->cImplTypes++; + } else if (This->typekind == TKIND_INTERFACE) { if (This->typeinfo->cImplTypes && index==1) return TYPE_E_BADMODULEKIND; if( index != 0) return TYPE_E_ELEMENTNOTFOUND; This->typeinfo->datatype1 = hRefType; + This->typeinfo->cImplTypes = 1; + } else if (This->typekind == TKIND_DISPATCH) { + if(index != 0) return TYPE_E_ELEMENTNOTFOUND; + + /* FIXME: Check if referenced typeinfo is IDispatch */ + This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE; + This->typeinfo->cImplTypes = 1; } else { - FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15); + FIXME("AddImplType unsupported on typekind %d\n", This->typekind); return E_OUTOFMEMORY; } - This->typeinfo->cImplTypes++; return S_OK; } @@ -1856,7 +1892,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags( TRACE("(%p,%d,0x%x)\n", iface, index, implTypeFlags); - if ((This->typeinfo->typekind & 15) != TKIND_COCLASS) { + if (This->typekind != TKIND_COCLASS) { return TYPE_E_BADMODULEKIND; } @@ -1889,7 +1925,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment( This->typeinfo->typekind |= cbAlignment << 6; /* FIXME: There's probably some way to simplify this. */ - switch (This->typeinfo->typekind & 15) { + switch (This->typekind) { case TKIND_ALIAS: default: break; @@ -1963,6 +1999,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( This->typedata->next = This->typedata; This->typedata->u.val = 0; + + if(This->dual) + This->dual->typedata = This->typedata; } /* allocate type data space for us */ @@ -1979,6 +2018,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( This->typedata->next = insert; This->typedata = insert; + if(This->dual) + This->dual->typedata = This->typedata; + This->typedata->next->u.val += 0x14; typedata = This->typedata->u.data; @@ -2003,6 +2045,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( /* add the new variable to the total data width */ This->datawidth += var_datawidth; + if(This->dual) + This->dual->datawidth = This->datawidth; /* add type description size to total required allocation */ typedata[3] += var_type_size << 16; @@ -2125,7 +2169,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; namedata[9] |= 0x10; } - if ((This->typeinfo->typekind & 15) == TKIND_ENUM) { + if (This->typekind == TKIND_ENUM) { namedata[9] |= 0x20; } @@ -2151,7 +2195,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias( int encoded_typedesc; int width; - if ((This->typeinfo->typekind & 15) != TKIND_ALIAS) { + if (This->typekind != TKIND_ALIAS) { return TYPE_E_WRONGTYPEKIND; } @@ -2225,8 +2269,42 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext( UINT index, DWORD dwHelpContext) { - FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpContext); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + CyclicList *func; + int *typedata; + int size; + + TRACE("(%p,%d,%d)\n", iface, index, dwHelpContext); + + if(This->typeinfo->cElementtypeinfo->cElement == index) + func = This->typedata; + else + for(func=This->typedata->next->next; func!=This->typedata; func=func->next) + if(index-- == 0) + break; + + typedata = func->u.data; + + /* Compute func size without arguments */ + size = typedata[0] - typedata[5]*(typedata[4]&0x1000?16:12); + + /* Allocate memory for HelpContext if needed */ + if(size < 7*sizeof(int)) { + typedata = HeapReAlloc(GetProcessHeap(), 0, typedata, typedata[0]+sizeof(int)); + if(!typedata) + return E_OUTOFMEMORY; + + memmove(&typedata[7], &typedata[6], typedata[0]-sizeof(int)*6); + typedata[0] += sizeof(int); + This->typedata->next->u.val += sizeof(int); + func->u.data = typedata; + } + + typedata[6] = dwHelpContext; + return S_OK; } /****************************************************************************** @@ -2282,11 +2360,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( CyclicList *iter, *iter2, **typedata; HREFTYPE hreftype; HRESULT hres; + unsigned user_vft = 0; int i; TRACE("(%p)\n", iface); - if((This->typeinfo->typekind&0xf) == TKIND_COCLASS) + /* FIXME: LayOut should be run on all ImplTypes */ + if(This->typekind == TKIND_COCLASS) return S_OK; /* Validate inheritance */ @@ -2317,15 +2397,17 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( return hres; hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur); + ITypeInfo_Release(next); if(FAILED(hres)) return hres; - ITypeInfo_Release(next); while(1) { hres = ITypeInfo_GetTypeAttr(cur, &typeattr); - if(FAILED(hres)) + if(FAILED(hres)) { + ITypeInfo_Release(cur); return hres; + } if(!memcmp(&typeattr->guid, &IID_IDispatch, sizeof(IDispatch))) This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE; @@ -2336,19 +2418,51 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype); if(hres == TYPE_E_ELEMENTNOTFOUND) break; - if(FAILED(hres)) + if(FAILED(hres)) { + ITypeInfo_Release(cur); return hres; + } hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next); - if(FAILED(hres)) + if(FAILED(hres)) { + ITypeInfo_Release(cur); return hres; + } ITypeInfo_Release(cur); cur = next; } + ITypeInfo_Release(cur); } - This->typeinfo->cbSizeVft = (This->typeinfo->datatype2>>16) * 4; + /* Get cbSizeVft of inherited interface */ + /* Makes LayOut running recursively */ + if(This->typeinfo->datatype1 != -1) { + ITypeInfo *cur, *inherited; + TYPEATTR *typeattr; + + hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&cur); + if(FAILED(hres)) + return hres; + + hres = ITypeInfo_GetRefTypeInfo(cur, This->typeinfo->datatype1, &inherited); + ITypeInfo_Release(cur); + if(FAILED(hres)) + return hres; + + hres = ITypeInfo_GetTypeAttr(inherited, &typeattr); + if(FAILED(hres)) { + ITypeInfo_Release(inherited); + return hres; + } + + This->typeinfo->cbSizeVft = typeattr->cbSizeVft; + + ITypeInfo_ReleaseTypeAttr(inherited, typeattr); + ITypeInfo_Release(inherited); + } else + This->typeinfo->cbSizeVft = 0; + if(!This->typedata) return S_OK; @@ -2358,6 +2472,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) { @@ -2370,8 +2487,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { if(iter == iter2) continue; - if(iter2->indice == iter->indice) + if(iter2->indice == iter->indice) { + HeapFree(GetProcessHeap(), 0, typedata); return E_ACCESSDENIED; + } } break; @@ -2383,7 +2502,20 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16); - if((This->typeinfo->typekind&0xf) != TKIND_MODULE) { + if((iter->u.data[3]&1) != (user_vft&1)) { + HeapFree(GetProcessHeap(), 0, typedata); + 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) { + HeapFree(GetProcessHeap(), 0, typedata); + 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; } @@ -2406,6 +2538,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; @@ -2787,11 +2922,13 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid; (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size; - (*ppTypeAttr)->typekind = This->typeinfo->typekind&0xf; + (*ppTypeAttr)->typekind = This->typekind; (*ppTypeAttr)->cFuncs = This->typeinfo->cElement&0xffff; + if(This->typeinfo->flags&TYPEFLAG_FDUAL && This->typekind==TKIND_DISPATCH) + (*ppTypeAttr)->cFuncs += 7; (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16; (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes; - (*ppTypeAttr)->cbSizeVft = This->typeinfo->cbSizeVft; + (*ppTypeAttr)->cbSizeVft = This->typekind==TKIND_DISPATCH ? 28 : This->typeinfo->cbSizeVft; (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f; (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags; (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff; @@ -2879,15 +3016,21 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType( if(!pRefType) return E_INVALIDARG; - if(index == -1) { - FIXME("Dual interfaces not handled yet\n"); - return E_NOTIMPL; + if(This->typeinfo->flags&TYPEFLAG_FDUAL) { + if(index == -1) { + *pRefType = -2; + return S_OK; + } + + if(This->typekind == TKIND_DISPATCH) + return ITypeInfo2_GetRefTypeOfImplType((ITypeInfo2*)&This->dual->lpVtblTypeInfo2, + index, pRefType); } - if(index >= This->typeinfo->cImplTypes) + if(index>=This->typeinfo->cImplTypes) return TYPE_E_ELEMENTNOTFOUND; - if((This->typeinfo->typekind&0xf) == TKIND_INTERFACE) { + if(This->typekind == TKIND_INTERFACE) { *pRefType = This->typeinfo->datatype1 + 2; return S_OK; } @@ -2923,7 +3066,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags( if(index >= This->typeinfo->cImplTypes) return TYPE_E_ELEMENTNOTFOUND; - if((This->typeinfo->typekind&0xf) != TKIND_COCLASS) { + if(This->typekind != TKIND_COCLASS) { *pImplTypeFlags = 0; return S_OK; } @@ -3022,6 +3165,12 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( if(!ppTInfo) return E_INVALIDARG; + if(hRefType==-2 && This->dual) { + *ppTInfo = (ITypeInfo*)&This->dual->lpVtblTypeInfo2; + ITypeInfo_AddRef(*ppTInfo); + return S_OK; + } + if(hRefType&1) { ITypeLib *tl; MSFT_ImpInfo *impinfo; @@ -3124,7 +3273,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib( TRACE("(%p,%p,%p)\n", iface, ppTLib, pIndex); *ppTLib = (ITypeLib *)&This->typelib->lpVtblTypeLib2; - This->typelib->ref++; + ICreateTypeLib_AddRef((ICreateTypeLib*)This->typelib); *pIndex = This->typeinfo->typekind >> 16; return S_OK; @@ -3573,7 +3722,7 @@ static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typel pCreateTypeInfo2Impl->ref = 1; pCreateTypeInfo2Impl->typelib = typelib; - typelib->ref++; + ICreateTypeLib_AddRef((ICreateTypeLib*)typelib); nameoffset = ctl2_alloc_name(typelib, szName); typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset); @@ -3584,6 +3733,7 @@ static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typel pCreateTypeInfo2Impl->typeinfo = typeinfo; + pCreateTypeInfo2Impl->typekind = tkind; typeinfo->typekind |= tkind | 0x20; ICreateTypeInfo2_SetAlignment((ICreateTypeInfo2 *)pCreateTypeInfo2Impl, 4); @@ -3717,7 +3867,9 @@ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) HeapFree(GetProcessHeap(), 0, rem); } } - HeapFree(GetProcessHeap(), 0, typeinfo); + + HeapFree(GetProcessHeap(), 0, typeinfo->dual); + HeapFree(GetProcessHeap(), 0, typeinfo); } HeapFree(GetProcessHeap(),0,This); -- 2.17.1