sapi: Implement ISpRegDataKey CreateKey.
[wine.git] / dlls / wmp / events.c
blob9f2b1cb4b296cf485bb5c2da2d82d0905c15e991
1 /*
2 * Implementation of event-related interfaces for WMP control:
4 * - IConnectionPointContainer
5 * - IConnectionPoint
7 * Copyright 2001 John R. Sheets (for CodeWeavers)
8 * Copyright 2006 Jacek Caban for CodeWeavers
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wmp_private.h"
26 #include "olectl.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(wmp);
31 static inline WindowsMediaPlayer *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
33 return CONTAINING_RECORD(iface, WindowsMediaPlayer, IConnectionPointContainer_iface);
36 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
37 REFIID riid, LPVOID *ppv)
39 WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
40 return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv);
43 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
45 WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
46 return IOleObject_AddRef(&This->IOleObject_iface);
49 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
51 WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
52 return IOleObject_Release(&This->IOleObject_iface);
55 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
56 IEnumConnectionPoints **ppEnum)
58 WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
59 FIXME("(%p)->(%p)\n", This, ppEnum);
60 return E_NOTIMPL;
63 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
64 REFIID riid, IConnectionPoint **ppCP){
65 WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
67 if(!ppCP) {
68 WARN("ppCP == NULL\n");
69 return E_POINTER;
72 *ppCP = NULL;
74 if(IsEqualGUID(&IID__WMPOCXEvents, riid)) {
75 TRACE("(%p)->(IID__WMPOCXEvents %p)\n", This, ppCP);
76 *ppCP = &This->wmpocx->IConnectionPoint_iface;
79 if(*ppCP) {
80 IConnectionPoint_AddRef(*ppCP);
81 return S_OK;
84 WARN("Unsupported IID %s\n", debugstr_guid(riid));
85 return CONNECT_E_NOCONNECTION;
88 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl =
90 ConnectionPointContainer_QueryInterface,
91 ConnectionPointContainer_AddRef,
92 ConnectionPointContainer_Release,
93 ConnectionPointContainer_EnumConnectionPoints,
94 ConnectionPointContainer_FindConnectionPoint
97 static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
99 return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
102 typedef struct {
103 IEnumConnections IEnumConnections_iface;
105 LONG ref;
107 ConnectionPoint *cp;
108 DWORD iter;
109 } EnumConnections;
111 static inline EnumConnections *impl_from_IEnumConnections(IEnumConnections *iface)
113 return CONTAINING_RECORD(iface, EnumConnections, IEnumConnections_iface);
116 static HRESULT WINAPI EnumConnections_QueryInterface(IEnumConnections *iface, REFIID riid, void **ppv)
118 EnumConnections *This = impl_from_IEnumConnections(iface);
120 if(IsEqualGUID(&IID_IUnknown, riid)) {
121 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
122 *ppv = &This->IEnumConnections_iface;
123 }else if(IsEqualGUID(&IID_IEnumConnections, riid)) {
124 TRACE("(%p)->(IID_IEnumConnections %p)\n", This, ppv);
125 *ppv = &This->IEnumConnections_iface;
126 }else {
127 WARN("Unsupported interface %s\n", debugstr_guid(riid));
128 *ppv = NULL;
129 return E_NOINTERFACE;
132 IUnknown_AddRef((IUnknown*)*ppv);
133 return S_OK;
136 static ULONG WINAPI EnumConnections_AddRef(IEnumConnections *iface)
138 EnumConnections *This = impl_from_IEnumConnections(iface);
139 LONG ref = InterlockedIncrement(&This->ref);
141 TRACE("(%p) ref=%ld\n", This, ref);
143 return ref;
146 static ULONG WINAPI EnumConnections_Release(IEnumConnections *iface)
148 EnumConnections *This = impl_from_IEnumConnections(iface);
149 LONG ref = InterlockedDecrement(&This->ref);
151 TRACE("(%p) ref=%ld\n", This, ref);
153 if(!ref) {
154 IConnectionPoint_Release(&This->cp->IConnectionPoint_iface);
155 free(This);
158 return ref;
161 static HRESULT WINAPI EnumConnections_Next(IEnumConnections *iface, ULONG cConnections, CONNECTDATA *pgcd, ULONG *pcFetched)
163 EnumConnections *This = impl_from_IEnumConnections(iface);
164 ULONG cnt = 0;
166 TRACE("(%p)->(%lu %p %p)\n", This, cConnections, pgcd, pcFetched);
168 while(cConnections--) {
169 while(This->iter < This->cp->sinks_size && !This->cp->sinks[This->iter])
170 This->iter++;
171 if(This->iter == This->cp->sinks_size)
172 break;
174 pgcd[cnt].pUnk = (IUnknown*)This->cp->sinks[This->iter];
175 pgcd[cnt].dwCookie = cnt+1;
176 This->iter++;
177 cnt++;
178 IUnknown_AddRef(pgcd[cnt].pUnk);
181 if(pcFetched)
182 *pcFetched = cnt;
183 return cnt ? S_OK : S_FALSE;
186 static HRESULT WINAPI EnumConnections_Skip(IEnumConnections *iface, ULONG cConnections)
188 EnumConnections *This = impl_from_IEnumConnections(iface);
189 FIXME("(%p)->(%lu)\n", This, cConnections);
190 return E_NOTIMPL;
193 static HRESULT WINAPI EnumConnections_Reset(IEnumConnections *iface)
195 EnumConnections *This = impl_from_IEnumConnections(iface);
196 FIXME("(%p)\n", This);
197 return E_NOTIMPL;
200 static HRESULT WINAPI EnumConnections_Clone(IEnumConnections *iface, IEnumConnections **ppEnum)
202 EnumConnections *This = impl_from_IEnumConnections(iface);
203 FIXME("(%p)->(%p)\n", This, ppEnum);
204 return E_NOTIMPL;
207 static const IEnumConnectionsVtbl EnumConnectionsVtbl = {
208 EnumConnections_QueryInterface,
209 EnumConnections_AddRef,
210 EnumConnections_Release,
211 EnumConnections_Next,
212 EnumConnections_Skip,
213 EnumConnections_Reset,
214 EnumConnections_Clone
217 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
218 REFIID riid, LPVOID *ppv)
220 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
222 *ppv = NULL;
224 if(IsEqualGUID(&IID_IUnknown, riid)) {
225 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
226 *ppv = &This->IConnectionPoint_iface;
227 }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
228 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This, ppv);
229 *ppv = &This->IConnectionPoint_iface;
232 if(*ppv) {
233 IConnectionPointContainer_AddRef(This->container);
234 return S_OK;
237 WARN("Unsupported interface %s\n", debugstr_guid(riid));
238 return E_NOINTERFACE;
241 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
243 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
244 return IConnectionPointContainer_AddRef(This->container);
247 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
249 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
250 return IConnectionPointContainer_Release(This->container);
253 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
255 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
257 TRACE("(%p)->(%p)\n", This, pIID);
259 *pIID = This->iid;
260 return S_OK;
263 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
264 IConnectionPointContainer **ppCPC)
266 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
268 TRACE("(%p)->(%p)\n", This, ppCPC);
270 *ppCPC = This->container;
271 IConnectionPointContainer_AddRef(This->container);
272 return S_OK;
275 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink,
276 DWORD *pdwCookie)
278 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
279 IDispatch *disp;
280 DWORD i;
281 HRESULT hres;
283 TRACE("(%p)->(%p %p)\n", This, pUnkSink, pdwCookie);
285 hres = IUnknown_QueryInterface(pUnkSink, &This->iid, (void**)&disp);
286 if(FAILED(hres)) {
287 hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatch, (void**)&disp);
288 if(FAILED(hres))
289 return CONNECT_E_CANNOTCONNECT;
292 if(This->sinks) {
293 for(i=0; i<This->sinks_size; i++) {
294 if(!This->sinks[i])
295 break;
298 if(i == This->sinks_size)
299 This->sinks = realloc(This->sinks, (++This->sinks_size)*sizeof(*This->sinks));
300 }else {
301 This->sinks = malloc(sizeof(*This->sinks));
302 This->sinks_size = 1;
303 i = 0;
306 This->sinks[i] = disp;
307 *pdwCookie = i+1;
309 return S_OK;
312 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
314 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
316 TRACE("(%p)->(%ld)\n", This, dwCookie);
318 if(!dwCookie || dwCookie > This->sinks_size || !This->sinks[dwCookie-1])
319 return CONNECT_E_NOCONNECTION;
321 IDispatch_Release(This->sinks[dwCookie-1]);
322 This->sinks[dwCookie-1] = NULL;
324 return S_OK;
327 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
328 IEnumConnections **ppEnum)
330 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
331 EnumConnections *ret;
333 TRACE("(%p)->(%p)\n", This, ppEnum);
335 ret = malloc(sizeof(*ret));
336 if(!ret)
337 return E_OUTOFMEMORY;
339 ret->IEnumConnections_iface.lpVtbl = &EnumConnectionsVtbl;
340 ret->ref = 1;
341 ret->iter = 0;
343 IConnectionPoint_AddRef(&This->IConnectionPoint_iface);
344 ret->cp = This;
346 *ppEnum = &ret->IEnumConnections_iface;
347 return S_OK;
351 static const IConnectionPointVtbl ConnectionPointVtbl =
353 ConnectionPoint_QueryInterface,
354 ConnectionPoint_AddRef,
355 ConnectionPoint_Release,
356 ConnectionPoint_GetConnectionInterface,
357 ConnectionPoint_GetConnectionPointContainer,
358 ConnectionPoint_Advise,
359 ConnectionPoint_Unadvise,
360 ConnectionPoint_EnumConnections
363 static void ConnectionPoint_Destroy(ConnectionPoint *This)
365 DWORD i;
367 for(i=0; i<This->sinks_size; i++) {
368 if(This->sinks[i])
369 IDispatch_Release(This->sinks[i]);
372 free(This->sinks);
373 free(This);
376 static void ConnectionPoint_Create(REFIID riid, ConnectionPoint **cp,
377 IConnectionPointContainer *container)
379 ConnectionPoint *ret = malloc(sizeof(ConnectionPoint));
381 ret->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl;
383 ret->sinks = NULL;
384 ret->sinks_size = 0;
385 ret->container = container;
387 ret->iid = *riid;
389 *cp = ret;
392 void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp)
394 wmp->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
395 ConnectionPoint_Create(&IID__WMPOCXEvents, &wmp->wmpocx, &wmp->IConnectionPointContainer_iface);
398 void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp)
400 ConnectionPoint_Destroy(wmp->wmpocx);
403 void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams)
405 DWORD i;
407 for(i=0; i<This->sinks_size; i++) {
408 if(This->sinks[i])
409 IDispatch_Invoke(This->sinks[i], dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
410 DISPATCH_METHOD, dispparams, NULL, NULL, NULL);