netprofm: Implement INetworkListManager::IsConnectedToInternet and INetworkListManage...
[wine/multimedia.git] / dlls / netprofm / list.c
blob197ef688a48765980ad5b60b185b4ecb3452b71d
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 "wine/list.h"
40 #include "netprofm_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(netprofm);
44 static inline void *heap_alloc( SIZE_T size )
46 return HeapAlloc( GetProcessHeap(), 0, size );
49 static inline BOOL heap_free( void *mem )
51 return HeapFree( GetProcessHeap(), 0, mem );
54 struct network
56 INetwork INetwork_iface;
57 LONG refs;
58 struct list entry;
59 GUID id;
60 VARIANT_BOOL connected_to_internet;
61 VARIANT_BOOL connected;
64 struct connection
66 INetworkConnection INetworkConnection_iface;
67 INetworkConnectionCost INetworkConnectionCost_iface;
68 LONG refs;
69 struct list entry;
70 GUID id;
71 INetwork *network;
72 VARIANT_BOOL connected_to_internet;
73 VARIANT_BOOL connected;
76 struct list_manager
78 INetworkListManager INetworkListManager_iface;
79 INetworkCostManager INetworkCostManager_iface;
80 IConnectionPointContainer IConnectionPointContainer_iface;
81 LONG refs;
82 struct list networks;
83 struct list connections;
86 struct connection_point
88 IConnectionPoint IConnectionPoint_iface;
89 IConnectionPointContainer *container;
90 LONG refs;
91 IID iid;
94 static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
96 return CONTAINING_RECORD(iface, struct list_manager, IConnectionPointContainer_iface);
99 static inline struct list_manager *impl_from_INetworkCostManager(
100 INetworkCostManager *iface )
102 return CONTAINING_RECORD( iface, struct list_manager, INetworkCostManager_iface );
105 static inline struct connection_point *impl_from_IConnectionPoint(
106 IConnectionPoint *iface )
108 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
111 static HRESULT WINAPI connection_point_QueryInterface(
112 IConnectionPoint *iface,
113 REFIID riid,
114 void **obj )
116 struct connection_point *cp = impl_from_IConnectionPoint( iface );
117 TRACE( "%p, %s, %p\n", cp, debugstr_guid(riid), obj );
119 if (IsEqualGUID( riid, &IID_IConnectionPoint ) ||
120 IsEqualGUID( riid, &IID_IUnknown ))
122 *obj = iface;
124 else
126 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
127 *obj = NULL;
128 return E_NOINTERFACE;
130 IConnectionPoint_AddRef( iface );
131 return S_OK;
134 static ULONG WINAPI connection_point_AddRef(
135 IConnectionPoint *iface )
137 struct connection_point *cp = impl_from_IConnectionPoint( iface );
138 return InterlockedIncrement( &cp->refs );
141 static ULONG WINAPI connection_point_Release(
142 IConnectionPoint *iface )
144 struct connection_point *cp = impl_from_IConnectionPoint( iface );
145 LONG refs = InterlockedDecrement( &cp->refs );
146 if (!refs)
148 TRACE( "destroying %p\n", cp );
149 IConnectionPointContainer_Release( cp->container );
150 heap_free( cp );
152 return refs;
155 static HRESULT WINAPI connection_point_GetConnectionInterface(
156 IConnectionPoint *iface,
157 IID *iid )
159 struct connection_point *cp = impl_from_IConnectionPoint( iface );
160 TRACE( "%p, %p\n", cp, iid );
162 if (!iid)
163 return E_POINTER;
165 memcpy( iid, &cp->iid, sizeof(*iid) );
166 return S_OK;
169 static HRESULT WINAPI connection_point_GetConnectionPointContainer(
170 IConnectionPoint *iface,
171 IConnectionPointContainer **container )
173 struct connection_point *cp = impl_from_IConnectionPoint( iface );
174 TRACE( "%p, %p\n", cp, container );
176 if (!container)
177 return E_POINTER;
179 IConnectionPointContainer_AddRef( cp->container );
180 *container = cp->container;
181 return S_OK;
184 static HRESULT WINAPI connection_point_Advise(
185 IConnectionPoint *iface,
186 IUnknown *sink,
187 DWORD *cookie )
189 struct connection_point *cp = impl_from_IConnectionPoint( iface );
190 FIXME( "%p, %p, %p - stub\n", cp, sink, cookie );
192 if (!sink || !cookie)
193 return E_POINTER;
195 return CONNECT_E_CANNOTCONNECT;
198 static HRESULT WINAPI connection_point_Unadvise(
199 IConnectionPoint *iface,
200 DWORD cookie )
202 struct connection_point *cp = impl_from_IConnectionPoint( iface );
203 FIXME( "%p, %d - stub\n", cp, cookie );
205 return E_POINTER;
208 static HRESULT WINAPI connection_point_EnumConnections(
209 IConnectionPoint *iface,
210 IEnumConnections **connections )
212 struct connection_point *cp = impl_from_IConnectionPoint( iface );
213 FIXME( "%p, %p - stub\n", cp, connections );
215 return E_NOTIMPL;
218 static const IConnectionPointVtbl connection_point_vtbl =
220 connection_point_QueryInterface,
221 connection_point_AddRef,
222 connection_point_Release,
223 connection_point_GetConnectionInterface,
224 connection_point_GetConnectionPointContainer,
225 connection_point_Advise,
226 connection_point_Unadvise,
227 connection_point_EnumConnections
230 static HRESULT connection_point_create(
231 IConnectionPoint **obj,
232 REFIID riid,
233 IConnectionPointContainer *container )
235 struct connection_point *cp;
236 TRACE( "%p, %s, %p\n", obj, debugstr_guid(riid), container );
238 if (!(cp = heap_alloc( sizeof(*cp) ))) return E_OUTOFMEMORY;
239 cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
240 cp->container = container;
241 cp->refs = 1;
243 memcpy( &cp->iid, riid, sizeof(*riid) );
244 IConnectionPointContainer_AddRef( container );
246 *obj = &cp->IConnectionPoint_iface;
247 TRACE( "returning iface %p\n", *obj );
248 return S_OK;
251 static inline struct network *impl_from_INetwork(
252 INetwork *iface )
254 return CONTAINING_RECORD( iface, struct network, INetwork_iface );
257 static HRESULT WINAPI network_QueryInterface(
258 INetwork *iface, REFIID riid, void **obj )
260 struct network *network = impl_from_INetwork( iface );
262 TRACE( "%p, %s, %p\n", network, debugstr_guid(riid), obj );
264 if (IsEqualIID( riid, &IID_INetwork ) ||
265 IsEqualIID( riid, &IID_IDispatch ) ||
266 IsEqualIID( riid, &IID_IUnknown ))
268 *obj = iface;
269 INetwork_AddRef( iface );
270 return S_OK;
272 else
274 WARN( "interface not supported %s\n", debugstr_guid(riid) );
275 *obj = NULL;
276 return E_NOINTERFACE;
280 static ULONG WINAPI network_AddRef(
281 INetwork *iface )
283 struct network *network = impl_from_INetwork( iface );
285 TRACE( "%p\n", network );
286 return InterlockedIncrement( &network->refs );
289 static ULONG WINAPI network_Release(
290 INetwork *iface )
292 struct network *network = impl_from_INetwork( iface );
293 LONG refs;
295 TRACE( "%p\n", network );
297 if (!(refs = InterlockedDecrement( &network->refs )))
299 list_remove( &network->entry );
300 heap_free( network );
302 return refs;
305 static HRESULT WINAPI network_GetTypeInfoCount(
306 INetwork *iface,
307 UINT *count )
309 FIXME("\n");
310 return E_NOTIMPL;
313 static HRESULT WINAPI network_GetTypeInfo(
314 INetwork *iface,
315 UINT index,
316 LCID lcid,
317 ITypeInfo **info )
319 FIXME("\n");
320 return E_NOTIMPL;
323 static HRESULT WINAPI network_GetIDsOfNames(
324 INetwork *iface,
325 REFIID riid,
326 LPOLESTR *names,
327 UINT count,
328 LCID lcid,
329 DISPID *dispid )
331 FIXME("\n");
332 return E_NOTIMPL;
335 static HRESULT WINAPI network_Invoke(
336 INetwork *iface,
337 DISPID member,
338 REFIID riid,
339 LCID lcid,
340 WORD flags,
341 DISPPARAMS *params,
342 VARIANT *result,
343 EXCEPINFO *excep_info,
344 UINT *arg_err )
346 FIXME("\n");
347 return E_NOTIMPL;
350 static HRESULT WINAPI network_GetName(
351 INetwork *iface,
352 BSTR *pszNetworkName )
354 FIXME( "%p, %p\n", iface, pszNetworkName );
355 return E_NOTIMPL;
358 static HRESULT WINAPI network_SetName(
359 INetwork *iface,
360 BSTR szNetworkNewName )
362 FIXME( "%p, %s\n", iface, debugstr_w(szNetworkNewName) );
363 return E_NOTIMPL;
366 static HRESULT WINAPI network_GetDescription(
367 INetwork *iface,
368 BSTR *pszDescription )
370 FIXME( "%p, %p\n", iface, pszDescription );
371 return E_NOTIMPL;
374 static HRESULT WINAPI network_SetDescription(
375 INetwork *iface,
376 BSTR szDescription )
378 FIXME( "%p, %s\n", iface, debugstr_w(szDescription) );
379 return E_NOTIMPL;
382 static HRESULT WINAPI network_GetNetworkId(
383 INetwork *iface,
384 GUID *pgdGuidNetworkId )
386 struct network *network = impl_from_INetwork( iface );
388 TRACE( "%p, %p\n", iface, pgdGuidNetworkId );
390 *pgdGuidNetworkId = network->id;
391 return S_OK;
394 static HRESULT WINAPI network_GetDomainType(
395 INetwork *iface,
396 NLM_DOMAIN_TYPE *pDomainType )
398 FIXME( "%p, %p\n", iface, pDomainType );
400 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
401 return S_OK;
404 static HRESULT WINAPI network_GetNetworkConnections(
405 INetwork *iface,
406 IEnumNetworkConnections **ppEnumNetworkConnection )
408 FIXME( "%p, %p\n", iface, ppEnumNetworkConnection );
409 return E_NOTIMPL;
412 static HRESULT WINAPI network_GetTimeCreatedAndConnected(
413 INetwork *iface,
414 DWORD *pdwLowDateTimeCreated,
415 DWORD *pdwHighDateTimeCreated,
416 DWORD *pdwLowDateTimeConnected,
417 DWORD *pdwHighDateTimeConnected )
419 FIXME( "%p, %p, %p, %p, %p\n", iface, pdwLowDateTimeCreated, pdwHighDateTimeCreated,
420 pdwLowDateTimeConnected, pdwHighDateTimeConnected );
421 return E_NOTIMPL;
424 static HRESULT WINAPI network_get_IsConnectedToInternet(
425 INetwork *iface,
426 VARIANT_BOOL *pbIsConnected )
428 struct network *network = impl_from_INetwork( iface );
430 TRACE( "%p, %p\n", iface, pbIsConnected );
432 *pbIsConnected = network->connected_to_internet;
433 return S_OK;
436 static HRESULT WINAPI network_get_IsConnected(
437 INetwork *iface,
438 VARIANT_BOOL *pbIsConnected )
440 struct network *network = impl_from_INetwork( iface );
442 TRACE( "%p, %p\n", iface, pbIsConnected );
444 *pbIsConnected = network->connected;
445 return S_OK;
448 static HRESULT WINAPI network_GetConnectivity(
449 INetwork *iface,
450 NLM_CONNECTIVITY *pConnectivity )
452 FIXME( "%p, %p\n", iface, pConnectivity );
454 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
455 return S_OK;
458 static HRESULT WINAPI network_GetCategory(
459 INetwork *iface,
460 NLM_NETWORK_CATEGORY *pCategory )
462 FIXME( "%p, %p\n", iface, pCategory );
464 *pCategory = NLM_NETWORK_CATEGORY_PUBLIC;
465 return S_OK;
468 static HRESULT WINAPI network_SetCategory(
469 INetwork *iface,
470 NLM_NETWORK_CATEGORY NewCategory )
472 FIXME( "%p, %u\n", iface, NewCategory );
473 return E_NOTIMPL;
476 static const struct INetworkVtbl network_vtbl =
478 network_QueryInterface,
479 network_AddRef,
480 network_Release,
481 network_GetTypeInfoCount,
482 network_GetTypeInfo,
483 network_GetIDsOfNames,
484 network_Invoke,
485 network_GetName,
486 network_SetName,
487 network_GetDescription,
488 network_SetDescription,
489 network_GetNetworkId,
490 network_GetDomainType,
491 network_GetNetworkConnections,
492 network_GetTimeCreatedAndConnected,
493 network_get_IsConnectedToInternet,
494 network_get_IsConnected,
495 network_GetConnectivity,
496 network_GetCategory,
497 network_SetCategory
500 static struct network *create_network( const GUID *id )
502 struct network *ret;
504 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
506 ret->INetwork_iface.lpVtbl = &network_vtbl;
507 ret->refs = 1;
508 ret->id = *id;
509 ret->connected = VARIANT_FALSE;
510 ret->connected_to_internet = VARIANT_FALSE;
511 list_init( &ret->entry );
513 return ret;
516 static HRESULT WINAPI cost_manager_QueryInterface(
517 INetworkCostManager *iface,
518 REFIID riid,
519 void **obj )
521 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
522 return INetworkListManager_QueryInterface( &mgr->INetworkListManager_iface, riid, obj );
525 static ULONG WINAPI cost_manager_AddRef(
526 INetworkCostManager *iface )
528 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
529 return INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
532 static ULONG WINAPI cost_manager_Release(
533 INetworkCostManager *iface )
535 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
536 return INetworkListManager_Release( &mgr->INetworkListManager_iface );
539 static HRESULT WINAPI cost_manager_GetCost(
540 INetworkCostManager *iface, DWORD *pCost, NLM_SOCKADDR *pDestIPAddr)
542 FIXME( "%p, %p, %p\n", iface, pCost, pDestIPAddr );
544 if (!pCost) return E_POINTER;
546 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
547 return S_OK;
550 static BOOL map_address_6to4( const SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
552 ULONG i;
554 if (addr6->sin6_family != WS_AF_INET6) return FALSE;
556 for (i = 0; i < 5; i++)
557 if (addr6->sin6_addr.u.Word[i]) return FALSE;
559 if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
561 addr4->sin_family = WS_AF_INET;
562 addr4->sin_port = addr6->sin6_port;
563 addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
564 memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
566 return TRUE;
569 static HRESULT WINAPI cost_manager_GetDataPlanStatus(
570 INetworkCostManager *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus,
571 NLM_SOCKADDR *pDestIPAddr)
573 DWORD ret, index;
574 NET_LUID luid;
575 SOCKADDR *dst = (SOCKADDR *)pDestIPAddr;
576 SOCKADDR_IN addr4, *dst4;
578 FIXME( "%p, %p, %p\n", iface, pDataPlanStatus, pDestIPAddr );
580 if (!pDataPlanStatus) return E_POINTER;
582 if (dst && ((dst->sa_family == WS_AF_INET && (dst4 = (SOCKADDR_IN *)dst)) ||
583 ((dst->sa_family == WS_AF_INET6 && map_address_6to4( (const SOCKADDR_IN6 *)dst, &addr4 )
584 && (dst4 = &addr4)))))
586 if ((ret = GetBestInterface( dst4->sin_addr.S_un.S_addr, &index )))
587 return HRESULT_FROM_WIN32( ret );
589 if ((ret = ConvertInterfaceIndexToLuid( index, &luid )))
590 return HRESULT_FROM_WIN32( ret );
592 if ((ret = ConvertInterfaceLuidToGuid( &luid, &pDataPlanStatus->InterfaceGuid )))
593 return HRESULT_FROM_WIN32( ret );
595 else
597 FIXME( "interface guid not found\n" );
598 memset( &pDataPlanStatus->InterfaceGuid, 0, sizeof(pDataPlanStatus->InterfaceGuid) );
601 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
602 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
603 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
604 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
605 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
606 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
607 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
608 pDataPlanStatus->Reserved = 0;
610 return S_OK;
613 static HRESULT WINAPI cost_manager_SetDestinationAddresses(
614 INetworkCostManager *iface, UINT32 length, NLM_SOCKADDR *pDestIPAddrList,
615 VARIANT_BOOL bAppend)
617 FIXME( "%p, %u, %p, %x\n", iface, length, pDestIPAddrList, bAppend );
618 return E_NOTIMPL;
621 static const INetworkCostManagerVtbl cost_manager_vtbl =
623 cost_manager_QueryInterface,
624 cost_manager_AddRef,
625 cost_manager_Release,
626 cost_manager_GetCost,
627 cost_manager_GetDataPlanStatus,
628 cost_manager_SetDestinationAddresses
631 struct networks_enum
633 IEnumNetworks IEnumNetworks_iface;
634 LONG refs;
635 struct list_manager *mgr;
636 struct list *cursor;
639 static inline struct networks_enum *impl_from_IEnumNetworks(
640 IEnumNetworks *iface )
642 return CONTAINING_RECORD( iface, struct networks_enum, IEnumNetworks_iface );
645 static HRESULT WINAPI networks_enum_QueryInterface(
646 IEnumNetworks *iface, REFIID riid, void **obj )
648 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
650 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
652 if (IsEqualIID( riid, &IID_IEnumNetworks ) ||
653 IsEqualIID( riid, &IID_IDispatch ) ||
654 IsEqualIID( riid, &IID_IUnknown ))
656 *obj = iface;
657 IEnumNetworks_AddRef( iface );
658 return S_OK;
660 else
662 WARN( "interface not supported %s\n", debugstr_guid(riid) );
663 *obj = NULL;
664 return E_NOINTERFACE;
668 static ULONG WINAPI networks_enum_AddRef(
669 IEnumNetworks *iface )
671 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
673 TRACE( "%p\n", iter );
674 return InterlockedIncrement( &iter->refs );
677 static ULONG WINAPI networks_enum_Release(
678 IEnumNetworks *iface )
680 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
681 LONG refs;
683 TRACE( "%p\n", iter );
685 if (!(refs = InterlockedDecrement( &iter->refs )))
687 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
688 heap_free( iter );
690 return refs;
693 static HRESULT WINAPI networks_enum_GetTypeInfoCount(
694 IEnumNetworks *iface,
695 UINT *count )
697 FIXME("\n");
698 return E_NOTIMPL;
701 static HRESULT WINAPI networks_enum_GetTypeInfo(
702 IEnumNetworks *iface,
703 UINT index,
704 LCID lcid,
705 ITypeInfo **info )
707 FIXME("\n");
708 return E_NOTIMPL;
711 static HRESULT WINAPI networks_enum_GetIDsOfNames(
712 IEnumNetworks *iface,
713 REFIID riid,
714 LPOLESTR *names,
715 UINT count,
716 LCID lcid,
717 DISPID *dispid )
719 FIXME("\n");
720 return E_NOTIMPL;
723 static HRESULT WINAPI networks_enum_Invoke(
724 IEnumNetworks *iface,
725 DISPID member,
726 REFIID riid,
727 LCID lcid,
728 WORD flags,
729 DISPPARAMS *params,
730 VARIANT *result,
731 EXCEPINFO *excep_info,
732 UINT *arg_err )
734 FIXME("\n");
735 return E_NOTIMPL;
738 static HRESULT WINAPI networks_enum_get__NewEnum(
739 IEnumNetworks *iface, IEnumVARIANT **ppEnumVar )
741 FIXME("\n");
742 return E_NOTIMPL;
745 static HRESULT WINAPI networks_enum_Next(
746 IEnumNetworks *iface, ULONG count, INetwork **ret, ULONG *fetched )
748 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
749 ULONG i = 0;
751 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
753 if (fetched) *fetched = 0;
754 if (!count) return S_OK;
756 while (iter->cursor && i < count)
758 struct network *network = LIST_ENTRY( iter->cursor, struct network, entry );
759 ret[i] = &network->INetwork_iface;
760 INetwork_AddRef( ret[i] );
761 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
762 i++;
764 if (fetched) *fetched = i;
766 return i < count ? S_FALSE : S_OK;
769 static HRESULT WINAPI networks_enum_Skip(
770 IEnumNetworks *iface, ULONG count )
772 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
774 TRACE( "%p, %u\n", iter, count);
776 if (!count) return S_OK;
777 if (!iter->cursor) return S_FALSE;
779 while (count--)
781 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
782 if (!iter->cursor) break;
785 return count ? S_FALSE : S_OK;
788 static HRESULT WINAPI networks_enum_Reset(
789 IEnumNetworks *iface )
791 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
793 TRACE( "%p\n", iter );
795 iter->cursor = list_head( &iter->mgr->networks );
796 return S_OK;
799 static HRESULT create_networks_enum(
800 struct list_manager *, IEnumNetworks** );
802 static HRESULT WINAPI networks_enum_Clone(
803 IEnumNetworks *iface, IEnumNetworks **ret )
805 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
807 TRACE( "%p, %p\n", iter, ret );
808 return create_networks_enum( iter->mgr, ret );
811 static const IEnumNetworksVtbl networks_enum_vtbl =
813 networks_enum_QueryInterface,
814 networks_enum_AddRef,
815 networks_enum_Release,
816 networks_enum_GetTypeInfoCount,
817 networks_enum_GetTypeInfo,
818 networks_enum_GetIDsOfNames,
819 networks_enum_Invoke,
820 networks_enum_get__NewEnum,
821 networks_enum_Next,
822 networks_enum_Skip,
823 networks_enum_Reset,
824 networks_enum_Clone
827 static HRESULT create_networks_enum(
828 struct list_manager *mgr, IEnumNetworks **ret )
830 struct networks_enum *iter;
832 *ret = NULL;
833 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
835 iter->IEnumNetworks_iface.lpVtbl = &networks_enum_vtbl;
836 iter->cursor = list_head( &mgr->networks );
837 iter->mgr = mgr;
838 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
839 iter->refs = 1;
841 *ret = &iter->IEnumNetworks_iface;
842 return S_OK;
845 static inline struct list_manager *impl_from_INetworkListManager(
846 INetworkListManager *iface )
848 return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface );
851 struct connections_enum
853 IEnumNetworkConnections IEnumNetworkConnections_iface;
854 LONG refs;
855 struct list_manager *mgr;
856 struct list *cursor;
859 static inline struct connections_enum *impl_from_IEnumNetworkConnections(
860 IEnumNetworkConnections *iface )
862 return CONTAINING_RECORD( iface, struct connections_enum, IEnumNetworkConnections_iface );
865 static HRESULT WINAPI connections_enum_QueryInterface(
866 IEnumNetworkConnections *iface, REFIID riid, void **obj )
868 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
870 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
872 if (IsEqualIID( riid, &IID_IEnumNetworkConnections ) ||
873 IsEqualIID( riid, &IID_IDispatch ) ||
874 IsEqualIID( riid, &IID_IUnknown ))
876 *obj = iface;
877 IEnumNetworkConnections_AddRef( iface );
878 return S_OK;
880 else
882 WARN( "interface not supported %s\n", debugstr_guid(riid) );
883 *obj = NULL;
884 return E_NOINTERFACE;
888 static ULONG WINAPI connections_enum_AddRef(
889 IEnumNetworkConnections *iface )
891 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
893 TRACE( "%p\n", iter );
894 return InterlockedIncrement( &iter->refs );
897 static ULONG WINAPI connections_enum_Release(
898 IEnumNetworkConnections *iface )
900 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
901 LONG refs;
903 TRACE( "%p\n", iter );
905 if (!(refs = InterlockedDecrement( &iter->refs )))
907 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
908 heap_free( iter );
910 return refs;
913 static HRESULT WINAPI connections_enum_GetTypeInfoCount(
914 IEnumNetworkConnections *iface,
915 UINT *count )
917 FIXME("\n");
918 return E_NOTIMPL;
921 static HRESULT WINAPI connections_enum_GetTypeInfo(
922 IEnumNetworkConnections *iface,
923 UINT index,
924 LCID lcid,
925 ITypeInfo **info )
927 FIXME("\n");
928 return E_NOTIMPL;
931 static HRESULT WINAPI connections_enum_GetIDsOfNames(
932 IEnumNetworkConnections *iface,
933 REFIID riid,
934 LPOLESTR *names,
935 UINT count,
936 LCID lcid,
937 DISPID *dispid )
939 FIXME("\n");
940 return E_NOTIMPL;
943 static HRESULT WINAPI connections_enum_Invoke(
944 IEnumNetworkConnections *iface,
945 DISPID member,
946 REFIID riid,
947 LCID lcid,
948 WORD flags,
949 DISPPARAMS *params,
950 VARIANT *result,
951 EXCEPINFO *excep_info,
952 UINT *arg_err )
954 FIXME("\n");
955 return E_NOTIMPL;
958 static HRESULT WINAPI connections_enum_get__NewEnum(
959 IEnumNetworkConnections *iface, IEnumVARIANT **ppEnumVar )
961 FIXME("\n");
962 return E_NOTIMPL;
965 static HRESULT WINAPI connections_enum_Next(
966 IEnumNetworkConnections *iface, ULONG count, INetworkConnection **ret, ULONG *fetched )
968 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
969 ULONG i = 0;
971 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
973 if (fetched) *fetched = 0;
974 if (!count) return S_OK;
976 while (iter->cursor && i < count)
978 struct connection *connection = LIST_ENTRY( iter->cursor, struct connection, entry );
979 ret[i] = &connection->INetworkConnection_iface;
980 INetworkConnection_AddRef( ret[i] );
981 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
982 i++;
984 if (fetched) *fetched = i;
986 return i < count ? S_FALSE : S_OK;
989 static HRESULT WINAPI connections_enum_Skip(
990 IEnumNetworkConnections *iface, ULONG count )
992 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
994 TRACE( "%p, %u\n", iter, count);
996 if (!count) return S_OK;
997 if (!iter->cursor) return S_FALSE;
999 while (count--)
1001 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1002 if (!iter->cursor) break;
1005 return count ? S_FALSE : S_OK;
1008 static HRESULT WINAPI connections_enum_Reset(
1009 IEnumNetworkConnections *iface )
1011 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1013 TRACE( "%p\n", iter );
1015 iter->cursor = list_head( &iter->mgr->connections );
1016 return S_OK;
1019 static HRESULT create_connections_enum(
1020 struct list_manager *, IEnumNetworkConnections** );
1022 static HRESULT WINAPI connections_enum_Clone(
1023 IEnumNetworkConnections *iface, IEnumNetworkConnections **ret )
1025 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1027 TRACE( "%p, %p\n", iter, ret );
1028 return create_connections_enum( iter->mgr, ret );
1031 static const IEnumNetworkConnectionsVtbl connections_enum_vtbl =
1033 connections_enum_QueryInterface,
1034 connections_enum_AddRef,
1035 connections_enum_Release,
1036 connections_enum_GetTypeInfoCount,
1037 connections_enum_GetTypeInfo,
1038 connections_enum_GetIDsOfNames,
1039 connections_enum_Invoke,
1040 connections_enum_get__NewEnum,
1041 connections_enum_Next,
1042 connections_enum_Skip,
1043 connections_enum_Reset,
1044 connections_enum_Clone
1047 static HRESULT create_connections_enum(
1048 struct list_manager *mgr, IEnumNetworkConnections **ret )
1050 struct connections_enum *iter;
1052 *ret = NULL;
1053 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
1055 iter->IEnumNetworkConnections_iface.lpVtbl = &connections_enum_vtbl;
1056 iter->mgr = mgr;
1057 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
1058 iter->cursor = list_head( &iter->mgr->connections );
1059 iter->refs = 1;
1061 *ret = &iter->IEnumNetworkConnections_iface;
1062 return S_OK;
1065 static ULONG WINAPI list_manager_AddRef(
1066 INetworkListManager *iface )
1068 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1069 return InterlockedIncrement( &mgr->refs );
1072 static ULONG WINAPI list_manager_Release(
1073 INetworkListManager *iface )
1075 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1076 LONG refs = InterlockedDecrement( &mgr->refs );
1077 if (!refs)
1079 struct list *ptr;
1081 TRACE( "destroying %p\n", mgr );
1083 while ((ptr = list_head( &mgr->networks )))
1085 struct network *network = LIST_ENTRY( ptr, struct network, entry );
1086 list_remove( &network->entry );
1087 INetwork_Release( &network->INetwork_iface );
1089 while ((ptr = list_head( &mgr->connections )))
1091 struct connection *connection = LIST_ENTRY( ptr, struct connection, entry );
1092 list_remove( &connection->entry );
1093 INetworkConnection_Release( &connection->INetworkConnection_iface );
1095 heap_free( mgr );
1097 return refs;
1100 static HRESULT WINAPI list_manager_QueryInterface(
1101 INetworkListManager *iface,
1102 REFIID riid,
1103 void **obj )
1105 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1107 TRACE( "%p, %s, %p\n", mgr, debugstr_guid(riid), obj );
1109 if (IsEqualGUID( riid, &IID_INetworkListManager ) ||
1110 IsEqualGUID( riid, &IID_IDispatch ) ||
1111 IsEqualGUID( riid, &IID_IUnknown ))
1113 *obj = iface;
1115 else if (IsEqualGUID( riid, &IID_INetworkCostManager ))
1117 *obj = &mgr->INetworkCostManager_iface;
1119 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
1121 *obj = &mgr->IConnectionPointContainer_iface;
1123 else
1125 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1126 *obj = NULL;
1127 return E_NOINTERFACE;
1129 INetworkListManager_AddRef( iface );
1130 return S_OK;
1133 static HRESULT WINAPI list_manager_GetTypeInfoCount(
1134 INetworkListManager *iface,
1135 UINT *count )
1137 FIXME("\n");
1138 return E_NOTIMPL;
1141 static HRESULT WINAPI list_manager_GetTypeInfo(
1142 INetworkListManager *iface,
1143 UINT index,
1144 LCID lcid,
1145 ITypeInfo **info )
1147 FIXME("\n");
1148 return E_NOTIMPL;
1151 static HRESULT WINAPI list_manager_GetIDsOfNames(
1152 INetworkListManager *iface,
1153 REFIID riid,
1154 LPOLESTR *names,
1155 UINT count,
1156 LCID lcid,
1157 DISPID *dispid )
1159 FIXME("\n");
1160 return E_NOTIMPL;
1163 static HRESULT WINAPI list_manager_Invoke(
1164 INetworkListManager *iface,
1165 DISPID member,
1166 REFIID riid,
1167 LCID lcid,
1168 WORD flags,
1169 DISPPARAMS *params,
1170 VARIANT *result,
1171 EXCEPINFO *excep_info,
1172 UINT *arg_err )
1174 FIXME("\n");
1175 return E_NOTIMPL;
1178 static HRESULT WINAPI list_manager_GetNetworks(
1179 INetworkListManager *iface,
1180 NLM_ENUM_NETWORK Flags,
1181 IEnumNetworks **ppEnumNetwork )
1183 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1185 TRACE( "%p, %x, %p\n", iface, Flags, ppEnumNetwork );
1186 if (Flags) FIXME( "flags %08x not supported\n", Flags );
1188 return create_networks_enum( mgr, ppEnumNetwork );
1191 static HRESULT WINAPI list_manager_GetNetwork(
1192 INetworkListManager *iface,
1193 GUID gdNetworkId,
1194 INetwork **ppNetwork )
1196 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1197 struct network *network;
1199 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkId), ppNetwork );
1201 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1203 if (IsEqualGUID( &network->id, &gdNetworkId ))
1205 *ppNetwork = &network->INetwork_iface;
1206 INetwork_AddRef( *ppNetwork );
1207 return S_OK;
1211 return S_FALSE;
1214 static HRESULT WINAPI list_manager_GetNetworkConnections(
1215 INetworkListManager *iface,
1216 IEnumNetworkConnections **ppEnum )
1218 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1220 TRACE( "%p, %p\n", iface, ppEnum );
1221 return create_connections_enum( mgr, ppEnum );
1224 static HRESULT WINAPI list_manager_GetNetworkConnection(
1225 INetworkListManager *iface,
1226 GUID gdNetworkConnectionId,
1227 INetworkConnection **ppNetworkConnection )
1229 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1230 struct connection *connection;
1232 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkConnectionId),
1233 ppNetworkConnection );
1235 LIST_FOR_EACH_ENTRY( connection, &mgr->connections, struct connection, entry )
1237 if (IsEqualGUID( &connection->id, &gdNetworkConnectionId ))
1239 *ppNetworkConnection = &connection->INetworkConnection_iface;
1240 INetworkConnection_AddRef( *ppNetworkConnection );
1241 return S_OK;
1245 return S_FALSE;
1248 static HRESULT WINAPI list_manager_IsConnectedToInternet(
1249 INetworkListManager *iface,
1250 VARIANT_BOOL *pbIsConnected )
1252 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1253 struct network *network;
1255 TRACE( "%p, %p\n", iface, pbIsConnected );
1257 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1259 if (network->connected_to_internet)
1261 *pbIsConnected = VARIANT_TRUE;
1262 return S_OK;
1266 *pbIsConnected = VARIANT_FALSE;
1267 return S_OK;
1270 static HRESULT WINAPI list_manager_IsConnected(
1271 INetworkListManager *iface,
1272 VARIANT_BOOL *pbIsConnected )
1274 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1275 struct network *network;
1277 TRACE( "%p, %p\n", iface, pbIsConnected );
1279 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1281 if (network->connected)
1283 *pbIsConnected = VARIANT_TRUE;
1284 return S_OK;
1288 *pbIsConnected = VARIANT_FALSE;
1289 return S_OK;
1292 static HRESULT WINAPI list_manager_GetConnectivity(
1293 INetworkListManager *iface,
1294 NLM_CONNECTIVITY *pConnectivity )
1296 FIXME( "%p, %p\n", iface, pConnectivity );
1298 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1299 return S_OK;
1302 static const INetworkListManagerVtbl list_manager_vtbl =
1304 list_manager_QueryInterface,
1305 list_manager_AddRef,
1306 list_manager_Release,
1307 list_manager_GetTypeInfoCount,
1308 list_manager_GetTypeInfo,
1309 list_manager_GetIDsOfNames,
1310 list_manager_Invoke,
1311 list_manager_GetNetworks,
1312 list_manager_GetNetwork,
1313 list_manager_GetNetworkConnections,
1314 list_manager_GetNetworkConnection,
1315 list_manager_IsConnectedToInternet,
1316 list_manager_IsConnected,
1317 list_manager_GetConnectivity
1320 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
1321 REFIID riid, void **ppv)
1323 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1324 return INetworkListManager_QueryInterface(&This->INetworkListManager_iface, riid, ppv);
1327 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
1329 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1330 return INetworkListManager_AddRef(&This->INetworkListManager_iface);
1333 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
1335 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1336 return INetworkListManager_Release(&This->INetworkListManager_iface);
1339 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
1340 IEnumConnectionPoints **ppEnum)
1342 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1343 FIXME("(%p)->(%p): stub\n", This, ppEnum);
1344 return E_NOTIMPL;
1347 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
1348 REFIID riid, IConnectionPoint **cp)
1350 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1352 TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
1354 if (!riid || !cp)
1355 return E_POINTER;
1357 if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ) ||
1358 IsEqualGUID( riid, &IID_INetworkCostManagerEvents ) ||
1359 IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
1360 return connection_point_create( cp, riid, iface );
1362 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1364 *cp = NULL;
1365 return E_NOINTERFACE;
1368 static const struct IConnectionPointContainerVtbl cpc_vtbl =
1370 ConnectionPointContainer_QueryInterface,
1371 ConnectionPointContainer_AddRef,
1372 ConnectionPointContainer_Release,
1373 ConnectionPointContainer_EnumConnectionPoints,
1374 ConnectionPointContainer_FindConnectionPoint
1377 static inline struct connection *impl_from_INetworkConnection(
1378 INetworkConnection *iface )
1380 return CONTAINING_RECORD( iface, struct connection, INetworkConnection_iface );
1383 static HRESULT WINAPI connection_QueryInterface(
1384 INetworkConnection *iface, REFIID riid, void **obj )
1386 struct connection *connection = impl_from_INetworkConnection( iface );
1388 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
1390 if (IsEqualIID( riid, &IID_INetworkConnection ) ||
1391 IsEqualIID( riid, &IID_IDispatch ) ||
1392 IsEqualIID( riid, &IID_IUnknown ))
1394 *obj = iface;
1396 else if (IsEqualIID( riid, &IID_INetworkConnectionCost ))
1398 *obj = &connection->INetworkConnectionCost_iface;
1400 else
1402 WARN( "interface not supported %s\n", debugstr_guid(riid) );
1403 *obj = NULL;
1404 return E_NOINTERFACE;
1406 INetworkConnection_AddRef( iface );
1407 return S_OK;
1410 static ULONG WINAPI connection_AddRef(
1411 INetworkConnection *iface )
1413 struct connection *connection = impl_from_INetworkConnection( iface );
1415 TRACE( "%p\n", connection );
1416 return InterlockedIncrement( &connection->refs );
1419 static ULONG WINAPI connection_Release(
1420 INetworkConnection *iface )
1422 struct connection *connection = impl_from_INetworkConnection( iface );
1423 LONG refs;
1425 TRACE( "%p\n", connection );
1427 if (!(refs = InterlockedDecrement( &connection->refs )))
1429 INetwork_Release( connection->network );
1430 list_remove( &connection->entry );
1431 heap_free( connection );
1433 return refs;
1436 static HRESULT WINAPI connection_GetTypeInfoCount(
1437 INetworkConnection *iface,
1438 UINT *count )
1440 FIXME("\n");
1441 return E_NOTIMPL;
1444 static HRESULT WINAPI connection_GetTypeInfo(
1445 INetworkConnection *iface,
1446 UINT index,
1447 LCID lcid,
1448 ITypeInfo **info )
1450 FIXME("\n");
1451 return E_NOTIMPL;
1454 static HRESULT WINAPI connection_GetIDsOfNames(
1455 INetworkConnection *iface,
1456 REFIID riid,
1457 LPOLESTR *names,
1458 UINT count,
1459 LCID lcid,
1460 DISPID *dispid )
1462 FIXME("\n");
1463 return E_NOTIMPL;
1466 static HRESULT WINAPI connection_Invoke(
1467 INetworkConnection *iface,
1468 DISPID member,
1469 REFIID riid,
1470 LCID lcid,
1471 WORD flags,
1472 DISPPARAMS *params,
1473 VARIANT *result,
1474 EXCEPINFO *excep_info,
1475 UINT *arg_err )
1477 FIXME("\n");
1478 return E_NOTIMPL;
1481 static HRESULT WINAPI connection_GetNetwork(
1482 INetworkConnection *iface,
1483 INetwork **ppNetwork )
1485 struct connection *connection = impl_from_INetworkConnection( iface );
1487 TRACE( "%p, %p\n", iface, ppNetwork );
1489 *ppNetwork = connection->network;
1490 INetwork_AddRef( *ppNetwork );
1491 return S_OK;
1494 static HRESULT WINAPI connection_get_IsConnectedToInternet(
1495 INetworkConnection *iface,
1496 VARIANT_BOOL *pbIsConnected )
1498 struct connection *connection = impl_from_INetworkConnection( iface );
1500 TRACE( "%p, %p\n", iface, pbIsConnected );
1502 *pbIsConnected = connection->connected_to_internet;
1503 return S_OK;
1506 static HRESULT WINAPI connection_get_IsConnected(
1507 INetworkConnection *iface,
1508 VARIANT_BOOL *pbIsConnected )
1510 struct connection *connection = impl_from_INetworkConnection( iface );
1512 TRACE( "%p, %p\n", iface, pbIsConnected );
1514 *pbIsConnected = connection->connected;
1515 return S_OK;
1518 static HRESULT WINAPI connection_GetConnectivity(
1519 INetworkConnection *iface,
1520 NLM_CONNECTIVITY *pConnectivity )
1522 FIXME( "%p, %p\n", iface, pConnectivity );
1524 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1525 return S_OK;
1528 static HRESULT WINAPI connection_GetConnectionId(
1529 INetworkConnection *iface,
1530 GUID *pgdConnectionId )
1532 struct connection *connection = impl_from_INetworkConnection( iface );
1534 TRACE( "%p, %p\n", iface, pgdConnectionId );
1536 *pgdConnectionId = connection->id;
1537 return S_OK;
1540 static HRESULT WINAPI connection_GetAdapterId(
1541 INetworkConnection *iface,
1542 GUID *pgdAdapterId )
1544 struct connection *connection = impl_from_INetworkConnection( iface );
1546 FIXME( "%p, %p\n", iface, pgdAdapterId );
1548 *pgdAdapterId = connection->id;
1549 return S_OK;
1552 static HRESULT WINAPI connection_GetDomainType(
1553 INetworkConnection *iface,
1554 NLM_DOMAIN_TYPE *pDomainType )
1556 FIXME( "%p, %p\n", iface, pDomainType );
1558 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
1559 return S_OK;
1562 static const struct INetworkConnectionVtbl connection_vtbl =
1564 connection_QueryInterface,
1565 connection_AddRef,
1566 connection_Release,
1567 connection_GetTypeInfoCount,
1568 connection_GetTypeInfo,
1569 connection_GetIDsOfNames,
1570 connection_Invoke,
1571 connection_GetNetwork,
1572 connection_get_IsConnectedToInternet,
1573 connection_get_IsConnected,
1574 connection_GetConnectivity,
1575 connection_GetConnectionId,
1576 connection_GetAdapterId,
1577 connection_GetDomainType
1580 static inline struct connection *impl_from_INetworkConnectionCost(
1581 INetworkConnectionCost *iface )
1583 return CONTAINING_RECORD( iface, struct connection, INetworkConnectionCost_iface );
1586 static HRESULT WINAPI connection_cost_QueryInterface(
1587 INetworkConnectionCost *iface,
1588 REFIID riid,
1589 void **obj )
1591 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1592 return INetworkConnection_QueryInterface( &conn->INetworkConnection_iface, riid, obj );
1595 static ULONG WINAPI connection_cost_AddRef(
1596 INetworkConnectionCost *iface )
1598 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1599 return INetworkConnection_AddRef( &conn->INetworkConnection_iface );
1602 static ULONG WINAPI connection_cost_Release(
1603 INetworkConnectionCost *iface )
1605 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1606 return INetworkConnection_Release( &conn->INetworkConnection_iface );
1609 static HRESULT WINAPI connection_cost_GetCost(
1610 INetworkConnectionCost *iface, DWORD *pCost )
1612 FIXME( "%p, %p\n", iface, pCost );
1614 if (!pCost) return E_POINTER;
1616 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
1617 return S_OK;
1620 static HRESULT WINAPI connection_cost_GetDataPlanStatus(
1621 INetworkConnectionCost *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus )
1623 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1625 FIXME( "%p, %p\n", iface, pDataPlanStatus );
1627 if (!pDataPlanStatus) return E_POINTER;
1629 memcpy( &pDataPlanStatus->InterfaceGuid, &conn->id, sizeof(conn->id) );
1630 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1631 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
1632 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1633 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1634 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1635 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
1636 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1637 pDataPlanStatus->Reserved = 0;
1639 return S_OK;
1642 static const INetworkConnectionCostVtbl connection_cost_vtbl =
1644 connection_cost_QueryInterface,
1645 connection_cost_AddRef,
1646 connection_cost_Release,
1647 connection_cost_GetCost,
1648 connection_cost_GetDataPlanStatus
1651 static struct connection *create_connection( const GUID *id )
1653 struct connection *ret;
1655 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
1657 ret->INetworkConnection_iface.lpVtbl = &connection_vtbl;
1658 ret->INetworkConnectionCost_iface.lpVtbl = &connection_cost_vtbl;
1659 ret->refs = 1;
1660 ret->id = *id;
1661 ret->network = NULL;
1662 ret->connected = VARIANT_FALSE;
1663 ret->connected_to_internet = VARIANT_FALSE;
1664 list_init( &ret->entry );
1666 return ret;
1669 static void init_networks( struct list_manager *mgr )
1671 DWORD size = 0;
1672 IP_ADAPTER_ADDRESSES *buf, *aa;
1673 GUID id;
1674 ULONG ret, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
1675 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_GATEWAYS;
1677 list_init( &mgr->networks );
1678 list_init( &mgr->connections );
1680 ret = GetAdaptersAddresses( WS_AF_UNSPEC, flags, NULL, NULL, &size );
1681 if (ret != ERROR_BUFFER_OVERFLOW) return;
1683 if (!(buf = heap_alloc( size ))) return;
1684 if (GetAdaptersAddresses( WS_AF_UNSPEC, flags, NULL, buf, &size )) return;
1686 memset( &id, 0, sizeof(id) );
1687 for (aa = buf; aa; aa = aa->Next)
1689 struct network *network;
1690 struct connection *connection;
1692 id.Data1 = aa->IfIndex;
1694 /* assume a one-to-one mapping between networks and connections */
1695 if (!(network = create_network( &id ))) goto done;
1696 if (!(connection = create_connection( &id )))
1698 INetwork_Release( &network->INetwork_iface );
1699 goto done;
1702 if (aa->FirstUnicastAddress)
1704 network->connected = VARIANT_TRUE;
1705 connection->connected = VARIANT_TRUE;
1707 if (aa->FirstGatewayAddress)
1709 network->connected_to_internet = VARIANT_TRUE;
1710 connection->connected_to_internet = VARIANT_TRUE;
1713 connection->network = &network->INetwork_iface;
1714 INetwork_AddRef( connection->network );
1716 list_add_tail( &mgr->networks, &network->entry );
1717 list_add_tail( &mgr->connections, &connection->entry );
1720 done:
1721 heap_free( buf );
1724 HRESULT list_manager_create( void **obj )
1726 struct list_manager *mgr;
1728 TRACE( "%p\n", obj );
1730 if (!(mgr = heap_alloc( sizeof(*mgr) ))) return E_OUTOFMEMORY;
1731 mgr->INetworkListManager_iface.lpVtbl = &list_manager_vtbl;
1732 mgr->INetworkCostManager_iface.lpVtbl = &cost_manager_vtbl;
1733 mgr->IConnectionPointContainer_iface.lpVtbl = &cpc_vtbl;
1734 init_networks( mgr );
1735 mgr->refs = 1;
1737 *obj = &mgr->INetworkListManager_iface;
1738 TRACE( "returning iface %p\n", *obj );
1739 return S_OK;