wsdapi/tests: Add tests for AppSequence in Probe message.
[wine.git] / dlls / netprofm / list.c
blobf6823f09cf0757eb4859cd3e421d48c63c78308f
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
21 #define NONAMELESSUNION
22 #define NONAMELESSSTRUCT
24 #include "config.h"
25 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #define USE_WS_PREFIX
29 #include "winsock2.h"
30 #include "ws2ipdef.h"
31 #include "iphlpapi.h"
32 #include "ifdef.h"
33 #include "netioapi.h"
34 #include "initguid.h"
35 #include "objbase.h"
36 #include "ocidl.h"
37 #include "netlistmgr.h"
38 #include "olectl.h"
40 #include "wine/debug.h"
41 #include "wine/heap.h"
42 #include "wine/list.h"
43 #include "netprofm_private.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(netprofm);
47 struct network
49 INetwork INetwork_iface;
50 LONG refs;
51 struct list entry;
52 GUID id;
53 VARIANT_BOOL connected_to_internet;
54 VARIANT_BOOL connected;
57 struct connection
59 INetworkConnection INetworkConnection_iface;
60 INetworkConnectionCost INetworkConnectionCost_iface;
61 LONG refs;
62 struct list entry;
63 GUID id;
64 INetwork *network;
65 VARIANT_BOOL connected_to_internet;
66 VARIANT_BOOL connected;
69 struct connection_point
71 IConnectionPoint IConnectionPoint_iface;
72 IConnectionPointContainer *container;
73 IID iid;
74 struct list sinks;
75 DWORD cookie;
78 struct list_manager
80 INetworkListManager INetworkListManager_iface;
81 INetworkCostManager INetworkCostManager_iface;
82 IConnectionPointContainer IConnectionPointContainer_iface;
83 LONG refs;
84 struct list networks;
85 struct list connections;
86 struct connection_point list_mgr_cp;
87 struct connection_point cost_mgr_cp;
88 struct connection_point conn_mgr_cp;
91 struct sink_entry
93 struct list entry;
94 DWORD cookie;
95 IUnknown *unk;
98 static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
100 return CONTAINING_RECORD(iface, struct list_manager, IConnectionPointContainer_iface);
103 static inline struct list_manager *impl_from_INetworkCostManager(
104 INetworkCostManager *iface )
106 return CONTAINING_RECORD( iface, struct list_manager, INetworkCostManager_iface );
109 static inline struct connection_point *impl_from_IConnectionPoint(
110 IConnectionPoint *iface )
112 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
115 static HRESULT WINAPI connection_point_QueryInterface(
116 IConnectionPoint *iface,
117 REFIID riid,
118 void **obj )
120 struct connection_point *cp = impl_from_IConnectionPoint( iface );
121 TRACE( "%p, %s, %p\n", cp, debugstr_guid(riid), obj );
123 if (IsEqualGUID( riid, &IID_IConnectionPoint ) ||
124 IsEqualGUID( riid, &IID_IUnknown ))
126 *obj = iface;
128 else
130 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
131 *obj = NULL;
132 return E_NOINTERFACE;
134 IConnectionPoint_AddRef( iface );
135 return S_OK;
138 static ULONG WINAPI connection_point_AddRef(
139 IConnectionPoint *iface )
141 struct connection_point *cp = impl_from_IConnectionPoint( iface );
142 return IConnectionPointContainer_AddRef( cp->container );
145 static ULONG WINAPI connection_point_Release(
146 IConnectionPoint *iface )
148 struct connection_point *cp = impl_from_IConnectionPoint( iface );
149 return IConnectionPointContainer_Release( cp->container );
152 static HRESULT WINAPI connection_point_GetConnectionInterface(
153 IConnectionPoint *iface,
154 IID *iid )
156 struct connection_point *cp = impl_from_IConnectionPoint( iface );
157 TRACE( "%p, %p\n", cp, iid );
159 if (!iid)
160 return E_POINTER;
162 memcpy( iid, &cp->iid, sizeof(*iid) );
163 return S_OK;
166 static HRESULT WINAPI connection_point_GetConnectionPointContainer(
167 IConnectionPoint *iface,
168 IConnectionPointContainer **container )
170 struct connection_point *cp = impl_from_IConnectionPoint( iface );
171 TRACE( "%p, %p\n", cp, container );
173 if (!container)
174 return E_POINTER;
176 IConnectionPointContainer_AddRef( cp->container );
177 *container = cp->container;
178 return S_OK;
181 static HRESULT WINAPI connection_point_Advise(
182 IConnectionPoint *iface,
183 IUnknown *sink,
184 DWORD *cookie )
186 struct connection_point *cp = impl_from_IConnectionPoint( iface );
187 struct sink_entry *sink_entry;
188 IUnknown *unk;
189 HRESULT hr;
191 FIXME( "%p, %p, %p - semi-stub\n", cp, sink, cookie );
193 if (!sink || !cookie)
194 return E_POINTER;
196 hr = IUnknown_QueryInterface( sink, &cp->iid, (void**)&unk );
197 if (FAILED(hr))
199 WARN( "iface %s not implemented by sink\n", debugstr_guid(&cp->iid) );
200 return CO_E_FAILEDTOOPENTHREADTOKEN;
203 sink_entry = heap_alloc( sizeof(*sink_entry) );
204 if (!sink_entry)
206 IUnknown_Release( unk );
207 return E_OUTOFMEMORY;
210 sink_entry->unk = unk;
211 *cookie = sink_entry->cookie = ++cp->cookie;
212 list_add_tail( &cp->sinks, &sink_entry->entry );
213 return S_OK;
216 static void sink_entry_release( struct sink_entry *entry )
218 list_remove( &entry->entry );
219 IUnknown_Release( entry->unk );
220 heap_free( entry );
223 static HRESULT WINAPI connection_point_Unadvise(
224 IConnectionPoint *iface,
225 DWORD cookie )
227 struct connection_point *cp = impl_from_IConnectionPoint( iface );
228 struct sink_entry *iter;
230 TRACE( "%p, %d\n", cp, cookie );
232 LIST_FOR_EACH_ENTRY( iter, &cp->sinks, struct sink_entry, entry )
234 if (iter->cookie != cookie) continue;
235 sink_entry_release( iter );
236 return S_OK;
239 WARN( "invalid cookie\n" );
240 return OLE_E_NOCONNECTION;
243 static HRESULT WINAPI connection_point_EnumConnections(
244 IConnectionPoint *iface,
245 IEnumConnections **connections )
247 struct connection_point *cp = impl_from_IConnectionPoint( iface );
248 FIXME( "%p, %p - stub\n", cp, connections );
250 return E_NOTIMPL;
253 static const IConnectionPointVtbl connection_point_vtbl =
255 connection_point_QueryInterface,
256 connection_point_AddRef,
257 connection_point_Release,
258 connection_point_GetConnectionInterface,
259 connection_point_GetConnectionPointContainer,
260 connection_point_Advise,
261 connection_point_Unadvise,
262 connection_point_EnumConnections
265 static void connection_point_init(
266 struct connection_point *cp,
267 REFIID riid,
268 IConnectionPointContainer *container )
270 cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
271 cp->container = container;
272 cp->cookie = 0;
273 cp->iid = *riid;
274 list_init( &cp->sinks );
277 static void connection_point_release( struct connection_point *cp )
279 while (!list_empty( &cp->sinks ))
280 sink_entry_release( LIST_ENTRY( list_head( &cp->sinks ), struct sink_entry, entry ) );
283 static inline struct network *impl_from_INetwork(
284 INetwork *iface )
286 return CONTAINING_RECORD( iface, struct network, INetwork_iface );
289 static HRESULT WINAPI network_QueryInterface(
290 INetwork *iface, REFIID riid, void **obj )
292 struct network *network = impl_from_INetwork( iface );
294 TRACE( "%p, %s, %p\n", network, debugstr_guid(riid), obj );
296 if (IsEqualIID( riid, &IID_INetwork ) ||
297 IsEqualIID( riid, &IID_IDispatch ) ||
298 IsEqualIID( riid, &IID_IUnknown ))
300 *obj = iface;
301 INetwork_AddRef( iface );
302 return S_OK;
304 else
306 WARN( "interface not supported %s\n", debugstr_guid(riid) );
307 *obj = NULL;
308 return E_NOINTERFACE;
312 static ULONG WINAPI network_AddRef(
313 INetwork *iface )
315 struct network *network = impl_from_INetwork( iface );
317 TRACE( "%p\n", network );
318 return InterlockedIncrement( &network->refs );
321 static ULONG WINAPI network_Release(
322 INetwork *iface )
324 struct network *network = impl_from_INetwork( iface );
325 LONG refs;
327 TRACE( "%p\n", network );
329 if (!(refs = InterlockedDecrement( &network->refs )))
331 list_remove( &network->entry );
332 heap_free( network );
334 return refs;
337 static HRESULT WINAPI network_GetTypeInfoCount(
338 INetwork *iface,
339 UINT *count )
341 FIXME("\n");
342 return E_NOTIMPL;
345 static HRESULT WINAPI network_GetTypeInfo(
346 INetwork *iface,
347 UINT index,
348 LCID lcid,
349 ITypeInfo **info )
351 FIXME("\n");
352 return E_NOTIMPL;
355 static HRESULT WINAPI network_GetIDsOfNames(
356 INetwork *iface,
357 REFIID riid,
358 LPOLESTR *names,
359 UINT count,
360 LCID lcid,
361 DISPID *dispid )
363 FIXME("\n");
364 return E_NOTIMPL;
367 static HRESULT WINAPI network_Invoke(
368 INetwork *iface,
369 DISPID member,
370 REFIID riid,
371 LCID lcid,
372 WORD flags,
373 DISPPARAMS *params,
374 VARIANT *result,
375 EXCEPINFO *excep_info,
376 UINT *arg_err )
378 FIXME("\n");
379 return E_NOTIMPL;
382 static HRESULT WINAPI network_GetName(
383 INetwork *iface,
384 BSTR *pszNetworkName )
386 FIXME( "%p, %p\n", iface, pszNetworkName );
387 return E_NOTIMPL;
390 static HRESULT WINAPI network_SetName(
391 INetwork *iface,
392 BSTR szNetworkNewName )
394 FIXME( "%p, %s\n", iface, debugstr_w(szNetworkNewName) );
395 return E_NOTIMPL;
398 static HRESULT WINAPI network_GetDescription(
399 INetwork *iface,
400 BSTR *pszDescription )
402 FIXME( "%p, %p\n", iface, pszDescription );
403 return E_NOTIMPL;
406 static HRESULT WINAPI network_SetDescription(
407 INetwork *iface,
408 BSTR szDescription )
410 FIXME( "%p, %s\n", iface, debugstr_w(szDescription) );
411 return E_NOTIMPL;
414 static HRESULT WINAPI network_GetNetworkId(
415 INetwork *iface,
416 GUID *pgdGuidNetworkId )
418 struct network *network = impl_from_INetwork( iface );
420 TRACE( "%p, %p\n", iface, pgdGuidNetworkId );
422 *pgdGuidNetworkId = network->id;
423 return S_OK;
426 static HRESULT WINAPI network_GetDomainType(
427 INetwork *iface,
428 NLM_DOMAIN_TYPE *pDomainType )
430 FIXME( "%p, %p\n", iface, pDomainType );
432 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
433 return S_OK;
436 static HRESULT WINAPI network_GetNetworkConnections(
437 INetwork *iface,
438 IEnumNetworkConnections **ppEnumNetworkConnection )
440 FIXME( "%p, %p\n", iface, ppEnumNetworkConnection );
441 return E_NOTIMPL;
444 static HRESULT WINAPI network_GetTimeCreatedAndConnected(
445 INetwork *iface,
446 DWORD *pdwLowDateTimeCreated,
447 DWORD *pdwHighDateTimeCreated,
448 DWORD *pdwLowDateTimeConnected,
449 DWORD *pdwHighDateTimeConnected )
451 FIXME( "%p, %p, %p, %p, %p\n", iface, pdwLowDateTimeCreated, pdwHighDateTimeCreated,
452 pdwLowDateTimeConnected, pdwHighDateTimeConnected );
453 return E_NOTIMPL;
456 static HRESULT WINAPI network_get_IsConnectedToInternet(
457 INetwork *iface,
458 VARIANT_BOOL *pbIsConnected )
460 struct network *network = impl_from_INetwork( iface );
462 TRACE( "%p, %p\n", iface, pbIsConnected );
464 *pbIsConnected = network->connected_to_internet;
465 return S_OK;
468 static HRESULT WINAPI network_get_IsConnected(
469 INetwork *iface,
470 VARIANT_BOOL *pbIsConnected )
472 struct network *network = impl_from_INetwork( iface );
474 TRACE( "%p, %p\n", iface, pbIsConnected );
476 *pbIsConnected = network->connected;
477 return S_OK;
480 static HRESULT WINAPI network_GetConnectivity(
481 INetwork *iface,
482 NLM_CONNECTIVITY *pConnectivity )
484 FIXME( "%p, %p\n", iface, pConnectivity );
486 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
487 return S_OK;
490 static HRESULT WINAPI network_GetCategory(
491 INetwork *iface,
492 NLM_NETWORK_CATEGORY *pCategory )
494 FIXME( "%p, %p\n", iface, pCategory );
496 *pCategory = NLM_NETWORK_CATEGORY_PUBLIC;
497 return S_OK;
500 static HRESULT WINAPI network_SetCategory(
501 INetwork *iface,
502 NLM_NETWORK_CATEGORY NewCategory )
504 FIXME( "%p, %u\n", iface, NewCategory );
505 return E_NOTIMPL;
508 static const struct INetworkVtbl network_vtbl =
510 network_QueryInterface,
511 network_AddRef,
512 network_Release,
513 network_GetTypeInfoCount,
514 network_GetTypeInfo,
515 network_GetIDsOfNames,
516 network_Invoke,
517 network_GetName,
518 network_SetName,
519 network_GetDescription,
520 network_SetDescription,
521 network_GetNetworkId,
522 network_GetDomainType,
523 network_GetNetworkConnections,
524 network_GetTimeCreatedAndConnected,
525 network_get_IsConnectedToInternet,
526 network_get_IsConnected,
527 network_GetConnectivity,
528 network_GetCategory,
529 network_SetCategory
532 static struct network *create_network( const GUID *id )
534 struct network *ret;
536 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
538 ret->INetwork_iface.lpVtbl = &network_vtbl;
539 ret->refs = 1;
540 ret->id = *id;
541 ret->connected = VARIANT_FALSE;
542 ret->connected_to_internet = VARIANT_FALSE;
543 list_init( &ret->entry );
545 return ret;
548 static HRESULT WINAPI cost_manager_QueryInterface(
549 INetworkCostManager *iface,
550 REFIID riid,
551 void **obj )
553 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
554 return INetworkListManager_QueryInterface( &mgr->INetworkListManager_iface, riid, obj );
557 static ULONG WINAPI cost_manager_AddRef(
558 INetworkCostManager *iface )
560 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
561 return INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
564 static ULONG WINAPI cost_manager_Release(
565 INetworkCostManager *iface )
567 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
568 return INetworkListManager_Release( &mgr->INetworkListManager_iface );
571 static HRESULT WINAPI cost_manager_GetCost(
572 INetworkCostManager *iface, DWORD *pCost, NLM_SOCKADDR *pDestIPAddr)
574 FIXME( "%p, %p, %p\n", iface, pCost, pDestIPAddr );
576 if (!pCost) return E_POINTER;
578 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
579 return S_OK;
582 static BOOL map_address_6to4( const SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
584 ULONG i;
586 if (addr6->sin6_family != WS_AF_INET6) return FALSE;
588 for (i = 0; i < 5; i++)
589 if (addr6->sin6_addr.u.Word[i]) return FALSE;
591 if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
593 addr4->sin_family = WS_AF_INET;
594 addr4->sin_port = addr6->sin6_port;
595 addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
596 memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
598 return TRUE;
601 static HRESULT WINAPI cost_manager_GetDataPlanStatus(
602 INetworkCostManager *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus,
603 NLM_SOCKADDR *pDestIPAddr)
605 DWORD ret, index;
606 NET_LUID luid;
607 SOCKADDR *dst = (SOCKADDR *)pDestIPAddr;
608 SOCKADDR_IN addr4, *dst4;
610 FIXME( "%p, %p, %p\n", iface, pDataPlanStatus, pDestIPAddr );
612 if (!pDataPlanStatus) return E_POINTER;
614 if (dst && ((dst->sa_family == WS_AF_INET && (dst4 = (SOCKADDR_IN *)dst)) ||
615 ((dst->sa_family == WS_AF_INET6 && map_address_6to4( (const SOCKADDR_IN6 *)dst, &addr4 )
616 && (dst4 = &addr4)))))
618 if ((ret = GetBestInterface( dst4->sin_addr.S_un.S_addr, &index )))
619 return HRESULT_FROM_WIN32( ret );
621 if ((ret = ConvertInterfaceIndexToLuid( index, &luid )))
622 return HRESULT_FROM_WIN32( ret );
624 if ((ret = ConvertInterfaceLuidToGuid( &luid, &pDataPlanStatus->InterfaceGuid )))
625 return HRESULT_FROM_WIN32( ret );
627 else
629 FIXME( "interface guid not found\n" );
630 memset( &pDataPlanStatus->InterfaceGuid, 0, sizeof(pDataPlanStatus->InterfaceGuid) );
633 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
634 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
635 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
636 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
637 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
638 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
639 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
640 pDataPlanStatus->Reserved = 0;
642 return S_OK;
645 static HRESULT WINAPI cost_manager_SetDestinationAddresses(
646 INetworkCostManager *iface, UINT32 length, NLM_SOCKADDR *pDestIPAddrList,
647 VARIANT_BOOL bAppend)
649 FIXME( "%p, %u, %p, %x\n", iface, length, pDestIPAddrList, bAppend );
650 return E_NOTIMPL;
653 static const INetworkCostManagerVtbl cost_manager_vtbl =
655 cost_manager_QueryInterface,
656 cost_manager_AddRef,
657 cost_manager_Release,
658 cost_manager_GetCost,
659 cost_manager_GetDataPlanStatus,
660 cost_manager_SetDestinationAddresses
663 struct networks_enum
665 IEnumNetworks IEnumNetworks_iface;
666 LONG refs;
667 struct list_manager *mgr;
668 struct list *cursor;
671 static inline struct networks_enum *impl_from_IEnumNetworks(
672 IEnumNetworks *iface )
674 return CONTAINING_RECORD( iface, struct networks_enum, IEnumNetworks_iface );
677 static HRESULT WINAPI networks_enum_QueryInterface(
678 IEnumNetworks *iface, REFIID riid, void **obj )
680 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
682 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
684 if (IsEqualIID( riid, &IID_IEnumNetworks ) ||
685 IsEqualIID( riid, &IID_IDispatch ) ||
686 IsEqualIID( riid, &IID_IUnknown ))
688 *obj = iface;
689 IEnumNetworks_AddRef( iface );
690 return S_OK;
692 else
694 WARN( "interface not supported %s\n", debugstr_guid(riid) );
695 *obj = NULL;
696 return E_NOINTERFACE;
700 static ULONG WINAPI networks_enum_AddRef(
701 IEnumNetworks *iface )
703 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
705 TRACE( "%p\n", iter );
706 return InterlockedIncrement( &iter->refs );
709 static ULONG WINAPI networks_enum_Release(
710 IEnumNetworks *iface )
712 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
713 LONG refs;
715 TRACE( "%p\n", iter );
717 if (!(refs = InterlockedDecrement( &iter->refs )))
719 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
720 heap_free( iter );
722 return refs;
725 static HRESULT WINAPI networks_enum_GetTypeInfoCount(
726 IEnumNetworks *iface,
727 UINT *count )
729 FIXME("\n");
730 return E_NOTIMPL;
733 static HRESULT WINAPI networks_enum_GetTypeInfo(
734 IEnumNetworks *iface,
735 UINT index,
736 LCID lcid,
737 ITypeInfo **info )
739 FIXME("\n");
740 return E_NOTIMPL;
743 static HRESULT WINAPI networks_enum_GetIDsOfNames(
744 IEnumNetworks *iface,
745 REFIID riid,
746 LPOLESTR *names,
747 UINT count,
748 LCID lcid,
749 DISPID *dispid )
751 FIXME("\n");
752 return E_NOTIMPL;
755 static HRESULT WINAPI networks_enum_Invoke(
756 IEnumNetworks *iface,
757 DISPID member,
758 REFIID riid,
759 LCID lcid,
760 WORD flags,
761 DISPPARAMS *params,
762 VARIANT *result,
763 EXCEPINFO *excep_info,
764 UINT *arg_err )
766 FIXME("\n");
767 return E_NOTIMPL;
770 static HRESULT WINAPI networks_enum_get__NewEnum(
771 IEnumNetworks *iface, IEnumVARIANT **ppEnumVar )
773 FIXME("\n");
774 return E_NOTIMPL;
777 static HRESULT WINAPI networks_enum_Next(
778 IEnumNetworks *iface, ULONG count, INetwork **ret, ULONG *fetched )
780 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
781 ULONG i = 0;
783 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
785 if (fetched) *fetched = 0;
786 if (!count) return S_OK;
788 while (iter->cursor && i < count)
790 struct network *network = LIST_ENTRY( iter->cursor, struct network, entry );
791 ret[i] = &network->INetwork_iface;
792 INetwork_AddRef( ret[i] );
793 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
794 i++;
796 if (fetched) *fetched = i;
798 return i < count ? S_FALSE : S_OK;
801 static HRESULT WINAPI networks_enum_Skip(
802 IEnumNetworks *iface, ULONG count )
804 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
806 TRACE( "%p, %u\n", iter, count);
808 if (!count) return S_OK;
809 if (!iter->cursor) return S_FALSE;
811 while (count--)
813 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
814 if (!iter->cursor) break;
817 return count ? S_FALSE : S_OK;
820 static HRESULT WINAPI networks_enum_Reset(
821 IEnumNetworks *iface )
823 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
825 TRACE( "%p\n", iter );
827 iter->cursor = list_head( &iter->mgr->networks );
828 return S_OK;
831 static HRESULT create_networks_enum(
832 struct list_manager *, IEnumNetworks** );
834 static HRESULT WINAPI networks_enum_Clone(
835 IEnumNetworks *iface, IEnumNetworks **ret )
837 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
839 TRACE( "%p, %p\n", iter, ret );
840 return create_networks_enum( iter->mgr, ret );
843 static const IEnumNetworksVtbl networks_enum_vtbl =
845 networks_enum_QueryInterface,
846 networks_enum_AddRef,
847 networks_enum_Release,
848 networks_enum_GetTypeInfoCount,
849 networks_enum_GetTypeInfo,
850 networks_enum_GetIDsOfNames,
851 networks_enum_Invoke,
852 networks_enum_get__NewEnum,
853 networks_enum_Next,
854 networks_enum_Skip,
855 networks_enum_Reset,
856 networks_enum_Clone
859 static HRESULT create_networks_enum(
860 struct list_manager *mgr, IEnumNetworks **ret )
862 struct networks_enum *iter;
864 *ret = NULL;
865 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
867 iter->IEnumNetworks_iface.lpVtbl = &networks_enum_vtbl;
868 iter->cursor = list_head( &mgr->networks );
869 iter->mgr = mgr;
870 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
871 iter->refs = 1;
873 *ret = &iter->IEnumNetworks_iface;
874 return S_OK;
877 static inline struct list_manager *impl_from_INetworkListManager(
878 INetworkListManager *iface )
880 return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface );
883 struct connections_enum
885 IEnumNetworkConnections IEnumNetworkConnections_iface;
886 LONG refs;
887 struct list_manager *mgr;
888 struct list *cursor;
891 static inline struct connections_enum *impl_from_IEnumNetworkConnections(
892 IEnumNetworkConnections *iface )
894 return CONTAINING_RECORD( iface, struct connections_enum, IEnumNetworkConnections_iface );
897 static HRESULT WINAPI connections_enum_QueryInterface(
898 IEnumNetworkConnections *iface, REFIID riid, void **obj )
900 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
902 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
904 if (IsEqualIID( riid, &IID_IEnumNetworkConnections ) ||
905 IsEqualIID( riid, &IID_IDispatch ) ||
906 IsEqualIID( riid, &IID_IUnknown ))
908 *obj = iface;
909 IEnumNetworkConnections_AddRef( iface );
910 return S_OK;
912 else
914 WARN( "interface not supported %s\n", debugstr_guid(riid) );
915 *obj = NULL;
916 return E_NOINTERFACE;
920 static ULONG WINAPI connections_enum_AddRef(
921 IEnumNetworkConnections *iface )
923 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
925 TRACE( "%p\n", iter );
926 return InterlockedIncrement( &iter->refs );
929 static ULONG WINAPI connections_enum_Release(
930 IEnumNetworkConnections *iface )
932 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
933 LONG refs;
935 TRACE( "%p\n", iter );
937 if (!(refs = InterlockedDecrement( &iter->refs )))
939 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
940 heap_free( iter );
942 return refs;
945 static HRESULT WINAPI connections_enum_GetTypeInfoCount(
946 IEnumNetworkConnections *iface,
947 UINT *count )
949 FIXME("\n");
950 return E_NOTIMPL;
953 static HRESULT WINAPI connections_enum_GetTypeInfo(
954 IEnumNetworkConnections *iface,
955 UINT index,
956 LCID lcid,
957 ITypeInfo **info )
959 FIXME("\n");
960 return E_NOTIMPL;
963 static HRESULT WINAPI connections_enum_GetIDsOfNames(
964 IEnumNetworkConnections *iface,
965 REFIID riid,
966 LPOLESTR *names,
967 UINT count,
968 LCID lcid,
969 DISPID *dispid )
971 FIXME("\n");
972 return E_NOTIMPL;
975 static HRESULT WINAPI connections_enum_Invoke(
976 IEnumNetworkConnections *iface,
977 DISPID member,
978 REFIID riid,
979 LCID lcid,
980 WORD flags,
981 DISPPARAMS *params,
982 VARIANT *result,
983 EXCEPINFO *excep_info,
984 UINT *arg_err )
986 FIXME("\n");
987 return E_NOTIMPL;
990 static HRESULT WINAPI connections_enum_get__NewEnum(
991 IEnumNetworkConnections *iface, IEnumVARIANT **ppEnumVar )
993 FIXME("\n");
994 return E_NOTIMPL;
997 static HRESULT WINAPI connections_enum_Next(
998 IEnumNetworkConnections *iface, ULONG count, INetworkConnection **ret, ULONG *fetched )
1000 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1001 ULONG i = 0;
1003 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
1005 if (fetched) *fetched = 0;
1006 if (!count) return S_OK;
1008 while (iter->cursor && i < count)
1010 struct connection *connection = LIST_ENTRY( iter->cursor, struct connection, entry );
1011 ret[i] = &connection->INetworkConnection_iface;
1012 INetworkConnection_AddRef( ret[i] );
1013 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1014 i++;
1016 if (fetched) *fetched = i;
1018 return i < count ? S_FALSE : S_OK;
1021 static HRESULT WINAPI connections_enum_Skip(
1022 IEnumNetworkConnections *iface, ULONG count )
1024 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1026 TRACE( "%p, %u\n", iter, count);
1028 if (!count) return S_OK;
1029 if (!iter->cursor) return S_FALSE;
1031 while (count--)
1033 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1034 if (!iter->cursor) break;
1037 return count ? S_FALSE : S_OK;
1040 static HRESULT WINAPI connections_enum_Reset(
1041 IEnumNetworkConnections *iface )
1043 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1045 TRACE( "%p\n", iter );
1047 iter->cursor = list_head( &iter->mgr->connections );
1048 return S_OK;
1051 static HRESULT create_connections_enum(
1052 struct list_manager *, IEnumNetworkConnections** );
1054 static HRESULT WINAPI connections_enum_Clone(
1055 IEnumNetworkConnections *iface, IEnumNetworkConnections **ret )
1057 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1059 TRACE( "%p, %p\n", iter, ret );
1060 return create_connections_enum( iter->mgr, ret );
1063 static const IEnumNetworkConnectionsVtbl connections_enum_vtbl =
1065 connections_enum_QueryInterface,
1066 connections_enum_AddRef,
1067 connections_enum_Release,
1068 connections_enum_GetTypeInfoCount,
1069 connections_enum_GetTypeInfo,
1070 connections_enum_GetIDsOfNames,
1071 connections_enum_Invoke,
1072 connections_enum_get__NewEnum,
1073 connections_enum_Next,
1074 connections_enum_Skip,
1075 connections_enum_Reset,
1076 connections_enum_Clone
1079 static HRESULT create_connections_enum(
1080 struct list_manager *mgr, IEnumNetworkConnections **ret )
1082 struct connections_enum *iter;
1084 *ret = NULL;
1085 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
1087 iter->IEnumNetworkConnections_iface.lpVtbl = &connections_enum_vtbl;
1088 iter->mgr = mgr;
1089 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
1090 iter->cursor = list_head( &iter->mgr->connections );
1091 iter->refs = 1;
1093 *ret = &iter->IEnumNetworkConnections_iface;
1094 return S_OK;
1097 static ULONG WINAPI list_manager_AddRef(
1098 INetworkListManager *iface )
1100 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1101 return InterlockedIncrement( &mgr->refs );
1104 static ULONG WINAPI list_manager_Release(
1105 INetworkListManager *iface )
1107 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1108 LONG refs = InterlockedDecrement( &mgr->refs );
1109 if (!refs)
1111 struct list *ptr;
1113 TRACE( "destroying %p\n", mgr );
1115 connection_point_release( &mgr->conn_mgr_cp );
1116 connection_point_release( &mgr->cost_mgr_cp );
1117 connection_point_release( &mgr->list_mgr_cp );
1118 while ((ptr = list_head( &mgr->networks )))
1120 struct network *network = LIST_ENTRY( ptr, struct network, entry );
1121 list_remove( &network->entry );
1122 INetwork_Release( &network->INetwork_iface );
1124 while ((ptr = list_head( &mgr->connections )))
1126 struct connection *connection = LIST_ENTRY( ptr, struct connection, entry );
1127 list_remove( &connection->entry );
1128 INetworkConnection_Release( &connection->INetworkConnection_iface );
1130 heap_free( mgr );
1132 return refs;
1135 static HRESULT WINAPI list_manager_QueryInterface(
1136 INetworkListManager *iface,
1137 REFIID riid,
1138 void **obj )
1140 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1142 TRACE( "%p, %s, %p\n", mgr, debugstr_guid(riid), obj );
1144 if (IsEqualGUID( riid, &IID_INetworkListManager ) ||
1145 IsEqualGUID( riid, &IID_IDispatch ) ||
1146 IsEqualGUID( riid, &IID_IUnknown ))
1148 *obj = iface;
1150 else if (IsEqualGUID( riid, &IID_INetworkCostManager ))
1152 *obj = &mgr->INetworkCostManager_iface;
1154 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
1156 *obj = &mgr->IConnectionPointContainer_iface;
1158 else
1160 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1161 *obj = NULL;
1162 return E_NOINTERFACE;
1164 INetworkListManager_AddRef( iface );
1165 return S_OK;
1168 static HRESULT WINAPI list_manager_GetTypeInfoCount(
1169 INetworkListManager *iface,
1170 UINT *count )
1172 FIXME("\n");
1173 return E_NOTIMPL;
1176 static HRESULT WINAPI list_manager_GetTypeInfo(
1177 INetworkListManager *iface,
1178 UINT index,
1179 LCID lcid,
1180 ITypeInfo **info )
1182 FIXME("\n");
1183 return E_NOTIMPL;
1186 static HRESULT WINAPI list_manager_GetIDsOfNames(
1187 INetworkListManager *iface,
1188 REFIID riid,
1189 LPOLESTR *names,
1190 UINT count,
1191 LCID lcid,
1192 DISPID *dispid )
1194 FIXME("\n");
1195 return E_NOTIMPL;
1198 static HRESULT WINAPI list_manager_Invoke(
1199 INetworkListManager *iface,
1200 DISPID member,
1201 REFIID riid,
1202 LCID lcid,
1203 WORD flags,
1204 DISPPARAMS *params,
1205 VARIANT *result,
1206 EXCEPINFO *excep_info,
1207 UINT *arg_err )
1209 FIXME("\n");
1210 return E_NOTIMPL;
1213 static HRESULT WINAPI list_manager_GetNetworks(
1214 INetworkListManager *iface,
1215 NLM_ENUM_NETWORK Flags,
1216 IEnumNetworks **ppEnumNetwork )
1218 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1220 TRACE( "%p, %x, %p\n", iface, Flags, ppEnumNetwork );
1221 if (Flags) FIXME( "flags %08x not supported\n", Flags );
1223 return create_networks_enum( mgr, ppEnumNetwork );
1226 static HRESULT WINAPI list_manager_GetNetwork(
1227 INetworkListManager *iface,
1228 GUID gdNetworkId,
1229 INetwork **ppNetwork )
1231 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1232 struct network *network;
1234 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkId), ppNetwork );
1236 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1238 if (IsEqualGUID( &network->id, &gdNetworkId ))
1240 *ppNetwork = &network->INetwork_iface;
1241 INetwork_AddRef( *ppNetwork );
1242 return S_OK;
1246 return S_FALSE;
1249 static HRESULT WINAPI list_manager_GetNetworkConnections(
1250 INetworkListManager *iface,
1251 IEnumNetworkConnections **ppEnum )
1253 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1255 TRACE( "%p, %p\n", iface, ppEnum );
1256 return create_connections_enum( mgr, ppEnum );
1259 static HRESULT WINAPI list_manager_GetNetworkConnection(
1260 INetworkListManager *iface,
1261 GUID gdNetworkConnectionId,
1262 INetworkConnection **ppNetworkConnection )
1264 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1265 struct connection *connection;
1267 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkConnectionId),
1268 ppNetworkConnection );
1270 LIST_FOR_EACH_ENTRY( connection, &mgr->connections, struct connection, entry )
1272 if (IsEqualGUID( &connection->id, &gdNetworkConnectionId ))
1274 *ppNetworkConnection = &connection->INetworkConnection_iface;
1275 INetworkConnection_AddRef( *ppNetworkConnection );
1276 return S_OK;
1280 return S_FALSE;
1283 static HRESULT WINAPI list_manager_IsConnectedToInternet(
1284 INetworkListManager *iface,
1285 VARIANT_BOOL *pbIsConnected )
1287 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1288 struct network *network;
1290 TRACE( "%p, %p\n", iface, pbIsConnected );
1292 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1294 if (network->connected_to_internet)
1296 *pbIsConnected = VARIANT_TRUE;
1297 return S_OK;
1301 *pbIsConnected = VARIANT_FALSE;
1302 return S_OK;
1305 static HRESULT WINAPI list_manager_IsConnected(
1306 INetworkListManager *iface,
1307 VARIANT_BOOL *pbIsConnected )
1309 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1310 struct network *network;
1312 TRACE( "%p, %p\n", iface, pbIsConnected );
1314 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1316 if (network->connected)
1318 *pbIsConnected = VARIANT_TRUE;
1319 return S_OK;
1323 *pbIsConnected = VARIANT_FALSE;
1324 return S_OK;
1327 static HRESULT WINAPI list_manager_GetConnectivity(
1328 INetworkListManager *iface,
1329 NLM_CONNECTIVITY *pConnectivity )
1331 FIXME( "%p, %p\n", iface, pConnectivity );
1333 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1334 return S_OK;
1337 static const INetworkListManagerVtbl list_manager_vtbl =
1339 list_manager_QueryInterface,
1340 list_manager_AddRef,
1341 list_manager_Release,
1342 list_manager_GetTypeInfoCount,
1343 list_manager_GetTypeInfo,
1344 list_manager_GetIDsOfNames,
1345 list_manager_Invoke,
1346 list_manager_GetNetworks,
1347 list_manager_GetNetwork,
1348 list_manager_GetNetworkConnections,
1349 list_manager_GetNetworkConnection,
1350 list_manager_IsConnectedToInternet,
1351 list_manager_IsConnected,
1352 list_manager_GetConnectivity
1355 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
1356 REFIID riid, void **ppv)
1358 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1359 return INetworkListManager_QueryInterface(&This->INetworkListManager_iface, riid, ppv);
1362 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
1364 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1365 return INetworkListManager_AddRef(&This->INetworkListManager_iface);
1368 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
1370 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1371 return INetworkListManager_Release(&This->INetworkListManager_iface);
1374 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
1375 IEnumConnectionPoints **ppEnum)
1377 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1378 FIXME("(%p)->(%p): stub\n", This, ppEnum);
1379 return E_NOTIMPL;
1382 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
1383 REFIID riid, IConnectionPoint **cp)
1385 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1386 struct connection_point *ret;
1388 TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
1390 if (!riid || !cp)
1391 return E_POINTER;
1393 if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ))
1394 ret = &This->list_mgr_cp;
1395 else if (IsEqualGUID( riid, &IID_INetworkCostManagerEvents ))
1396 ret = &This->cost_mgr_cp;
1397 else if (IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
1398 ret = &This->conn_mgr_cp;
1399 else
1401 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1402 *cp = NULL;
1403 return E_NOINTERFACE;
1406 IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface );
1407 return S_OK;
1410 static const struct IConnectionPointContainerVtbl cpc_vtbl =
1412 ConnectionPointContainer_QueryInterface,
1413 ConnectionPointContainer_AddRef,
1414 ConnectionPointContainer_Release,
1415 ConnectionPointContainer_EnumConnectionPoints,
1416 ConnectionPointContainer_FindConnectionPoint
1419 static inline struct connection *impl_from_INetworkConnection(
1420 INetworkConnection *iface )
1422 return CONTAINING_RECORD( iface, struct connection, INetworkConnection_iface );
1425 static HRESULT WINAPI connection_QueryInterface(
1426 INetworkConnection *iface, REFIID riid, void **obj )
1428 struct connection *connection = impl_from_INetworkConnection( iface );
1430 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
1432 if (IsEqualIID( riid, &IID_INetworkConnection ) ||
1433 IsEqualIID( riid, &IID_IDispatch ) ||
1434 IsEqualIID( riid, &IID_IUnknown ))
1436 *obj = iface;
1438 else if (IsEqualIID( riid, &IID_INetworkConnectionCost ))
1440 *obj = &connection->INetworkConnectionCost_iface;
1442 else
1444 WARN( "interface not supported %s\n", debugstr_guid(riid) );
1445 *obj = NULL;
1446 return E_NOINTERFACE;
1448 INetworkConnection_AddRef( iface );
1449 return S_OK;
1452 static ULONG WINAPI connection_AddRef(
1453 INetworkConnection *iface )
1455 struct connection *connection = impl_from_INetworkConnection( iface );
1457 TRACE( "%p\n", connection );
1458 return InterlockedIncrement( &connection->refs );
1461 static ULONG WINAPI connection_Release(
1462 INetworkConnection *iface )
1464 struct connection *connection = impl_from_INetworkConnection( iface );
1465 LONG refs;
1467 TRACE( "%p\n", connection );
1469 if (!(refs = InterlockedDecrement( &connection->refs )))
1471 INetwork_Release( connection->network );
1472 list_remove( &connection->entry );
1473 heap_free( connection );
1475 return refs;
1478 static HRESULT WINAPI connection_GetTypeInfoCount(
1479 INetworkConnection *iface,
1480 UINT *count )
1482 FIXME("\n");
1483 return E_NOTIMPL;
1486 static HRESULT WINAPI connection_GetTypeInfo(
1487 INetworkConnection *iface,
1488 UINT index,
1489 LCID lcid,
1490 ITypeInfo **info )
1492 FIXME("\n");
1493 return E_NOTIMPL;
1496 static HRESULT WINAPI connection_GetIDsOfNames(
1497 INetworkConnection *iface,
1498 REFIID riid,
1499 LPOLESTR *names,
1500 UINT count,
1501 LCID lcid,
1502 DISPID *dispid )
1504 FIXME("\n");
1505 return E_NOTIMPL;
1508 static HRESULT WINAPI connection_Invoke(
1509 INetworkConnection *iface,
1510 DISPID member,
1511 REFIID riid,
1512 LCID lcid,
1513 WORD flags,
1514 DISPPARAMS *params,
1515 VARIANT *result,
1516 EXCEPINFO *excep_info,
1517 UINT *arg_err )
1519 FIXME("\n");
1520 return E_NOTIMPL;
1523 static HRESULT WINAPI connection_GetNetwork(
1524 INetworkConnection *iface,
1525 INetwork **ppNetwork )
1527 struct connection *connection = impl_from_INetworkConnection( iface );
1529 TRACE( "%p, %p\n", iface, ppNetwork );
1531 *ppNetwork = connection->network;
1532 INetwork_AddRef( *ppNetwork );
1533 return S_OK;
1536 static HRESULT WINAPI connection_get_IsConnectedToInternet(
1537 INetworkConnection *iface,
1538 VARIANT_BOOL *pbIsConnected )
1540 struct connection *connection = impl_from_INetworkConnection( iface );
1542 TRACE( "%p, %p\n", iface, pbIsConnected );
1544 *pbIsConnected = connection->connected_to_internet;
1545 return S_OK;
1548 static HRESULT WINAPI connection_get_IsConnected(
1549 INetworkConnection *iface,
1550 VARIANT_BOOL *pbIsConnected )
1552 struct connection *connection = impl_from_INetworkConnection( iface );
1554 TRACE( "%p, %p\n", iface, pbIsConnected );
1556 *pbIsConnected = connection->connected;
1557 return S_OK;
1560 static HRESULT WINAPI connection_GetConnectivity(
1561 INetworkConnection *iface,
1562 NLM_CONNECTIVITY *pConnectivity )
1564 FIXME( "%p, %p\n", iface, pConnectivity );
1566 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1567 return S_OK;
1570 static HRESULT WINAPI connection_GetConnectionId(
1571 INetworkConnection *iface,
1572 GUID *pgdConnectionId )
1574 struct connection *connection = impl_from_INetworkConnection( iface );
1576 TRACE( "%p, %p\n", iface, pgdConnectionId );
1578 *pgdConnectionId = connection->id;
1579 return S_OK;
1582 static HRESULT WINAPI connection_GetAdapterId(
1583 INetworkConnection *iface,
1584 GUID *pgdAdapterId )
1586 struct connection *connection = impl_from_INetworkConnection( iface );
1588 FIXME( "%p, %p\n", iface, pgdAdapterId );
1590 *pgdAdapterId = connection->id;
1591 return S_OK;
1594 static HRESULT WINAPI connection_GetDomainType(
1595 INetworkConnection *iface,
1596 NLM_DOMAIN_TYPE *pDomainType )
1598 FIXME( "%p, %p\n", iface, pDomainType );
1600 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
1601 return S_OK;
1604 static const struct INetworkConnectionVtbl connection_vtbl =
1606 connection_QueryInterface,
1607 connection_AddRef,
1608 connection_Release,
1609 connection_GetTypeInfoCount,
1610 connection_GetTypeInfo,
1611 connection_GetIDsOfNames,
1612 connection_Invoke,
1613 connection_GetNetwork,
1614 connection_get_IsConnectedToInternet,
1615 connection_get_IsConnected,
1616 connection_GetConnectivity,
1617 connection_GetConnectionId,
1618 connection_GetAdapterId,
1619 connection_GetDomainType
1622 static inline struct connection *impl_from_INetworkConnectionCost(
1623 INetworkConnectionCost *iface )
1625 return CONTAINING_RECORD( iface, struct connection, INetworkConnectionCost_iface );
1628 static HRESULT WINAPI connection_cost_QueryInterface(
1629 INetworkConnectionCost *iface,
1630 REFIID riid,
1631 void **obj )
1633 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1634 return INetworkConnection_QueryInterface( &conn->INetworkConnection_iface, riid, obj );
1637 static ULONG WINAPI connection_cost_AddRef(
1638 INetworkConnectionCost *iface )
1640 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1641 return INetworkConnection_AddRef( &conn->INetworkConnection_iface );
1644 static ULONG WINAPI connection_cost_Release(
1645 INetworkConnectionCost *iface )
1647 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1648 return INetworkConnection_Release( &conn->INetworkConnection_iface );
1651 static HRESULT WINAPI connection_cost_GetCost(
1652 INetworkConnectionCost *iface, DWORD *pCost )
1654 FIXME( "%p, %p\n", iface, pCost );
1656 if (!pCost) return E_POINTER;
1658 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
1659 return S_OK;
1662 static HRESULT WINAPI connection_cost_GetDataPlanStatus(
1663 INetworkConnectionCost *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus )
1665 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1667 FIXME( "%p, %p\n", iface, pDataPlanStatus );
1669 if (!pDataPlanStatus) return E_POINTER;
1671 memcpy( &pDataPlanStatus->InterfaceGuid, &conn->id, sizeof(conn->id) );
1672 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1673 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
1674 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1675 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1676 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1677 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
1678 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1679 pDataPlanStatus->Reserved = 0;
1681 return S_OK;
1684 static const INetworkConnectionCostVtbl connection_cost_vtbl =
1686 connection_cost_QueryInterface,
1687 connection_cost_AddRef,
1688 connection_cost_Release,
1689 connection_cost_GetCost,
1690 connection_cost_GetDataPlanStatus
1693 static struct connection *create_connection( const GUID *id )
1695 struct connection *ret;
1697 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
1699 ret->INetworkConnection_iface.lpVtbl = &connection_vtbl;
1700 ret->INetworkConnectionCost_iface.lpVtbl = &connection_cost_vtbl;
1701 ret->refs = 1;
1702 ret->id = *id;
1703 ret->network = NULL;
1704 ret->connected = VARIANT_FALSE;
1705 ret->connected_to_internet = VARIANT_FALSE;
1706 list_init( &ret->entry );
1708 return ret;
1711 static void init_networks( struct list_manager *mgr )
1713 DWORD size = 0;
1714 IP_ADAPTER_ADDRESSES *buf, *aa;
1715 GUID id;
1716 ULONG ret, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
1717 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_GATEWAYS;
1719 list_init( &mgr->networks );
1720 list_init( &mgr->connections );
1722 ret = GetAdaptersAddresses( WS_AF_UNSPEC, flags, NULL, NULL, &size );
1723 if (ret != ERROR_BUFFER_OVERFLOW) return;
1725 if (!(buf = heap_alloc( size ))) return;
1726 if (GetAdaptersAddresses( WS_AF_UNSPEC, flags, NULL, buf, &size ))
1728 heap_free( buf );
1729 return;
1732 memset( &id, 0, sizeof(id) );
1733 for (aa = buf; aa; aa = aa->Next)
1735 struct network *network;
1736 struct connection *connection;
1738 id.Data1 = aa->u.s.IfIndex;
1740 /* assume a one-to-one mapping between networks and connections */
1741 if (!(network = create_network( &id ))) goto done;
1742 if (!(connection = create_connection( &id )))
1744 INetwork_Release( &network->INetwork_iface );
1745 goto done;
1748 if (aa->FirstUnicastAddress)
1750 network->connected = VARIANT_TRUE;
1751 connection->connected = VARIANT_TRUE;
1753 if (aa->FirstGatewayAddress)
1755 network->connected_to_internet = VARIANT_TRUE;
1756 connection->connected_to_internet = VARIANT_TRUE;
1759 connection->network = &network->INetwork_iface;
1760 INetwork_AddRef( connection->network );
1762 list_add_tail( &mgr->networks, &network->entry );
1763 list_add_tail( &mgr->connections, &connection->entry );
1766 done:
1767 heap_free( buf );
1770 HRESULT list_manager_create( void **obj )
1772 struct list_manager *mgr;
1774 TRACE( "%p\n", obj );
1776 if (!(mgr = heap_alloc( sizeof(*mgr) ))) return E_OUTOFMEMORY;
1777 mgr->INetworkListManager_iface.lpVtbl = &list_manager_vtbl;
1778 mgr->INetworkCostManager_iface.lpVtbl = &cost_manager_vtbl;
1779 mgr->IConnectionPointContainer_iface.lpVtbl = &cpc_vtbl;
1780 init_networks( mgr );
1781 mgr->refs = 1;
1783 connection_point_init( &mgr->list_mgr_cp, &IID_INetworkListManagerEvents,
1784 &mgr->IConnectionPointContainer_iface );
1785 connection_point_init( &mgr->cost_mgr_cp, &IID_INetworkCostManagerEvents,
1786 &mgr->IConnectionPointContainer_iface);
1787 connection_point_init( &mgr->conn_mgr_cp, &IID_INetworkConnectionEvents,
1788 &mgr->IConnectionPointContainer_iface );
1790 *obj = &mgr->INetworkListManager_iface;
1791 TRACE( "returning iface %p\n", *obj );
1792 return S_OK;