source: trunk/src/quartz/iunk.c@ 6710

Last change on this file since 6710 was 6710, checked in by sandervl, 24 years ago

wine update

File size: 2.7 KB
Line 
1/*
2 * An implementation of IUnknown.
3 *
4 * hidenori@a2.ctktv.ne.jp
5 */
6
7#include "config.h"
8
9#include "windef.h"
10#include "winerror.h"
11#include "winbase.h"
12#include "wine/obj_base.h"
13
14#include "debugtools.h"
15DEFAULT_DEBUG_CHANNEL(quartz);
16
17#include "quartz_private.h"
18#include "iunk.h"
19
20
21static HRESULT WINAPI
22IUnknown_fnQueryInterface(IUnknown* iface,REFIID riid,LPVOID *ppobj)
23{
24 ICOM_THIS(QUARTZ_IUnkImpl,iface);
25 size_t ofs;
26 DWORD dwIndex;
27 QUARTZ_IFDelegation* pDelegation;
28 HRESULT hr;
29
30 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
31
32 if ( ppobj == NULL )
33 return E_POINTER;
34 *ppobj = NULL;
35
36 ofs = 0;
37
38 if ( IsEqualGUID( &IID_IUnknown, riid ) )
39 {
40 TRACE("IID_IUnknown - returns inner object.\n");
41 }
42 else
43 {
44 for ( dwIndex = 0; dwIndex < This->dwEntries; dwIndex++ )
45 {
46 if ( IsEqualGUID( This->pEntries[dwIndex].piid, riid ) )
47 {
48 ofs = This->pEntries[dwIndex].ofsVTPtr;
49 break;
50 }
51 }
52 if ( dwIndex == This->dwEntries )
53 {
54 hr = E_NOINTERFACE;
55
56 /* delegation */
57 pDelegation = This->pDelegationFirst;
58 while ( pDelegation != NULL )
59 {
60 hr = (*pDelegation->pOnQueryInterface)( iface, riid, ppobj );
61 if ( hr != E_NOINTERFACE )
62 break;
63 pDelegation = pDelegation->pNext;
64 }
65
66 if ( hr == E_NOINTERFACE )
67 {
68 FIXME("unknown interface: %s\n",debugstr_guid(riid));
69 }
70
71 return hr;
72 }
73 }
74
75 *ppobj = (LPVOID)(((char*)This) + ofs);
76 IUnknown_AddRef((IUnknown*)(*ppobj));
77
78 return S_OK;
79}
80
81static ULONG WINAPI
82IUnknown_fnAddRef(IUnknown* iface)
83{
84 ICOM_THIS(QUARTZ_IUnkImpl,iface);
85
86 TRACE("(%p)->()\n",This);
87
88 return InterlockedExchangeAdd(&(This->ref),1) + 1;
89}
90
91static ULONG WINAPI
92IUnknown_fnRelease(IUnknown* iface)
93{
94 ICOM_THIS(QUARTZ_IUnkImpl,iface);
95 LONG ref;
96
97 TRACE("(%p)->()\n",This);
98 ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
99 if ( ref > 0 )
100 return (ULONG)ref;
101
102 if ( This->pOnFinalRelease != NULL )
103 (*(This->pOnFinalRelease))(iface);
104
105 QUARTZ_FreeObj(This);
106
107 return 0;
108}
109
110static ICOM_VTABLE(IUnknown) iunknown =
111{
112 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
113 /* IUnknown fields */
114 IUnknown_fnQueryInterface,
115 IUnknown_fnAddRef,
116 IUnknown_fnRelease,
117};
118
119
120void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl, IUnknown* punkOuter )
121{
122 TRACE("(%p)\n",pImpl);
123
124 ICOM_VTBL(pImpl) = &iunknown;
125 pImpl->pEntries = NULL;
126 pImpl->dwEntries = 0;
127 pImpl->pDelegationFirst = NULL;
128 pImpl->pOnFinalRelease = NULL;
129 pImpl->ref = 1;
130 pImpl->punkControl = (IUnknown*)pImpl;
131
132 /* for implementing aggregation. */
133 if ( punkOuter != NULL )
134 pImpl->punkControl = punkOuter;
135}
136
137void QUARTZ_IUnkAddDelegation(
138 QUARTZ_IUnkImpl* pImpl, QUARTZ_IFDelegation* pDelegation )
139{
140 pDelegation->pNext = pImpl->pDelegationFirst;
141 pImpl->pDelegationFirst = pDelegation;
142}
143
Note: See TracBrowser for help on using the repository browser.