Commit 4f555e3c authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

oleaut32: Added partial ICreateTypeInfo2_AddFuncDesc arguments with default values handling.

parent 324984ef
......@@ -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 = &paramdescex;
V_VT(&paramdescex.varDefaultValue) = VT_INT;
V_INT(&paramdescex.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 = &paramdescex;
V_VT(&paramdescex.varDefaultValue) = VT_UI2;
V_UI2(&paramdescex.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);
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment