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 = &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);
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