diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index b31466e0f56..797ac022929 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 59f431e06d3..3a92badaa16 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;