Andrew Eikum : oleaut32: Improve TYPEFLAG_FDUAL handling.
Alexandre Julliard
julliard at winehq.org
Wed May 29 14:47:32 CDT 2013
Module: wine
Branch: master
Commit: 8c6984ab7a509b95116710b29b533c5da6947af7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8c6984ab7a509b95116710b29b533c5da6947af7
Author: Andrew Eikum <aeikum at 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;
}
More information about the wine-cvs
mailing list