From 810ec233c0bffe4a4bd0cac4e36c1f72b9079190 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Mon, 26 Aug 2013 12:40:08 -0500 Subject: [PATCH] oleaut32: Implement ICreateTypeInfo::SetTypeDescAlias. --- dlls/oleaut32/tests/typelib.c | 341 +++++++++++++++++++++++++++++++++- dlls/oleaut32/typelib.c | 82 +++++--- 2 files changed, 393 insertions(+), 30 deletions(-) diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index 5e15564c9d3..bc759c0f17b 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -1538,6 +1538,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}; @@ -2530,6 +2531,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); @@ -2565,12 +2569,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_I1; + 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 == 1, "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 == 1, "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_I1, "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"); @@ -3396,6 +3470,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); @@ -4587,6 +4681,245 @@ if (hr == S_OK) pReleaseActCtx(handle); } +#define AUX_HREF 1 +#define AUX_TDESC 2 +#define AUX_ADESC 3 +static struct _TDATest { + VARTYPE vt; + ULONG size; /* -1 == typelib ptr size */ + WORD align; + WORD align3264; /* for 32-bit typelibs loaded in 64-bit mode */ + DWORD aux; + TYPEDESC tdesc; + ARRAYDESC adesc; +} TDATests[] = { + { VT_I2, 2, 2, 2 }, + { VT_I4, 4, 4, 4 }, + { VT_R4, 4, 4, 4 }, + { VT_R8, 8, 4, 8 }, + { VT_CY, 8, 4, 8 }, + { VT_DATE, 8, 4, 8 }, + { VT_BSTR, -1, 4, 8 }, + { VT_DISPATCH, -1, 4, 8 }, + { VT_ERROR, 4, 4, 4 }, + { VT_BOOL, 2, 2, 2 }, + { VT_VARIANT, 0 /* see code below */, 4, 8 }, + { VT_UNKNOWN, -1, 4, 8 }, + { VT_DECIMAL, 16, 4, 8 }, + { VT_I1, 1, 1, 1 }, + { VT_UI1, 1, 1, 1 }, + { VT_UI2, 2, 2, 2 }, + { VT_UI4, 4, 4, 4 }, + { VT_I8, 8, 4, 8 }, + { VT_UI8, 8, 4, 8 }, + { VT_INT, 4, 4, 4 }, + { VT_UINT, 4, 4, 4 }, + { VT_VOID, 0, 0, 0 }, + { VT_HRESULT, 4, 4, 4 }, + { VT_PTR, -1, 4, 8, AUX_TDESC, { { 0 }, VT_INT } }, + { VT_SAFEARRAY, -1, 4, 8, AUX_TDESC, { { 0 }, VT_INT } }, + { VT_CARRAY, 16 /* == 4 * sizeof(int) */, 4, 4, AUX_ADESC, { { 0 } }, { { { 0 }, VT_INT }, 1, { { 4, 0 } } } }, + { VT_USERDEFINED, 0, 0, 0, AUX_HREF }, + { VT_LPSTR, -1, 4, 8 }, + { VT_LPWSTR, -1, 4, 8 }, + { 0 } +}; + +static void testTDA(ITypeLib *tl, struct _TDATest *TDATest, + ULONG ptr_size, HREFTYPE hreftype, ULONG href_cbSizeInstance, + WORD href_cbAlignment, BOOL create) +{ + TYPEDESC tdesc; + WCHAR nameW[32]; + ITypeInfo *ti; + ICreateTypeInfo *cti; + ICreateTypeLib2 *ctl; + ULONG size; + WORD alignment; + TYPEATTR *typeattr; + HRESULT hr; + + static const WCHAR name_fmtW[] = {'a','l','i','a','s','%','0','2','u',0}; + + wsprintfW(nameW, name_fmtW, TDATest->vt); + + if(create){ + hr = ITypeLib_QueryInterface(tl, &IID_ICreateTypeLib2, (void**)&ctl); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_CreateTypeInfo(ctl, nameW, TKIND_ALIAS, &cti); + ok(hr == S_OK, "got %08x\n", hr); + + tdesc.vt = TDATest->vt; + if(TDATest->aux == AUX_TDESC) + U(tdesc).lptdesc = &TDATest->tdesc; + else if(TDATest->aux == AUX_ADESC) + U(tdesc).lpadesc = &TDATest->adesc; + else if(TDATest->aux == AUX_HREF) + U(tdesc).hreftype = hreftype; + + hr = ICreateTypeInfo_SetTypeDescAlias(cti, &tdesc); + ok(hr == S_OK, "for VT %u, got %08x\n", TDATest->vt, hr); + + hr = ICreateTypeInfo_QueryInterface(cti, &IID_ITypeInfo, (void**)&ti); + ok(hr == S_OK, "got %08x\n", hr); + + ICreateTypeInfo_Release(cti); + ICreateTypeLib2_Release(ctl); + }else{ + USHORT found = 1; + MEMBERID memid; + + hr = ITypeLib_FindName(tl, nameW, 0, &ti, &memid, &found); + ok(hr == S_OK, "for VT %u, got %08x\n", TDATest->vt, hr); + } + + hr = ITypeInfo_GetTypeAttr(ti, &typeattr); + ok(hr == S_OK, "got %08x\n", hr); + + if(TDATest->aux == AUX_HREF){ + size = href_cbSizeInstance; + alignment = href_cbAlignment; + }else{ + size = TDATest->size; + if(size == -1){ + if(create) + size = ptr_size; + else + size = sizeof(void*); + }else if(TDATest->vt == VT_VARIANT){ + if(create){ + size = sizeof(VARIANT); +#ifdef _WIN64 + if(ptr_size != sizeof(void*)) + size -= 8; /* 32-bit variant is 4 bytes smaller than 64-bit variant */ +#endif + }else + size = sizeof(VARIANT); + } + alignment = TDATest->align; +#ifdef _WIN64 + if(!create && ptr_size != sizeof(void*)) + alignment = TDATest->align3264; +#endif + } + + ok(typeattr->cbSizeInstance == size || + broken(TDATest->vt == VT_VARIANT && ptr_size != sizeof(void*) && typeattr->cbSizeInstance == sizeof(VARIANT)) /* winxp64 */, + "got wrong size for VT %u: 0x%x\n", TDATest->vt, typeattr->cbSizeInstance); + ok(typeattr->cbAlignment == alignment, "got wrong alignment for VT %u: 0x%x\n", TDATest->vt, typeattr->cbAlignment); + ok(typeattr->tdescAlias.vt == TDATest->vt, "got wrong VT for VT %u: 0x%x\n", TDATest->vt, typeattr->tdescAlias.vt); + + switch(TDATest->aux){ + case AUX_HREF: + ok(U(typeattr->tdescAlias).hreftype == hreftype, "got wrong hreftype for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).hreftype); + break; + case AUX_TDESC: + ok(U(typeattr->tdescAlias).lptdesc->vt == TDATest->tdesc.vt, "got wrong typedesc VT for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lptdesc->vt); + break; + case AUX_ADESC: + ok(U(typeattr->tdescAlias).lpadesc->tdescElem.vt == TDATest->adesc.tdescElem.vt, "got wrong arraydesc element VT for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lpadesc->tdescElem.vt); + ok(U(typeattr->tdescAlias).lpadesc->cDims == TDATest->adesc.cDims, "got wrong arraydesc dimension count for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lpadesc->cDims); + ok(U(typeattr->tdescAlias).lpadesc->rgbounds[0].cElements == TDATest->adesc.rgbounds[0].cElements, "got wrong arraydesc element count for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lpadesc->rgbounds[0].cElements); + ok(U(typeattr->tdescAlias).lpadesc->rgbounds[0].lLbound == TDATest->adesc.rgbounds[0].lLbound, "got wrong arraydesc lower bound for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lpadesc->rgbounds[0].lLbound); + break; + } + + ITypeInfo_Release(ti); +} + +static void test_SetTypeDescAlias(SYSKIND kind) +{ + CHAR filenameA[MAX_PATH]; + WCHAR filenameW[MAX_PATH]; + ITypeLib *tl; + ICreateTypeLib2 *ctl; + ITypeInfo *ti; + ICreateTypeInfo *cti; + HREFTYPE hreftype; + TYPEATTR *typeattr; + ULONG href_cbSizeInstance, i; + WORD href_cbAlignment, ptr_size; + HRESULT hr; + + static OLECHAR interfaceW[] = {'i','n','t','e','r','f','a','c','e',0}; + + switch(kind){ + case SYS_WIN32: + trace("testing SYS_WIN32\n"); + ptr_size = 4; + break; + case SYS_WIN64: + trace("testing SYS_WIN64\n"); + ptr_size = 8; + break; + default: + return; + } + + GetTempFileNameA(".", "tlb", 0, filenameA); + MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH); + + hr = CreateTypeLib2(kind, filenameW, &ctl); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_CreateTypeInfo(ctl, interfaceW, TKIND_INTERFACE, &cti); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_QueryInterface(cti, &IID_ITypeInfo, (void**)&ti); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_AddRefTypeInfo(cti, ti, &hreftype); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ITypeInfo_GetTypeAttr(ti, &typeattr); + ok(hr == S_OK, "got %08x\n", hr); + + href_cbSizeInstance = typeattr->cbSizeInstance; + href_cbAlignment = typeattr->cbAlignment; + + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + + ITypeInfo_Release(ti); + ICreateTypeInfo_Release(cti); + + hr = ICreateTypeLib2_QueryInterface(ctl, &IID_ITypeLib, (void**)&tl); + ok(hr == S_OK, "got %08x\n", hr); + + for(i = 0; TDATests[i].vt; ++i) + testTDA(tl, &TDATests[i], ptr_size, hreftype, href_cbSizeInstance, href_cbAlignment, TRUE); + + hr = ICreateTypeLib2_SaveAllChanges(ctl); + ok(hr == S_OK, "got %08x\n", hr); + + ITypeLib_Release(tl); + ok(0 == ICreateTypeLib2_Release(ctl), "typelib should have been released"); + + trace("after save...\n"); + + hr = LoadTypeLibEx(filenameW, REGKIND_NONE, &tl); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ITypeLib_GetTypeInfo(tl, 0, &ti); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ITypeInfo_GetTypeAttr(ti, &typeattr); + ok(hr == S_OK, "got %08x\n", hr); + + href_cbSizeInstance = typeattr->cbSizeInstance; + href_cbAlignment = typeattr->cbAlignment; + + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + ITypeInfo_Release(ti); + + for(i = 0; TDATests[i].vt; ++i) + testTDA(tl, &TDATests[i], ptr_size, hreftype, href_cbSizeInstance, href_cbAlignment, FALSE); + + ok(0 == ITypeLib_Release(tl), "typelib should have been released"); + + DeleteFileA(filenameA); +} + START_TEST(typelib) { const char *filename; @@ -4602,8 +4935,10 @@ START_TEST(typelib) if(sizeof(void*) == 8){ test_QueryPathOfRegTypeLib(64); test_CreateTypeLib(SYS_WIN64); + test_SetTypeDescAlias(SYS_WIN64); } test_CreateTypeLib(SYS_WIN32); + test_SetTypeDescAlias(SYS_WIN32); test_inheritance(); test_SetVarHelpContext(); test_SetFuncAndParamNames(); diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 8985a02d2e8..02f9cedc710 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 */ @@ -2331,8 +2331,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; @@ -2464,8 +2463,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) @@ -2487,8 +2485,7 @@ MSFT_DoFuncs(TLBContext* pcx, MSFT_GetTdesc(pcx, paraminfo.DataType, - &elemdesc->tdesc, - pTI); + &elemdesc->tdesc); elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags; @@ -2592,7 +2589,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)); @@ -2633,7 +2630,7 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info) { if(info->typekind == TKIND_ALIAS){ - switch(info->tdescAlias.vt){ + switch(info->tdescAlias->vt){ case VT_BSTR: case VT_DISPATCH: case VT_UNKNOWN: @@ -2646,7 +2643,7 @@ static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info) break; case VT_CARRAY: case VT_USERDEFINED: - TLB_size_instance(info, SYS_WIN64, &info->tdescAlias, &info->cbSizeInstance, &info->cbAlignment); + TLB_size_instance(info, SYS_WIN64, info->tdescAlias, &info->cbSizeInstance, &info->cbAlignment); break; case VT_VARIANT: info->cbSizeInstance = sizeof(VARIANT); @@ -2701,9 +2698,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 */ @@ -4308,9 +4308,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) { @@ -4321,7 +4322,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); } @@ -4800,8 +4802,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; @@ -5678,8 +5682,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) @@ -5700,12 +5704,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 */ @@ -9122,14 +9129,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; @@ -9619,7 +9630,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; @@ -10684,8 +10695,25 @@ 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; + HRESULT hr; + + TRACE("%p %p\n", This, tdescAlias); + + if(!tdescAlias) + return E_INVALIDARG; + + if(This->typekind != TKIND_ALIAS) + return TYPE_E_BADMODULEKIND; + + hr = TLB_size_instance(This, This->pTypeLib->syskind, tdescAlias, &This->cbSizeInstance, &This->cbAlignment); + if(FAILED(hr)) + return hr; + + heap_free(This->tdescAlias); + This->tdescAlias = heap_alloc(TLB_SizeTypeDesc(tdescAlias, TRUE)); + TLB_CopyTypeDesc(NULL, tdescAlias, This->tdescAlias); + + return S_OK; } static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(ICreateTypeInfo2 *iface,