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