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
33 #include "netlistmgr.h"
36 #include "wine/debug.h"
37 #include "wine/list.h"
38 #include "netprofm_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(netprofm
);
44 INetwork INetwork_iface
;
48 INetworkListManager
*mgr
;
49 VARIANT_BOOL connected_to_internet
;
50 VARIANT_BOOL connected
;
55 INetworkConnection INetworkConnection_iface
;
56 INetworkConnectionCost INetworkConnectionCost_iface
;
61 VARIANT_BOOL connected_to_internet
;
62 VARIANT_BOOL connected
;
65 struct connection_point
67 IConnectionPoint IConnectionPoint_iface
;
68 IConnectionPointContainer
*container
;
76 INetworkListManager INetworkListManager_iface
;
77 INetworkCostManager INetworkCostManager_iface
;
78 IConnectionPointContainer IConnectionPointContainer_iface
;
81 struct list connections
;
82 struct connection_point list_mgr_cp
;
83 struct connection_point cost_mgr_cp
;
84 struct connection_point conn_mgr_cp
;
85 struct connection_point events_cp
;
95 static inline struct list_manager
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
97 return CONTAINING_RECORD(iface
, struct list_manager
, IConnectionPointContainer_iface
);
100 static inline struct list_manager
*impl_from_INetworkCostManager(
101 INetworkCostManager
*iface
)
103 return CONTAINING_RECORD( iface
, struct list_manager
, INetworkCostManager_iface
);
106 static inline struct connection_point
*impl_from_IConnectionPoint(
107 IConnectionPoint
*iface
)
109 return CONTAINING_RECORD( iface
, struct connection_point
, IConnectionPoint_iface
);
112 static HRESULT WINAPI
connection_point_QueryInterface(
113 IConnectionPoint
*iface
,
117 struct connection_point
*cp
= impl_from_IConnectionPoint( iface
);
118 TRACE( "%p, %s, %p\n", cp
, debugstr_guid(riid
), obj
);
120 if (IsEqualGUID( riid
, &IID_IConnectionPoint
) ||
121 IsEqualGUID( riid
, &IID_IUnknown
))
127 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
129 return E_NOINTERFACE
;
131 IConnectionPoint_AddRef( iface
);
135 static ULONG WINAPI
connection_point_AddRef(
136 IConnectionPoint
*iface
)
138 struct connection_point
*cp
= impl_from_IConnectionPoint( iface
);
139 return IConnectionPointContainer_AddRef( cp
->container
);
142 static ULONG WINAPI
connection_point_Release(
143 IConnectionPoint
*iface
)
145 struct connection_point
*cp
= impl_from_IConnectionPoint( iface
);
146 return IConnectionPointContainer_Release( cp
->container
);
149 static HRESULT WINAPI
connection_point_GetConnectionInterface(
150 IConnectionPoint
*iface
,
153 struct connection_point
*cp
= impl_from_IConnectionPoint( iface
);
154 TRACE( "%p, %p\n", cp
, iid
);
159 memcpy( iid
, &cp
->iid
, sizeof(*iid
) );
163 static HRESULT WINAPI
connection_point_GetConnectionPointContainer(
164 IConnectionPoint
*iface
,
165 IConnectionPointContainer
**container
)
167 struct connection_point
*cp
= impl_from_IConnectionPoint( iface
);
168 TRACE( "%p, %p\n", cp
, container
);
173 IConnectionPointContainer_AddRef( cp
->container
);
174 *container
= cp
->container
;
178 static HRESULT WINAPI
connection_point_Advise(
179 IConnectionPoint
*iface
,
183 struct connection_point
*cp
= impl_from_IConnectionPoint( iface
);
184 struct sink_entry
*sink_entry
;
188 FIXME( "%p, %p, %p - semi-stub\n", cp
, sink
, cookie
);
190 if (!sink
|| !cookie
)
193 hr
= IUnknown_QueryInterface( sink
, &cp
->iid
, (void**)&unk
);
196 WARN( "iface %s not implemented by sink\n", debugstr_guid(&cp
->iid
) );
197 return CO_E_FAILEDTOOPENTHREADTOKEN
;
200 sink_entry
= malloc( sizeof(*sink_entry
) );
203 IUnknown_Release( unk
);
204 return E_OUTOFMEMORY
;
207 sink_entry
->unk
= unk
;
208 *cookie
= sink_entry
->cookie
= ++cp
->cookie
;
209 list_add_tail( &cp
->sinks
, &sink_entry
->entry
);
213 static void sink_entry_release( struct sink_entry
*entry
)
215 list_remove( &entry
->entry
);
216 IUnknown_Release( entry
->unk
);
220 static HRESULT WINAPI
connection_point_Unadvise(
221 IConnectionPoint
*iface
,
224 struct connection_point
*cp
= impl_from_IConnectionPoint( iface
);
225 struct sink_entry
*iter
;
227 TRACE( "%p, %ld\n", cp
, cookie
);
229 LIST_FOR_EACH_ENTRY( iter
, &cp
->sinks
, struct sink_entry
, entry
)
231 if (iter
->cookie
!= cookie
) continue;
232 sink_entry_release( iter
);
236 WARN( "invalid cookie\n" );
237 return OLE_E_NOCONNECTION
;
240 static HRESULT WINAPI
connection_point_EnumConnections(
241 IConnectionPoint
*iface
,
242 IEnumConnections
**connections
)
244 struct connection_point
*cp
= impl_from_IConnectionPoint( iface
);
245 FIXME( "%p, %p - stub\n", cp
, connections
);
250 static const IConnectionPointVtbl connection_point_vtbl
=
252 connection_point_QueryInterface
,
253 connection_point_AddRef
,
254 connection_point_Release
,
255 connection_point_GetConnectionInterface
,
256 connection_point_GetConnectionPointContainer
,
257 connection_point_Advise
,
258 connection_point_Unadvise
,
259 connection_point_EnumConnections
262 static void connection_point_init(
263 struct connection_point
*cp
,
265 IConnectionPointContainer
*container
)
267 cp
->IConnectionPoint_iface
.lpVtbl
= &connection_point_vtbl
;
268 cp
->container
= container
;
271 list_init( &cp
->sinks
);
274 static void connection_point_release( struct connection_point
*cp
)
276 while (!list_empty( &cp
->sinks
))
277 sink_entry_release( LIST_ENTRY( list_head( &cp
->sinks
), struct sink_entry
, entry
) );
280 static inline struct network
*impl_from_INetwork(
283 return CONTAINING_RECORD( iface
, struct network
, INetwork_iface
);
286 static HRESULT WINAPI
network_QueryInterface(
287 INetwork
*iface
, REFIID riid
, void **obj
)
289 struct network
*network
= impl_from_INetwork( iface
);
291 TRACE( "%p, %s, %p\n", network
, debugstr_guid(riid
), obj
);
293 if (IsEqualIID( riid
, &IID_INetwork
) ||
294 IsEqualIID( riid
, &IID_IDispatch
) ||
295 IsEqualIID( riid
, &IID_IUnknown
))
298 INetwork_AddRef( iface
);
303 WARN( "interface not supported %s\n", debugstr_guid(riid
) );
305 return E_NOINTERFACE
;
309 static ULONG WINAPI
network_AddRef(
312 struct network
*network
= impl_from_INetwork( iface
);
314 TRACE( "%p\n", network
);
315 return InterlockedIncrement( &network
->refs
);
318 static ULONG WINAPI
network_Release(
321 struct network
*network
= impl_from_INetwork( iface
);
324 TRACE( "%p\n", network
);
326 if (!(refs
= InterlockedDecrement( &network
->refs
)))
328 list_remove( &network
->entry
);
329 INetworkListManager_Release( network
->mgr
);
335 static HRESULT WINAPI
network_GetTypeInfoCount(
343 static HRESULT WINAPI
network_GetTypeInfo(
353 static HRESULT WINAPI
network_GetIDsOfNames(
365 static HRESULT WINAPI
network_Invoke(
373 EXCEPINFO
*excep_info
,
380 static HRESULT WINAPI
network_GetName(
382 BSTR
*pszNetworkName
)
384 FIXME( "%p, %p\n", iface
, pszNetworkName
);
388 static HRESULT WINAPI
network_SetName(
390 BSTR szNetworkNewName
)
392 FIXME( "%p, %s\n", iface
, debugstr_w(szNetworkNewName
) );
396 static HRESULT WINAPI
network_GetDescription(
398 BSTR
*pszDescription
)
400 FIXME( "%p, %p\n", iface
, pszDescription
);
404 static HRESULT WINAPI
network_SetDescription(
408 FIXME( "%p, %s\n", iface
, debugstr_w(szDescription
) );
412 static HRESULT WINAPI
network_GetNetworkId(
414 GUID
*pgdGuidNetworkId
)
416 struct network
*network
= impl_from_INetwork( iface
);
418 TRACE( "%p, %p\n", iface
, pgdGuidNetworkId
);
420 *pgdGuidNetworkId
= network
->id
;
424 static HRESULT WINAPI
network_GetDomainType(
426 NLM_DOMAIN_TYPE
*pDomainType
)
428 FIXME( "%p, %p\n", iface
, pDomainType
);
430 *pDomainType
= NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK
;
434 static inline struct list_manager
*impl_from_INetworkListManager(
435 INetworkListManager
*iface
)
437 return CONTAINING_RECORD( iface
, struct list_manager
, INetworkListManager_iface
);
440 static HRESULT
create_connections_enum(
441 struct list_manager
*, IEnumNetworkConnections
** );
443 static HRESULT WINAPI
network_GetNetworkConnections(
445 IEnumNetworkConnections
**ppEnum
)
447 struct network
*network
= impl_from_INetwork( iface
);
448 struct list_manager
*mgr
= impl_from_INetworkListManager( network
->mgr
);
450 TRACE( "%p, %p\n", iface
, ppEnum
);
451 return create_connections_enum( mgr
, ppEnum
);
454 static HRESULT WINAPI
network_GetTimeCreatedAndConnected(
456 DWORD
*pdwLowDateTimeCreated
,
457 DWORD
*pdwHighDateTimeCreated
,
458 DWORD
*pdwLowDateTimeConnected
,
459 DWORD
*pdwHighDateTimeConnected
)
461 FIXME( "%p, %p, %p, %p, %p\n", iface
, pdwLowDateTimeCreated
, pdwHighDateTimeCreated
,
462 pdwLowDateTimeConnected
, pdwHighDateTimeConnected
);
466 static HRESULT WINAPI
network_get_IsConnectedToInternet(
468 VARIANT_BOOL
*pbIsConnected
)
470 struct network
*network
= impl_from_INetwork( iface
);
472 TRACE( "%p, %p\n", iface
, pbIsConnected
);
474 *pbIsConnected
= network
->connected_to_internet
;
478 static HRESULT WINAPI
network_get_IsConnected(
480 VARIANT_BOOL
*pbIsConnected
)
482 struct network
*network
= impl_from_INetwork( iface
);
484 TRACE( "%p, %p\n", iface
, pbIsConnected
);
486 *pbIsConnected
= network
->connected
;
490 static HRESULT WINAPI
network_GetConnectivity(
492 NLM_CONNECTIVITY
*pConnectivity
)
494 struct network
*network
= impl_from_INetwork( iface
);
496 FIXME( "%p, %p\n", iface
, pConnectivity
);
498 *pConnectivity
= NLM_CONNECTIVITY_DISCONNECTED
;
500 if (network
->connected_to_internet
)
501 *pConnectivity
|= NLM_CONNECTIVITY_IPV4_INTERNET
;
502 else if (network
->connected
)
503 *pConnectivity
|= NLM_CONNECTIVITY_IPV4_LOCALNETWORK
;
508 static HRESULT WINAPI
network_GetCategory(
510 NLM_NETWORK_CATEGORY
*pCategory
)
512 FIXME( "%p, %p\n", iface
, pCategory
);
514 *pCategory
= NLM_NETWORK_CATEGORY_PUBLIC
;
518 static HRESULT WINAPI
network_SetCategory(
520 NLM_NETWORK_CATEGORY NewCategory
)
522 FIXME( "%p, %u\n", iface
, NewCategory
);
526 static const struct INetworkVtbl network_vtbl
=
528 network_QueryInterface
,
531 network_GetTypeInfoCount
,
533 network_GetIDsOfNames
,
537 network_GetDescription
,
538 network_SetDescription
,
539 network_GetNetworkId
,
540 network_GetDomainType
,
541 network_GetNetworkConnections
,
542 network_GetTimeCreatedAndConnected
,
543 network_get_IsConnectedToInternet
,
544 network_get_IsConnected
,
545 network_GetConnectivity
,
550 static struct network
*create_network( const GUID
*id
)
554 if (!(ret
= calloc( 1, sizeof(*ret
) ))) return NULL
;
556 ret
->INetwork_iface
.lpVtbl
= &network_vtbl
;
559 ret
->connected
= VARIANT_FALSE
;
560 ret
->connected_to_internet
= VARIANT_FALSE
;
561 list_init( &ret
->entry
);
566 static HRESULT WINAPI
cost_manager_QueryInterface(
567 INetworkCostManager
*iface
,
571 struct list_manager
*mgr
= impl_from_INetworkCostManager( iface
);
572 return INetworkListManager_QueryInterface( &mgr
->INetworkListManager_iface
, riid
, obj
);
575 static ULONG WINAPI
cost_manager_AddRef(
576 INetworkCostManager
*iface
)
578 struct list_manager
*mgr
= impl_from_INetworkCostManager( iface
);
579 return INetworkListManager_AddRef( &mgr
->INetworkListManager_iface
);
582 static ULONG WINAPI
cost_manager_Release(
583 INetworkCostManager
*iface
)
585 struct list_manager
*mgr
= impl_from_INetworkCostManager( iface
);
586 return INetworkListManager_Release( &mgr
->INetworkListManager_iface
);
589 static HRESULT WINAPI
cost_manager_GetCost(
590 INetworkCostManager
*iface
, DWORD
*pCost
, NLM_SOCKADDR
*pDestIPAddr
)
592 FIXME( "%p, %p, %p\n", iface
, pCost
, pDestIPAddr
);
594 if (!pCost
) return E_POINTER
;
596 *pCost
= NLM_CONNECTION_COST_UNRESTRICTED
;
600 static BOOL
map_address_6to4( const SOCKADDR_IN6
*addr6
, SOCKADDR_IN
*addr4
)
604 if (addr6
->sin6_family
!= AF_INET6
) return FALSE
;
606 for (i
= 0; i
< 5; i
++)
607 if (addr6
->sin6_addr
.u
.Word
[i
]) return FALSE
;
609 if (addr6
->sin6_addr
.u
.Word
[5] != 0xffff) return FALSE
;
611 addr4
->sin_family
= AF_INET
;
612 addr4
->sin_port
= addr6
->sin6_port
;
613 addr4
->sin_addr
.S_un
.S_addr
= addr6
->sin6_addr
.u
.Word
[6] << 16 | addr6
->sin6_addr
.u
.Word
[7];
614 memset( &addr4
->sin_zero
, 0, sizeof(addr4
->sin_zero
) );
619 static HRESULT WINAPI
cost_manager_GetDataPlanStatus(
620 INetworkCostManager
*iface
, NLM_DATAPLAN_STATUS
*pDataPlanStatus
,
621 NLM_SOCKADDR
*pDestIPAddr
)
625 SOCKADDR
*dst
= (SOCKADDR
*)pDestIPAddr
;
626 SOCKADDR_IN addr4
, *dst4
;
628 FIXME( "%p, %p, %p\n", iface
, pDataPlanStatus
, pDestIPAddr
);
630 if (!pDataPlanStatus
) return E_POINTER
;
632 if (dst
&& ((dst
->sa_family
== AF_INET
&& (dst4
= (SOCKADDR_IN
*)dst
)) ||
633 ((dst
->sa_family
== AF_INET6
&& map_address_6to4( (const SOCKADDR_IN6
*)dst
, &addr4
)
634 && (dst4
= &addr4
)))))
636 if ((ret
= GetBestInterface( dst4
->sin_addr
.S_un
.S_addr
, &index
)))
637 return HRESULT_FROM_WIN32( ret
);
639 if ((ret
= ConvertInterfaceIndexToLuid( index
, &luid
)))
640 return HRESULT_FROM_WIN32( ret
);
642 if ((ret
= ConvertInterfaceLuidToGuid( &luid
, &pDataPlanStatus
->InterfaceGuid
)))
643 return HRESULT_FROM_WIN32( ret
);
647 FIXME( "interface guid not found\n" );
648 memset( &pDataPlanStatus
->InterfaceGuid
, 0, sizeof(pDataPlanStatus
->InterfaceGuid
) );
651 pDataPlanStatus
->UsageData
.UsageInMegabytes
= NLM_UNKNOWN_DATAPLAN_STATUS
;
652 memset( &pDataPlanStatus
->UsageData
.LastSyncTime
, 0, sizeof(pDataPlanStatus
->UsageData
.LastSyncTime
) );
653 pDataPlanStatus
->DataLimitInMegabytes
= NLM_UNKNOWN_DATAPLAN_STATUS
;
654 pDataPlanStatus
->InboundBandwidthInKbps
= NLM_UNKNOWN_DATAPLAN_STATUS
;
655 pDataPlanStatus
->OutboundBandwidthInKbps
= NLM_UNKNOWN_DATAPLAN_STATUS
;
656 memset( &pDataPlanStatus
->NextBillingCycle
, 0, sizeof(pDataPlanStatus
->NextBillingCycle
) );
657 pDataPlanStatus
->MaxTransferSizeInMegabytes
= NLM_UNKNOWN_DATAPLAN_STATUS
;
658 pDataPlanStatus
->Reserved
= 0;
663 static HRESULT WINAPI
cost_manager_SetDestinationAddresses(
664 INetworkCostManager
*iface
, UINT32 length
, NLM_SOCKADDR
*pDestIPAddrList
,
665 VARIANT_BOOL bAppend
)
667 FIXME( "%p, %u, %p, %x\n", iface
, length
, pDestIPAddrList
, bAppend
);
671 static const INetworkCostManagerVtbl cost_manager_vtbl
=
673 cost_manager_QueryInterface
,
675 cost_manager_Release
,
676 cost_manager_GetCost
,
677 cost_manager_GetDataPlanStatus
,
678 cost_manager_SetDestinationAddresses
683 IEnumNetworks IEnumNetworks_iface
;
685 struct list_manager
*mgr
;
689 static inline struct networks_enum
*impl_from_IEnumNetworks(
690 IEnumNetworks
*iface
)
692 return CONTAINING_RECORD( iface
, struct networks_enum
, IEnumNetworks_iface
);
695 static HRESULT WINAPI
networks_enum_QueryInterface(
696 IEnumNetworks
*iface
, REFIID riid
, void **obj
)
698 struct networks_enum
*iter
= impl_from_IEnumNetworks( iface
);
700 TRACE( "%p, %s, %p\n", iter
, debugstr_guid(riid
), obj
);
702 if (IsEqualIID( riid
, &IID_IEnumNetworks
) ||
703 IsEqualIID( riid
, &IID_IDispatch
) ||
704 IsEqualIID( riid
, &IID_IUnknown
))
707 IEnumNetworks_AddRef( iface
);
712 WARN( "interface not supported %s\n", debugstr_guid(riid
) );
714 return E_NOINTERFACE
;
718 static ULONG WINAPI
networks_enum_AddRef(
719 IEnumNetworks
*iface
)
721 struct networks_enum
*iter
= impl_from_IEnumNetworks( iface
);
723 TRACE( "%p\n", iter
);
724 return InterlockedIncrement( &iter
->refs
);
727 static ULONG WINAPI
networks_enum_Release(
728 IEnumNetworks
*iface
)
730 struct networks_enum
*iter
= impl_from_IEnumNetworks( iface
);
733 TRACE( "%p\n", iter
);
735 if (!(refs
= InterlockedDecrement( &iter
->refs
)))
737 INetworkListManager_Release( &iter
->mgr
->INetworkListManager_iface
);
743 static HRESULT WINAPI
networks_enum_GetTypeInfoCount(
744 IEnumNetworks
*iface
,
751 static HRESULT WINAPI
networks_enum_GetTypeInfo(
752 IEnumNetworks
*iface
,
761 static HRESULT WINAPI
networks_enum_GetIDsOfNames(
762 IEnumNetworks
*iface
,
773 static HRESULT WINAPI
networks_enum_Invoke(
774 IEnumNetworks
*iface
,
781 EXCEPINFO
*excep_info
,
788 static HRESULT WINAPI
networks_enum_get__NewEnum(
789 IEnumNetworks
*iface
, IEnumVARIANT
**ppEnumVar
)
795 static HRESULT WINAPI
networks_enum_Next(
796 IEnumNetworks
*iface
, ULONG count
, INetwork
**ret
, ULONG
*fetched
)
798 struct networks_enum
*iter
= impl_from_IEnumNetworks( iface
);
801 TRACE( "%p, %lu %p %p\n", iter
, count
, ret
, fetched
);
803 if (fetched
) *fetched
= 0;
804 if (!count
) return S_OK
;
806 while (iter
->cursor
&& i
< count
)
808 struct network
*network
= LIST_ENTRY( iter
->cursor
, struct network
, entry
);
809 ret
[i
] = &network
->INetwork_iface
;
810 INetwork_AddRef( ret
[i
] );
811 iter
->cursor
= list_next( &iter
->mgr
->networks
, iter
->cursor
);
814 if (fetched
) *fetched
= i
;
816 return i
< count
? S_FALSE
: S_OK
;
819 static HRESULT WINAPI
networks_enum_Skip(
820 IEnumNetworks
*iface
, ULONG count
)
822 struct networks_enum
*iter
= impl_from_IEnumNetworks( iface
);
824 TRACE( "%p, %lu\n", iter
, count
);
826 if (!count
) return S_OK
;
827 if (!iter
->cursor
) return S_FALSE
;
831 iter
->cursor
= list_next( &iter
->mgr
->networks
, iter
->cursor
);
832 if (!iter
->cursor
) break;
835 return count
? S_FALSE
: S_OK
;
838 static HRESULT WINAPI
networks_enum_Reset(
839 IEnumNetworks
*iface
)
841 struct networks_enum
*iter
= impl_from_IEnumNetworks( iface
);
843 TRACE( "%p\n", iter
);
845 iter
->cursor
= list_head( &iter
->mgr
->networks
);
849 static HRESULT
create_networks_enum(
850 struct list_manager
*, IEnumNetworks
** );
852 static HRESULT WINAPI
networks_enum_Clone(
853 IEnumNetworks
*iface
, IEnumNetworks
**ret
)
855 struct networks_enum
*iter
= impl_from_IEnumNetworks( iface
);
857 TRACE( "%p, %p\n", iter
, ret
);
858 return create_networks_enum( iter
->mgr
, ret
);
861 static const IEnumNetworksVtbl networks_enum_vtbl
=
863 networks_enum_QueryInterface
,
864 networks_enum_AddRef
,
865 networks_enum_Release
,
866 networks_enum_GetTypeInfoCount
,
867 networks_enum_GetTypeInfo
,
868 networks_enum_GetIDsOfNames
,
869 networks_enum_Invoke
,
870 networks_enum_get__NewEnum
,
877 static HRESULT
create_networks_enum(
878 struct list_manager
*mgr
, IEnumNetworks
**ret
)
880 struct networks_enum
*iter
;
883 if (!(iter
= calloc( 1, sizeof(*iter
) ))) return E_OUTOFMEMORY
;
885 iter
->IEnumNetworks_iface
.lpVtbl
= &networks_enum_vtbl
;
886 iter
->cursor
= list_head( &mgr
->networks
);
888 INetworkListManager_AddRef( &mgr
->INetworkListManager_iface
);
891 *ret
= &iter
->IEnumNetworks_iface
;
895 struct connections_enum
897 IEnumNetworkConnections IEnumNetworkConnections_iface
;
899 struct list_manager
*mgr
;
903 static inline struct connections_enum
*impl_from_IEnumNetworkConnections(
904 IEnumNetworkConnections
*iface
)
906 return CONTAINING_RECORD( iface
, struct connections_enum
, IEnumNetworkConnections_iface
);
909 static HRESULT WINAPI
connections_enum_QueryInterface(
910 IEnumNetworkConnections
*iface
, REFIID riid
, void **obj
)
912 struct connections_enum
*iter
= impl_from_IEnumNetworkConnections( iface
);
914 TRACE( "%p, %s, %p\n", iter
, debugstr_guid(riid
), obj
);
916 if (IsEqualIID( riid
, &IID_IEnumNetworkConnections
) ||
917 IsEqualIID( riid
, &IID_IDispatch
) ||
918 IsEqualIID( riid
, &IID_IUnknown
))
921 IEnumNetworkConnections_AddRef( iface
);
926 WARN( "interface not supported %s\n", debugstr_guid(riid
) );
928 return E_NOINTERFACE
;
932 static ULONG WINAPI
connections_enum_AddRef(
933 IEnumNetworkConnections
*iface
)
935 struct connections_enum
*iter
= impl_from_IEnumNetworkConnections( iface
);
937 TRACE( "%p\n", iter
);
938 return InterlockedIncrement( &iter
->refs
);
941 static ULONG WINAPI
connections_enum_Release(
942 IEnumNetworkConnections
*iface
)
944 struct connections_enum
*iter
= impl_from_IEnumNetworkConnections( iface
);
947 TRACE( "%p\n", iter
);
949 if (!(refs
= InterlockedDecrement( &iter
->refs
)))
951 INetworkListManager_Release( &iter
->mgr
->INetworkListManager_iface
);
957 static HRESULT WINAPI
connections_enum_GetTypeInfoCount(
958 IEnumNetworkConnections
*iface
,
965 static HRESULT WINAPI
connections_enum_GetTypeInfo(
966 IEnumNetworkConnections
*iface
,
975 static HRESULT WINAPI
connections_enum_GetIDsOfNames(
976 IEnumNetworkConnections
*iface
,
987 static HRESULT WINAPI
connections_enum_Invoke(
988 IEnumNetworkConnections
*iface
,
995 EXCEPINFO
*excep_info
,
1002 static HRESULT WINAPI
connections_enum_get__NewEnum(
1003 IEnumNetworkConnections
*iface
, IEnumVARIANT
**ppEnumVar
)
1009 static HRESULT WINAPI
connections_enum_Next(
1010 IEnumNetworkConnections
*iface
, ULONG count
, INetworkConnection
**ret
, ULONG
*fetched
)
1012 struct connections_enum
*iter
= impl_from_IEnumNetworkConnections( iface
);
1015 TRACE( "%p, %lu %p %p\n", iter
, count
, ret
, fetched
);
1017 if (!ret
) return E_POINTER
;
1019 if (fetched
) *fetched
= 0;
1020 if (!count
) return S_OK
;
1022 while (iter
->cursor
&& i
< count
)
1024 struct connection
*connection
= LIST_ENTRY( iter
->cursor
, struct connection
, entry
);
1025 ret
[i
] = &connection
->INetworkConnection_iface
;
1026 INetworkConnection_AddRef( ret
[i
] );
1027 iter
->cursor
= list_next( &iter
->mgr
->connections
, iter
->cursor
);
1030 if (fetched
) *fetched
= i
;
1032 return i
< count
? S_FALSE
: S_OK
;
1035 static HRESULT WINAPI
connections_enum_Skip(
1036 IEnumNetworkConnections
*iface
, ULONG count
)
1038 struct connections_enum
*iter
= impl_from_IEnumNetworkConnections( iface
);
1040 TRACE( "%p, %lu\n", iter
, count
);
1042 if (!count
) return S_OK
;
1043 if (!iter
->cursor
) return S_FALSE
;
1047 iter
->cursor
= list_next( &iter
->mgr
->connections
, iter
->cursor
);
1048 if (!iter
->cursor
) break;
1051 return count
? S_FALSE
: S_OK
;
1054 static HRESULT WINAPI
connections_enum_Reset(
1055 IEnumNetworkConnections
*iface
)
1057 struct connections_enum
*iter
= impl_from_IEnumNetworkConnections( iface
);
1059 TRACE( "%p\n", iter
);
1061 iter
->cursor
= list_head( &iter
->mgr
->connections
);
1065 static HRESULT WINAPI
connections_enum_Clone(
1066 IEnumNetworkConnections
*iface
, IEnumNetworkConnections
**ret
)
1068 struct connections_enum
*iter
= impl_from_IEnumNetworkConnections( iface
);
1070 TRACE( "%p, %p\n", iter
, ret
);
1071 return create_connections_enum( iter
->mgr
, ret
);
1074 static const IEnumNetworkConnectionsVtbl connections_enum_vtbl
=
1076 connections_enum_QueryInterface
,
1077 connections_enum_AddRef
,
1078 connections_enum_Release
,
1079 connections_enum_GetTypeInfoCount
,
1080 connections_enum_GetTypeInfo
,
1081 connections_enum_GetIDsOfNames
,
1082 connections_enum_Invoke
,
1083 connections_enum_get__NewEnum
,
1084 connections_enum_Next
,
1085 connections_enum_Skip
,
1086 connections_enum_Reset
,
1087 connections_enum_Clone
1090 static HRESULT
create_connections_enum(
1091 struct list_manager
*mgr
, IEnumNetworkConnections
**ret
)
1093 struct connections_enum
*iter
;
1096 if (!(iter
= calloc( 1, sizeof(*iter
) ))) return E_OUTOFMEMORY
;
1098 iter
->IEnumNetworkConnections_iface
.lpVtbl
= &connections_enum_vtbl
;
1100 INetworkListManager_AddRef( &mgr
->INetworkListManager_iface
);
1101 iter
->cursor
= list_head( &iter
->mgr
->connections
);
1104 *ret
= &iter
->IEnumNetworkConnections_iface
;
1108 static ULONG WINAPI
list_manager_AddRef(
1109 INetworkListManager
*iface
)
1111 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1112 return InterlockedIncrement( &mgr
->refs
);
1115 static ULONG WINAPI
list_manager_Release(
1116 INetworkListManager
*iface
)
1118 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1119 LONG refs
= InterlockedDecrement( &mgr
->refs
);
1122 struct network
*network
, *next_network
;
1123 struct connection
*connection
, *next_connection
;
1125 TRACE( "destroying %p\n", mgr
);
1127 connection_point_release( &mgr
->events_cp
);
1128 connection_point_release( &mgr
->conn_mgr_cp
);
1129 connection_point_release( &mgr
->cost_mgr_cp
);
1130 connection_point_release( &mgr
->list_mgr_cp
);
1131 LIST_FOR_EACH_ENTRY_SAFE( connection
, next_connection
, &mgr
->connections
, struct connection
, entry
)
1133 INetworkConnection_Release( &connection
->INetworkConnection_iface
);
1135 LIST_FOR_EACH_ENTRY_SAFE( network
, next_network
, &mgr
->networks
, struct network
, entry
)
1137 INetwork_Release( &network
->INetwork_iface
);
1144 static HRESULT WINAPI
list_manager_QueryInterface(
1145 INetworkListManager
*iface
,
1149 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1151 TRACE( "%p, %s, %p\n", mgr
, debugstr_guid(riid
), obj
);
1153 if (IsEqualGUID( riid
, &IID_INetworkListManager
) ||
1154 IsEqualGUID( riid
, &IID_IDispatch
) ||
1155 IsEqualGUID( riid
, &IID_IUnknown
))
1159 else if (IsEqualGUID( riid
, &IID_INetworkCostManager
))
1161 *obj
= &mgr
->INetworkCostManager_iface
;
1163 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
1165 *obj
= &mgr
->IConnectionPointContainer_iface
;
1169 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
1171 return E_NOINTERFACE
;
1173 INetworkListManager_AddRef( iface
);
1177 static HRESULT WINAPI
list_manager_GetTypeInfoCount(
1178 INetworkListManager
*iface
,
1185 static HRESULT WINAPI
list_manager_GetTypeInfo(
1186 INetworkListManager
*iface
,
1195 static HRESULT WINAPI
list_manager_GetIDsOfNames(
1196 INetworkListManager
*iface
,
1207 static HRESULT WINAPI
list_manager_Invoke(
1208 INetworkListManager
*iface
,
1215 EXCEPINFO
*excep_info
,
1222 static HRESULT WINAPI
list_manager_GetNetworks(
1223 INetworkListManager
*iface
,
1224 NLM_ENUM_NETWORK Flags
,
1225 IEnumNetworks
**ppEnumNetwork
)
1227 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1229 TRACE( "%p, %x, %p\n", iface
, Flags
, ppEnumNetwork
);
1230 if (Flags
) FIXME( "flags %08x not supported\n", Flags
);
1232 return create_networks_enum( mgr
, ppEnumNetwork
);
1235 static HRESULT WINAPI
list_manager_GetNetwork(
1236 INetworkListManager
*iface
,
1238 INetwork
**ppNetwork
)
1240 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1241 struct network
*network
;
1243 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(&gdNetworkId
), ppNetwork
);
1245 LIST_FOR_EACH_ENTRY( network
, &mgr
->networks
, struct network
, entry
)
1247 if (IsEqualGUID( &network
->id
, &gdNetworkId
))
1249 *ppNetwork
= &network
->INetwork_iface
;
1250 INetwork_AddRef( *ppNetwork
);
1258 static HRESULT WINAPI
list_manager_GetNetworkConnections(
1259 INetworkListManager
*iface
,
1260 IEnumNetworkConnections
**ppEnum
)
1262 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1264 TRACE( "%p, %p\n", iface
, ppEnum
);
1265 return create_connections_enum( mgr
, ppEnum
);
1268 static HRESULT WINAPI
list_manager_GetNetworkConnection(
1269 INetworkListManager
*iface
,
1270 GUID gdNetworkConnectionId
,
1271 INetworkConnection
**ppNetworkConnection
)
1273 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1274 struct connection
*connection
;
1276 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(&gdNetworkConnectionId
),
1277 ppNetworkConnection
);
1279 LIST_FOR_EACH_ENTRY( connection
, &mgr
->connections
, struct connection
, entry
)
1281 if (IsEqualGUID( &connection
->id
, &gdNetworkConnectionId
))
1283 *ppNetworkConnection
= &connection
->INetworkConnection_iface
;
1284 INetworkConnection_AddRef( *ppNetworkConnection
);
1292 static HRESULT WINAPI
list_manager_IsConnectedToInternet(
1293 INetworkListManager
*iface
,
1294 VARIANT_BOOL
*pbIsConnected
)
1296 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1297 struct network
*network
;
1299 TRACE( "%p, %p\n", iface
, pbIsConnected
);
1301 LIST_FOR_EACH_ENTRY( network
, &mgr
->networks
, struct network
, entry
)
1303 if (network
->connected_to_internet
)
1305 *pbIsConnected
= VARIANT_TRUE
;
1310 *pbIsConnected
= VARIANT_FALSE
;
1314 static HRESULT WINAPI
list_manager_IsConnected(
1315 INetworkListManager
*iface
,
1316 VARIANT_BOOL
*pbIsConnected
)
1318 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1319 struct network
*network
;
1321 TRACE( "%p, %p\n", iface
, pbIsConnected
);
1323 LIST_FOR_EACH_ENTRY( network
, &mgr
->networks
, struct network
, entry
)
1325 if (network
->connected
)
1327 *pbIsConnected
= VARIANT_TRUE
;
1332 *pbIsConnected
= VARIANT_FALSE
;
1336 static HRESULT WINAPI
list_manager_GetConnectivity(
1337 INetworkListManager
*iface
,
1338 NLM_CONNECTIVITY
*pConnectivity
)
1340 struct list_manager
*mgr
= impl_from_INetworkListManager( iface
);
1341 struct network
*network
;
1343 FIXME( "%p, %p\n", iface
, pConnectivity
);
1345 *pConnectivity
= NLM_CONNECTIVITY_DISCONNECTED
;
1347 LIST_FOR_EACH_ENTRY( network
, &mgr
->networks
, struct network
, entry
)
1349 if (network
->connected_to_internet
)
1350 *pConnectivity
|= NLM_CONNECTIVITY_IPV4_INTERNET
;
1351 else if (network
->connected
)
1352 *pConnectivity
|= NLM_CONNECTIVITY_IPV4_LOCALNETWORK
;
1358 static const INetworkListManagerVtbl list_manager_vtbl
=
1360 list_manager_QueryInterface
,
1361 list_manager_AddRef
,
1362 list_manager_Release
,
1363 list_manager_GetTypeInfoCount
,
1364 list_manager_GetTypeInfo
,
1365 list_manager_GetIDsOfNames
,
1366 list_manager_Invoke
,
1367 list_manager_GetNetworks
,
1368 list_manager_GetNetwork
,
1369 list_manager_GetNetworkConnections
,
1370 list_manager_GetNetworkConnection
,
1371 list_manager_IsConnectedToInternet
,
1372 list_manager_IsConnected
,
1373 list_manager_GetConnectivity
1376 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
1377 REFIID riid
, void **ppv
)
1379 struct list_manager
*This
= impl_from_IConnectionPointContainer( iface
);
1380 return INetworkListManager_QueryInterface(&This
->INetworkListManager_iface
, riid
, ppv
);
1383 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
1385 struct list_manager
*This
= impl_from_IConnectionPointContainer( iface
);
1386 return INetworkListManager_AddRef(&This
->INetworkListManager_iface
);
1389 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
1391 struct list_manager
*This
= impl_from_IConnectionPointContainer( iface
);
1392 return INetworkListManager_Release(&This
->INetworkListManager_iface
);
1395 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
1396 IEnumConnectionPoints
**ppEnum
)
1398 struct list_manager
*This
= impl_from_IConnectionPointContainer( iface
);
1399 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
1403 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
1404 REFIID riid
, IConnectionPoint
**cp
)
1406 struct list_manager
*This
= impl_from_IConnectionPointContainer( iface
);
1407 struct connection_point
*ret
;
1409 TRACE( "%p, %s, %p\n", This
, debugstr_guid(riid
), cp
);
1414 if (IsEqualGUID( riid
, &IID_INetworkListManagerEvents
))
1415 ret
= &This
->list_mgr_cp
;
1416 else if (IsEqualGUID( riid
, &IID_INetworkCostManagerEvents
))
1417 ret
= &This
->cost_mgr_cp
;
1418 else if (IsEqualGUID( riid
, &IID_INetworkConnectionEvents
))
1419 ret
= &This
->conn_mgr_cp
;
1420 else if (IsEqualGUID( riid
, &IID_INetworkEvents
))
1421 ret
= &This
->events_cp
;
1424 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
1426 return E_NOINTERFACE
;
1429 IConnectionPoint_AddRef( *cp
= &ret
->IConnectionPoint_iface
);
1433 static const struct IConnectionPointContainerVtbl cpc_vtbl
=
1435 ConnectionPointContainer_QueryInterface
,
1436 ConnectionPointContainer_AddRef
,
1437 ConnectionPointContainer_Release
,
1438 ConnectionPointContainer_EnumConnectionPoints
,
1439 ConnectionPointContainer_FindConnectionPoint
1442 static inline struct connection
*impl_from_INetworkConnection(
1443 INetworkConnection
*iface
)
1445 return CONTAINING_RECORD( iface
, struct connection
, INetworkConnection_iface
);
1448 static HRESULT WINAPI
connection_QueryInterface(
1449 INetworkConnection
*iface
, REFIID riid
, void **obj
)
1451 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1453 TRACE( "%p, %s, %p\n", connection
, debugstr_guid(riid
), obj
);
1455 if (IsEqualIID( riid
, &IID_INetworkConnection
) ||
1456 IsEqualIID( riid
, &IID_IDispatch
) ||
1457 IsEqualIID( riid
, &IID_IUnknown
))
1461 else if (IsEqualIID( riid
, &IID_INetworkConnectionCost
))
1463 *obj
= &connection
->INetworkConnectionCost_iface
;
1467 WARN( "interface not supported %s\n", debugstr_guid(riid
) );
1469 return E_NOINTERFACE
;
1471 INetworkConnection_AddRef( iface
);
1475 static ULONG WINAPI
connection_AddRef(
1476 INetworkConnection
*iface
)
1478 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1480 TRACE( "%p\n", connection
);
1481 return InterlockedIncrement( &connection
->refs
);
1484 static ULONG WINAPI
connection_Release(
1485 INetworkConnection
*iface
)
1487 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1490 TRACE( "%p\n", connection
);
1492 if (!(refs
= InterlockedDecrement( &connection
->refs
)))
1494 list_remove( &connection
->entry
);
1495 INetwork_Release( connection
->network
);
1501 static HRESULT WINAPI
connection_GetTypeInfoCount(
1502 INetworkConnection
*iface
,
1509 static HRESULT WINAPI
connection_GetTypeInfo(
1510 INetworkConnection
*iface
,
1519 static HRESULT WINAPI
connection_GetIDsOfNames(
1520 INetworkConnection
*iface
,
1531 static HRESULT WINAPI
connection_Invoke(
1532 INetworkConnection
*iface
,
1539 EXCEPINFO
*excep_info
,
1546 static HRESULT WINAPI
connection_GetNetwork(
1547 INetworkConnection
*iface
,
1548 INetwork
**ppNetwork
)
1550 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1552 TRACE( "%p, %p\n", iface
, ppNetwork
);
1554 *ppNetwork
= connection
->network
;
1555 INetwork_AddRef( *ppNetwork
);
1559 static HRESULT WINAPI
connection_get_IsConnectedToInternet(
1560 INetworkConnection
*iface
,
1561 VARIANT_BOOL
*pbIsConnected
)
1563 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1565 TRACE( "%p, %p\n", iface
, pbIsConnected
);
1567 *pbIsConnected
= connection
->connected_to_internet
;
1571 static HRESULT WINAPI
connection_get_IsConnected(
1572 INetworkConnection
*iface
,
1573 VARIANT_BOOL
*pbIsConnected
)
1575 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1577 TRACE( "%p, %p\n", iface
, pbIsConnected
);
1579 *pbIsConnected
= connection
->connected
;
1583 static HRESULT WINAPI
connection_GetConnectivity(
1584 INetworkConnection
*iface
,
1585 NLM_CONNECTIVITY
*pConnectivity
)
1587 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1589 FIXME( "%p, %p\n", iface
, pConnectivity
);
1591 *pConnectivity
= NLM_CONNECTIVITY_DISCONNECTED
;
1593 if (connection
->connected_to_internet
)
1594 *pConnectivity
|= NLM_CONNECTIVITY_IPV4_INTERNET
;
1595 else if (connection
->connected
)
1596 *pConnectivity
|= NLM_CONNECTIVITY_IPV4_LOCALNETWORK
;
1601 static HRESULT WINAPI
connection_GetConnectionId(
1602 INetworkConnection
*iface
,
1603 GUID
*pgdConnectionId
)
1605 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1607 TRACE( "%p, %p\n", iface
, pgdConnectionId
);
1609 *pgdConnectionId
= connection
->id
;
1613 static HRESULT WINAPI
connection_GetAdapterId(
1614 INetworkConnection
*iface
,
1615 GUID
*pgdAdapterId
)
1617 struct connection
*connection
= impl_from_INetworkConnection( iface
);
1619 FIXME( "%p, %p\n", iface
, pgdAdapterId
);
1621 *pgdAdapterId
= connection
->id
;
1625 static HRESULT WINAPI
connection_GetDomainType(
1626 INetworkConnection
*iface
,
1627 NLM_DOMAIN_TYPE
*pDomainType
)
1629 FIXME( "%p, %p\n", iface
, pDomainType
);
1631 *pDomainType
= NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK
;
1635 static const struct INetworkConnectionVtbl connection_vtbl
=
1637 connection_QueryInterface
,
1640 connection_GetTypeInfoCount
,
1641 connection_GetTypeInfo
,
1642 connection_GetIDsOfNames
,
1644 connection_GetNetwork
,
1645 connection_get_IsConnectedToInternet
,
1646 connection_get_IsConnected
,
1647 connection_GetConnectivity
,
1648 connection_GetConnectionId
,
1649 connection_GetAdapterId
,
1650 connection_GetDomainType
1653 static inline struct connection
*impl_from_INetworkConnectionCost(
1654 INetworkConnectionCost
*iface
)
1656 return CONTAINING_RECORD( iface
, struct connection
, INetworkConnectionCost_iface
);
1659 static HRESULT WINAPI
connection_cost_QueryInterface(
1660 INetworkConnectionCost
*iface
,
1664 struct connection
*conn
= impl_from_INetworkConnectionCost( iface
);
1665 return INetworkConnection_QueryInterface( &conn
->INetworkConnection_iface
, riid
, obj
);
1668 static ULONG WINAPI
connection_cost_AddRef(
1669 INetworkConnectionCost
*iface
)
1671 struct connection
*conn
= impl_from_INetworkConnectionCost( iface
);
1672 return INetworkConnection_AddRef( &conn
->INetworkConnection_iface
);
1675 static ULONG WINAPI
connection_cost_Release(
1676 INetworkConnectionCost
*iface
)
1678 struct connection
*conn
= impl_from_INetworkConnectionCost( iface
);
1679 return INetworkConnection_Release( &conn
->INetworkConnection_iface
);
1682 static HRESULT WINAPI
connection_cost_GetCost(
1683 INetworkConnectionCost
*iface
, DWORD
*pCost
)
1685 FIXME( "%p, %p\n", iface
, pCost
);
1687 if (!pCost
) return E_POINTER
;
1689 *pCost
= NLM_CONNECTION_COST_UNRESTRICTED
;
1693 static HRESULT WINAPI
connection_cost_GetDataPlanStatus(
1694 INetworkConnectionCost
*iface
, NLM_DATAPLAN_STATUS
*pDataPlanStatus
)
1696 struct connection
*conn
= impl_from_INetworkConnectionCost( iface
);
1698 FIXME( "%p, %p\n", iface
, pDataPlanStatus
);
1700 if (!pDataPlanStatus
) return E_POINTER
;
1702 memcpy( &pDataPlanStatus
->InterfaceGuid
, &conn
->id
, sizeof(conn
->id
) );
1703 pDataPlanStatus
->UsageData
.UsageInMegabytes
= NLM_UNKNOWN_DATAPLAN_STATUS
;
1704 memset( &pDataPlanStatus
->UsageData
.LastSyncTime
, 0, sizeof(pDataPlanStatus
->UsageData
.LastSyncTime
) );
1705 pDataPlanStatus
->DataLimitInMegabytes
= NLM_UNKNOWN_DATAPLAN_STATUS
;
1706 pDataPlanStatus
->InboundBandwidthInKbps
= NLM_UNKNOWN_DATAPLAN_STATUS
;
1707 pDataPlanStatus
->OutboundBandwidthInKbps
= NLM_UNKNOWN_DATAPLAN_STATUS
;
1708 memset( &pDataPlanStatus
->NextBillingCycle
, 0, sizeof(pDataPlanStatus
->NextBillingCycle
) );
1709 pDataPlanStatus
->MaxTransferSizeInMegabytes
= NLM_UNKNOWN_DATAPLAN_STATUS
;
1710 pDataPlanStatus
->Reserved
= 0;
1715 static const INetworkConnectionCostVtbl connection_cost_vtbl
=
1717 connection_cost_QueryInterface
,
1718 connection_cost_AddRef
,
1719 connection_cost_Release
,
1720 connection_cost_GetCost
,
1721 connection_cost_GetDataPlanStatus
1724 static struct connection
*create_connection( const GUID
*id
)
1726 struct connection
*ret
;
1728 if (!(ret
= calloc( 1, sizeof(*ret
) ))) return NULL
;
1730 ret
->INetworkConnection_iface
.lpVtbl
= &connection_vtbl
;
1731 ret
->INetworkConnectionCost_iface
.lpVtbl
= &connection_cost_vtbl
;
1734 ret
->network
= NULL
;
1735 ret
->connected
= VARIANT_FALSE
;
1736 ret
->connected_to_internet
= VARIANT_FALSE
;
1737 list_init( &ret
->entry
);
1742 static IP_ADAPTER_ADDRESSES
*get_network_adapters(void)
1744 ULONG err
, size
= 4096, flags
= GAA_FLAG_SKIP_ANYCAST
| GAA_FLAG_SKIP_MULTICAST
|
1745 GAA_FLAG_SKIP_DNS_SERVER
| GAA_FLAG_INCLUDE_GATEWAYS
;
1746 IP_ADAPTER_ADDRESSES
*tmp
, *ret
;
1748 if (!(ret
= malloc( size
))) return NULL
;
1749 err
= GetAdaptersAddresses( AF_UNSPEC
, flags
, NULL
, ret
, &size
);
1750 while (err
== ERROR_BUFFER_OVERFLOW
)
1752 if (!(tmp
= realloc( ret
, size
))) break;
1754 err
= GetAdaptersAddresses( AF_UNSPEC
, flags
, NULL
, ret
, &size
);
1756 if (err
== ERROR_SUCCESS
) return ret
;
1761 static void init_networks( struct list_manager
*mgr
)
1763 IP_ADAPTER_ADDRESSES
*buf
, *aa
;
1766 list_init( &mgr
->networks
);
1767 list_init( &mgr
->connections
);
1769 if (!(buf
= get_network_adapters())) return;
1771 memset( &id
, 0, sizeof(id
) );
1772 for (aa
= buf
; aa
; aa
= aa
->Next
)
1774 struct network
*network
;
1775 struct connection
*connection
;
1778 ConvertInterfaceIndexToLuid(aa
->IfIndex
, &luid
);
1779 ConvertInterfaceLuidToGuid(&luid
, &id
);
1781 /* assume a one-to-one mapping between networks and connections */
1782 if (!(network
= create_network( &id
))) goto done
;
1783 if (!(connection
= create_connection( &id
)))
1785 INetwork_Release( &network
->INetwork_iface
);
1789 if (aa
->FirstUnicastAddress
)
1791 network
->connected
= VARIANT_TRUE
;
1792 connection
->connected
= VARIANT_TRUE
;
1794 if (aa
->FirstGatewayAddress
)
1796 network
->connected_to_internet
= VARIANT_TRUE
;
1797 connection
->connected_to_internet
= VARIANT_TRUE
;
1800 network
->mgr
= &mgr
->INetworkListManager_iface
;
1801 INetworkListManager_AddRef( network
->mgr
);
1802 connection
->network
= &network
->INetwork_iface
;
1803 INetwork_AddRef( connection
->network
);
1805 list_add_tail( &mgr
->networks
, &network
->entry
);
1806 list_add_tail( &mgr
->connections
, &connection
->entry
);
1813 HRESULT
list_manager_create( void **obj
)
1815 struct list_manager
*mgr
;
1817 TRACE( "%p\n", obj
);
1819 if (!(mgr
= calloc( 1, sizeof(*mgr
) ))) return E_OUTOFMEMORY
;
1820 mgr
->INetworkListManager_iface
.lpVtbl
= &list_manager_vtbl
;
1821 mgr
->INetworkCostManager_iface
.lpVtbl
= &cost_manager_vtbl
;
1822 mgr
->IConnectionPointContainer_iface
.lpVtbl
= &cpc_vtbl
;
1823 init_networks( mgr
);
1826 connection_point_init( &mgr
->list_mgr_cp
, &IID_INetworkListManagerEvents
,
1827 &mgr
->IConnectionPointContainer_iface
);
1828 connection_point_init( &mgr
->cost_mgr_cp
, &IID_INetworkCostManagerEvents
,
1829 &mgr
->IConnectionPointContainer_iface
);
1830 connection_point_init( &mgr
->conn_mgr_cp
, &IID_INetworkConnectionEvents
,
1831 &mgr
->IConnectionPointContainer_iface
);
1832 connection_point_init( &mgr
->events_cp
, &IID_INetworkEvents
,
1833 &mgr
->IConnectionPointContainer_iface
);
1835 *obj
= &mgr
->INetworkListManager_iface
;
1836 TRACE( "returning iface %p\n", *obj
);