[PATCH 2/4] oleaut32: Implement ICreateTypeInfo::SetTypeDescAlias

Andrew Eikum aeikum at codeweavers.com
Tue Aug 20 09:57:01 CDT 2013


---
 dlls/oleaut32/tests/typelib.c | 100 ++++++++++++++++++++++++++++++++++++++++--
 dlls/oleaut32/typelib.c       |  81 +++++++++++++++++++++++-----------
 dlls/oleaut32/variant.c       |  10 ++---
 dlls/oleaut32/variant.h       |   1 +
 4 files changed, 159 insertions(+), 33 deletions(-)

diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index d12181c..d800047 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -1514,6 +1514,7 @@ static void test_CreateTypeLib(SYSKIND sys) {
     static OLECHAR param1W[] = {'p','a','r','a','m','1',0};
     static OLECHAR param2W[] = {'p','a','r','a','m','2',0};
     static OLECHAR asdfW[] = {'A','s','d','f',0};
+    static OLECHAR aliasW[] = {'a','l','i','a','s',0};
     static OLECHAR *names1[] = {func1W, param1W, param2W};
     static OLECHAR *names2[] = {func2W, param1W, param2W};
     static OLECHAR *propname[] = {prop1W, param1W};
@@ -2506,6 +2507,9 @@ static void test_CreateTypeLib(SYSKIND sys) {
 
     ITypeInfo_Release(ti);
 
+    hres = ICreateTypeInfo_SetTypeDescAlias(createti, &typedesc1);
+    ok(hres == TYPE_E_BADMODULEKIND, "got %08x\n", hres);
+
     ICreateTypeInfo_Release(createti);
 
     hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
@@ -2541,12 +2545,82 @@ static void test_CreateTypeLib(SYSKIND sys) {
 
     ITypeInfo_ReleaseTypeAttr(interface2, typeattr);
 
-    hres = ICreateTypeLib2_SaveAllChanges(createtl);
-    ok(hres == S_OK, "got %08x\n", hres);
-
     ok(ITypeInfo_Release(interface2)==0, "Object should be freed\n");
     ok(ITypeInfo_Release(interface1)==0, "Object should be freed\n");
     ok(ITypeInfo_Release(dual)==0, "Object should be freed\n");
+
+    hres = ICreateTypeLib2_CreateTypeInfo(createtl, aliasW, TKIND_ALIAS, &createti);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&interface1);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    if(0){
+        /* windows gives invalid values here, and even breaks the typeinfo permanently
+         * on winxp. only call GetTypeAttr() on a TKIND_ALIAS after SetTypeDescAlias. */
+        hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
+        ok(hres == S_OK, "got %08x\n", hres);
+        ok(typeattr->cbSizeInstance == 0xffffffb4, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
+        ok(typeattr->typekind == TKIND_ALIAS, "typekind = %d\n", typeattr->typekind);
+        ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
+        ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
+        ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
+        ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
+        ok(typeattr->cbAlignment == 0, "cbAlignment = %d\n", typeattr->cbAlignment);
+        ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
+        ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
+        ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
+        ok(typeattr->tdescAlias.vt == VT_EMPTY, "Got wrong tdescAlias.vt: %u\n", typeattr->tdescAlias.vt);
+        ITypeInfo_ReleaseTypeAttr(interface1, typeattr);
+    }
+
+    hres = ICreateTypeInfo_SetTypeDescAlias(createti, NULL);
+    ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
+    typedesc1.vt = VT_BSTR;
+    hres = ICreateTypeInfo_SetTypeDescAlias(createti, &typedesc1);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
+    ok(hres == S_OK, "got %08x\n", hres);
+    ok(typeattr->cbSizeInstance == ptr_size, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
+    ok(typeattr->typekind == TKIND_ALIAS, "typekind = %d\n", typeattr->typekind);
+    ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
+    ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
+    ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
+    ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
+    ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
+    ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
+    ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
+    ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
+    ok(typeattr->tdescAlias.vt == VT_BSTR, "Got wrong tdescAlias.vt: %u\n", typeattr->tdescAlias.vt);
+    ITypeInfo_ReleaseTypeAttr(interface1, typeattr);
+
+    typedesc1.vt = VT_R8;
+    hres = ICreateTypeInfo_SetTypeDescAlias(createti, &typedesc1);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
+    ok(hres == S_OK, "got %08x\n", hres);
+    ok(typeattr->cbSizeInstance == 8, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
+    ok(typeattr->typekind == TKIND_ALIAS, "typekind = %d\n", typeattr->typekind);
+    ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
+    ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
+    ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
+    ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
+    ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
+    ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
+    ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
+    ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
+    ok(typeattr->tdescAlias.vt == VT_R8, "Got wrong tdescAlias.vt: %u\n", typeattr->tdescAlias.vt);
+    ITypeInfo_ReleaseTypeAttr(interface1, typeattr);
+
+    ITypeInfo_Release(interface1);
+    ICreateTypeInfo_Release(createti);
+
+    hres = ICreateTypeLib2_SaveAllChanges(createtl);
+    ok(hres == S_OK, "got %08x\n", hres);
+
     ok(ICreateTypeLib2_Release(createtl)==0, "Object should be freed\n");
 
     ok(ITypeInfo_Release(dispatch)==0, "Object should be freed\n");
@@ -3372,6 +3446,26 @@ static void test_CreateTypeLib(SYSKIND sys) {
 
     ok(ITypeInfo_Release(ti) == 0, "Object should be freed\n");
 
+    hres = ITypeLib_GetTypeInfo(tl, 5, &ti);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
+    ok(hres == S_OK, "got %08x\n", hres);
+    ok(typeattr->cbSizeInstance == 8, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
+    ok(typeattr->typekind == TKIND_ALIAS, "typekind = %d\n", typeattr->typekind);
+    ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
+    ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
+    ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
+    ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
+    ok(typeattr->cbAlignment == alignment, "cbAlignment = %d\n", typeattr->cbAlignment);
+    ok(typeattr->wTypeFlags == 0, "wTypeFlags = 0x%x\n", typeattr->wTypeFlags);
+    ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
+    ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
+    ok(typeattr->tdescAlias.vt == VT_R8, "Got wrong tdescAlias.vt: %u\n", typeattr->tdescAlias.vt);
+    ITypeInfo_ReleaseTypeAttr(ti, typeattr);
+
+    ok(ITypeInfo_Release(ti) == 0, "Object should be freed\n");
+
     ok(ITypeLib_Release(tl)==0, "Object should be freed\n");
 
     DeleteFileA(filename);
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index b396f17..65fe47a 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -1160,7 +1160,7 @@ typedef struct tagITypeInfoImpl
     WORD wTypeFlags;
     WORD wMajorVerNum;
     WORD wMinorVerNum;
-    TYPEDESC tdescAlias;
+    TYPEDESC *tdescAlias;
     IDLDESC idldescType;
 
     ITypeLibImpl * pTypeLib;        /* back pointer to typelib */
@@ -2217,8 +2217,7 @@ static int MSFT_CustData( TLBContext *pcx, int offset, struct list *custdata_lis
     return count;
 }
 
-static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd,
-			  ITypeInfoImpl *pTI)
+static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd)
 {
     if(type <0)
         pTd->vt=type & VT_TYPEMASK;
@@ -2350,8 +2349,7 @@ MSFT_DoFuncs(TLBContext*     pcx,
 
         MSFT_GetTdesc(pcx,
 		      pFuncRec->DataType,
-		      &ptfd->funcdesc.elemdescFunc.tdesc,
-		      pTI);
+		      &ptfd->funcdesc.elemdescFunc.tdesc);
 
         /* do the parameters/arguments */
         if(pFuncRec->nrargs)
@@ -2373,8 +2371,7 @@ MSFT_DoFuncs(TLBContext*     pcx,
 
                 MSFT_GetTdesc(pcx,
 			      paraminfo.DataType,
-			      &elemdesc->tdesc,
-			      pTI);
+			      &elemdesc->tdesc);
 
                 elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags;
 
@@ -2478,7 +2475,7 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
         ptvd->vardesc.varkind = pVarRec->VarKind;
         ptvd->vardesc.wVarFlags = pVarRec->Flags;
         MSFT_GetTdesc(pcx, pVarRec->DataType,
-            &ptvd->vardesc.elemdescVar.tdesc, pTI);
+            &ptvd->vardesc.elemdescVar.tdesc);
 /*   ptvd->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
         if(pVarRec->VarKind == VAR_CONST ){
             ptvd->vardesc.u.lpvarValue = heap_alloc_zero(sizeof(VARIANT));
@@ -2554,9 +2551,12 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
     ptiRet->wMinorVerNum=HIWORD(tiBase.version);
     ptiRet->cImplTypes=tiBase.cImplTypes;
     ptiRet->cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
-    if(ptiRet->typekind == TKIND_ALIAS)
-        MSFT_GetTdesc(pcx, tiBase.datatype1,
-            &ptiRet->tdescAlias, ptiRet);
+    if(ptiRet->typekind == TKIND_ALIAS){
+        TYPEDESC tmp;
+        MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
+        ptiRet->tdescAlias = heap_alloc(TLB_SizeTypeDesc(&tmp, TRUE));
+        TLB_CopyTypeDesc(NULL, &tmp, ptiRet->tdescAlias);
+    }
 
 /*  FIXME: */
 /*    IDLDESC  idldescType; *//* never saw this one != zero  */
@@ -4154,9 +4154,10 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
   sltg_ref_lookup_t *ref_lookup = NULL;
 
   if (pTITail->simple_alias) {
-    /* if simple alias, no more processing required */
-    pTI->tdescAlias.vt = pTITail->tdescalias_vt;
-    return;
+      /* if simple alias, no more processing required */
+      pTI->tdescAlias = heap_alloc_zero(sizeof(TYPEDESC));
+      pTI->tdescAlias->vt = pTITail->tdescalias_vt;
+      return;
   }
 
   if(pTIHeader->href_table != 0xffffffff) {
@@ -4167,7 +4168,8 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
   /* otherwise it is an offset to a type */
   pType = (WORD *)(pBlk + pTITail->tdescalias_vt);
 
-  SLTG_DoType(pType, pBlk, &pTI->tdescAlias, ref_lookup);
+  pTI->tdescAlias = heap_alloc(sizeof(TYPEDESC));
+  SLTG_DoType(pType, pBlk, pTI->tdescAlias, ref_lookup);
 
   heap_free(ref_lookup);
 }
@@ -4646,8 +4648,10 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
           heap_free(ref_type);
       }
 
-      for (i = 0; i < This->TypeInfoCount; ++i)
+      for (i = 0; i < This->TypeInfoCount; ++i){
+          heap_free(This->typeinfos[i]->tdescAlias);
           ITypeInfoImpl_Destroy(This->typeinfos[i]);
+      }
       heap_free(This->typeinfos);
       heap_free(This);
       return 0;
@@ -5524,8 +5528,8 @@ static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
     TRACE("(%p)\n",This);
 
     size = sizeof(**ppTypeAttr);
-    if (This->typekind == TKIND_ALIAS)
-        size += TLB_SizeTypeDesc(&This->tdescAlias, FALSE);
+    if (This->typekind == TKIND_ALIAS && This->tdescAlias)
+        size += TLB_SizeTypeDesc(This->tdescAlias, FALSE);
 
     *ppTypeAttr = heap_alloc(size);
     if (!*ppTypeAttr)
@@ -5546,12 +5550,15 @@ static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
     (*ppTypeAttr)->wTypeFlags = This->wTypeFlags;
     (*ppTypeAttr)->wMajorVerNum = This->wMajorVerNum;
     (*ppTypeAttr)->wMinorVerNum = This->wMinorVerNum;
-    (*ppTypeAttr)->tdescAlias = This->tdescAlias;
     (*ppTypeAttr)->idldescType = This->idldescType;
 
-    if (This->typekind == TKIND_ALIAS)
+    if (This->tdescAlias)
         TLB_CopyTypeDesc(&(*ppTypeAttr)->tdescAlias,
-            &This->tdescAlias, *ppTypeAttr + 1);
+            This->tdescAlias, *ppTypeAttr + 1);
+    else{
+        (*ppTypeAttr)->tdescAlias.vt = VT_EMPTY;
+        (*ppTypeAttr)->tdescAlias.u.lptdesc = NULL;
+    }
 
     if((*ppTypeAttr)->typekind == TKIND_DISPATCH) {
         /* This should include all the inherited funcs */
@@ -8968,14 +8975,18 @@ static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *o
     INT16 junk2;
     DWORD offs = 0;
     DWORD encoded[2];
-    VARTYPE vt = desc->vt & VT_TYPEMASK, subtype;
+    VARTYPE vt, subtype;
     char *data;
 
+    if(!desc)
+        return -1;
+
     if(!out_mix)
         out_mix = &junk;
     if(!out_size)
         out_size = &junk2;
 
+    vt = desc->vt & VT_TYPEMASK;
     switch(vt){
     case VT_INT:
         subtype = VT_I4;
@@ -9465,7 +9476,7 @@ static DWORD WMSFT_compile_typeinfo(ITypeInfoImpl *info, INT16 index, WMSFT_TLBF
         if(info->typekind == TKIND_COCLASS){
             base->datatype1 = WMSFT_compile_typeinfo_ref(info, file);
         }else if(info->typekind == TKIND_ALIAS){
-            base->datatype1 = WMSFT_append_typedesc(&info->tdescAlias, file, NULL, NULL);
+            base->datatype1 = WMSFT_append_typedesc(info->tdescAlias, file, NULL, NULL);
         }else if(info->typekind == TKIND_MODULE){
             if(info->DllName)
                 base->datatype1 = info->DllName->offset;
@@ -10530,8 +10541,28 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(ICreateTypeInfo2 *ifac
         TYPEDESC *tdescAlias)
 {
     ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
-    FIXME("%p %p - stub\n", This, tdescAlias);
-    return E_NOTIMPL;
+
+    TRACE("%p %p\n", This, tdescAlias);
+
+    if(!tdescAlias)
+        return E_INVALIDARG;
+
+    if(This->typekind != TKIND_ALIAS)
+        return TYPE_E_BADMODULEKIND;
+
+    heap_free(This->tdescAlias);
+    This->tdescAlias = heap_alloc(TLB_SizeTypeDesc(tdescAlias, TRUE));
+    TLB_CopyTypeDesc(NULL, tdescAlias, This->tdescAlias);
+
+    This->cbSizeInstance = VARIANT_DataSize(This->tdescAlias->vt, This->pTypeLib->ptr_size);
+    if(!This->cbSizeInstance){
+        FIXME("Wrong size for variant type! 0x%x\n", This->tdescAlias->vt);
+        This->cbSizeInstance = 4;
+    }
+
+    This->cbAlignment = 4;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(ICreateTypeInfo2 *iface,
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index c343578..0c25c27 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -801,9 +801,9 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
 }
 
 /* Return the byte size of a variants data */
-static inline size_t VARIANT_DataSize(const VARIANT* pv)
+size_t VARIANT_DataSize(VARTYPE t, size_t ptr_size)
 {
-  switch (V_TYPE(pv))
+  switch (t)
   {
   case VT_I1:
   case VT_UI1:   return sizeof(BYTE);
@@ -821,11 +821,11 @@ static inline size_t VARIANT_DataSize(const VARIANT* pv)
   case VT_BOOL:  return sizeof(VARIANT_BOOL);
   case VT_DISPATCH:
   case VT_UNKNOWN:
-  case VT_BSTR:  return sizeof(void*);
+  case VT_BSTR:  return ptr_size;
   case VT_CY:    return sizeof(CY);
   case VT_ERROR: return sizeof(SCODE);
   }
-  TRACE("Shouldn't be called for vt %s%s!\n", debugstr_VT(pv), debugstr_VF(pv));
+  TRACE("Can't size vt 0x%x!\n", t);
   return 0;
 }
 
@@ -942,7 +942,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
   else
   {
     /* Copy the pointed to data into this variant */
-    memcpy(&V_BYREF(pvargDest), V_BYREF(pSrc), VARIANT_DataSize(pSrc));
+    memcpy(&V_BYREF(pvargDest), V_BYREF(pSrc), VARIANT_DataSize(V_TYPE(pSrc), sizeof(void*)));
   }
 
   V_VT(pvargDest) = V_VT(pSrc) & ~VT_BYREF;
diff --git a/dlls/oleaut32/variant.h b/dlls/oleaut32/variant.h
index 765c0c4..2fad53f 100644
--- a/dlls/oleaut32/variant.h
+++ b/dlls/oleaut32/variant.h
@@ -129,3 +129,4 @@ BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *) DECLSPEC_HIDDEN;
 HRESULT VARIANT_ClearInd(VARIANTARG *) DECLSPEC_HIDDEN;
 BOOL get_date_format(LCID, DWORD, const SYSTEMTIME *,
         const WCHAR *, WCHAR *, int) DECLSPEC_HIDDEN;
+size_t VARIANT_DataSize(VARTYPE, size_t) DECLSPEC_HIDDEN;
-- 
1.8.3.4





More information about the wine-patches mailing list