ole: CreateDispTypeInfo
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Mon Feb 6 06:07:31 CST 2006
Huw Davies <huw at codeweavers.com>
ole: Fixes and tests for CreateDispTypeInfo.
CreateDispTypeInfo returns the typeinfo of a coclass which implements
the described interface.
--
Huw Davies
huw at codeweavers.com
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index ecaf597..b5e4fad 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -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();
}
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index bf4a21b..8791736 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -2314,6 +2314,20 @@ int TLB_ReadTypeLib(LPCWSTR pszFileName,
/*================== 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_
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_
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(
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;
+
+ 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 = &pTIImpl->funclist;
+ 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;
}
More information about the wine-patches
mailing list