[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