netprofm: Clear the object pointer on failure in QueryInterface.
[wine/multimedia.git] / dlls / netprofm / list.c
blobee0f7b71d37afe8e0236c4db614bddf21c93edc6
1 /*
2 * Copyright 2014 Hans Leidekker for CodeWeavers
3 * Copyright 2015 Michael Müller
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define COBJMACROS
22 #include "config.h"
23 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #define USE_WS_PREFIX
27 #include "winsock2.h"
28 #include "ws2ipdef.h"
29 #include "iphlpapi.h"
30 #include "ifdef.h"
31 #include "netioapi.h"
32 #include "initguid.h"
33 #include "objbase.h"
34 #include "ocidl.h"
35 #include "netlistmgr.h"
36 #include "olectl.h"
38 #include "wine/debug.h"
39 #include "netprofm_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(netprofm);
43 static inline void *heap_alloc( SIZE_T size )
45 return HeapAlloc( GetProcessHeap(), 0, size );
48 static inline BOOL heap_free( void *mem )
50 return HeapFree( GetProcessHeap(), 0, mem );
53 struct list_manager
55 INetworkListManager INetworkListManager_iface;
56 INetworkCostManager INetworkCostManager_iface;
57 IConnectionPointContainer IConnectionPointContainer_iface;
58 LONG refs;
61 struct connection_point
63 IConnectionPoint IConnectionPoint_iface;
64 IConnectionPointContainer *container;
65 LONG refs;
66 IID iid;
69 static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
71 return CONTAINING_RECORD(iface, struct list_manager, IConnectionPointContainer_iface);
74 static inline struct list_manager *impl_from_INetworkCostManager(
75 INetworkCostManager *iface )
77 return CONTAINING_RECORD( iface, struct list_manager, INetworkCostManager_iface );
80 static inline struct connection_point *impl_from_IConnectionPoint(
81 IConnectionPoint *iface )
83 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
86 static HRESULT WINAPI connection_point_QueryInterface(
87 IConnectionPoint *iface,
88 REFIID riid,
89 void **obj )
91 struct connection_point *cp = impl_from_IConnectionPoint( iface );
92 TRACE( "%p, %s, %p\n", cp, debugstr_guid(riid), obj );
94 if (IsEqualGUID( riid, &IID_IConnectionPoint ) ||
95 IsEqualGUID( riid, &IID_IUnknown ))
97 *obj = iface;
99 else
101 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
102 *obj = NULL;
103 return E_NOINTERFACE;
105 IConnectionPoint_AddRef( iface );
106 return S_OK;
109 static ULONG WINAPI connection_point_AddRef(
110 IConnectionPoint *iface )
112 struct connection_point *cp = impl_from_IConnectionPoint( iface );
113 return InterlockedIncrement( &cp->refs );
116 static ULONG WINAPI connection_point_Release(
117 IConnectionPoint *iface )
119 struct connection_point *cp = impl_from_IConnectionPoint( iface );
120 LONG refs = InterlockedDecrement( &cp->refs );
121 if (!refs)
123 TRACE( "destroying %p\n", cp );
124 IConnectionPointContainer_Release( cp->container );
125 heap_free( cp );
127 return refs;
130 static HRESULT WINAPI connection_point_GetConnectionInterface(
131 IConnectionPoint *iface,
132 IID *iid )
134 struct connection_point *cp = impl_from_IConnectionPoint( iface );
135 TRACE( "%p, %p\n", cp, iid );
137 if (!iid)
138 return E_POINTER;
140 memcpy( iid, &cp->iid, sizeof(*iid) );
141 return S_OK;
144 static HRESULT WINAPI connection_point_GetConnectionPointContainer(
145 IConnectionPoint *iface,
146 IConnectionPointContainer **container )
148 struct connection_point *cp = impl_from_IConnectionPoint( iface );
149 TRACE( "%p, %p\n", cp, container );
151 if (!container)
152 return E_POINTER;
154 IConnectionPointContainer_AddRef( cp->container );
155 *container = cp->container;
156 return S_OK;
159 static HRESULT WINAPI connection_point_Advise(
160 IConnectionPoint *iface,
161 IUnknown *sink,
162 DWORD *cookie )
164 struct connection_point *cp = impl_from_IConnectionPoint( iface );
165 FIXME( "%p, %p, %p - stub\n", cp, sink, cookie );
167 if (!sink || !cookie)
168 return E_POINTER;
170 return CONNECT_E_CANNOTCONNECT;
173 static HRESULT WINAPI connection_point_Unadvise(
174 IConnectionPoint *iface,
175 DWORD cookie )
177 struct connection_point *cp = impl_from_IConnectionPoint( iface );
178 FIXME( "%p, %d - stub\n", cp, cookie );
180 return E_POINTER;
183 static HRESULT WINAPI connection_point_EnumConnections(
184 IConnectionPoint *iface,
185 IEnumConnections **connections )
187 struct connection_point *cp = impl_from_IConnectionPoint( iface );
188 FIXME( "%p, %p - stub\n", cp, connections );
190 return E_NOTIMPL;
193 static const IConnectionPointVtbl connection_point_vtbl =
195 connection_point_QueryInterface,
196 connection_point_AddRef,
197 connection_point_Release,
198 connection_point_GetConnectionInterface,
199 connection_point_GetConnectionPointContainer,
200 connection_point_Advise,
201 connection_point_Unadvise,
202 connection_point_EnumConnections
205 static HRESULT connection_point_create(
206 IConnectionPoint **obj,
207 REFIID riid,
208 IConnectionPointContainer *container )
210 struct connection_point *cp;
211 TRACE( "%p, %s, %p\n", obj, debugstr_guid(riid), container );
213 if (!(cp = heap_alloc( sizeof(*cp) ))) return E_OUTOFMEMORY;
214 cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
215 cp->container = container;
216 cp->refs = 1;
218 memcpy( &cp->iid, riid, sizeof(*riid) );
219 IConnectionPointContainer_AddRef( container );
221 *obj = &cp->IConnectionPoint_iface;
222 TRACE( "returning iface %p\n", *obj );
223 return S_OK;
226 static HRESULT WINAPI cost_manager_QueryInterface(
227 INetworkCostManager *iface,
228 REFIID riid,
229 void **obj )
231 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
232 return INetworkListManager_QueryInterface( &mgr->INetworkListManager_iface, riid, obj );
235 static ULONG WINAPI cost_manager_AddRef(
236 INetworkCostManager *iface )
238 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
239 return INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
242 static ULONG WINAPI cost_manager_Release(
243 INetworkCostManager *iface )
245 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
246 return INetworkListManager_Release( &mgr->INetworkListManager_iface );
249 static HRESULT WINAPI cost_manager_GetCost(
250 INetworkCostManager *iface, DWORD *pCost, NLM_SOCKADDR *pDestIPAddr)
252 FIXME( "%p, %p, %p\n", iface, pCost, pDestIPAddr );
254 if (!pCost) return E_POINTER;
256 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
257 return S_OK;
260 static BOOL map_address_6to4( const SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
262 ULONG i;
264 if (addr6->sin6_family != WS_AF_INET6) return FALSE;
266 for (i = 0; i < 5; i++)
267 if (addr6->sin6_addr.u.Word[i]) return FALSE;
269 if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
271 addr4->sin_family = WS_AF_INET;
272 addr4->sin_port = addr6->sin6_port;
273 addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
274 memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
276 return TRUE;
279 static HRESULT WINAPI cost_manager_GetDataPlanStatus(
280 INetworkCostManager *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus,
281 NLM_SOCKADDR *pDestIPAddr)
283 DWORD ret, index;
284 NET_LUID luid;
285 SOCKADDR *dst = (SOCKADDR *)pDestIPAddr;
286 SOCKADDR_IN addr4, *dst4;
288 FIXME( "%p, %p, %p\n", iface, pDataPlanStatus, pDestIPAddr );
290 if (!pDataPlanStatus) return E_POINTER;
292 if (dst && ((dst->sa_family == WS_AF_INET && (dst4 = (SOCKADDR_IN *)dst)) ||
293 ((dst->sa_family == WS_AF_INET6 && map_address_6to4( (const SOCKADDR_IN6 *)dst, &addr4 )
294 && (dst4 = &addr4)))))
296 if ((ret = GetBestInterface( dst4->sin_addr.S_un.S_addr, &index )))
297 return HRESULT_FROM_WIN32( ret );
299 if ((ret = ConvertInterfaceIndexToLuid( index, &luid )))
300 return HRESULT_FROM_WIN32( ret );
302 if ((ret = ConvertInterfaceLuidToGuid( &luid, &pDataPlanStatus->InterfaceGuid )))
303 return HRESULT_FROM_WIN32( ret );
305 else
307 FIXME( "interface guid not found\n" );
308 memset( &pDataPlanStatus->InterfaceGuid, 0, sizeof(pDataPlanStatus->InterfaceGuid) );
311 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
312 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
313 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
314 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
315 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
316 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
317 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
318 pDataPlanStatus->Reserved = 0;
320 return S_OK;
323 static HRESULT WINAPI cost_manager_SetDestinationAddresses(
324 INetworkCostManager *iface, UINT32 length, NLM_SOCKADDR *pDestIPAddrList,
325 VARIANT_BOOL bAppend)
327 FIXME( "%p, %u, %p, %x\n", iface, length, pDestIPAddrList, bAppend );
328 return E_NOTIMPL;
331 static const INetworkCostManagerVtbl cost_manager_vtbl =
333 cost_manager_QueryInterface,
334 cost_manager_AddRef,
335 cost_manager_Release,
336 cost_manager_GetCost,
337 cost_manager_GetDataPlanStatus,
338 cost_manager_SetDestinationAddresses
341 static inline struct list_manager *impl_from_INetworkListManager(
342 INetworkListManager *iface )
344 return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface );
347 static ULONG WINAPI list_manager_AddRef(
348 INetworkListManager *iface )
350 struct list_manager *mgr = impl_from_INetworkListManager( iface );
351 return InterlockedIncrement( &mgr->refs );
354 static ULONG WINAPI list_manager_Release(
355 INetworkListManager *iface )
357 struct list_manager *mgr = impl_from_INetworkListManager( iface );
358 LONG refs = InterlockedDecrement( &mgr->refs );
359 if (!refs)
361 TRACE( "destroying %p\n", mgr );
362 heap_free( mgr );
364 return refs;
367 static HRESULT WINAPI list_manager_QueryInterface(
368 INetworkListManager *iface,
369 REFIID riid,
370 void **obj )
372 struct list_manager *mgr = impl_from_INetworkListManager( iface );
374 TRACE( "%p, %s, %p\n", mgr, debugstr_guid(riid), obj );
376 if (IsEqualGUID( riid, &IID_INetworkListManager ) ||
377 IsEqualGUID( riid, &IID_IUnknown ))
379 *obj = iface;
381 else if (IsEqualGUID( riid, &IID_INetworkCostManager ))
383 *obj = &mgr->INetworkCostManager_iface;
385 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
387 *obj = &mgr->IConnectionPointContainer_iface;
389 else
391 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
392 *obj = NULL;
393 return E_NOINTERFACE;
395 INetworkListManager_AddRef( iface );
396 return S_OK;
399 static HRESULT WINAPI list_manager_GetTypeInfoCount(
400 INetworkListManager *iface,
401 UINT *count )
403 FIXME("\n");
404 return E_NOTIMPL;
407 static HRESULT WINAPI list_manager_GetTypeInfo(
408 INetworkListManager *iface,
409 UINT index,
410 LCID lcid,
411 ITypeInfo **info )
413 FIXME("\n");
414 return E_NOTIMPL;
417 static HRESULT WINAPI list_manager_GetIDsOfNames(
418 INetworkListManager *iface,
419 REFIID riid,
420 LPOLESTR *names,
421 UINT count,
422 LCID lcid,
423 DISPID *dispid )
425 FIXME("\n");
426 return E_NOTIMPL;
429 static HRESULT WINAPI list_manager_Invoke(
430 INetworkListManager *iface,
431 DISPID member,
432 REFIID riid,
433 LCID lcid,
434 WORD flags,
435 DISPPARAMS *params,
436 VARIANT *result,
437 EXCEPINFO *excep_info,
438 UINT *arg_err )
440 FIXME("\n");
441 return E_NOTIMPL;
444 static HRESULT WINAPI list_manager_GetNetworks(
445 INetworkListManager *iface,
446 NLM_ENUM_NETWORK Flags,
447 IEnumNetworks **ppEnumNetwork )
449 FIXME( "%p, %x, %p\n", iface, Flags, ppEnumNetwork );
450 return E_NOTIMPL;
453 static HRESULT WINAPI list_manager_GetNetwork(
454 INetworkListManager *iface,
455 GUID gdNetworkId,
456 INetwork **ppNetwork )
458 FIXME( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkId), ppNetwork );
459 return E_NOTIMPL;
462 static HRESULT WINAPI list_manager_GetNetworkConnections(
463 INetworkListManager *iface,
464 IEnumNetworkConnections **ppEnum )
466 FIXME( "%p, %p\n", iface, ppEnum );
467 return E_NOTIMPL;
470 static HRESULT WINAPI list_manager_GetNetworkConnection(
471 INetworkListManager *iface,
472 GUID gdNetworkConnectionId,
473 INetworkConnection **ppNetworkConnection )
475 FIXME( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkConnectionId),
476 ppNetworkConnection );
477 return E_NOTIMPL;
480 static HRESULT WINAPI list_manager_IsConnectedToInternet(
481 INetworkListManager *iface,
482 VARIANT_BOOL *pbIsConnected )
484 FIXME( "%p, %p\n", iface, pbIsConnected );
486 *pbIsConnected = VARIANT_TRUE;
487 return S_OK;
490 static HRESULT WINAPI list_manager_IsConnected(
491 INetworkListManager *iface,
492 VARIANT_BOOL *pbIsConnected )
494 FIXME( "%p, %p\n", iface, pbIsConnected );
496 *pbIsConnected = VARIANT_TRUE;
497 return S_OK;
500 static HRESULT WINAPI list_manager_GetConnectivity(
501 INetworkListManager *iface,
502 NLM_CONNECTIVITY *pConnectivity )
504 FIXME( "%p, %p\n", iface, pConnectivity );
506 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
507 return S_OK;
510 static const INetworkListManagerVtbl list_manager_vtbl =
512 list_manager_QueryInterface,
513 list_manager_AddRef,
514 list_manager_Release,
515 list_manager_GetTypeInfoCount,
516 list_manager_GetTypeInfo,
517 list_manager_GetIDsOfNames,
518 list_manager_Invoke,
519 list_manager_GetNetworks,
520 list_manager_GetNetwork,
521 list_manager_GetNetworkConnections,
522 list_manager_GetNetworkConnection,
523 list_manager_IsConnectedToInternet,
524 list_manager_IsConnected,
525 list_manager_GetConnectivity
528 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
529 REFIID riid, void **ppv)
531 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
532 return INetworkListManager_QueryInterface(&This->INetworkListManager_iface, riid, ppv);
535 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
537 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
538 return INetworkListManager_AddRef(&This->INetworkListManager_iface);
541 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
543 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
544 return INetworkListManager_Release(&This->INetworkListManager_iface);
547 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
548 IEnumConnectionPoints **ppEnum)
550 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
551 FIXME("(%p)->(%p): stub\n", This, ppEnum);
552 return E_NOTIMPL;
555 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
556 REFIID riid, IConnectionPoint **cp)
558 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
560 TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
562 if (!riid || !cp)
563 return E_POINTER;
565 if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ) ||
566 IsEqualGUID( riid, &IID_INetworkCostManagerEvents ) ||
567 IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
568 return connection_point_create( cp, riid, iface );
570 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
572 *cp = NULL;
573 return E_NOINTERFACE;
576 static const struct IConnectionPointContainerVtbl cpc_vtbl =
578 ConnectionPointContainer_QueryInterface,
579 ConnectionPointContainer_AddRef,
580 ConnectionPointContainer_Release,
581 ConnectionPointContainer_EnumConnectionPoints,
582 ConnectionPointContainer_FindConnectionPoint
585 HRESULT list_manager_create( void **obj )
587 struct list_manager *mgr;
589 TRACE( "%p\n", obj );
591 if (!(mgr = heap_alloc( sizeof(*mgr) ))) return E_OUTOFMEMORY;
592 mgr->INetworkListManager_iface.lpVtbl = &list_manager_vtbl;
593 mgr->INetworkCostManager_iface.lpVtbl = &cost_manager_vtbl;
594 mgr->IConnectionPointContainer_iface.lpVtbl = &cpc_vtbl;
595 mgr->refs = 1;
597 *obj = &mgr->INetworkListManager_iface;
598 TRACE( "returning iface %p\n", *obj );
599 return S_OK;