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