ReactOS 0.4.17-dev-573-g8315b8c
connpt.c
Go to the documentation of this file.
1/*
2 * Implementation of a generic ConnectionPoint object.
3 *
4 * Copyright 2000 Huw D M Davies for CodeWeavers
5 *
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.
10 *
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.
15 *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 * NOTES:
21 * See one exported function here is CreateConnectionPoint, see
22 * comments just above that function for information.
23 */
24
25#include <assert.h>
26#include <stdarg.h>
27#include <string.h>
28
29#define COBJMACROS
30
31#include "winerror.h"
32#include "windef.h"
33#include "winbase.h"
34#include "wingdi.h"
35#include "winuser.h"
36#include "ole2.h"
37#include "olectl.h"
38#include "connpt.h"
39
40#include "wine/debug.h"
41
43
44#define MAXSINKS 10
45
46/************************************************************************
47 * Implementation of IConnectionPoint
48 */
49typedef struct ConnectionPointImpl {
50
52
53 /* IUnknown of our main object*/
55
56 /* Reference count */
58
59 /* IID of sink interface */
61
62 /* Array of sink IUnknowns */
65
68
69/************************************************************************
70 * Implementation of IEnumConnections
71 */
72typedef struct EnumConnectionsImpl {
73
75
77
78 /* IUnknown of ConnectionPoint, used for ref counting */
80
81 /* Connection Data */
82 CONNECTDATA *pCD;
84
85 /* Next connection to enumerate from */
87
89
91 DWORD nSinks,
92 CONNECTDATA *pCD);
93
95{
96 return CONTAINING_RECORD(iface, ConnectionPointImpl, IConnectionPoint_iface);
97}
98
100{
101 return CONTAINING_RECORD(iface, EnumConnectionsImpl, IEnumConnections_iface);
102}
103
105{
106 DWORD i;
107 for(i = 0; i < Obj->maxSinks; i++) {
108 if(Obj->sinks[i]) {
109 IUnknown_Release(Obj->sinks[i]);
110 Obj->sinks[i] = NULL;
111 }
112 }
113 free(Obj->sinks);
114 free(Obj);
115 return;
116}
117
119 IConnectionPoint* iface,
120 REFIID riid,
121 void** ppvObject)
122{
124 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
125
126 /*
127 * Perform a sanity check on the parameters.
128 */
129 if (!ppvObject)
130 return E_INVALIDARG;
131
132 /*
133 * Initialize the return parameter.
134 */
135 *ppvObject = 0;
136
137
139 *ppvObject = iface;
140
141 /*
142 * Check that we obtained an interface.
143 */
144 if ((*ppvObject)==0)
145 {
146 FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid));
147 return E_NOINTERFACE;
148 }
149
150 IUnknown_AddRef((IUnknown*)*ppvObject);
151
152 return S_OK;
153}
154
156{
158 ULONG refCount = InterlockedIncrement(&This->ref);
159
160 TRACE("%p, refcount %lu.\n", iface, refCount);
161
162 return refCount;
163}
164
166 IConnectionPoint* iface)
167{
169 ULONG refCount = InterlockedDecrement(&This->ref);
170
171 TRACE("%p, refcount %lu.\n", iface, refCount);
172
173 if (!refCount) ConnectionPointImpl_Destroy(This);
174
175 return refCount;
176}
177
179 IConnectionPoint *iface,
180 IID *piid)
181{
183 TRACE("(%p)->(%p) returning %s\n", This, piid, debugstr_guid(&(This->iid)));
184 *piid = This->iid;
185 return S_OK;
186}
187
189 IConnectionPoint *iface,
191{
193 TRACE("(%p)->(%p)\n", This, ppCPC);
194
195 return IUnknown_QueryInterface(This->Obj, &IID_IConnectionPointContainer, (void**)ppCPC);
196}
197
199 IUnknown *lpUnk,
200 DWORD *pdwCookie)
201{
202 DWORD i;
204 IUnknown *lpSink;
205 TRACE("(%p)->(%p, %p)\n", This, lpUnk, pdwCookie);
206
207 *pdwCookie = 0;
208 if(FAILED(IUnknown_QueryInterface(lpUnk, &This->iid, (void**)&lpSink)))
210
211 for(i = 0; i < This->maxSinks; i++) {
212 if(This->sinks[i] == NULL)
213 break;
214 }
215 if(i == This->maxSinks) {
216 This->sinks = realloc(This->sinks, (This->maxSinks + MAXSINKS) * sizeof(IUnknown*));
217 memset(This->sinks + This->maxSinks, 0, MAXSINKS * sizeof(IUnknown*));
218 This->maxSinks += MAXSINKS;
219 }
220 This->sinks[i] = lpSink;
221 This->nSinks++;
222 *pdwCookie = i + 1;
223 return S_OK;
224}
225
226
228{
230
231 TRACE("%p, %#lx.\n", iface, dwCookie);
232
233 if(dwCookie == 0 || dwCookie > This->maxSinks) return E_INVALIDARG;
234
235 if(This->sinks[dwCookie-1] == NULL) return CONNECT_E_NOCONNECTION;
236
237 IUnknown_Release(This->sinks[dwCookie-1]);
238 This->sinks[dwCookie-1] = NULL;
239 This->nSinks--;
240 return S_OK;
241}
242
244{
246 CONNECTDATA *pCD;
247 DWORD i, nextslot;
248 EnumConnectionsImpl *EnumObj;
249 HRESULT hr;
250
251 TRACE("(%p)->(%p)\n", This, ppEnum);
252
253 *ppEnum = NULL;
254
255 if(This->nSinks == 0) return OLE_E_NOCONNECTION;
256
257 pCD = malloc(sizeof(CONNECTDATA) * This->nSinks);
258
259 for(i = 0, nextslot = 0; i < This->maxSinks; i++) {
260 if(This->sinks[i] != NULL) {
261 pCD[nextslot].pUnk = This->sinks[i];
262 pCD[nextslot].dwCookie = i + 1;
263 nextslot++;
264 }
265 }
266 assert(nextslot == This->nSinks);
267
268 /* Bump the ref count of this object up by one. It gets Released in
269 IEnumConnections_Release */
270 IConnectionPoint_AddRef(iface);
271
272 EnumObj = EnumConnectionsImpl_Construct((IUnknown*)iface, This->nSinks, pCD);
273 hr = IEnumConnections_QueryInterface(&EnumObj->IEnumConnections_iface,
274 &IID_IEnumConnections, (void**)ppEnum);
275 IEnumConnections_Release(&EnumObj->IEnumConnections_iface);
276
277 free(pCD);
278 return hr;
279}
280
281static const IConnectionPointVtbl ConnectionPointImpl_VTable =
282{
291};
292
293
294static const IEnumConnectionsVtbl EnumConnectionsImpl_VTable;
295
297 DWORD nSinks,
298 CONNECTDATA *pCD)
299{
300 EnumConnectionsImpl *Obj = malloc(sizeof(*Obj));
301 DWORD i;
302
303 Obj->IEnumConnections_iface.lpVtbl = &EnumConnectionsImpl_VTable;
304 Obj->ref = 1;
305 Obj->pUnk = pUnk;
306 Obj->pCD = malloc(nSinks * sizeof(CONNECTDATA));
307 Obj->nConns = nSinks;
308 Obj->nCur = 0;
309
310 for(i = 0; i < nSinks; i++) {
311 Obj->pCD[i] = pCD[i];
312 IUnknown_AddRef(Obj->pCD[i].pUnk);
313 }
314 return Obj;
315}
316
318{
319 DWORD i;
320
321 for(i = 0; i < Obj->nConns; i++)
322 IUnknown_Release(Obj->pCD[i].pUnk);
323
324 free(Obj->pCD);
325 free(Obj);
326 return;
327}
328
330 IEnumConnections* iface,
331 REFIID riid,
332 void** ppvObject)
333{
335 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
336
337 /*
338 * Perform a sanity check on the parameters.
339 */
340 if (!ppvObject)
341 return E_INVALIDARG;
342
343 /*
344 * Initialize the return parameter.
345 */
346 *ppvObject = 0;
347
349 *ppvObject = iface;
350
351 /*
352 * Check that we obtained an interface.
353 */
354 if ((*ppvObject)==0)
355 {
356 FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid));
357 return E_NOINTERFACE;
358 }
359
360 IUnknown_AddRef((IUnknown*)*ppvObject);
361
362 return S_OK;
363}
364
366{
368 ULONG refCount = InterlockedIncrement(&This->ref);
369
370 TRACE("%p, refcount %lu.\n", iface, refCount);
371
372 IUnknown_AddRef(This->pUnk);
373 return refCount;
374}
375
377{
379 ULONG refCount = InterlockedDecrement(&This->ref);
380
381 TRACE("%p, refcount %lu.\n", iface, refCount);
382
383 IUnknown_Release(This->pUnk);
384
385 if (!refCount) EnumConnectionsImpl_Destroy(This);
386
387 return refCount;
388}
389
390static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections* iface, ULONG cConn, LPCONNECTDATA pCD, ULONG *pEnum)
391{
393 DWORD nRet = 0;
394
395 TRACE("%p, %lu, %p, %p.\n", iface, cConn, pCD, pEnum);
396
397 if(pEnum == NULL) {
398 if(cConn != 1)
399 return E_POINTER;
400 } else
401 *pEnum = 0;
402
403 if(This->nCur >= This->nConns)
404 return S_FALSE;
405
406 while(This->nCur < This->nConns && cConn) {
407 *pCD++ = This->pCD[This->nCur];
408 IUnknown_AddRef(This->pCD[This->nCur].pUnk);
409 This->nCur++;
410 cConn--;
411 nRet++;
412 }
413
414 if(pEnum)
415 *pEnum = nRet;
416
417 return S_OK;
418}
419
421{
423
424 TRACE("%p, %lu.\n", iface, cSkip);
425
426 if(This->nCur + cSkip >= This->nConns)
427 return S_FALSE;
428
429 This->nCur += cSkip;
430
431 return S_OK;
432}
433
435{
437 TRACE("(%p)\n", This);
438
439 This->nCur = 0;
440
441 return S_OK;
442}
443
445{
447 EnumConnectionsImpl *newObj;
448 TRACE("(%p)->(%p)\n", This, ppEnum);
449
450 newObj = EnumConnectionsImpl_Construct(This->pUnk, This->nConns, This->pCD);
451 newObj->nCur = This->nCur;
452 *ppEnum = &newObj->IEnumConnections_iface;
453 IUnknown_AddRef(This->pUnk);
454 return S_OK;
455}
456
457static const IEnumConnectionsVtbl EnumConnectionsImpl_VTable =
458{
466};
467
468/************************************************************************
469 *
470 * The exported function to create the connection point.
471 * NB not a windows API
472 *
473 * PARAMS
474 * pUnk [in] IUnknown of object to which the ConnectionPoint is associated.
475 * Needed to access IConnectionPointContainer.
476 *
477 * riid [in] IID of sink interface that this ConnectionPoint manages
478 *
479 * pCP [out] returns IConnectionPoint
480 *
481 */
483 IConnectionPoint **pCP)
484{
486
487 TRACE("(%p %s %p)\n", pUnk, debugstr_guid(riid), pCP);
488
489 *pCP = NULL;
490 Obj = malloc(sizeof(*Obj));
491 if (!Obj)
492 return E_OUTOFMEMORY;
493
494 Obj->IConnectionPoint_iface.lpVtbl = &ConnectionPointImpl_VTable;
495 Obj->Obj = pUnk;
496 Obj->ref = 1;
497 Obj->iid = *riid;
498 Obj->maxSinks = MAXSINKS;
499 Obj->sinks = calloc(MAXSINKS, sizeof(IUnknown*));
500 Obj->nSinks = 0;
501
502 *pCP = &Obj->IConnectionPoint_iface;
503 return S_OK;
504}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
const GUID IID_IUnknown
Obj()
Definition: swap_test.cpp:67
static const IConnectionPointVtbl ConnectionPointImpl_VTable
Definition: connpt.c:281
static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface, IUnknown *lpUnk, DWORD *pdwCookie)
Definition: connpt.c:198
static HRESULT WINAPI ConnectionPointImpl_GetConnectionInterface(IConnectionPoint *iface, IID *piid)
Definition: connpt.c:178
static EnumConnectionsImpl * impl_from_IEnumConnections(IEnumConnections *iface)
Definition: connpt.c:99
static HRESULT WINAPI EnumConnectionsImpl_Reset(IEnumConnections *iface)
Definition: connpt.c:434
static void ConnectionPointImpl_Destroy(ConnectionPointImpl *Obj)
Definition: connpt.c:104
static ConnectionPointImpl * impl_from_IConnectionPoint(IConnectionPoint *iface)
Definition: connpt.c:94
static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections *iface, ULONG cSkip)
Definition: connpt.c:420
static const IEnumConnectionsVtbl EnumConnectionsImpl_VTable
Definition: connpt.c:294
static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint *iface)
Definition: connpt.c:155
static HRESULT WINAPI ConnectionPointImpl_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
Definition: connpt.c:227
static EnumConnectionsImpl * EnumConnectionsImpl_Construct(IUnknown *pUnk, DWORD nSinks, CONNECTDATA *pCD)
Definition: connpt.c:296
static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections *iface, ULONG cConn, LPCONNECTDATA pCD, ULONG *pEnum)
Definition: connpt.c:390
static void EnumConnectionsImpl_Destroy(EnumConnectionsImpl *Obj)
Definition: connpt.c:317
static HRESULT WINAPI EnumConnectionsImpl_QueryInterface(IEnumConnections *iface, REFIID riid, void **ppvObject)
Definition: connpt.c:329
static HRESULT WINAPI EnumConnectionsImpl_Clone(IEnumConnections *iface, IEnumConnections **ppEnum)
Definition: connpt.c:444
static HRESULT WINAPI ConnectionPointImpl_QueryInterface(IConnectionPoint *iface, REFIID riid, void **ppvObject)
Definition: connpt.c:118
static HRESULT WINAPI ConnectionPointImpl_EnumConnections(IConnectionPoint *iface, IEnumConnections **ppEnum)
Definition: connpt.c:243
HRESULT CreateConnectionPoint(IUnknown *pUnk, REFIID riid, IConnectionPoint **pCP)
Definition: connpt.c:482
static ULONG WINAPI EnumConnectionsImpl_Release(IEnumConnections *iface)
Definition: connpt.c:376
static ULONG WINAPI ConnectionPointImpl_Release(IConnectionPoint *iface)
Definition: connpt.c:165
static HRESULT WINAPI ConnectionPointImpl_GetConnectionPointContainer(IConnectionPoint *iface, IConnectionPointContainer **ppCPC)
Definition: connpt.c:188
#define MAXSINKS
Definition: connpt.c:44
static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections *iface)
Definition: connpt.c:365
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define assert(_expr)
Definition: assert.h:32
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define CONNECT_E_CANNOTCONNECT
Definition: olectl.h:253
#define CONNECT_E_NOCONNECTION
Definition: olectl.h:251
const GUID IID_IEnumConnections
const GUID IID_IConnectionPointContainer
const GUID IID_IConnectionPoint
long LONG
Definition: pedump.c:60
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define calloc
Definition: rosglue.h:14
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
IUnknown * Obj
Definition: connpt.c:54
IConnectionPoint IConnectionPoint_iface
Definition: connpt.c:51
IUnknown ** sinks
Definition: connpt.c:63
IEnumConnections IEnumConnections_iface
Definition: connpt.c:74
CONNECTDATA * pCD
Definition: connpt.c:82
IUnknown * pUnk
Definition: connpt.c:79
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define OLE_E_NOCONNECTION
Definition: winerror.h:3729
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480