2 * An implementation of IUnknown.
4 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "wine/obj_base.h"
28 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
31 #include "quartz_private.h"
36 IUnknown_fnQueryInterface(IUnknown* iface,REFIID riid,LPVOID *ppobj)
38 ICOM_THIS(QUARTZ_IUnkImpl,iface);
41 QUARTZ_IFDelegation* pDelegation;
44 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
52 if ( IsEqualGUID( &IID_IUnknown, riid ) )
54 TRACE("IID_IUnknown - returns inner object.\n");
58 for ( dwIndex = 0; dwIndex < This->dwEntries; dwIndex++ )
60 if ( IsEqualGUID( This->pEntries[dwIndex].piid, riid ) )
62 ofs = This->pEntries[dwIndex].ofsVTPtr;
66 if ( dwIndex == This->dwEntries )
71 pDelegation = This->pDelegationFirst;
72 while ( pDelegation != NULL )
74 hr = (*pDelegation->pOnQueryInterface)( iface, riid, ppobj );
75 if ( hr != E_NOINTERFACE )
77 pDelegation = pDelegation->pNext;
80 if ( hr == E_NOINTERFACE )
82 FIXME("(%p) unknown interface: %s\n",This,debugstr_guid(riid));
89 *ppobj = (LPVOID)(((char*)This) + ofs);
90 IUnknown_AddRef((IUnknown*)(*ppobj));
96 IUnknown_fnAddRef(IUnknown* iface)
98 ICOM_THIS(QUARTZ_IUnkImpl,iface);
100 TRACE("(%p)->()\n",This);
102 return InterlockedExchangeAdd(&(This->ref),1) + 1;
106 IUnknown_fnRelease(IUnknown* iface)
108 ICOM_THIS(QUARTZ_IUnkImpl,iface);
111 TRACE("(%p)->()\n",This);
112 ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
117 if ( This->pOnFinalRelease != NULL )
118 (*(This->pOnFinalRelease))(iface);
121 QUARTZ_FreeObj(This);
126 static ICOM_VTABLE(IUnknown) iunknown =
128 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
129 /* IUnknown fields */
130 IUnknown_fnQueryInterface,
136 void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl, IUnknown* punkOuter )
138 TRACE("(%p)\n",pImpl);
140 ICOM_VTBL(pImpl) = &iunknown;
141 pImpl->pEntries = NULL;
142 pImpl->dwEntries = 0;
143 pImpl->pDelegationFirst = NULL;
144 pImpl->pOnFinalRelease = NULL;
146 pImpl->punkControl = (IUnknown*)pImpl;
148 /* for implementing aggregation. */
149 if ( punkOuter != NULL )
150 pImpl->punkControl = punkOuter;
153 void QUARTZ_IUnkAddDelegation(
154 QUARTZ_IUnkImpl* pImpl, QUARTZ_IFDelegation* pDelegation )
156 pDelegation->pNext = pImpl->pDelegationFirst;
157 pImpl->pDelegationFirst = pDelegation;