Commit f9d42aee authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

oleaut32: Implement ICreateTypeInfo::AddRefTypeInfo.

This also corrects our HREFTYPE values a little bit.
parent 97f501be
...@@ -1055,6 +1055,7 @@ typedef struct tagTLBRefType ...@@ -1055,6 +1055,7 @@ typedef struct tagTLBRefType
it the format is SLTG. -2 indicates to it the format is SLTG. -2 indicates to
use guid */ use guid */
TYPEKIND tkind;
GUID guid; /* guid of the referenced type */ GUID guid; /* guid of the referenced type */
/* if index == TLB_REF_USE_GUID */ /* if index == TLB_REF_USE_GUID */
...@@ -2337,7 +2338,7 @@ static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL, ...@@ -2337,7 +2338,7 @@ static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL,
break; break;
if(&pImpLib->entry != &pcx->pLibInfo->implib_list){ if(&pImpLib->entry != &pcx->pLibInfo->implib_list){
ref->reference = offset; ref->reference = offset & (~0x3);
ref->pImpTLInfo = pImpLib; ref->pImpTLInfo = pImpLib;
if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) { if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
MSFT_ReadGuid(&ref->guid, impinfo.oGuid, pcx); MSFT_ReadGuid(&ref->guid, impinfo.oGuid, pcx);
...@@ -7121,22 +7122,27 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( ...@@ -7121,22 +7122,27 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo); result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo);
} else { } else {
TLBRefType *ref_type; TLBRefType *ref_type;
ITypeLib *pTLib = NULL;
UINT i; UINT i;
if(!(hRefType & 0x1)){
for(i = 0; i < This->pTypeLib->TypeInfoCount; ++i) for(i = 0; i < This->pTypeLib->TypeInfoCount; ++i)
{ {
if (This->pTypeLib->typeinfos[i]->hreftype == hRefType) if (This->pTypeLib->typeinfos[i]->hreftype == (hRefType&(~0x3)))
{ {
result = S_OK; result = S_OK;
*ppTInfo = (ITypeInfo*)This->pTypeLib->typeinfos[i]; *ppTInfo = (ITypeInfo*)&This->pTypeLib->typeinfos[i]->ITypeInfo2_iface;
ITypeInfo_AddRef(*ppTInfo); ITypeInfo_AddRef(*ppTInfo);
goto end; goto end;
} }
} }
result = TYPE_E_ELEMENTNOTFOUND;
goto end;
}
LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry) LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry)
{ {
if(ref_type->reference == hRefType) if(ref_type->reference == (hRefType & (~0x3)))
break; break;
} }
if(&ref_type->entry == &This->pTypeLib->ref_list) if(&ref_type->entry == &This->pTypeLib->ref_list)
...@@ -7144,11 +7150,10 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( ...@@ -7144,11 +7150,10 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
FIXME("Can't find pRefType for ref %x\n", hRefType); FIXME("Can't find pRefType for ref %x\n", hRefType);
goto end; goto end;
} }
if(hRefType != -1) {
ITypeLib *pTLib = NULL;
if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) { if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) {
UINT Index; UINT Index;
TRACE("internal reference\n");
result = ITypeInfo2_GetContainingTypeLib(iface, &pTLib, &Index); result = ITypeInfo2_GetContainingTypeLib(iface, &pTLib, &Index);
} else { } else {
if(ref_type->pImpTLInfo->pImpTypeLib) { if(ref_type->pImpTLInfo->pImpTypeLib) {
...@@ -7184,7 +7189,6 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( ...@@ -7184,7 +7189,6 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
if (pTLib != NULL) if (pTLib != NULL)
ITypeLib_Release(pTLib); ITypeLib_Release(pTLib);
} }
}
end: end:
TRACE("(%p) hreftype 0x%04x loaded %s (%p)\n", This, hRefType, TRACE("(%p) hreftype 0x%04x loaded %s (%p)\n", This, hRefType,
...@@ -7875,6 +7879,7 @@ HRESULT WINAPI CreateDispTypeInfo( ...@@ -7875,6 +7879,7 @@ HRESULT WINAPI CreateDispTypeInfo(
pTIIface->TypeAttr.cImplTypes = 0; pTIIface->TypeAttr.cImplTypes = 0;
pTIIface->TypeAttr.cVars = 0; pTIIface->TypeAttr.cVars = 0;
pTIIface->TypeAttr.wTypeFlags = 0; pTIIface->TypeAttr.wTypeFlags = 0;
pTIIface->hreftype = 0;
pTIIface->funcdescs = TLBFuncDesc_Constructor(pidata->cMembers); pTIIface->funcdescs = TLBFuncDesc_Constructor(pidata->cMembers);
pFuncDesc = pTIIface->funcdescs; pFuncDesc = pTIIface->funcdescs;
...@@ -7929,6 +7934,7 @@ HRESULT WINAPI CreateDispTypeInfo( ...@@ -7929,6 +7934,7 @@ HRESULT WINAPI CreateDispTypeInfo(
pTIClass->TypeAttr.cImplTypes = 1; pTIClass->TypeAttr.cImplTypes = 1;
pTIClass->TypeAttr.cVars = 0; pTIClass->TypeAttr.cVars = 0;
pTIClass->TypeAttr.wTypeFlags = 0; pTIClass->TypeAttr.wTypeFlags = 0;
pTIClass->hreftype = sizeof(MSFT_TypeInfoBase);
pTIClass->impltypes = TLBImplType_Constructor(1); pTIClass->impltypes = TLBImplType_Constructor(1);
...@@ -8441,8 +8447,108 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(ICreateTypeInfo2 *iface, ...@@ -8441,8 +8447,108 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(ICreateTypeInfo2 *iface,
ITypeInfo *typeInfo, HREFTYPE *refType) ITypeInfo *typeInfo, HREFTYPE *refType)
{ {
ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
FIXME("%p %p %p - stub\n", This, typeInfo, refType); UINT index;
return E_NOTIMPL; ITypeLib *container;
TLBRefType *ref_type;
TLBImpLib *implib;
TYPEATTR *typeattr;
TLIBATTR *libattr;
HRESULT hres;
TRACE("%p %p %p\n", This, typeInfo, refType);
if (!typeInfo || !refType)
return E_INVALIDARG;
hres = ITypeInfo_GetContainingTypeLib(typeInfo, &container, &index);
if (FAILED(hres))
return hres;
if (container == (ITypeLib*)&This->pTypeLib->ITypeLib2_iface) {
ITypeInfoImpl *target = impl_from_ITypeInfo(typeInfo);
ITypeLib_Release(container);
*refType = target->hreftype;
return S_OK;
}
hres = ITypeLib_GetLibAttr(container, &libattr);
if (FAILED(hres)) {
ITypeLib_Release(container);
return hres;
}
LIST_FOR_EACH_ENTRY(implib, &This->pTypeLib->implib_list, TLBImpLib, entry){
if(IsEqualGUID(&implib->guid, &libattr->guid) &&
implib->lcid == libattr->lcid &&
implib->wVersionMajor == libattr->wMajorVerNum &&
implib->wVersionMinor == libattr->wMinorVerNum)
break;
}
if(&implib->entry == &This->pTypeLib->implib_list){
implib = heap_alloc_zero(sizeof(TLBImpLib));
if((ITypeLib2Vtbl*)container->lpVtbl == &tlbvt){
const ITypeLibImpl *our_container = impl_from_ITypeLib2((ITypeLib2*)container);
implib->name = SysAllocString(our_container->path);
}else{
hres = QueryPathOfRegTypeLib(&libattr->guid, libattr->wMajorVerNum,
libattr->wMinorVerNum, libattr->lcid, &implib->name);
if(FAILED(hres)){
implib->name = NULL;
TRACE("QueryPathOfRegTypeLib failed, no name stored: %08x\n", hres);
}
}
implib->guid = libattr->guid;
implib->lcid = libattr->lcid;
implib->wVersionMajor = libattr->wMajorVerNum;
implib->wVersionMinor = libattr->wMinorVerNum;
list_add_tail(&This->pTypeLib->implib_list, &implib->entry);
}
ITypeLib_ReleaseTLibAttr(container, libattr);
ITypeLib_Release(container);
hres = ITypeInfo_GetTypeAttr(typeInfo, &typeattr);
if (FAILED(hres))
return hres;
index = 0;
LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry){
if(ref_type->index == TLB_REF_USE_GUID &&
IsEqualGUID(&ref_type->guid, &typeattr->guid) &&
ref_type->tkind == typeattr->typekind)
break;
++index;
}
if(&ref_type->entry == &This->pTypeLib->ref_list){
ref_type = heap_alloc_zero(sizeof(TLBRefType));
ref_type->tkind = typeattr->typekind;
ref_type->pImpTLInfo = implib;
ref_type->reference = index * sizeof(MSFT_ImpInfo);
ref_type->index = TLB_REF_USE_GUID;
ref_type->guid = typeattr->guid;
list_add_tail(&This->pTypeLib->ref_list, &ref_type->entry);
}
ITypeInfo_ReleaseTypeAttr(typeInfo, typeattr);
*refType = ref_type->reference | 0x1;
if(IsEqualGUID(&ref_type->guid, &IID_IDispatch))
This->pTypeLib->dispatch_href = *refType;
return S_OK;
} }
static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface, static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment