ReactOS 0.4.15-dev-7994-gb388cb6
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
104/************************************************************************
105 * ConnectionPointImpl_Destroy
106 */
108{
109 DWORD i;
110 for(i = 0; i < Obj->maxSinks; i++) {
111 if(Obj->sinks[i]) {
112 IUnknown_Release(Obj->sinks[i]);
113 Obj->sinks[i] = NULL;
114 }
115 }
116 HeapFree(GetProcessHeap(), 0, Obj->sinks);
118 return;
119}
120
121/************************************************************************
122 * ConnectionPointImpl_QueryInterface (IUnknown)
123 *
124 * See Windows documentation for more details on IUnknown methods.
125 */
127 IConnectionPoint* iface,
128 REFIID riid,
129 void** ppvObject)
130{
132 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
133
134 /*
135 * Perform a sanity check on the parameters.
136 */
137 if (!ppvObject)
138 return E_INVALIDARG;
139
140 /*
141 * Initialize the return parameter.
142 */
143 *ppvObject = 0;
144
145
147 *ppvObject = iface;
148
149 /*
150 * Check that we obtained an interface.
151 */
152 if ((*ppvObject)==0)
153 {
154 FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid));
155 return E_NOINTERFACE;
156 }
157
158 IUnknown_AddRef((IUnknown*)*ppvObject);
159
160 return S_OK;
161}
162
163
164/************************************************************************
165 * ConnectionPointImpl_AddRef (IUnknown)
166 *
167 * See Windows documentation for more details on IUnknown methods.
168 */
170{
172 ULONG refCount = InterlockedIncrement(&This->ref);
173
174 TRACE("(%p)->(ref before=%d)\n", This, refCount - 1);
175
176 return refCount;
177}
178
179/************************************************************************
180 * ConnectionPointImpl_Release (IUnknown)
181 *
182 * See Windows documentation for more details on IUnknown methods.
183 */
185 IConnectionPoint* iface)
186{
188 ULONG refCount = InterlockedDecrement(&This->ref);
189
190 TRACE("(%p)->(ref before=%d)\n", This, refCount + 1);
191
192 /*
193 * If the reference count goes down to 0, perform suicide.
194 */
195 if (!refCount) ConnectionPointImpl_Destroy(This);
196
197 return refCount;
198}
199
200/************************************************************************
201 * ConnectionPointImpl_GetConnectionInterface (IConnectionPoint)
202 *
203 */
205 IConnectionPoint *iface,
206 IID *piid)
207{
209 TRACE("(%p)->(%p) returning %s\n", This, piid, debugstr_guid(&(This->iid)));
210 *piid = This->iid;
211 return S_OK;
212}
213
214/************************************************************************
215 * ConnectionPointImpl_GetConnectionPointContainer (IConnectionPoint)
216 *
217 */
219 IConnectionPoint *iface,
221{
223 TRACE("(%p)->(%p)\n", This, ppCPC);
224
225 return IUnknown_QueryInterface(This->Obj, &IID_IConnectionPointContainer, (void**)ppCPC);
226}
227
228/************************************************************************
229 * ConnectionPointImpl_Advise (IConnectionPoint)
230 *
231 */
233 IUnknown *lpUnk,
234 DWORD *pdwCookie)
235{
236 DWORD i;
238 IUnknown *lpSink;
239 TRACE("(%p)->(%p, %p)\n", This, lpUnk, pdwCookie);
240
241 *pdwCookie = 0;
242 if(FAILED(IUnknown_QueryInterface(lpUnk, &This->iid, (void**)&lpSink)))
244
245 for(i = 0; i < This->maxSinks; i++) {
246 if(This->sinks[i] == NULL)
247 break;
248 }
249 if(i == This->maxSinks) {
250 This->maxSinks += MAXSINKS;
252 This->maxSinks * sizeof(IUnknown *));
253 }
254 This->sinks[i] = lpSink;
255 This->nSinks++;
256 *pdwCookie = i + 1;
257 return S_OK;
258}
259
260
261/************************************************************************
262 * ConnectionPointImpl_Unadvise (IConnectionPoint)
263 *
264 */
266 DWORD dwCookie)
267{
269 TRACE("(%p)->(%d)\n", This, dwCookie);
270
271 if(dwCookie == 0 || dwCookie > This->maxSinks) return E_INVALIDARG;
272
273 if(This->sinks[dwCookie-1] == NULL) return CONNECT_E_NOCONNECTION;
274
275 IUnknown_Release(This->sinks[dwCookie-1]);
276 This->sinks[dwCookie-1] = NULL;
277 This->nSinks--;
278 return S_OK;
279}
280
281/************************************************************************
282 * ConnectionPointImpl_EnumConnections (IConnectionPoint)
283 *
284 */
286 IConnectionPoint *iface,
287 LPENUMCONNECTIONS *ppEnum)
288{
290 CONNECTDATA *pCD;
291 DWORD i, nextslot;
292 EnumConnectionsImpl *EnumObj;
293 HRESULT hr;
294
295 TRACE("(%p)->(%p)\n", This, ppEnum);
296
297 *ppEnum = NULL;
298
299 if(This->nSinks == 0) return OLE_E_NOCONNECTION;
300
301 pCD = HeapAlloc(GetProcessHeap(), 0, sizeof(CONNECTDATA) * This->nSinks);
302
303 for(i = 0, nextslot = 0; i < This->maxSinks; i++) {
304 if(This->sinks[i] != NULL) {
305 pCD[nextslot].pUnk = This->sinks[i];
306 pCD[nextslot].dwCookie = i + 1;
307 nextslot++;
308 }
309 }
310 assert(nextslot == This->nSinks);
311
312 /* Bump the ref count of this object up by one. It gets Released in
313 IEnumConnections_Release */
314 IConnectionPoint_AddRef(iface);
315
316 EnumObj = EnumConnectionsImpl_Construct((IUnknown*)iface, This->nSinks, pCD);
317 hr = IEnumConnections_QueryInterface(&EnumObj->IEnumConnections_iface,
318 &IID_IEnumConnections, (void**)ppEnum);
319 IEnumConnections_Release(&EnumObj->IEnumConnections_iface);
320
321 HeapFree(GetProcessHeap(), 0, pCD);
322 return hr;
323}
324
325static const IConnectionPointVtbl ConnectionPointImpl_VTable =
326{
335};
336
337
338static const IEnumConnectionsVtbl EnumConnectionsImpl_VTable;
339
340/************************************************************************
341 * EnumConnectionsImpl_Construct
342 */
344 DWORD nSinks,
345 CONNECTDATA *pCD)
346{
348 DWORD i;
349
350 Obj->IEnumConnections_iface.lpVtbl = &EnumConnectionsImpl_VTable;
351 Obj->ref = 1;
352 Obj->pUnk = pUnk;
353 Obj->pCD = HeapAlloc(GetProcessHeap(), 0, nSinks * sizeof(CONNECTDATA));
354 Obj->nConns = nSinks;
355 Obj->nCur = 0;
356
357 for(i = 0; i < nSinks; i++) {
358 Obj->pCD[i] = pCD[i];
359 IUnknown_AddRef(Obj->pCD[i].pUnk);
360 }
361 return Obj;
362}
363
364/************************************************************************
365 * EnumConnectionsImpl_Destroy
366 */
368{
369 DWORD i;
370
371 for(i = 0; i < Obj->nConns; i++)
372 IUnknown_Release(Obj->pCD[i].pUnk);
373
374 HeapFree(GetProcessHeap(), 0, Obj->pCD);
376 return;
377}
378
379/************************************************************************
380 * EnumConnectionsImpl_QueryInterface (IUnknown)
381 *
382 * See Windows documentation for more details on IUnknown methods.
383 */
385 IEnumConnections* iface,
386 REFIID riid,
387 void** ppvObject)
388{
390 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
391
392 /*
393 * Perform a sanity check on the parameters.
394 */
395 if (!ppvObject)
396 return E_INVALIDARG;
397
398 /*
399 * Initialize the return parameter.
400 */
401 *ppvObject = 0;
402
404 *ppvObject = iface;
405
406 /*
407 * Check that we obtained an interface.
408 */
409 if ((*ppvObject)==0)
410 {
411 FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid));
412 return E_NOINTERFACE;
413 }
414
415 IUnknown_AddRef((IUnknown*)*ppvObject);
416
417 return S_OK;
418}
419
420
421/************************************************************************
422 * EnumConnectionsImpl_AddRef (IUnknown)
423 *
424 * See Windows documentation for more details on IUnknown methods.
425 */
427{
429 ULONG refCount = InterlockedIncrement(&This->ref);
430
431 TRACE("(%p)->(ref before=%d)\n", This, refCount - 1);
432
433 IUnknown_AddRef(This->pUnk);
434 return refCount;
435}
436
437/************************************************************************
438 * EnumConnectionsImpl_Release (IUnknown)
439 *
440 * See Windows documentation for more details on IUnknown methods.
441 */
443{
445 ULONG refCount = InterlockedDecrement(&This->ref);
446
447 TRACE("(%p)->(ref before=%d)\n", This, refCount + 1);
448
449 IUnknown_Release(This->pUnk);
450
451 /*
452 * If the reference count goes down to 0, perform suicide.
453 */
454 if (!refCount) EnumConnectionsImpl_Destroy(This);
455
456 return refCount;
457}
458
459/************************************************************************
460 * EnumConnectionsImpl_Next (IEnumConnections)
461 *
462 */
464 ULONG cConn, LPCONNECTDATA pCD,
465 ULONG *pEnum)
466{
468 DWORD nRet = 0;
469 TRACE("(%p)->(%d, %p, %p)\n", This, cConn, pCD, pEnum);
470
471 if(pEnum == NULL) {
472 if(cConn != 1)
473 return E_POINTER;
474 } else
475 *pEnum = 0;
476
477 if(This->nCur >= This->nConns)
478 return S_FALSE;
479
480 while(This->nCur < This->nConns && cConn) {
481 *pCD++ = This->pCD[This->nCur];
482 IUnknown_AddRef(This->pCD[This->nCur].pUnk);
483 This->nCur++;
484 cConn--;
485 nRet++;
486 }
487
488 if(pEnum)
489 *pEnum = nRet;
490
491 return S_OK;
492}
493
494
495/************************************************************************
496 * EnumConnectionsImpl_Skip (IEnumConnections)
497 *
498 */
500 ULONG cSkip)
501{
503 TRACE("(%p)->(%d)\n", This, cSkip);
504
505 if(This->nCur + cSkip >= This->nConns)
506 return S_FALSE;
507
508 This->nCur += cSkip;
509
510 return S_OK;
511}
512
513
514/************************************************************************
515 * EnumConnectionsImpl_Reset (IEnumConnections)
516 *
517 */
519{
521 TRACE("(%p)\n", This);
522
523 This->nCur = 0;
524
525 return S_OK;
526}
527
528
529/************************************************************************
530 * EnumConnectionsImpl_Clone (IEnumConnections)
531 *
532 */
534 LPENUMCONNECTIONS *ppEnum)
535{
537 EnumConnectionsImpl *newObj;
538 TRACE("(%p)->(%p)\n", This, ppEnum);
539
540 newObj = EnumConnectionsImpl_Construct(This->pUnk, This->nConns, This->pCD);
541 newObj->nCur = This->nCur;
542 *ppEnum = &newObj->IEnumConnections_iface;
543 IUnknown_AddRef(This->pUnk);
544 return S_OK;
545}
546
547static const IEnumConnectionsVtbl EnumConnectionsImpl_VTable =
548{
556};
557
558/************************************************************************
559 *
560 * The exported function to create the connection point.
561 * NB not a windows API
562 *
563 * PARAMS
564 * pUnk [in] IUnknown of object to which the ConnectionPoint is associated.
565 * Needed to access IConnectionPointContainer.
566 *
567 * riid [in] IID of sink interface that this ConnectionPoint manages
568 *
569 * pCP [out] returns IConnectionPoint
570 *
571 */
573 IConnectionPoint **pCP)
574{
576
577 TRACE("(%p %s %p)\n", pUnk, debugstr_guid(riid), pCP);
578
579 *pCP = NULL;
580 Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj));
581 if (!Obj)
582 return E_OUTOFMEMORY;
583
584 Obj->IConnectionPoint_iface.lpVtbl = &ConnectionPointImpl_VTable;
585 Obj->Obj = pUnk;
586 Obj->ref = 1;
587 Obj->iid = *riid;
588 Obj->maxSinks = MAXSINKS;
590 Obj->nSinks = 0;
591
592 *pCP = &Obj->IConnectionPoint_iface;
593 return S_OK;
594}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
Obj()
Definition: swap_test.cpp:67
static const IConnectionPointVtbl ConnectionPointImpl_VTable
Definition: connpt.c:325
static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface, IUnknown *lpUnk, DWORD *pdwCookie)
Definition: connpt.c:232
static HRESULT WINAPI ConnectionPointImpl_GetConnectionInterface(IConnectionPoint *iface, IID *piid)
Definition: connpt.c:204
static EnumConnectionsImpl * impl_from_IEnumConnections(IEnumConnections *iface)
Definition: connpt.c:99
static HRESULT WINAPI EnumConnectionsImpl_Reset(IEnumConnections *iface)
Definition: connpt.c:518
static void ConnectionPointImpl_Destroy(ConnectionPointImpl *Obj)
Definition: connpt.c:107
static ConnectionPointImpl * impl_from_IConnectionPoint(IConnectionPoint *iface)
Definition: connpt.c:94
static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections *iface, ULONG cSkip)
Definition: connpt.c:499
static const IEnumConnectionsVtbl EnumConnectionsImpl_VTable
Definition: connpt.c:338
static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint *iface)
Definition: connpt.c:169
static HRESULT WINAPI ConnectionPointImpl_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
Definition: connpt.c:265
static EnumConnectionsImpl * EnumConnectionsImpl_Construct(IUnknown *pUnk, DWORD nSinks, CONNECTDATA *pCD)
Definition: connpt.c:343
static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections *iface, ULONG cConn, LPCONNECTDATA pCD, ULONG *pEnum)
Definition: connpt.c:463
static void EnumConnectionsImpl_Destroy(EnumConnectionsImpl *Obj)
Definition: connpt.c:367
static HRESULT WINAPI EnumConnectionsImpl_Clone(IEnumConnections *iface, LPENUMCONNECTIONS *ppEnum)
Definition: connpt.c:533
static HRESULT WINAPI EnumConnectionsImpl_QueryInterface(IEnumConnections *iface, REFIID riid, void **ppvObject)
Definition: connpt.c:384
static HRESULT WINAPI ConnectionPointImpl_QueryInterface(IConnectionPoint *iface, REFIID riid, void **ppvObject)
Definition: connpt.c:126
HRESULT CreateConnectionPoint(IUnknown *pUnk, REFIID riid, IConnectionPoint **pCP)
Definition: connpt.c:572
static HRESULT WINAPI ConnectionPointImpl_EnumConnections(IConnectionPoint *iface, LPENUMCONNECTIONS *ppEnum)
Definition: connpt.c:285
static ULONG WINAPI EnumConnectionsImpl_Release(IEnumConnections *iface)
Definition: connpt.c:442
static ULONG WINAPI ConnectionPointImpl_Release(IConnectionPoint *iface)
Definition: connpt.c:184
static HRESULT WINAPI ConnectionPointImpl_GetConnectionPointContainer(IConnectionPoint *iface, IConnectionPointContainer **ppCPC)
Definition: connpt.c:218
#define MAXSINKS
Definition: connpt.c:44
static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections *iface)
Definition: connpt.c:426
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define assert(x)
Definition: debug.h:53
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
HRESULT hr
Definition: shlfolder.c:183
#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
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define OLE_E_NOCONNECTION
Definition: winerror.h:2618
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_POINTER
Definition: winerror.h:2365