shell32/tests: Drop progman DDE test workarounds for Windows <= 2000.
[wine.git] / dlls / netprofm / list.c
blobe28be12f2d65ef67667f36f43547dcb2b3f952d5
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/list.h"
42 #include "netprofm_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(netprofm);
46 static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t size)
48 return HeapAlloc(GetProcessHeap(), 0, size);
51 static inline BOOL heap_free(void *mem)
53 return HeapFree(GetProcessHeap(), 0, mem);
56 struct network
58 INetwork INetwork_iface;
59 LONG refs;
60 struct list entry;
61 GUID id;
62 VARIANT_BOOL connected_to_internet;
63 VARIANT_BOOL connected;
66 struct connection
68 INetworkConnection INetworkConnection_iface;
69 INetworkConnectionCost INetworkConnectionCost_iface;
70 LONG refs;
71 struct list entry;
72 GUID id;
73 INetwork *network;
74 VARIANT_BOOL connected_to_internet;
75 VARIANT_BOOL connected;
78 struct connection_point
80 IConnectionPoint IConnectionPoint_iface;
81 IConnectionPointContainer *container;
82 IID iid;
83 struct list sinks;
84 DWORD cookie;
87 struct list_manager
89 INetworkListManager INetworkListManager_iface;
90 INetworkCostManager INetworkCostManager_iface;
91 IConnectionPointContainer IConnectionPointContainer_iface;
92 LONG refs;
93 struct list networks;
94 struct list connections;
95 struct connection_point list_mgr_cp;
96 struct connection_point cost_mgr_cp;
97 struct connection_point conn_mgr_cp;
100 struct sink_entry
102 struct list entry;
103 DWORD cookie;
104 IUnknown *unk;
107 static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
109 return CONTAINING_RECORD(iface, struct list_manager, IConnectionPointContainer_iface);
112 static inline struct list_manager *impl_from_INetworkCostManager(
113 INetworkCostManager *iface )
115 return CONTAINING_RECORD( iface, struct list_manager, INetworkCostManager_iface );
118 static inline struct connection_point *impl_from_IConnectionPoint(
119 IConnectionPoint *iface )
121 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
124 static HRESULT WINAPI connection_point_QueryInterface(
125 IConnectionPoint *iface,
126 REFIID riid,
127 void **obj )
129 struct connection_point *cp = impl_from_IConnectionPoint( iface );
130 TRACE( "%p, %s, %p\n", cp, debugstr_guid(riid), obj );
132 if (IsEqualGUID( riid, &IID_IConnectionPoint ) ||
133 IsEqualGUID( riid, &IID_IUnknown ))
135 *obj = iface;
137 else
139 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
140 *obj = NULL;
141 return E_NOINTERFACE;
143 IConnectionPoint_AddRef( iface );
144 return S_OK;
147 static ULONG WINAPI connection_point_AddRef(
148 IConnectionPoint *iface )
150 struct connection_point *cp = impl_from_IConnectionPoint( iface );
151 return IConnectionPointContainer_AddRef( cp->container );
154 static ULONG WINAPI connection_point_Release(
155 IConnectionPoint *iface )
157 struct connection_point *cp = impl_from_IConnectionPoint( iface );
158 return IConnectionPointContainer_Release( cp->container );
161 static HRESULT WINAPI connection_point_GetConnectionInterface(
162 IConnectionPoint *iface,
163 IID *iid )
165 struct connection_point *cp = impl_from_IConnectionPoint( iface );
166 TRACE( "%p, %p\n", cp, iid );
168 if (!iid)
169 return E_POINTER;
171 memcpy( iid, &cp->iid, sizeof(*iid) );
172 return S_OK;
175 static HRESULT WINAPI connection_point_GetConnectionPointContainer(
176 IConnectionPoint *iface,
177 IConnectionPointContainer **container )
179 struct connection_point *cp = impl_from_IConnectionPoint( iface );
180 TRACE( "%p, %p\n", cp, container );
182 if (!container)
183 return E_POINTER;
185 IConnectionPointContainer_AddRef( cp->container );
186 *container = cp->container;
187 return S_OK;
190 static HRESULT WINAPI connection_point_Advise(
191 IConnectionPoint *iface,
192 IUnknown *sink,
193 DWORD *cookie )
195 struct connection_point *cp = impl_from_IConnectionPoint( iface );
196 struct sink_entry *sink_entry;
197 IUnknown *unk;
198 HRESULT hr;
200 FIXME( "%p, %p, %p - semi-stub\n", cp, sink, cookie );
202 if (!sink || !cookie)
203 return E_POINTER;
205 hr = IUnknown_QueryInterface( sink, &cp->iid, (void**)&unk );
206 if (FAILED(hr))
208 WARN( "iface %s not implemented by sink\n", debugstr_guid(&cp->iid) );
209 return CO_E_FAILEDTOOPENTHREADTOKEN;
212 sink_entry = heap_alloc( sizeof(*sink_entry) );
213 if (!sink_entry)
215 IUnknown_Release( unk );
216 return E_OUTOFMEMORY;
219 sink_entry->unk = unk;
220 *cookie = sink_entry->cookie = ++cp->cookie;
221 list_add_tail( &cp->sinks, &sink_entry->entry );
222 return S_OK;
225 static void sink_entry_release( struct sink_entry *entry )
227 list_remove( &entry->entry );
228 IUnknown_Release( entry->unk );
229 heap_free( entry );
232 static HRESULT WINAPI connection_point_Unadvise(
233 IConnectionPoint *iface,
234 DWORD cookie )
236 struct connection_point *cp = impl_from_IConnectionPoint( iface );
237 struct sink_entry *iter;
239 TRACE( "%p, %d\n", cp, cookie );
241 LIST_FOR_EACH_ENTRY( iter, &cp->sinks, struct sink_entry, entry )
243 if (iter->cookie != cookie) continue;
244 sink_entry_release( iter );
245 return S_OK;
248 WARN( "invalid cookie\n" );
249 return OLE_E_NOCONNECTION;
252 static HRESULT WINAPI connection_point_EnumConnections(
253 IConnectionPoint *iface,
254 IEnumConnections **connections )
256 struct connection_point *cp = impl_from_IConnectionPoint( iface );
257 FIXME( "%p, %p - stub\n", cp, connections );
259 return E_NOTIMPL;
262 static const IConnectionPointVtbl connection_point_vtbl =
264 connection_point_QueryInterface,
265 connection_point_AddRef,
266 connection_point_Release,
267 connection_point_GetConnectionInterface,
268 connection_point_GetConnectionPointContainer,
269 connection_point_Advise,
270 connection_point_Unadvise,
271 connection_point_EnumConnections
274 static void connection_point_init(
275 struct connection_point *cp,
276 REFIID riid,
277 IConnectionPointContainer *container )
279 cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
280 cp->container = container;
281 cp->cookie = 0;
282 cp->iid = *riid;
283 list_init( &cp->sinks );
286 static void connection_point_release( struct connection_point *cp )
288 while (!list_empty( &cp->sinks ))
289 sink_entry_release( LIST_ENTRY( list_head( &cp->sinks ), struct sink_entry, entry ) );
292 static inline struct network *impl_from_INetwork(
293 INetwork *iface )
295 return CONTAINING_RECORD( iface, struct network, INetwork_iface );
298 static HRESULT WINAPI network_QueryInterface(
299 INetwork *iface, REFIID riid, void **obj )
301 struct network *network = impl_from_INetwork( iface );
303 TRACE( "%p, %s, %p\n", network, debugstr_guid(riid), obj );
305 if (IsEqualIID( riid, &IID_INetwork ) ||
306 IsEqualIID( riid, &IID_IDispatch ) ||
307 IsEqualIID( riid, &IID_IUnknown ))
309 *obj = iface;
310 INetwork_AddRef( iface );
311 return S_OK;
313 else
315 WARN( "interface not supported %s\n", debugstr_guid(riid) );
316 *obj = NULL;
317 return E_NOINTERFACE;
321 static ULONG WINAPI network_AddRef(
322 INetwork *iface )
324 struct network *network = impl_from_INetwork( iface );
326 TRACE( "%p\n", network );
327 return InterlockedIncrement( &network->refs );
330 static ULONG WINAPI network_Release(
331 INetwork *iface )
333 struct network *network = impl_from_INetwork( iface );
334 LONG refs;
336 TRACE( "%p\n", network );
338 if (!(refs = InterlockedDecrement( &network->refs )))
340 list_remove( &network->entry );
341 heap_free( network );
343 return refs;
346 static HRESULT WINAPI network_GetTypeInfoCount(
347 INetwork *iface,
348 UINT *count )
350 FIXME("\n");
351 return E_NOTIMPL;
354 static HRESULT WINAPI network_GetTypeInfo(
355 INetwork *iface,
356 UINT index,
357 LCID lcid,
358 ITypeInfo **info )
360 FIXME("\n");
361 return E_NOTIMPL;
364 static HRESULT WINAPI network_GetIDsOfNames(
365 INetwork *iface,
366 REFIID riid,
367 LPOLESTR *names,
368 UINT count,
369 LCID lcid,
370 DISPID *dispid )
372 FIXME("\n");
373 return E_NOTIMPL;
376 static HRESULT WINAPI network_Invoke(
377 INetwork *iface,
378 DISPID member,
379 REFIID riid,
380 LCID lcid,
381 WORD flags,
382 DISPPARAMS *params,
383 VARIANT *result,
384 EXCEPINFO *excep_info,
385 UINT *arg_err )
387 FIXME("\n");
388 return E_NOTIMPL;
391 static HRESULT WINAPI network_GetName(
392 INetwork *iface,
393 BSTR *pszNetworkName )
395 FIXME( "%p, %p\n", iface, pszNetworkName );
396 return E_NOTIMPL;
399 static HRESULT WINAPI network_SetName(
400 INetwork *iface,
401 BSTR szNetworkNewName )
403 FIXME( "%p, %s\n", iface, debugstr_w(szNetworkNewName) );
404 return E_NOTIMPL;
407 static HRESULT WINAPI network_GetDescription(
408 INetwork *iface,
409 BSTR *pszDescription )
411 FIXME( "%p, %p\n", iface, pszDescription );
412 return E_NOTIMPL;
415 static HRESULT WINAPI network_SetDescription(
416 INetwork *iface,
417 BSTR szDescription )
419 FIXME( "%p, %s\n", iface, debugstr_w(szDescription) );
420 return E_NOTIMPL;
423 static HRESULT WINAPI network_GetNetworkId(
424 INetwork *iface,
425 GUID *pgdGuidNetworkId )
427 struct network *network = impl_from_INetwork( iface );
429 TRACE( "%p, %p\n", iface, pgdGuidNetworkId );
431 *pgdGuidNetworkId = network->id;
432 return S_OK;
435 static HRESULT WINAPI network_GetDomainType(
436 INetwork *iface,
437 NLM_DOMAIN_TYPE *pDomainType )
439 FIXME( "%p, %p\n", iface, pDomainType );
441 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
442 return S_OK;
445 static HRESULT WINAPI network_GetNetworkConnections(
446 INetwork *iface,
447 IEnumNetworkConnections **ppEnumNetworkConnection )
449 FIXME( "%p, %p\n", iface, ppEnumNetworkConnection );
450 return E_NOTIMPL;
453 static HRESULT WINAPI network_GetTimeCreatedAndConnected(
454 INetwork *iface,
455 DWORD *pdwLowDateTimeCreated,
456 DWORD *pdwHighDateTimeCreated,
457 DWORD *pdwLowDateTimeConnected,
458 DWORD *pdwHighDateTimeConnected )
460 FIXME( "%p, %p, %p, %p, %p\n", iface, pdwLowDateTimeCreated, pdwHighDateTimeCreated,
461 pdwLowDateTimeConnected, pdwHighDateTimeConnected );
462 return E_NOTIMPL;
465 static HRESULT WINAPI network_get_IsConnectedToInternet(
466 INetwork *iface,
467 VARIANT_BOOL *pbIsConnected )
469 struct network *network = impl_from_INetwork( iface );
471 TRACE( "%p, %p\n", iface, pbIsConnected );
473 *pbIsConnected = network->connected_to_internet;
474 return S_OK;
477 static HRESULT WINAPI network_get_IsConnected(
478 INetwork *iface,
479 VARIANT_BOOL *pbIsConnected )
481 struct network *network = impl_from_INetwork( iface );
483 TRACE( "%p, %p\n", iface, pbIsConnected );
485 *pbIsConnected = network->connected;
486 return S_OK;
489 static HRESULT WINAPI network_GetConnectivity(
490 INetwork *iface,
491 NLM_CONNECTIVITY *pConnectivity )
493 FIXME( "%p, %p\n", iface, pConnectivity );
495 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
496 return S_OK;
499 static HRESULT WINAPI network_GetCategory(
500 INetwork *iface,
501 NLM_NETWORK_CATEGORY *pCategory )
503 FIXME( "%p, %p\n", iface, pCategory );
505 *pCategory = NLM_NETWORK_CATEGORY_PUBLIC;
506 return S_OK;
509 static HRESULT WINAPI network_SetCategory(
510 INetwork *iface,
511 NLM_NETWORK_CATEGORY NewCategory )
513 FIXME( "%p, %u\n", iface, NewCategory );
514 return E_NOTIMPL;
517 static const struct INetworkVtbl network_vtbl =
519 network_QueryInterface,
520 network_AddRef,
521 network_Release,
522 network_GetTypeInfoCount,
523 network_GetTypeInfo,
524 network_GetIDsOfNames,
525 network_Invoke,
526 network_GetName,
527 network_SetName,
528 network_GetDescription,
529 network_SetDescription,
530 network_GetNetworkId,
531 network_GetDomainType,
532 network_GetNetworkConnections,
533 network_GetTimeCreatedAndConnected,
534 network_get_IsConnectedToInternet,
535 network_get_IsConnected,
536 network_GetConnectivity,
537 network_GetCategory,
538 network_SetCategory
541 static struct network *create_network( const GUID *id )
543 struct network *ret;
545 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
547 ret->INetwork_iface.lpVtbl = &network_vtbl;
548 ret->refs = 1;
549 ret->id = *id;
550 ret->connected = VARIANT_FALSE;
551 ret->connected_to_internet = VARIANT_FALSE;
552 list_init( &ret->entry );
554 return ret;
557 static HRESULT WINAPI cost_manager_QueryInterface(
558 INetworkCostManager *iface,
559 REFIID riid,
560 void **obj )
562 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
563 return INetworkListManager_QueryInterface( &mgr->INetworkListManager_iface, riid, obj );
566 static ULONG WINAPI cost_manager_AddRef(
567 INetworkCostManager *iface )
569 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
570 return INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
573 static ULONG WINAPI cost_manager_Release(
574 INetworkCostManager *iface )
576 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
577 return INetworkListManager_Release( &mgr->INetworkListManager_iface );
580 static HRESULT WINAPI cost_manager_GetCost(
581 INetworkCostManager *iface, DWORD *pCost, NLM_SOCKADDR *pDestIPAddr)
583 FIXME( "%p, %p, %p\n", iface, pCost, pDestIPAddr );
585 if (!pCost) return E_POINTER;
587 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
588 return S_OK;
591 static BOOL map_address_6to4( const SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
593 ULONG i;
595 if (addr6->sin6_family != WS_AF_INET6) return FALSE;
597 for (i = 0; i < 5; i++)
598 if (addr6->sin6_addr.u.Word[i]) return FALSE;
600 if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
602 addr4->sin_family = WS_AF_INET;
603 addr4->sin_port = addr6->sin6_port;
604 addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
605 memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
607 return TRUE;
610 static HRESULT WINAPI cost_manager_GetDataPlanStatus(
611 INetworkCostManager *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus,
612 NLM_SOCKADDR *pDestIPAddr)
614 DWORD ret, index;
615 NET_LUID luid;
616 SOCKADDR *dst = (SOCKADDR *)pDestIPAddr;
617 SOCKADDR_IN addr4, *dst4;
619 FIXME( "%p, %p, %p\n", iface, pDataPlanStatus, pDestIPAddr );
621 if (!pDataPlanStatus) return E_POINTER;
623 if (dst && ((dst->sa_family == WS_AF_INET && (dst4 = (SOCKADDR_IN *)dst)) ||
624 ((dst->sa_family == WS_AF_INET6 && map_address_6to4( (const SOCKADDR_IN6 *)dst, &addr4 )
625 && (dst4 = &addr4)))))
627 if ((ret = GetBestInterface( dst4->sin_addr.S_un.S_addr, &index )))
628 return HRESULT_FROM_WIN32( ret );
630 if ((ret = ConvertInterfaceIndexToLuid( index, &luid )))
631 return HRESULT_FROM_WIN32( ret );
633 if ((ret = ConvertInterfaceLuidToGuid( &luid, &pDataPlanStatus->InterfaceGuid )))
634 return HRESULT_FROM_WIN32( ret );
636 else
638 FIXME( "interface guid not found\n" );
639 memset( &pDataPlanStatus->InterfaceGuid, 0, sizeof(pDataPlanStatus->InterfaceGuid) );
642 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
643 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
644 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
645 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
646 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
647 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
648 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
649 pDataPlanStatus->Reserved = 0;
651 return S_OK;
654 static HRESULT WINAPI cost_manager_SetDestinationAddresses(
655 INetworkCostManager *iface, UINT32 length, NLM_SOCKADDR *pDestIPAddrList,
656 VARIANT_BOOL bAppend)
658 FIXME( "%p, %u, %p, %x\n", iface, length, pDestIPAddrList, bAppend );
659 return E_NOTIMPL;
662 static const INetworkCostManagerVtbl cost_manager_vtbl =
664 cost_manager_QueryInterface,
665 cost_manager_AddRef,
666 cost_manager_Release,
667 cost_manager_GetCost,
668 cost_manager_GetDataPlanStatus,
669 cost_manager_SetDestinationAddresses
672 struct networks_enum
674 IEnumNetworks IEnumNetworks_iface;
675 LONG refs;
676 struct list_manager *mgr;
677 struct list *cursor;
680 static inline struct networks_enum *impl_from_IEnumNetworks(
681 IEnumNetworks *iface )
683 return CONTAINING_RECORD( iface, struct networks_enum, IEnumNetworks_iface );
686 static HRESULT WINAPI networks_enum_QueryInterface(
687 IEnumNetworks *iface, REFIID riid, void **obj )
689 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
691 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
693 if (IsEqualIID( riid, &IID_IEnumNetworks ) ||
694 IsEqualIID( riid, &IID_IDispatch ) ||
695 IsEqualIID( riid, &IID_IUnknown ))
697 *obj = iface;
698 IEnumNetworks_AddRef( iface );
699 return S_OK;
701 else
703 WARN( "interface not supported %s\n", debugstr_guid(riid) );
704 *obj = NULL;
705 return E_NOINTERFACE;
709 static ULONG WINAPI networks_enum_AddRef(
710 IEnumNetworks *iface )
712 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
714 TRACE( "%p\n", iter );
715 return InterlockedIncrement( &iter->refs );
718 static ULONG WINAPI networks_enum_Release(
719 IEnumNetworks *iface )
721 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
722 LONG refs;
724 TRACE( "%p\n", iter );
726 if (!(refs = InterlockedDecrement( &iter->refs )))
728 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
729 heap_free( iter );
731 return refs;
734 static HRESULT WINAPI networks_enum_GetTypeInfoCount(
735 IEnumNetworks *iface,
736 UINT *count )
738 FIXME("\n");
739 return E_NOTIMPL;
742 static HRESULT WINAPI networks_enum_GetTypeInfo(
743 IEnumNetworks *iface,
744 UINT index,
745 LCID lcid,
746 ITypeInfo **info )
748 FIXME("\n");
749 return E_NOTIMPL;
752 static HRESULT WINAPI networks_enum_GetIDsOfNames(
753 IEnumNetworks *iface,
754 REFIID riid,
755 LPOLESTR *names,
756 UINT count,
757 LCID lcid,
758 DISPID *dispid )
760 FIXME("\n");
761 return E_NOTIMPL;
764 static HRESULT WINAPI networks_enum_Invoke(
765 IEnumNetworks *iface,
766 DISPID member,
767 REFIID riid,
768 LCID lcid,
769 WORD flags,
770 DISPPARAMS *params,
771 VARIANT *result,
772 EXCEPINFO *excep_info,
773 UINT *arg_err )
775 FIXME("\n");
776 return E_NOTIMPL;
779 static HRESULT WINAPI networks_enum_get__NewEnum(
780 IEnumNetworks *iface, IEnumVARIANT **ppEnumVar )
782 FIXME("\n");
783 return E_NOTIMPL;
786 static HRESULT WINAPI networks_enum_Next(
787 IEnumNetworks *iface, ULONG count, INetwork **ret, ULONG *fetched )
789 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
790 ULONG i = 0;
792 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
794 if (fetched) *fetched = 0;
795 if (!count) return S_OK;
797 while (iter->cursor && i < count)
799 struct network *network = LIST_ENTRY( iter->cursor, struct network, entry );
800 ret[i] = &network->INetwork_iface;
801 INetwork_AddRef( ret[i] );
802 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
803 i++;
805 if (fetched) *fetched = i;
807 return i < count ? S_FALSE : S_OK;
810 static HRESULT WINAPI networks_enum_Skip(
811 IEnumNetworks *iface, ULONG count )
813 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
815 TRACE( "%p, %u\n", iter, count);
817 if (!count) return S_OK;
818 if (!iter->cursor) return S_FALSE;
820 while (count--)
822 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
823 if (!iter->cursor) break;
826 return count ? S_FALSE : S_OK;
829 static HRESULT WINAPI networks_enum_Reset(
830 IEnumNetworks *iface )
832 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
834 TRACE( "%p\n", iter );
836 iter->cursor = list_head( &iter->mgr->networks );
837 return S_OK;
840 static HRESULT create_networks_enum(
841 struct list_manager *, IEnumNetworks** );
843 static HRESULT WINAPI networks_enum_Clone(
844 IEnumNetworks *iface, IEnumNetworks **ret )
846 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
848 TRACE( "%p, %p\n", iter, ret );
849 return create_networks_enum( iter->mgr, ret );
852 static const IEnumNetworksVtbl networks_enum_vtbl =
854 networks_enum_QueryInterface,
855 networks_enum_AddRef,
856 networks_enum_Release,
857 networks_enum_GetTypeInfoCount,
858 networks_enum_GetTypeInfo,
859 networks_enum_GetIDsOfNames,
860 networks_enum_Invoke,
861 networks_enum_get__NewEnum,
862 networks_enum_Next,
863 networks_enum_Skip,
864 networks_enum_Reset,
865 networks_enum_Clone
868 static HRESULT create_networks_enum(
869 struct list_manager *mgr, IEnumNetworks **ret )
871 struct networks_enum *iter;
873 *ret = NULL;
874 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
876 iter->IEnumNetworks_iface.lpVtbl = &networks_enum_vtbl;
877 iter->cursor = list_head( &mgr->networks );
878 iter->mgr = mgr;
879 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
880 iter->refs = 1;
882 *ret = &iter->IEnumNetworks_iface;
883 return S_OK;
886 static inline struct list_manager *impl_from_INetworkListManager(
887 INetworkListManager *iface )
889 return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface );
892 struct connections_enum
894 IEnumNetworkConnections IEnumNetworkConnections_iface;
895 LONG refs;
896 struct list_manager *mgr;
897 struct list *cursor;
900 static inline struct connections_enum *impl_from_IEnumNetworkConnections(
901 IEnumNetworkConnections *iface )
903 return CONTAINING_RECORD( iface, struct connections_enum, IEnumNetworkConnections_iface );
906 static HRESULT WINAPI connections_enum_QueryInterface(
907 IEnumNetworkConnections *iface, REFIID riid, void **obj )
909 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
911 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
913 if (IsEqualIID( riid, &IID_IEnumNetworkConnections ) ||
914 IsEqualIID( riid, &IID_IDispatch ) ||
915 IsEqualIID( riid, &IID_IUnknown ))
917 *obj = iface;
918 IEnumNetworkConnections_AddRef( iface );
919 return S_OK;
921 else
923 WARN( "interface not supported %s\n", debugstr_guid(riid) );
924 *obj = NULL;
925 return E_NOINTERFACE;
929 static ULONG WINAPI connections_enum_AddRef(
930 IEnumNetworkConnections *iface )
932 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
934 TRACE( "%p\n", iter );
935 return InterlockedIncrement( &iter->refs );
938 static ULONG WINAPI connections_enum_Release(
939 IEnumNetworkConnections *iface )
941 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
942 LONG refs;
944 TRACE( "%p\n", iter );
946 if (!(refs = InterlockedDecrement( &iter->refs )))
948 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
949 heap_free( iter );
951 return refs;
954 static HRESULT WINAPI connections_enum_GetTypeInfoCount(
955 IEnumNetworkConnections *iface,
956 UINT *count )
958 FIXME("\n");
959 return E_NOTIMPL;
962 static HRESULT WINAPI connections_enum_GetTypeInfo(
963 IEnumNetworkConnections *iface,
964 UINT index,
965 LCID lcid,
966 ITypeInfo **info )
968 FIXME("\n");
969 return E_NOTIMPL;
972 static HRESULT WINAPI connections_enum_GetIDsOfNames(
973 IEnumNetworkConnections *iface,
974 REFIID riid,
975 LPOLESTR *names,
976 UINT count,
977 LCID lcid,
978 DISPID *dispid )
980 FIXME("\n");
981 return E_NOTIMPL;
984 static HRESULT WINAPI connections_enum_Invoke(
985 IEnumNetworkConnections *iface,
986 DISPID member,
987 REFIID riid,
988 LCID lcid,
989 WORD flags,
990 DISPPARAMS *params,
991 VARIANT *result,
992 EXCEPINFO *excep_info,
993 UINT *arg_err )
995 FIXME("\n");
996 return E_NOTIMPL;
999 static HRESULT WINAPI connections_enum_get__NewEnum(
1000 IEnumNetworkConnections *iface, IEnumVARIANT **ppEnumVar )
1002 FIXME("\n");
1003 return E_NOTIMPL;
1006 static HRESULT WINAPI connections_enum_Next(
1007 IEnumNetworkConnections *iface, ULONG count, INetworkConnection **ret, ULONG *fetched )
1009 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1010 ULONG i = 0;
1012 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
1014 if (fetched) *fetched = 0;
1015 if (!count) return S_OK;
1017 while (iter->cursor && i < count)
1019 struct connection *connection = LIST_ENTRY( iter->cursor, struct connection, entry );
1020 ret[i] = &connection->INetworkConnection_iface;
1021 INetworkConnection_AddRef( ret[i] );
1022 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1023 i++;
1025 if (fetched) *fetched = i;
1027 return i < count ? S_FALSE : S_OK;
1030 static HRESULT WINAPI connections_enum_Skip(
1031 IEnumNetworkConnections *iface, ULONG count )
1033 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1035 TRACE( "%p, %u\n", iter, count);
1037 if (!count) return S_OK;
1038 if (!iter->cursor) return S_FALSE;
1040 while (count--)
1042 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1043 if (!iter->cursor) break;
1046 return count ? S_FALSE : S_OK;
1049 static HRESULT WINAPI connections_enum_Reset(
1050 IEnumNetworkConnections *iface )
1052 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1054 TRACE( "%p\n", iter );
1056 iter->cursor = list_head( &iter->mgr->connections );
1057 return S_OK;
1060 static HRESULT create_connections_enum(
1061 struct list_manager *, IEnumNetworkConnections** );
1063 static HRESULT WINAPI connections_enum_Clone(
1064 IEnumNetworkConnections *iface, IEnumNetworkConnections **ret )
1066 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1068 TRACE( "%p, %p\n", iter, ret );
1069 return create_connections_enum( iter->mgr, ret );
1072 static const IEnumNetworkConnectionsVtbl connections_enum_vtbl =
1074 connections_enum_QueryInterface,
1075 connections_enum_AddRef,
1076 connections_enum_Release,
1077 connections_enum_GetTypeInfoCount,
1078 connections_enum_GetTypeInfo,
1079 connections_enum_GetIDsOfNames,
1080 connections_enum_Invoke,
1081 connections_enum_get__NewEnum,
1082 connections_enum_Next,
1083 connections_enum_Skip,
1084 connections_enum_Reset,
1085 connections_enum_Clone
1088 static HRESULT create_connections_enum(
1089 struct list_manager *mgr, IEnumNetworkConnections **ret )
1091 struct connections_enum *iter;
1093 *ret = NULL;
1094 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
1096 iter->IEnumNetworkConnections_iface.lpVtbl = &connections_enum_vtbl;
1097 iter->mgr = mgr;
1098 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
1099 iter->cursor = list_head( &iter->mgr->connections );
1100 iter->refs = 1;
1102 *ret = &iter->IEnumNetworkConnections_iface;
1103 return S_OK;
1106 static ULONG WINAPI list_manager_AddRef(
1107 INetworkListManager *iface )
1109 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1110 return InterlockedIncrement( &mgr->refs );
1113 static ULONG WINAPI list_manager_Release(
1114 INetworkListManager *iface )
1116 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1117 LONG refs = InterlockedDecrement( &mgr->refs );
1118 if (!refs)
1120 struct list *ptr;
1122 TRACE( "destroying %p\n", mgr );
1124 connection_point_release( &mgr->conn_mgr_cp );
1125 connection_point_release( &mgr->cost_mgr_cp );
1126 connection_point_release( &mgr->list_mgr_cp );
1127 while ((ptr = list_head( &mgr->networks )))
1129 struct network *network = LIST_ENTRY( ptr, struct network, entry );
1130 list_remove( &network->entry );
1131 INetwork_Release( &network->INetwork_iface );
1133 while ((ptr = list_head( &mgr->connections )))
1135 struct connection *connection = LIST_ENTRY( ptr, struct connection, entry );
1136 list_remove( &connection->entry );
1137 INetworkConnection_Release( &connection->INetworkConnection_iface );
1139 heap_free( mgr );
1141 return refs;
1144 static HRESULT WINAPI list_manager_QueryInterface(
1145 INetworkListManager *iface,
1146 REFIID riid,
1147 void **obj )
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 ))
1157 *obj = iface;
1159 else if (IsEqualGUID( riid, &IID_INetworkCostManager ))
1161 *obj = &mgr->INetworkCostManager_iface;
1163 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
1165 *obj = &mgr->IConnectionPointContainer_iface;
1167 else
1169 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1170 *obj = NULL;
1171 return E_NOINTERFACE;
1173 INetworkListManager_AddRef( iface );
1174 return S_OK;
1177 static HRESULT WINAPI list_manager_GetTypeInfoCount(
1178 INetworkListManager *iface,
1179 UINT *count )
1181 FIXME("\n");
1182 return E_NOTIMPL;
1185 static HRESULT WINAPI list_manager_GetTypeInfo(
1186 INetworkListManager *iface,
1187 UINT index,
1188 LCID lcid,
1189 ITypeInfo **info )
1191 FIXME("\n");
1192 return E_NOTIMPL;
1195 static HRESULT WINAPI list_manager_GetIDsOfNames(
1196 INetworkListManager *iface,
1197 REFIID riid,
1198 LPOLESTR *names,
1199 UINT count,
1200 LCID lcid,
1201 DISPID *dispid )
1203 FIXME("\n");
1204 return E_NOTIMPL;
1207 static HRESULT WINAPI list_manager_Invoke(
1208 INetworkListManager *iface,
1209 DISPID member,
1210 REFIID riid,
1211 LCID lcid,
1212 WORD flags,
1213 DISPPARAMS *params,
1214 VARIANT *result,
1215 EXCEPINFO *excep_info,
1216 UINT *arg_err )
1218 FIXME("\n");
1219 return E_NOTIMPL;
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,
1237 GUID gdNetworkId,
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 );
1251 return S_OK;
1255 return S_FALSE;
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 );
1285 return S_OK;
1289 return S_FALSE;
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;
1306 return S_OK;
1310 *pbIsConnected = VARIANT_FALSE;
1311 return S_OK;
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;
1328 return S_OK;
1332 *pbIsConnected = VARIANT_FALSE;
1333 return S_OK;
1336 static HRESULT WINAPI list_manager_GetConnectivity(
1337 INetworkListManager *iface,
1338 NLM_CONNECTIVITY *pConnectivity )
1340 FIXME( "%p, %p\n", iface, pConnectivity );
1342 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1343 return S_OK;
1346 static const INetworkListManagerVtbl list_manager_vtbl =
1348 list_manager_QueryInterface,
1349 list_manager_AddRef,
1350 list_manager_Release,
1351 list_manager_GetTypeInfoCount,
1352 list_manager_GetTypeInfo,
1353 list_manager_GetIDsOfNames,
1354 list_manager_Invoke,
1355 list_manager_GetNetworks,
1356 list_manager_GetNetwork,
1357 list_manager_GetNetworkConnections,
1358 list_manager_GetNetworkConnection,
1359 list_manager_IsConnectedToInternet,
1360 list_manager_IsConnected,
1361 list_manager_GetConnectivity
1364 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
1365 REFIID riid, void **ppv)
1367 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1368 return INetworkListManager_QueryInterface(&This->INetworkListManager_iface, riid, ppv);
1371 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
1373 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1374 return INetworkListManager_AddRef(&This->INetworkListManager_iface);
1377 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
1379 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1380 return INetworkListManager_Release(&This->INetworkListManager_iface);
1383 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
1384 IEnumConnectionPoints **ppEnum)
1386 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1387 FIXME("(%p)->(%p): stub\n", This, ppEnum);
1388 return E_NOTIMPL;
1391 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
1392 REFIID riid, IConnectionPoint **cp)
1394 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1395 struct connection_point *ret;
1397 TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
1399 if (!riid || !cp)
1400 return E_POINTER;
1402 if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ))
1403 ret = &This->list_mgr_cp;
1404 else if (IsEqualGUID( riid, &IID_INetworkCostManagerEvents ))
1405 ret = &This->cost_mgr_cp;
1406 else if (IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
1407 ret = &This->conn_mgr_cp;
1408 else
1410 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1411 *cp = NULL;
1412 return E_NOINTERFACE;
1415 IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface );
1416 return S_OK;
1419 static const struct IConnectionPointContainerVtbl cpc_vtbl =
1421 ConnectionPointContainer_QueryInterface,
1422 ConnectionPointContainer_AddRef,
1423 ConnectionPointContainer_Release,
1424 ConnectionPointContainer_EnumConnectionPoints,
1425 ConnectionPointContainer_FindConnectionPoint
1428 static inline struct connection *impl_from_INetworkConnection(
1429 INetworkConnection *iface )
1431 return CONTAINING_RECORD( iface, struct connection, INetworkConnection_iface );
1434 static HRESULT WINAPI connection_QueryInterface(
1435 INetworkConnection *iface, REFIID riid, void **obj )
1437 struct connection *connection = impl_from_INetworkConnection( iface );
1439 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
1441 if (IsEqualIID( riid, &IID_INetworkConnection ) ||
1442 IsEqualIID( riid, &IID_IDispatch ) ||
1443 IsEqualIID( riid, &IID_IUnknown ))
1445 *obj = iface;
1447 else if (IsEqualIID( riid, &IID_INetworkConnectionCost ))
1449 *obj = &connection->INetworkConnectionCost_iface;
1451 else
1453 WARN( "interface not supported %s\n", debugstr_guid(riid) );
1454 *obj = NULL;
1455 return E_NOINTERFACE;
1457 INetworkConnection_AddRef( iface );
1458 return S_OK;
1461 static ULONG WINAPI connection_AddRef(
1462 INetworkConnection *iface )
1464 struct connection *connection = impl_from_INetworkConnection( iface );
1466 TRACE( "%p\n", connection );
1467 return InterlockedIncrement( &connection->refs );
1470 static ULONG WINAPI connection_Release(
1471 INetworkConnection *iface )
1473 struct connection *connection = impl_from_INetworkConnection( iface );
1474 LONG refs;
1476 TRACE( "%p\n", connection );
1478 if (!(refs = InterlockedDecrement( &connection->refs )))
1480 INetwork_Release( connection->network );
1481 list_remove( &connection->entry );
1482 heap_free( connection );
1484 return refs;
1487 static HRESULT WINAPI connection_GetTypeInfoCount(
1488 INetworkConnection *iface,
1489 UINT *count )
1491 FIXME("\n");
1492 return E_NOTIMPL;
1495 static HRESULT WINAPI connection_GetTypeInfo(
1496 INetworkConnection *iface,
1497 UINT index,
1498 LCID lcid,
1499 ITypeInfo **info )
1501 FIXME("\n");
1502 return E_NOTIMPL;
1505 static HRESULT WINAPI connection_GetIDsOfNames(
1506 INetworkConnection *iface,
1507 REFIID riid,
1508 LPOLESTR *names,
1509 UINT count,
1510 LCID lcid,
1511 DISPID *dispid )
1513 FIXME("\n");
1514 return E_NOTIMPL;
1517 static HRESULT WINAPI connection_Invoke(
1518 INetworkConnection *iface,
1519 DISPID member,
1520 REFIID riid,
1521 LCID lcid,
1522 WORD flags,
1523 DISPPARAMS *params,
1524 VARIANT *result,
1525 EXCEPINFO *excep_info,
1526 UINT *arg_err )
1528 FIXME("\n");
1529 return E_NOTIMPL;
1532 static HRESULT WINAPI connection_GetNetwork(
1533 INetworkConnection *iface,
1534 INetwork **ppNetwork )
1536 struct connection *connection = impl_from_INetworkConnection( iface );
1538 TRACE( "%p, %p\n", iface, ppNetwork );
1540 *ppNetwork = connection->network;
1541 INetwork_AddRef( *ppNetwork );
1542 return S_OK;
1545 static HRESULT WINAPI connection_get_IsConnectedToInternet(
1546 INetworkConnection *iface,
1547 VARIANT_BOOL *pbIsConnected )
1549 struct connection *connection = impl_from_INetworkConnection( iface );
1551 TRACE( "%p, %p\n", iface, pbIsConnected );
1553 *pbIsConnected = connection->connected_to_internet;
1554 return S_OK;
1557 static HRESULT WINAPI connection_get_IsConnected(
1558 INetworkConnection *iface,
1559 VARIANT_BOOL *pbIsConnected )
1561 struct connection *connection = impl_from_INetworkConnection( iface );
1563 TRACE( "%p, %p\n", iface, pbIsConnected );
1565 *pbIsConnected = connection->connected;
1566 return S_OK;
1569 static HRESULT WINAPI connection_GetConnectivity(
1570 INetworkConnection *iface,
1571 NLM_CONNECTIVITY *pConnectivity )
1573 FIXME( "%p, %p\n", iface, pConnectivity );
1575 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1576 return S_OK;
1579 static HRESULT WINAPI connection_GetConnectionId(
1580 INetworkConnection *iface,
1581 GUID *pgdConnectionId )
1583 struct connection *connection = impl_from_INetworkConnection( iface );
1585 TRACE( "%p, %p\n", iface, pgdConnectionId );
1587 *pgdConnectionId = connection->id;
1588 return S_OK;
1591 static HRESULT WINAPI connection_GetAdapterId(
1592 INetworkConnection *iface,
1593 GUID *pgdAdapterId )
1595 struct connection *connection = impl_from_INetworkConnection( iface );
1597 FIXME( "%p, %p\n", iface, pgdAdapterId );
1599 *pgdAdapterId = connection->id;
1600 return S_OK;
1603 static HRESULT WINAPI connection_GetDomainType(
1604 INetworkConnection *iface,
1605 NLM_DOMAIN_TYPE *pDomainType )
1607 FIXME( "%p, %p\n", iface, pDomainType );
1609 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
1610 return S_OK;
1613 static const struct INetworkConnectionVtbl connection_vtbl =
1615 connection_QueryInterface,
1616 connection_AddRef,
1617 connection_Release,
1618 connection_GetTypeInfoCount,
1619 connection_GetTypeInfo,
1620 connection_GetIDsOfNames,
1621 connection_Invoke,
1622 connection_GetNetwork,
1623 connection_get_IsConnectedToInternet,
1624 connection_get_IsConnected,
1625 connection_GetConnectivity,
1626 connection_GetConnectionId,
1627 connection_GetAdapterId,
1628 connection_GetDomainType
1631 static inline struct connection *impl_from_INetworkConnectionCost(
1632 INetworkConnectionCost *iface )
1634 return CONTAINING_RECORD( iface, struct connection, INetworkConnectionCost_iface );
1637 static HRESULT WINAPI connection_cost_QueryInterface(
1638 INetworkConnectionCost *iface,
1639 REFIID riid,
1640 void **obj )
1642 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1643 return INetworkConnection_QueryInterface( &conn->INetworkConnection_iface, riid, obj );
1646 static ULONG WINAPI connection_cost_AddRef(
1647 INetworkConnectionCost *iface )
1649 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1650 return INetworkConnection_AddRef( &conn->INetworkConnection_iface );
1653 static ULONG WINAPI connection_cost_Release(
1654 INetworkConnectionCost *iface )
1656 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1657 return INetworkConnection_Release( &conn->INetworkConnection_iface );
1660 static HRESULT WINAPI connection_cost_GetCost(
1661 INetworkConnectionCost *iface, DWORD *pCost )
1663 FIXME( "%p, %p\n", iface, pCost );
1665 if (!pCost) return E_POINTER;
1667 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
1668 return S_OK;
1671 static HRESULT WINAPI connection_cost_GetDataPlanStatus(
1672 INetworkConnectionCost *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus )
1674 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1676 FIXME( "%p, %p\n", iface, pDataPlanStatus );
1678 if (!pDataPlanStatus) return E_POINTER;
1680 memcpy( &pDataPlanStatus->InterfaceGuid, &conn->id, sizeof(conn->id) );
1681 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1682 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
1683 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1684 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1685 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1686 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
1687 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1688 pDataPlanStatus->Reserved = 0;
1690 return S_OK;
1693 static const INetworkConnectionCostVtbl connection_cost_vtbl =
1695 connection_cost_QueryInterface,
1696 connection_cost_AddRef,
1697 connection_cost_Release,
1698 connection_cost_GetCost,
1699 connection_cost_GetDataPlanStatus
1702 static struct connection *create_connection( const GUID *id )
1704 struct connection *ret;
1706 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
1708 ret->INetworkConnection_iface.lpVtbl = &connection_vtbl;
1709 ret->INetworkConnectionCost_iface.lpVtbl = &connection_cost_vtbl;
1710 ret->refs = 1;
1711 ret->id = *id;
1712 ret->network = NULL;
1713 ret->connected = VARIANT_FALSE;
1714 ret->connected_to_internet = VARIANT_FALSE;
1715 list_init( &ret->entry );
1717 return ret;
1720 static void init_networks( struct list_manager *mgr )
1722 DWORD size = 0;
1723 IP_ADAPTER_ADDRESSES *buf, *aa;
1724 GUID id;
1725 ULONG ret, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
1726 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_GATEWAYS;
1728 list_init( &mgr->networks );
1729 list_init( &mgr->connections );
1731 ret = GetAdaptersAddresses( WS_AF_UNSPEC, flags, NULL, NULL, &size );
1732 if (ret != ERROR_BUFFER_OVERFLOW) return;
1734 if (!(buf = heap_alloc( size ))) return;
1735 if (GetAdaptersAddresses( WS_AF_UNSPEC, flags, NULL, buf, &size ))
1737 heap_free( buf );
1738 return;
1741 memset( &id, 0, sizeof(id) );
1742 for (aa = buf; aa; aa = aa->Next)
1744 struct network *network;
1745 struct connection *connection;
1747 id.Data1 = aa->u.s.IfIndex;
1749 /* assume a one-to-one mapping between networks and connections */
1750 if (!(network = create_network( &id ))) goto done;
1751 if (!(connection = create_connection( &id )))
1753 INetwork_Release( &network->INetwork_iface );
1754 goto done;
1757 if (aa->FirstUnicastAddress)
1759 network->connected = VARIANT_TRUE;
1760 connection->connected = VARIANT_TRUE;
1762 if (aa->FirstGatewayAddress)
1764 network->connected_to_internet = VARIANT_TRUE;
1765 connection->connected_to_internet = VARIANT_TRUE;
1768 connection->network = &network->INetwork_iface;
1769 INetwork_AddRef( connection->network );
1771 list_add_tail( &mgr->networks, &network->entry );
1772 list_add_tail( &mgr->connections, &connection->entry );
1775 done:
1776 heap_free( buf );
1779 HRESULT list_manager_create( void **obj )
1781 struct list_manager *mgr;
1783 TRACE( "%p\n", obj );
1785 if (!(mgr = heap_alloc( sizeof(*mgr) ))) return E_OUTOFMEMORY;
1786 mgr->INetworkListManager_iface.lpVtbl = &list_manager_vtbl;
1787 mgr->INetworkCostManager_iface.lpVtbl = &cost_manager_vtbl;
1788 mgr->IConnectionPointContainer_iface.lpVtbl = &cpc_vtbl;
1789 init_networks( mgr );
1790 mgr->refs = 1;
1792 connection_point_init( &mgr->list_mgr_cp, &IID_INetworkListManagerEvents,
1793 &mgr->IConnectionPointContainer_iface );
1794 connection_point_init( &mgr->cost_mgr_cp, &IID_INetworkCostManagerEvents,
1795 &mgr->IConnectionPointContainer_iface);
1796 connection_point_init( &mgr->conn_mgr_cp, &IID_INetworkConnectionEvents,
1797 &mgr->IConnectionPointContainer_iface );
1799 *obj = &mgr->INetworkListManager_iface;
1800 TRACE( "returning iface %p\n", *obj );
1801 return S_OK;