Module: wine Branch: master Commit: 4f555e3cc2a7875af59b8331d97c562df44f76a5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4f555e3cc2a7875af59b8331d9...
Author: Piotr Caban piotr@codeweavers.com Date: Mon Feb 22 23:11:57 2010 +0100
oleaut32: Added partial ICreateTypeInfo2_AddFuncDesc arguments with default values handling.
---
dlls/oleaut32/tests/typelib.c | 32 ++++++++-- dlls/oleaut32/typelib2.c | 136 +++++++++++++++++++++++++++++++++-------- 2 files changed, 137 insertions(+), 31 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index e75d320..b9bb396 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -977,7 +977,8 @@ static void test_CreateTypeLib(void) { ICreateTypeInfo *createti; ITypeLib *tl; FUNCDESC funcdesc; - ELEMDESC elemdesc; + ELEMDESC elemdesc[5]; + PARAMDESCEX paramdescex; HRESULT hres;
trace("CreateTypeLib tests\n"); @@ -1018,11 +1019,11 @@ static void test_CreateTypeLib(void) { hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc); ok(hres == TYPE_E_INCONSISTENTPROPFUNCS, "got %08x\n", hres);
- elemdesc.tdesc.vt = VT_BSTR; - elemdesc.idldesc.dwReserved = 0; - elemdesc.idldesc.wIDLFlags = IDLFLAG_FIN; + elemdesc[0].tdesc.vt = VT_BSTR; + elemdesc[0].idldesc.dwReserved = 0; + elemdesc[0].idldesc.wIDLFlags = IDLFLAG_FIN;
- funcdesc.lprgelemdescParam = &elemdesc; + funcdesc.lprgelemdescParam = elemdesc; funcdesc.invkind = INVOKE_PROPERTYPUT; funcdesc.cParams = 1; funcdesc.elemdescFunc.tdesc.vt = VT_VOID; @@ -1045,6 +1046,27 @@ static void test_CreateTypeLib(void) { hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc); ok(hres == S_OK, "got %08x\n", hres);
+ elemdesc[0].tdesc.vt = VT_INT; + elemdesc[0].paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT; + elemdesc[0].paramdesc.pparamdescex = ¶mdescex; + V_VT(¶mdescex.varDefaultValue) = VT_INT; + V_INT(¶mdescex.varDefaultValue) = 0x123; + funcdesc.lprgelemdescParam = elemdesc; + funcdesc.cParams = 1; + hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc); + ok(hres == S_OK, "got %08x\n", hres); + + elemdesc[0].idldesc.dwReserved = 0; + elemdesc[0].idldesc.wIDLFlags = IDLFLAG_FIN; + elemdesc[1].tdesc.vt = VT_UI2; + elemdesc[1].paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT; + elemdesc[1].paramdesc.pparamdescex = ¶mdescex; + V_VT(¶mdescex.varDefaultValue) = VT_UI2; + V_UI2(¶mdescex.varDefaultValue) = 0xffff; + funcdesc.cParams = 2; + hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc); + ok(hres == S_OK, "got %08x\n", hres); + ICreateTypeInfo_Release(createti);
hres = ICreateTypeLib_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti); diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c index e1a36b2..41b7891 100644 --- a/dlls/oleaut32/typelib2.c +++ b/dlls/oleaut32/typelib2.c @@ -1109,6 +1109,64 @@ static HRESULT ctl2_find_typeinfo_from_offset( return TYPE_E_ELEMENTNOTFOUND; }
+/**************************************************************************** + * ctl2_add_default_value + * + * Adds default value of an argument + * + * RETURNS + * + * Success: S_OK + * Failure: Error code from winerror.h + */ +static HRESULT ctl2_add_default_value( + ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */ + int *encoded_value, /* [O] The encoded default value or data offset */ + VARIANT *value, /* [I] Default value to be encoded */ + VARTYPE arg_type) /* [I] Argument type */ +{ + VARIANT v; + HRESULT hres; + + TRACE("%p %d %d\n", This, V_VT(value), arg_type); + + if(arg_type == VT_INT) + arg_type = VT_I4; + if(arg_type == VT_UINT) + arg_type = VT_UI4; + + v = *value; + if(V_VT(value) != arg_type) { + hres = VariantChangeType(&v, value, 0, arg_type); + if(FAILED(hres)) + return hres; + } + + /* Check if default value can be stored in encoded_value */ + switch(arg_type) { + int mask = 0; + case VT_I4: + case VT_UI4: + mask = 0x3ffffff; + if(V_UI4(&v)>0x3ffffff) + break; + case VT_I1: + case VT_UI1: + case VT_BOOL: + if(!mask) + mask = 0xff; + case VT_I2: + case VT_UI2: + if(!mask) + mask = 0xffff; + *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24); + return S_OK; + } + + FIXME("default values not implemented\n"); + return S_OK; +} + /*================== ICreateTypeInfo2 Implementation ===================================*/
/****************************************************************************** @@ -1384,8 +1442,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
CyclicList *iter, *insert; int *typedata; - int i; + int i, num_defaults = 0; int decoded_size; + HRESULT hres;
TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);
@@ -1419,6 +1478,11 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( !pFuncDesc->cParams) return TYPE_E_INCONSISTENTPROPFUNCS;
+ /* get number of arguments with default values specified */ + for (i = 0; i < pFuncDesc->cParams; i++) + if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) + num_defaults++; + if (!This->typedata) { This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); if(!This->typedata) @@ -1432,56 +1496,76 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); if(!insert) return E_OUTOFMEMORY; - insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[6])+sizeof(int[3])*pFuncDesc->cParams); + insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[6])+sizeof(int[(num_defaults?4:3)])*pFuncDesc->cParams); if(!insert->u.data) { HeapFree(GetProcessHeap(), 0, insert); return E_OUTOFMEMORY; }
- /* insert type data to list */ - if(index == This->typeinfo->cElement) { - insert->next = This->typedata->next; - This->typedata->next = insert; - This->typedata = insert; - } else { - iter = This->typedata->next; - for(i=0; i<index; i++) - iter = iter->next; - - insert->next = iter->next; - iter->next = insert; - } - - /* update type data size */ - This->typedata->next->u.val += 0x18 + (pFuncDesc->cParams * 12); - /* fill out the basic type information */ typedata = insert->u.data; - typedata[0] = 0x18 + pFuncDesc->cParams * 12; + 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[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind; + if(num_defaults) typedata[4] |= 0x1000; typedata[5] = pFuncDesc->cParams;
/* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16; + typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16; + + /* add default values */ + if(num_defaults) { + for (i = 0; i < pFuncDesc->cParams; i++) + if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) { + hres = ctl2_add_default_value(This->typelib, typedata+6+i, + &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue, + pFuncDesc->lprgelemdescParam[i].tdesc.vt); + + if(FAILED(hres)) { + HeapFree(GetProcessHeap(), 0, insert->u.data); + HeapFree(GetProcessHeap(), 0, insert); + return hres; + } + } else + typedata[6+i] = 0xffffffff; + + num_defaults = pFuncDesc->cParams; + }
+ /* add arguments */ for (i = 0; i < pFuncDesc->cParams; i++) { - ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc, &typedata[6+(i*3)], NULL, NULL, &decoded_size); - typedata[7+(i*3)] = -1; - typedata[8+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags; + ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc, + &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size); + typedata[7+num_defaults+(i*3)] = -1; + typedata[8+num_defaults+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags; typedata[3] += decoded_size << 16; - - if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) - FIXME("default values not implemented\n"); }
/* update the index data */ insert->indice = (This->typeinfo->cImplTypes << 16) | pFuncDesc->memid; insert->name = -1;
+ /* insert type data to list */ + if(index == This->typeinfo->cElement) { + insert->next = This->typedata->next; + This->typedata->next = insert; + This->typedata = insert; + } else { + iter = This->typedata->next; + for(i=0; i<index; i++) + iter = iter->next; + + insert->next = iter->next; + iter->next = insert; + } + + /* update type data size */ + This->typedata->next->u.val += 0x18 + pFuncDesc->cParams*(num_defaults?16:12); + /* Increment the number of function elements */ This->typeinfo->cElement += 1;