Andrew Eikum : oleaut32: Implement ICreateTypeInfo::AddFuncDesc.

Alexandre Julliard julliard at winehq.org
Wed May 29 14:47:33 CDT 2013


Module: wine
Branch: master
Commit: 479ffebf40ab43fc32df90ef41a4606f9c63c6e1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=479ffebf40ab43fc32df90ef41a4606f9c63c6e1

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Tue May 28 17:00:29 2013 -0500

oleaut32: Implement ICreateTypeInfo::AddFuncDesc.

---

 dlls/oleaut32/typelib.c |  156 ++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 148 insertions(+), 8 deletions(-)

diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 827b6b4..9b84c06 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -1697,7 +1697,12 @@ static TLBParDesc *TLBParDesc_Constructor(UINT n)
     return ret;
 }
 
-static TLBFuncDesc *TLBFuncDesc_Constructor(UINT n)
+static void TLBFuncDesc_Constructor(TLBFuncDesc *func_desc)
+{
+    list_init(&func_desc->custdata_list);
+}
+
+static TLBFuncDesc *TLBFuncDesc_Alloc(UINT n)
 {
     TLBFuncDesc *ret;
 
@@ -1706,7 +1711,7 @@ static TLBFuncDesc *TLBFuncDesc_Constructor(UINT n)
         return NULL;
 
     while(n){
-        list_init(&ret[n-1].custdata_list);
+        TLBFuncDesc_Constructor(&ret[n-1]);
         --n;
     }
 
@@ -2093,7 +2098,7 @@ MSFT_DoFuncs(TLBContext*     pcx,
 
     MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);
 
-    *pptfd = TLBFuncDesc_Constructor(cFuncs);
+    *pptfd = TLBFuncDesc_Alloc(cFuncs);
     ptfd = *pptfd;
     for ( i = 0; i < cFuncs ; i++ )
     {
@@ -3725,7 +3730,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
     unsigned short i;
     TLBFuncDesc *pFuncDesc;
 
-    pTI->funcdescs = TLBFuncDesc_Constructor(cFuncs);
+    pTI->funcdescs = TLBFuncDesc_Alloc(cFuncs);
 
     pFuncDesc = pTI->funcdescs;
     for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs && pFunc != (SLTG_Function*)0xFFFF;
@@ -5339,6 +5344,27 @@ static HRESULT TLB_CopyElemDesc( const ELEMDESC *src, ELEMDESC *dest, char **buf
     return S_OK;
 }
 
+static HRESULT TLB_SanitizeBSTR(BSTR str)
+{
+    UINT len = SysStringLen(str), i;
+    for (i = 0; i < len; ++i)
+        if (str[i] > 0x7f)
+            str[i] = '?';
+    return S_OK;
+}
+
+static HRESULT TLB_SanitizeVariant(VARIANT *var)
+{
+    if (V_VT(var) == VT_INT)
+        return VariantChangeType(var, var, 0, VT_I4);
+    else if (V_VT(var) == VT_UINT)
+        return VariantChangeType(var, var, 0, VT_UI4);
+    else if (V_VT(var) == VT_BSTR)
+        return TLB_SanitizeBSTR(V_BSTR(var));
+
+    return S_OK;
+}
+
 static void TLB_FreeElemDesc( ELEMDESC *elemdesc )
 {
     if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
@@ -5369,6 +5395,8 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt
         dest->funckind = FUNC_DISPATCH;
     buffer = (char *)(dest + 1);
 
+    dest->oVft = dest->oVft & 0xFFFC;
+
     if (dest->cScodes) {
         dest->lprgscode = (SCODE *)buffer;
         memcpy(dest->lprgscode, src->lprgscode, sizeof(*src->lprgscode) * src->cScodes);
@@ -6713,7 +6741,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                 if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
             }
 
-            hres = DispCallFunc(pIUnk, func_desc->oVft, func_desc->callconv,
+            hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, func_desc->callconv,
                                 V_VT(&varresult), func_desc->cParams, rgvt,
                                 prgpvarg, &varresult);
 
@@ -7885,7 +7913,7 @@ HRESULT WINAPI CreateDispTypeInfo(
     pTIIface->TypeAttr.wTypeFlags = 0;
     pTIIface->hreftype = 0;
 
-    pTIIface->funcdescs = TLBFuncDesc_Constructor(pidata->cMembers);
+    pTIIface->funcdescs = TLBFuncDesc_Alloc(pidata->cMembers);
     pFuncDesc = pTIIface->funcdescs;
     for(func = 0; func < pidata->cMembers; func++) {
         METHODDATA *md = pidata->pmethdata + func;
@@ -8578,8 +8606,120 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface,
         UINT index, FUNCDESC *funcDesc)
 {
     ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
-    FIXME("%p %u %p - stub\n", This, index, funcDesc);
-    return E_NOTIMPL;
+    TLBFuncDesc tmp_func_desc, *func_desc;
+    int buf_size, i;
+    char *buffer;
+    HRESULT hres;
+
+    TRACE("%p %u %p\n", This, index, funcDesc);
+
+    if (!funcDesc || funcDesc->oVft & 3)
+        return E_INVALIDARG;
+
+    switch (This->TypeAttr.typekind) {
+    case TKIND_MODULE:
+        if (funcDesc->funckind != FUNC_STATIC)
+            return TYPE_E_BADMODULEKIND;
+        break;
+    case TKIND_DISPATCH:
+        if (funcDesc->funckind != FUNC_DISPATCH)
+            return TYPE_E_BADMODULEKIND;
+        break;
+    default:
+        if (funcDesc->funckind != FUNC_PUREVIRTUAL)
+            return TYPE_E_BADMODULEKIND;
+    }
+
+    if (index > This->TypeAttr.cFuncs)
+        return TYPE_E_ELEMENTNOTFOUND;
+
+    if (funcDesc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF) &&
+            !funcDesc->cParams)
+        return TYPE_E_INCONSISTENTPROPFUNCS;
+
+    memset(&tmp_func_desc, 0, sizeof(tmp_func_desc));
+    TLBFuncDesc_Constructor(&tmp_func_desc);
+
+    tmp_func_desc.funcdesc = *funcDesc;
+
+    if (tmp_func_desc.funcdesc.oVft != 0)
+        tmp_func_desc.funcdesc.oVft |= 1;
+
+    if (funcDesc->cScodes) {
+        tmp_func_desc.funcdesc.lprgscode = heap_alloc(sizeof(SCODE) * funcDesc->cScodes);
+        memcpy(tmp_func_desc.funcdesc.lprgscode, funcDesc->lprgscode, sizeof(SCODE) * funcDesc->cScodes);
+    } else
+        tmp_func_desc.funcdesc.lprgscode = NULL;
+
+    buf_size = TLB_SizeElemDesc(&funcDesc->elemdescFunc);
+    for (i = 0; i < funcDesc->cParams; ++i) {
+        buf_size += sizeof(ELEMDESC);
+        buf_size += TLB_SizeElemDesc(funcDesc->lprgelemdescParam + i);
+    }
+    tmp_func_desc.funcdesc.lprgelemdescParam = heap_alloc(buf_size);
+    buffer = (char*)(tmp_func_desc.funcdesc.lprgelemdescParam + funcDesc->cParams);
+
+    hres = TLB_CopyElemDesc(&funcDesc->elemdescFunc, &tmp_func_desc.funcdesc.elemdescFunc, &buffer);
+    if (FAILED(hres)) {
+        heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
+        heap_free(tmp_func_desc.funcdesc.lprgscode);
+        return hres;
+    }
+
+    for (i = 0; i < funcDesc->cParams; ++i) {
+        hres = TLB_CopyElemDesc(funcDesc->lprgelemdescParam + i,
+                tmp_func_desc.funcdesc.lprgelemdescParam + i, &buffer);
+        if (FAILED(hres)) {
+            heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
+            heap_free(tmp_func_desc.funcdesc.lprgscode);
+            return hres;
+        }
+        if (tmp_func_desc.funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT &&
+                tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_VARIANT &&
+                tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED){
+            hres = TLB_SanitizeVariant(&tmp_func_desc.funcdesc.lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
+            if (FAILED(hres)) {
+                heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
+                heap_free(tmp_func_desc.funcdesc.lprgscode);
+                return hres;
+            }
+        }
+    }
+
+    tmp_func_desc.pParamDesc = TLBParDesc_Constructor(funcDesc->cParams);
+
+    if (This->funcdescs) {
+        This->funcdescs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->funcdescs,
+                sizeof(TLBFuncDesc) * (This->TypeAttr.cFuncs + 1));
+
+        if (index < This->TypeAttr.cFuncs) {
+            memmove(This->funcdescs + index + 1, This->funcdescs + index,
+                    (This->TypeAttr.cFuncs - index) * sizeof(TLBFuncDesc));
+            func_desc = This->funcdescs + index;
+        } else
+            func_desc = This->funcdescs + This->TypeAttr.cFuncs;
+
+        /* move custdata lists to the new memory location */
+        for(i = 0; i < This->TypeAttr.cFuncs + 1; ++i){
+            if(index != i){
+                TLBFuncDesc *fd = &This->funcdescs[i];
+                if(fd->custdata_list.prev == fd->custdata_list.next)
+                    list_init(&fd->custdata_list);
+                else{
+                    fd->custdata_list.prev->next = &fd->custdata_list;
+                    fd->custdata_list.next->prev = &fd->custdata_list;
+                }
+            }
+        }
+    } else
+        func_desc = This->funcdescs = heap_alloc(sizeof(TLBFuncDesc));
+
+    memcpy(func_desc, &tmp_func_desc, sizeof(tmp_func_desc));
+    list_init(&func_desc->custdata_list);
+
+    ++This->TypeAttr.cFuncs;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface,




More information about the wine-cvs mailing list