oleaut32: Implement ICreateTypeInfo::AddFuncDesc.

This commit is contained in:
Andrew Eikum 2013-05-28 17:00:29 -05:00 committed by Alexandre Julliard
parent 8c6984ab7a
commit 479ffebf40
1 changed files with 148 additions and 8 deletions

View File

@ -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,