Module: wine Branch: master Commit: 8c6984ab7a509b95116710b29b533c5da6947af7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8c6984ab7a509b95116710b29b...
Author: Andrew Eikum aeikum@codeweavers.com Date: Tue May 28 17:00:18 2013 -0500
oleaut32: Improve TYPEFLAG_FDUAL handling.
---
dlls/oleaut32/typelib.c | 91 +++++++++++++++++++++++++++++------------------ 1 files changed, 56 insertions(+), 35 deletions(-)
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index c5a8e8d..827b6b4 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -5730,11 +5730,10 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( /* only valid on dual interfaces; retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH */ - if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL) { - *pRefType = -1; + *pRefType = -2; } else { @@ -7083,44 +7082,44 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( if(!ppTInfo) return E_INVALIDARG;
- if ((This->hreftype != -1) && (This->hreftype == hRefType)) - { - *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface; - ITypeInfo_AddRef(*ppTInfo); - result = S_OK; - } - else if (hRefType == -1 && - (This->TypeAttr.typekind == TKIND_DISPATCH) && - (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)) - { - /* when we meet a DUAL dispinterface, we must create the interface - * version of it. - */ - ITypeInfoImpl *pTypeInfoImpl = ITypeInfoImpl_Constructor(); - + if ((INT)hRefType < 0) { + ITypeInfoImpl *pTypeInfoImpl;
- /* the interface version contains the same information as the dispinterface - * copy the contents of the structs. - */ - *pTypeInfoImpl = *This; - pTypeInfoImpl->ref = 0; + if (!(This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL) || + !(This->TypeAttr.typekind == TKIND_INTERFACE || + This->TypeAttr.typekind == TKIND_DISPATCH)) + return TYPE_E_ELEMENTNOTFOUND;
- /* change the type to interface */ - pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE; + /* when we meet a DUAL typeinfo, we must create the alternate + * version of it. + */ + pTypeInfoImpl = ITypeInfoImpl_Constructor();
- *ppTInfo = (ITypeInfo*) pTypeInfoImpl; + *pTypeInfoImpl = *This; + pTypeInfoImpl->ref = 0;
- /* the AddRef implicitly adds a reference to the parent typelib, which - * stops the copied data from being destroyed until the new typeinfo's - * refcount goes to zero, but we need to signal to the new instance to - * not free its data structures when it is destroyed */ - pTypeInfoImpl->not_attached_to_typelib = TRUE; + if (This->TypeAttr.typekind == TKIND_INTERFACE) + pTypeInfoImpl->TypeAttr.typekind = TKIND_DISPATCH; + else + pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
- ITypeInfo_AddRef(*ppTInfo); + *ppTInfo = (ITypeInfo *)&pTypeInfoImpl->ITypeInfo2_iface; + /* the AddRef implicitly adds a reference to the parent typelib, which + * stops the copied data from being destroyed until the new typeinfo's + * refcount goes to zero, but we need to signal to the new instance to + * not free its data structures when it is destroyed */ + pTypeInfoImpl->not_attached_to_typelib = TRUE;
- result = S_OK; + ITypeInfo_AddRef(*ppTInfo);
- } else if ((hRefType != -1) && (hRefType & DISPATCH_HREF_MASK) && + result = S_OK; + } + else if (This->hreftype == hRefType) + { + *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface; + ITypeInfo_AddRef(*ppTInfo); + result = S_OK; + } else if ((hRefType & DISPATCH_HREF_MASK) && (This->TypeAttr.typekind == TKIND_DISPATCH)) { HREFTYPE href_dispatch = hRefType; @@ -8399,8 +8398,27 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface,
TRACE("%p %x\n", This, typeFlags);
- if (typeFlags & TYPEFLAG_FDUAL) - typeFlags |= TYPEFLAG_FDISPATCHABLE; + if (typeFlags & TYPEFLAG_FDUAL) { + static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 }; + ITypeLib *stdole; + ITypeInfo *dispatch; + HREFTYPE hreftype; + HRESULT hres; + + hres = LoadTypeLib(stdole2tlb, &stdole); + if(FAILED(hres)) + return hres; + + hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch); + ITypeLib_Release(stdole); + if(FAILED(hres)) + return hres; + + hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype); + ITypeInfo_Release(dispatch); + if(FAILED(hres)) + return hres; + }
This->TypeAttr.wTypeFlags = typeFlags;
@@ -8628,6 +8646,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface,
++This->TypeAttr.cImplTypes;
+ if((refType & (~0x3)) == (This->pTypeLib->dispatch_href & (~0x3))) + This->TypeAttr.wTypeFlags |= TYPEFLAG_FDISPATCHABLE; + return S_OK; }