From 7000aca824780255f9342c5e645eac1f76b5a71a Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Mon, 6 Feb 2006 20:57:09 +0100 Subject: [PATCH] oleaut32: Fixes and tests for CreateDispTypeInfo. CreateDispTypeInfo returns the typeinfo of a coclass which implements the described interface. --- dlls/oleaut32/tests/typelib.c | 150 ++++++++++++++++++++++++++++++++++ dlls/oleaut32/typelib.c | 131 +++++++++++++++++++---------- 2 files changed, 240 insertions(+), 41 deletions(-) diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index ecaf5974fe6..b5e4fadda1b 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -19,6 +19,8 @@ */ #define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT #include #include @@ -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(); } diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index bf4a21b4591..8791736e429 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -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; }