Ove Kaaven wrote: > I've done these changes to the StdDispatch you did, perhaps it might > interest you. > 1) Judging by the example on MSDN, the ITypeInfo should be AddRef-ed > when creating the dispatch interface. > 2) C&C Generals doesn't seem to like having its outer unknown AddRef-ed, > for unknown reasons. Testing on Windows confirms that it doesn't use the outer unknown passed in to CreateStdDispatch at all. License: X11 Changelog: - AddRef type info stored in StdDispatch - Don't use outer unknown in StdDispatch
Index: wine/dlls/oleaut32/dispatch.c =================================================================== RCS file: /home/wine/wine/dlls/oleaut32/dispatch.c,v retrieving revision 1.13 diff -u -r1.13 dispatch.c --- wine/dlls/oleaut32/dispatch.c 18 Mar 2003 18:35:49 -0000 1.13 +++ wine/dlls/oleaut32/dispatch.c 8 Jul 2003 19:48:16 -0000 @@ -160,6 +160,9 @@ * RETURNS * Success: S_OK. ppunkStdDisp contains the new object. * Failure: An HRESULT error code. + * + * NOTES + * Outer unknown appears to be completely ignored. */ HRESULT WINAPI CreateStdDispatch( IUnknown* punkOuter, @@ -235,7 +238,6 @@ typedef struct { ICOM_VFIELD(IDispatch); - IUnknown * outerUnknown; void * pvThis; ITypeInfo * pTypeInfo; ULONG ref; @@ -254,9 +256,6 @@ ICOM_THIS(StdDispatch, iface); TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject); - if (This->outerUnknown) - return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); - if (IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) { @@ -276,11 +275,8 @@ { ICOM_THIS(StdDispatch, iface); TRACE("()\n"); - This->ref++; - if (This->outerUnknown) - return IUnknown_AddRef(This->outerUnknown); - else - return This->ref; + + return ++This->ref; } /****************************************************************************** @@ -294,15 +290,13 @@ ULONG ret; TRACE("(%p)->()\n", This); - This->ref--; + ret = This->ref--; - if (This->outerUnknown) - ret = IUnknown_Release(This->outerUnknown); - else - ret = This->ref; - - if (This->ref <= 0) + if (This->ref == 0) + { + ITypeInfo_Release(This->pTypeInfo); CoTaskMemFree(This); + } return ret; } @@ -469,10 +463,13 @@ return (IDispatch *)pStdDispatch; pStdDispatch->lpVtbl = &StdDispatch_VTable; - pStdDispatch->outerUnknown = punkOuter; pStdDispatch->pvThis = pvThis; pStdDispatch->pTypeInfo = pTypeInfo; pStdDispatch->ref = 1; + + /* we keep a reference to the type info so prevent it from + * being destroyed until we done with it */ + ITypeInfo_AddRef(pTypeInfo); return (IDispatch *)pStdDispatch; }