Piotr Caban : oleaut32: Added partial ICreateTypeInfo2_AddFuncDesc arguments with default values handling .
Alexandre Julliard
julliard at winehq.org
Tue Feb 23 11:17:21 CST 2010
Module: wine
Branch: master
Commit: 4f555e3cc2a7875af59b8331d97c562df44f76a5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4f555e3cc2a7875af59b8331d97c562df44f76a5
Author: Piotr Caban <piotr at 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;
More information about the wine-cvs
mailing list