oleaut32: Fixes and tests for CreateDispTypeInfo.

CreateDispTypeInfo returns the typeinfo of a coclass which implements
the described interface.
This commit is contained in:
Huw Davies 2006-02-06 20:57:09 +01:00 committed by Alexandre Julliard
parent 7660614b0d
commit 7000aca824
2 changed files with 240 additions and 41 deletions

View File

@ -19,6 +19,8 @@
*/
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include <wine/test.h>
#include <stdarg.h>
@ -213,9 +215,157 @@ static void test_TypeComp(void)
ITypeLib_Release(pTypeLib);
}
static void test_CreateDispTypeInfo(void)
{
ITypeInfo *pTypeInfo, *pTI2;
HRESULT hr;
INTERFACEDATA ifdata;
METHODDATA methdata[4];
PARAMDATA parms1[2];
PARAMDATA parms3[1];
TYPEATTR *pTypeAttr;
HREFTYPE href;
FUNCDESC *pFuncDesc;
static const WCHAR func1[] = {'f','u','n','c','1',0};
static const WCHAR func2[] = {'f','u','n','c','2',0};
static const WCHAR func3[] = {'f','u','n','c','3',0};
static const WCHAR parm1[] = {'p','a','r','m','1',0};
static const WCHAR parm2[] = {'p','a','r','m','2',0};
ifdata.pmethdata = methdata;
ifdata.cMembers = sizeof(methdata) / sizeof(methdata[0]);
methdata[0].szName = SysAllocString(func1);
methdata[0].ppdata = parms1;
methdata[0].dispid = 0x123;
methdata[0].iMeth = 0;
methdata[0].cc = CC_STDCALL;
methdata[0].cArgs = 2;
methdata[0].wFlags = DISPATCH_METHOD;
methdata[0].vtReturn = VT_HRESULT;
parms1[0].szName = SysAllocString(parm1);
parms1[0].vt = VT_I4;
parms1[1].szName = SysAllocString(parm2);
parms1[1].vt = VT_BSTR;
methdata[1].szName = SysAllocString(func2);
methdata[1].ppdata = NULL;
methdata[1].dispid = 0x124;
methdata[1].iMeth = 1;
methdata[1].cc = CC_STDCALL;
methdata[1].cArgs = 0;
methdata[1].wFlags = DISPATCH_PROPERTYGET;
methdata[1].vtReturn = VT_I4;
methdata[2].szName = SysAllocString(func3);
methdata[2].ppdata = parms3;
methdata[2].dispid = 0x125;
methdata[2].iMeth = 3;
methdata[2].cc = CC_STDCALL;
methdata[2].cArgs = 1;
methdata[2].wFlags = DISPATCH_PROPERTYPUT;
methdata[2].vtReturn = VT_HRESULT;
parms3[0].szName = SysAllocString(parm1);
parms3[0].vt = VT_I4;
methdata[3].szName = SysAllocString(func3);
methdata[3].ppdata = NULL;
methdata[3].dispid = 0x125;
methdata[3].iMeth = 4;
methdata[3].cc = CC_STDCALL;
methdata[3].cArgs = 0;
methdata[3].wFlags = DISPATCH_PROPERTYGET;
methdata[3].vtReturn = VT_I4;
hr = CreateDispTypeInfo(&ifdata, LOCALE_NEUTRAL, &pTypeInfo);
ok(hr == S_OK, "hr %08lx\n", hr);
hr = ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
ok(hr == S_OK, "hr %08lx\n", hr);
ok(pTypeAttr->typekind == TKIND_COCLASS, "typekind %0x\n", pTypeAttr->typekind);
ok(pTypeAttr->cImplTypes == 1, "cImplTypes %d\n", pTypeAttr->cImplTypes);
ok(pTypeAttr->cFuncs == 0, "cFuncs %d\n", pTypeAttr->cFuncs);
ok(pTypeAttr->wTypeFlags == 0, "wTypeFlags %04x\n", pTypeAttr->cFuncs);
ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
hr = ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &href);
ok(hr == S_OK, "hr %08lx\n", hr);
hr = ITypeInfo_GetRefTypeInfo(pTypeInfo, href, &pTI2);
ok(hr == S_OK, "hr %08lx\n", hr);
hr = ITypeInfo_GetTypeAttr(pTI2, &pTypeAttr);
ok(hr == S_OK, "hr %08lx\n", hr);
ok(pTypeAttr->typekind == TKIND_INTERFACE, "typekind %0x\n", pTypeAttr->typekind);
ITypeInfo_ReleaseTypeAttr(pTI2, pTypeAttr);
hr = ITypeInfo_GetFuncDesc(pTI2, 0, &pFuncDesc);
ok(hr == S_OK, "hr %08lx\n", hr);
ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
ok(pFuncDesc->invkind == methdata[0].wFlags, "invkind %d\n", pFuncDesc->invkind);
ok(pFuncDesc->callconv == methdata[0].cc, "callconv %d\n", pFuncDesc->callconv);
ok(pFuncDesc->cParams == methdata[0].cArgs, "cParams %d\n", pFuncDesc->cParams);
ok(pFuncDesc->oVft == 0, "oVft %d\n", pFuncDesc->oVft);
ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
ok(pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags);
ok(pFuncDesc->lprgelemdescParam[1].tdesc.vt == VT_BSTR, "parm 1 vt %x\n", pFuncDesc->lprgelemdescParam[1].tdesc.vt);
ok(pFuncDesc->lprgelemdescParam[1].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 1 flags %x\n", pFuncDesc->lprgelemdescParam[1].u.paramdesc.wParamFlags);
ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
hr = ITypeInfo_GetFuncDesc(pTI2, 1, &pFuncDesc);
ok(hr == S_OK, "hr %08lx\n", hr);
ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
ok(pFuncDesc->invkind == methdata[1].wFlags, "invkind %d\n", pFuncDesc->invkind);
ok(pFuncDesc->callconv == methdata[1].cc, "callconv %d\n", pFuncDesc->callconv);
ok(pFuncDesc->cParams == methdata[1].cArgs, "cParams %d\n", pFuncDesc->cParams);
ok(pFuncDesc->oVft == 4, "oVft %d\n", pFuncDesc->oVft);
ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
hr = ITypeInfo_GetFuncDesc(pTI2, 2, &pFuncDesc);
ok(hr == S_OK, "hr %08lx\n", hr);
ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
ok(pFuncDesc->invkind == methdata[2].wFlags, "invkind %d\n", pFuncDesc->invkind);
ok(pFuncDesc->callconv == methdata[2].cc, "callconv %d\n", pFuncDesc->callconv);
ok(pFuncDesc->cParams == methdata[2].cArgs, "cParams %d\n", pFuncDesc->cParams);
ok(pFuncDesc->oVft == 12, "oVft %d\n", pFuncDesc->oVft);
ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
ok(pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags);
ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
hr = ITypeInfo_GetFuncDesc(pTI2, 3, &pFuncDesc);
ok(hr == S_OK, "hr %08lx\n", hr);
ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
ok(pFuncDesc->invkind == methdata[3].wFlags, "invkind %d\n", pFuncDesc->invkind);
ok(pFuncDesc->callconv == methdata[3].cc, "callconv %d\n", pFuncDesc->callconv);
ok(pFuncDesc->cParams == methdata[3].cArgs, "cParams %d\n", pFuncDesc->cParams);
ok(pFuncDesc->oVft == 16, "oVft %d\n", pFuncDesc->oVft);
ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
ITypeInfo_Release(pTI2);
ITypeInfo_Release(pTypeInfo);
SysFreeString(parms1[0].szName);
SysFreeString(parms1[1].szName);
SysFreeString(parms3[0].szName);
SysFreeString(methdata[0].szName);
SysFreeString(methdata[1].szName);
SysFreeString(methdata[2].szName);
SysFreeString(methdata[3].szName);
}
START_TEST(typelib)
{
static const WCHAR type_lib_stdole32[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0};
ref_count_test(type_lib_stdole32);
test_TypeComp();
test_CreateDispTypeInfo();
}

View File

@ -2314,6 +2314,20 @@ int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
/*================== ITypeLib(2) Methods ===================================*/
static ITypeLibImpl* TypeLibImpl_Constructor(void)
{
ITypeLibImpl* pTypeLibImpl;
pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
if (!pTypeLibImpl) return NULL;
pTypeLibImpl->lpVtbl = &tlbvt;
pTypeLibImpl->lpVtblTypeComp = &tlbtcvt;
pTypeLibImpl->ref = 1;
return pTypeLibImpl;
}
/****************************************************************************
* ITypeLib2_Constructor_MSFT
*
@ -2329,13 +2343,9 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength);
pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
pTypeLibImpl = TypeLibImpl_Constructor();
if (!pTypeLibImpl) return NULL;
pTypeLibImpl->lpVtbl = &tlbvt;
pTypeLibImpl->lpVtblTypeComp = &tlbtcvt;
pTypeLibImpl->ref = 1;
/* get pointer to beginning of typelib data */
cx.pos = 0;
cx.oStart=0;
@ -3155,11 +3165,9 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
TRACE_(typelib)("%p, TLB length = %ld\n", pLib, dwTLBLength);
pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
if (!pTypeLibImpl) return NULL;
pTypeLibImpl->lpVtbl = &tlbvt;
pTypeLibImpl->ref = 1;
pTypeLibImpl = TypeLibImpl_Constructor();
if (!pTypeLibImpl) return NULL;
pHeader = pLib;
@ -3475,13 +3483,16 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
if (!ref)
{
/* remove cache entry */
TRACE("removing from cache list\n");
EnterCriticalSection(&cache_section);
if (This->next) This->next->prev = This->prev;
if (This->prev) This->prev->next = This->next;
else tlb_cache_first = This->next;
LeaveCriticalSection(&cache_section);
if(This->path)
{
TRACE("removing from cache list\n");
EnterCriticalSection(&cache_section);
if (This->next) This->next->prev = This->prev;
if (This->prev) This->prev->next = This->next;
else tlb_cache_first = This->next;
LeaveCriticalSection(&cache_section);
HeapFree(GetProcessHeap(), 0, This->path);
}
/* FIXME destroy child objects */
TRACE(" destroying ITypeLib(%p)\n",This);
@ -6368,44 +6379,49 @@ HRESULT WINAPI CreateDispTypeInfo(
LCID lcid, /* [I] Locale Id */
ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
{
ITypeInfoImpl *pTIImpl;
ITypeInfoImpl *pTIClass, *pTIIface;
ITypeLibImpl *pTypeLibImpl;
int param, func;
TLBFuncDesc **ppFuncDesc;
pTIImpl = (ITypeInfoImpl*)ITypeInfo_Constructor();
pTIImpl->pTypeLib = NULL;
pTIImpl->index = 0;
pTIImpl->Name = NULL;
pTIImpl->dwHelpContext = -1;
memset(&pTIImpl->TypeAttr.guid, 0, sizeof(GUID));
pTIImpl->TypeAttr.lcid = lcid;
pTIImpl->TypeAttr.typekind = TKIND_COCLASS;
pTIImpl->TypeAttr.wMajorVerNum = 0;
pTIImpl->TypeAttr.wMinorVerNum = 0;
pTIImpl->TypeAttr.cbAlignment = 2;
pTIImpl->TypeAttr.cbSizeInstance = -1;
pTIImpl->TypeAttr.cbSizeVft = -1;
pTIImpl->TypeAttr.cFuncs = 0;
pTIImpl->TypeAttr.cImplTypes = 1;
pTIImpl->TypeAttr.cVars = 0;
pTIImpl->TypeAttr.wTypeFlags = 0;
TRACE_(typelib)("\n");
pTypeLibImpl = TypeLibImpl_Constructor();
if (!pTypeLibImpl) return E_FAIL;
ppFuncDesc = &pTIImpl->funclist;
pTIIface = (ITypeInfoImpl*)ITypeInfo_Constructor();
pTIIface->pTypeLib = pTypeLibImpl;
pTIIface->index = 0;
pTIIface->Name = NULL;
pTIIface->dwHelpContext = -1;
memset(&pTIIface->TypeAttr.guid, 0, sizeof(GUID));
pTIIface->TypeAttr.lcid = lcid;
pTIIface->TypeAttr.typekind = TKIND_INTERFACE;
pTIIface->TypeAttr.wMajorVerNum = 0;
pTIIface->TypeAttr.wMinorVerNum = 0;
pTIIface->TypeAttr.cbAlignment = 2;
pTIIface->TypeAttr.cbSizeInstance = -1;
pTIIface->TypeAttr.cbSizeVft = -1;
pTIIface->TypeAttr.cFuncs = 0;
pTIIface->TypeAttr.cImplTypes = 0;
pTIIface->TypeAttr.cVars = 0;
pTIIface->TypeAttr.wTypeFlags = 0;
ppFuncDesc = &pTIIface->funclist;
for(func = 0; func < pidata->cMembers; func++) {
METHODDATA *md = pidata->pmethdata + func;
*ppFuncDesc = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppFuncDesc));
(*ppFuncDesc)->Name = SysAllocString(md->szName);
(*ppFuncDesc)->funcdesc.memid = md->dispid;
(*ppFuncDesc)->funcdesc.funckind = FUNC_DISPATCH;
(*ppFuncDesc)->funcdesc.funckind = FUNC_VIRTUAL;
(*ppFuncDesc)->funcdesc.invkind = md->wFlags;
(*ppFuncDesc)->funcdesc.callconv = md->cc;
(*ppFuncDesc)->funcdesc.cParams = md->cArgs;
(*ppFuncDesc)->funcdesc.cParamsOpt = 0;
(*ppFuncDesc)->funcdesc.oVft = md->iMeth;
(*ppFuncDesc)->funcdesc.wFuncFlags = 0; /*??*/
(*ppFuncDesc)->funcdesc.oVft = md->iMeth << 2;
(*ppFuncDesc)->funcdesc.wFuncFlags = 0;
(*ppFuncDesc)->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
(*ppFuncDesc)->funcdesc.elemdescFunc.u.paramdesc.wParamFlags = PARAMFLAG_NONE;
(*ppFuncDesc)->funcdesc.elemdescFunc.u.paramdesc.pparamdescex = NULL;
(*ppFuncDesc)->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
(*ppFuncDesc)->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
md->cArgs * sizeof(ELEMDESC));
(*ppFuncDesc)->pParamDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
@ -6422,8 +6438,41 @@ HRESULT WINAPI CreateDispTypeInfo(
(*ppFuncDesc)->pCustData = NULL;
(*ppFuncDesc)->next = NULL;
ppFuncDesc = &(*ppFuncDesc)->next;
}
*pptinfo = (ITypeInfo*)pTIImpl;
}
pTypeLibImpl->pTypeInfo = pTIIface;
pTypeLibImpl->TypeInfoCount++;
pTIClass = (ITypeInfoImpl*)ITypeInfo_Constructor();
pTIClass->pTypeLib = pTypeLibImpl;
pTIClass->index = 1;
pTIClass->Name = NULL;
pTIClass->dwHelpContext = -1;
memset(&pTIClass->TypeAttr.guid, 0, sizeof(GUID));
pTIClass->TypeAttr.lcid = lcid;
pTIClass->TypeAttr.typekind = TKIND_COCLASS;
pTIClass->TypeAttr.wMajorVerNum = 0;
pTIClass->TypeAttr.wMinorVerNum = 0;
pTIClass->TypeAttr.cbAlignment = 2;
pTIClass->TypeAttr.cbSizeInstance = -1;
pTIClass->TypeAttr.cbSizeVft = -1;
pTIClass->TypeAttr.cFuncs = 0;
pTIClass->TypeAttr.cImplTypes = 1;
pTIClass->TypeAttr.cVars = 0;
pTIClass->TypeAttr.wTypeFlags = 0;
pTIClass->impltypelist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pTIClass->impltypelist));
pTIClass->impltypelist->hRef = 1;
pTIClass->reflist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pTIClass->reflist));
pTIClass->reflist->index = 0;
pTIClass->reflist->reference = 1;
pTIClass->reflist->pImpTLInfo = TLB_REF_INTERNAL;
pTIIface->next = pTIClass;
pTypeLibImpl->TypeInfoCount++;
*pptinfo = (ITypeInfo*)pTIClass;
return S_OK;
}