Commit 8c6984ab authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

oleaut32: Improve TYPEFLAG_FDUAL handling.

parent 0082256a
...@@ -5730,11 +5730,10 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( ...@@ -5730,11 +5730,10 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
/* only valid on dual interfaces; /* only valid on dual interfaces;
retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH 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) if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)
{ {
*pRefType = -1; *pRefType = -2;
} }
else else
{ {
...@@ -7083,44 +7082,44 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( ...@@ -7083,44 +7082,44 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
if(!ppTInfo) if(!ppTInfo)
return E_INVALIDARG; return E_INVALIDARG;
if ((This->hreftype != -1) && (This->hreftype == hRefType)) if ((INT)hRefType < 0) {
{ ITypeInfoImpl *pTypeInfoImpl;
*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();
/* the interface version contains the same information as the dispinterface if (!(This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL) ||
* copy the contents of the structs. !(This->TypeAttr.typekind == TKIND_INTERFACE ||
*/ This->TypeAttr.typekind == TKIND_DISPATCH))
*pTypeInfoImpl = *This; return TYPE_E_ELEMENTNOTFOUND;
pTypeInfoImpl->ref = 0;
/* change the type to interface */ /* when we meet a DUAL typeinfo, we must create the alternate
pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE; * 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 if (This->TypeAttr.typekind == TKIND_INTERFACE)
* stops the copied data from being destroyed until the new typeinfo's pTypeInfoImpl->TypeAttr.typekind = TKIND_DISPATCH;
* refcount goes to zero, but we need to signal to the new instance to else
* not free its data structures when it is destroyed */ pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
pTypeInfoImpl->not_attached_to_typelib = TRUE;
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)) (This->TypeAttr.typekind == TKIND_DISPATCH))
{ {
HREFTYPE href_dispatch = hRefType; HREFTYPE href_dispatch = hRefType;
...@@ -8399,8 +8398,27 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, ...@@ -8399,8 +8398,27 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface,
TRACE("%p %x\n", This, typeFlags); TRACE("%p %x\n", This, typeFlags);
if (typeFlags & TYPEFLAG_FDUAL) if (typeFlags & TYPEFLAG_FDUAL) {
typeFlags |= TYPEFLAG_FDISPATCHABLE; 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; This->TypeAttr.wTypeFlags = typeFlags;
...@@ -8628,6 +8646,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface, ...@@ -8628,6 +8646,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface,
++This->TypeAttr.cImplTypes; ++This->TypeAttr.cImplTypes;
if((refType & (~0x3)) == (This->pTypeLib->dispatch_href & (~0x3)))
This->TypeAttr.wTypeFlags |= TYPEFLAG_FDISPATCHABLE;
return S_OK; return S_OK;
} }
......
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