include: Make sure __int64 is correctly defined on PPC64.
[wine.git] / dlls / netprofm / list.c
blobf9b9e2ea312861ba2b137801fcab1cb967c23e13
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 <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winsock2.h"
28 #include "ws2ipdef.h"
29 #include "iphlpapi.h"
30 #include "ifdef.h"
31 #include "netioapi.h"
32 #include "initguid.h"
33 #include "objbase.h"
34 #include "ocidl.h"
35 #include "netlistmgr.h"
36 #include "olectl.h"
38 #include "wine/debug.h"
39 #include "wine/heap.h"
40 #include "wine/list.h"
41 #include "netprofm_private.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(netprofm);
45 struct network
47 INetwork INetwork_iface;
48 LONG refs;
49 struct list entry;
50 GUID id;
51 VARIANT_BOOL connected_to_internet;
52 VARIANT_BOOL connected;
55 struct connection
57 INetworkConnection INetworkConnection_iface;
58 INetworkConnectionCost INetworkConnectionCost_iface;
59 LONG refs;
60 struct list entry;
61 GUID id;
62 INetwork *network;
63 VARIANT_BOOL connected_to_internet;
64 VARIANT_BOOL connected;
67 struct connection_point
69 IConnectionPoint IConnectionPoint_iface;
70 IConnectionPointContainer *container;
71 IID iid;
72 struct list sinks;
73 DWORD cookie;
76 struct list_manager
78 INetworkListManager INetworkListManager_iface;
79 INetworkCostManager INetworkCostManager_iface;
80 IConnectionPointContainer IConnectionPointContainer_iface;
81 LONG refs;
82 struct list networks;
83 struct list connections;
84 struct connection_point list_mgr_cp;
85 struct connection_point cost_mgr_cp;
86 struct connection_point conn_mgr_cp;
87 struct connection_point events_cp;
90 struct sink_entry
92 struct list entry;
93 DWORD cookie;
94 IUnknown *unk;
97 static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
99 return CONTAINING_RECORD(iface, struct list_manager, IConnectionPointContainer_iface);
102 static inline struct list_manager *impl_from_INetworkCostManager(
103 INetworkCostManager *iface )
105 return CONTAINING_RECORD( iface, struct list_manager, INetworkCostManager_iface );
108 static inline struct connection_point *impl_from_IConnectionPoint(
109 IConnectionPoint *iface )
111 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
114 static HRESULT WINAPI connection_point_QueryInterface(
115 IConnectionPoint *iface,
116 REFIID riid,
117 void **obj )
119 struct connection_point *cp = impl_from_IConnectionPoint( iface );
120 TRACE( "%p, %s, %p\n", cp, debugstr_guid(riid), obj );
122 if (IsEqualGUID( riid, &IID_IConnectionPoint ) ||
123 IsEqualGUID( riid, &IID_IUnknown ))
125 *obj = iface;
127 else
129 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
130 *obj = NULL;
131 return E_NOINTERFACE;
133 IConnectionPoint_AddRef( iface );
134 return S_OK;
137 static ULONG WINAPI connection_point_AddRef(
138 IConnectionPoint *iface )
140 struct connection_point *cp = impl_from_IConnectionPoint( iface );
141 return IConnectionPointContainer_AddRef( cp->container );
144 static ULONG WINAPI connection_point_Release(
145 IConnectionPoint *iface )
147 struct connection_point *cp = impl_from_IConnectionPoint( iface );
148 return IConnectionPointContainer_Release( cp->container );
151 static HRESULT WINAPI connection_point_GetConnectionInterface(
152 IConnectionPoint *iface,
153 IID *iid )
155 struct connection_point *cp = impl_from_IConnectionPoint( iface );
156 TRACE( "%p, %p\n", cp, iid );
158 if (!iid)
159 return E_POINTER;
161 memcpy( iid, &cp->iid, sizeof(*iid) );
162 return S_OK;
165 static HRESULT WINAPI connection_point_GetConnectionPointContainer(
166 IConnectionPoint *iface,
167 IConnectionPointContainer **container )
169 struct connection_point *cp = impl_from_IConnectionPoint( iface );
170 TRACE( "%p, %p\n", cp, container );
172 if (!container)
173 return E_POINTER;
175 IConnectionPointContainer_AddRef( cp->container );
176 *container = cp->container;
177 return S_OK;
180 static HRESULT WINAPI connection_point_Advise(
181 IConnectionPoint *iface,
182 IUnknown *sink,
183 DWORD *cookie )
185 struct connection_point *cp = impl_from_IConnectionPoint( iface );
186 struct sink_entry *sink_entry;
187 IUnknown *unk;
188 HRESULT hr;
190 FIXME( "%p, %p, %p - semi-stub\n", cp, sink, cookie );
192 if (!sink || !cookie)
193 return E_POINTER;
195 hr = IUnknown_QueryInterface( sink, &cp->iid, (void**)&unk );
196 if (FAILED(hr))
198 WARN( "iface %s not implemented by sink\n", debugstr_guid(&cp->iid) );
199 return CO_E_FAILEDTOOPENTHREADTOKEN;
202 sink_entry = heap_alloc( sizeof(*sink_entry) );
203 if (!sink_entry)
205 IUnknown_Release( unk );
206 return E_OUTOFMEMORY;
209 sink_entry->unk = unk;
210 *cookie = sink_entry->cookie = ++cp->cookie;
211 list_add_tail( &cp->sinks, &sink_entry->entry );
212 return S_OK;
215 static void sink_entry_release( struct sink_entry *entry )
217 list_remove( &entry->entry );
218 IUnknown_Release( entry->unk );
219 heap_free( entry );
222 static HRESULT WINAPI connection_point_Unadvise(
223 IConnectionPoint *iface,
224 DWORD cookie )
226 struct connection_point *cp = impl_from_IConnectionPoint( iface );
227 struct sink_entry *iter;
229 TRACE( "%p, %d\n", cp, cookie );
231 LIST_FOR_EACH_ENTRY( iter, &cp->sinks, struct sink_entry, entry )
233 if (iter->cookie != cookie) continue;
234 sink_entry_release( iter );
235 return S_OK;
238 WARN( "invalid cookie\n" );
239 return OLE_E_NOCONNECTION;
242 static HRESULT WINAPI connection_point_EnumConnections(
243 IConnectionPoint *iface,
244 IEnumConnections **connections )
246 struct connection_point *cp = impl_from_IConnectionPoint( iface );
247 FIXME( "%p, %p - stub\n", cp, connections );
249 return E_NOTIMPL;
252 static const IConnectionPointVtbl connection_point_vtbl =
254 connection_point_QueryInterface,
255 connection_point_AddRef,
256 connection_point_Release,
257 connection_point_GetConnectionInterface,
258 connection_point_GetConnectionPointContainer,
259 connection_point_Advise,
260 connection_point_Unadvise,
261 connection_point_EnumConnections
264 static void connection_point_init(
265 struct connection_point *cp,
266 REFIID riid,
267 IConnectionPointContainer *container )
269 cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
270 cp->container = container;
271 cp->cookie = 0;
272 cp->iid = *riid;
273 list_init( &cp->sinks );
276 static void connection_point_release( struct connection_point *cp )
278 while (!list_empty( &cp->sinks ))
279 sink_entry_release( LIST_ENTRY( list_head( &cp->sinks ), struct sink_entry, entry ) );
282 static inline struct network *impl_from_INetwork(
283 INetwork *iface )
285 return CONTAINING_RECORD( iface, struct network, INetwork_iface );
288 static HRESULT WINAPI network_QueryInterface(
289 INetwork *iface, REFIID riid, void **obj )
291 struct network *network = impl_from_INetwork( iface );
293 TRACE( "%p, %s, %p\n", network, debugstr_guid(riid), obj );
295 if (IsEqualIID( riid, &IID_INetwork ) ||
296 IsEqualIID( riid, &IID_IDispatch ) ||
297 IsEqualIID( riid, &IID_IUnknown ))
299 *obj = iface;
300 INetwork_AddRef( iface );
301 return S_OK;
303 else
305 WARN( "interface not supported %s\n", debugstr_guid(riid) );
306 *obj = NULL;
307 return E_NOINTERFACE;
311 static ULONG WINAPI network_AddRef(
312 INetwork *iface )
314 struct network *network = impl_from_INetwork( iface );
316 TRACE( "%p\n", network );
317 return InterlockedIncrement( &network->refs );
320 static ULONG WINAPI network_Release(
321 INetwork *iface )
323 struct network *network = impl_from_INetwork( iface );
324 LONG refs;
326 TRACE( "%p\n", network );
328 if (!(refs = InterlockedDecrement( &network->refs )))
330 list_remove( &network->entry );
331 heap_free( network );
333 return refs;
336 static HRESULT WINAPI network_GetTypeInfoCount(
337 INetwork *iface,
338 UINT *count )
340 FIXME("\n");
341 return E_NOTIMPL;
344 static HRESULT WINAPI network_GetTypeInfo(
345 INetwork *iface,
346 UINT index,
347 LCID lcid,
348 ITypeInfo **info )
350 FIXME("\n");
351 return E_NOTIMPL;
354 static HRESULT WINAPI network_GetIDsOfNames(
355 INetwork *iface,
356 REFIID riid,
357 LPOLESTR *names,
358 UINT count,
359 LCID lcid,
360 DISPID *dispid )
362 FIXME("\n");
363 return E_NOTIMPL;
366 static HRESULT WINAPI network_Invoke(
367 INetwork *iface,
368 DISPID member,
369 REFIID riid,
370 LCID lcid,
371 WORD flags,
372 DISPPARAMS *params,
373 VARIANT *result,
374 EXCEPINFO *excep_info,
375 UINT *arg_err )
377 FIXME("\n");
378 return E_NOTIMPL;
381 static HRESULT WINAPI network_GetName(
382 INetwork *iface,
383 BSTR *pszNetworkName )
385 FIXME( "%p, %p\n", iface, pszNetworkName );
386 return E_NOTIMPL;
389 static HRESULT WINAPI network_SetName(
390 INetwork *iface,
391 BSTR szNetworkNewName )
393 FIXME( "%p, %s\n", iface, debugstr_w(szNetworkNewName) );
394 return E_NOTIMPL;
397 static HRESULT WINAPI network_GetDescription(
398 INetwork *iface,
399 BSTR *pszDescription )
401 FIXME( "%p, %p\n", iface, pszDescription );
402 return E_NOTIMPL;
405 static HRESULT WINAPI network_SetDescription(
406 INetwork *iface,
407 BSTR szDescription )
409 FIXME( "%p, %s\n", iface, debugstr_w(szDescription) );
410 return E_NOTIMPL;
413 static HRESULT WINAPI network_GetNetworkId(
414 INetwork *iface,
415 GUID *pgdGuidNetworkId )
417 struct network *network = impl_from_INetwork( iface );
419 TRACE( "%p, %p\n", iface, pgdGuidNetworkId );
421 *pgdGuidNetworkId = network->id;
422 return S_OK;
425 static HRESULT WINAPI network_GetDomainType(
426 INetwork *iface,
427 NLM_DOMAIN_TYPE *pDomainType )
429 FIXME( "%p, %p\n", iface, pDomainType );
431 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
432 return S_OK;
435 static HRESULT WINAPI network_GetNetworkConnections(
436 INetwork *iface,
437 IEnumNetworkConnections **ppEnumNetworkConnection )
439 FIXME( "%p, %p\n", iface, ppEnumNetworkConnection );
440 return E_NOTIMPL;
443 static HRESULT WINAPI network_GetTimeCreatedAndConnected(
444 INetwork *iface,
445 DWORD *pdwLowDateTimeCreated,
446 DWORD *pdwHighDateTimeCreated,
447 DWORD *pdwLowDateTimeConnected,
448 DWORD *pdwHighDateTimeConnected )
450 FIXME( "%p, %p, %p, %p, %p\n", iface, pdwLowDateTimeCreated, pdwHighDateTimeCreated,
451 pdwLowDateTimeConnected, pdwHighDateTimeConnected );
452 return E_NOTIMPL;
455 static HRESULT WINAPI network_get_IsConnectedToInternet(
456 INetwork *iface,
457 VARIANT_BOOL *pbIsConnected )
459 struct network *network = impl_from_INetwork( iface );
461 TRACE( "%p, %p\n", iface, pbIsConnected );
463 *pbIsConnected = network->connected_to_internet;
464 return S_OK;
467 static HRESULT WINAPI network_get_IsConnected(
468 INetwork *iface,
469 VARIANT_BOOL *pbIsConnected )
471 struct network *network = impl_from_INetwork( iface );
473 TRACE( "%p, %p\n", iface, pbIsConnected );
475 *pbIsConnected = network->connected;
476 return S_OK;
479 static HRESULT WINAPI network_GetConnectivity(
480 INetwork *iface,
481 NLM_CONNECTIVITY *pConnectivity )
483 FIXME( "%p, %p\n", iface, pConnectivity );
485 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
486 return S_OK;
489 static HRESULT WINAPI network_GetCategory(
490 INetwork *iface,
491 NLM_NETWORK_CATEGORY *pCategory )
493 FIXME( "%p, %p\n", iface, pCategory );
495 *pCategory = NLM_NETWORK_CATEGORY_PUBLIC;
496 return S_OK;
499 static HRESULT WINAPI network_SetCategory(
500 INetwork *iface,
501 NLM_NETWORK_CATEGORY NewCategory )
503 FIXME( "%p, %u\n", iface, NewCategory );
504 return E_NOTIMPL;
507 static const struct INetworkVtbl network_vtbl =
509 network_QueryInterface,
510 network_AddRef,
511 network_Release,
512 network_GetTypeInfoCount,
513 network_GetTypeInfo,
514 network_GetIDsOfNames,
515 network_Invoke,
516 network_GetName,
517 network_SetName,
518 network_GetDescription,
519 network_SetDescription,
520 network_GetNetworkId,
521 network_GetDomainType,
522 network_GetNetworkConnections,
523 network_GetTimeCreatedAndConnected,
524 network_get_IsConnectedToInternet,
525 network_get_IsConnected,
526 network_GetConnectivity,
527 network_GetCategory,
528 network_SetCategory
531 static struct network *create_network( const GUID *id )
533 struct network *ret;
535 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
537 ret->INetwork_iface.lpVtbl = &network_vtbl;
538 ret->refs = 1;
539 ret->id = *id;
540 ret->connected = VARIANT_FALSE;
541 ret->connected_to_internet = VARIANT_FALSE;
542 list_init( &ret->entry );
544 return ret;
547 static HRESULT WINAPI cost_manager_QueryInterface(
548 INetworkCostManager *iface,
549 REFIID riid,
550 void **obj )
552 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
553 return INetworkListManager_QueryInterface( &mgr->INetworkListManager_iface, riid, obj );
556 static ULONG WINAPI cost_manager_AddRef(
557 INetworkCostManager *iface )
559 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
560 return INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
563 static ULONG WINAPI cost_manager_Release(
564 INetworkCostManager *iface )
566 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
567 return INetworkListManager_Release( &mgr->INetworkListManager_iface );
570 static HRESULT WINAPI cost_manager_GetCost(
571 INetworkCostManager *iface, DWORD *pCost, NLM_SOCKADDR *pDestIPAddr)
573 FIXME( "%p, %p, %p\n", iface, pCost, pDestIPAddr );
575 if (!pCost) return E_POINTER;
577 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
578 return S_OK;
581 static BOOL map_address_6to4( const SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
583 ULONG i;
585 if (addr6->sin6_family != AF_INET6) return FALSE;
587 for (i = 0; i < 5; i++)
588 if (addr6->sin6_addr.u.Word[i]) return FALSE;
590 if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
592 addr4->sin_family = AF_INET;
593 addr4->sin_port = addr6->sin6_port;
594 addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
595 memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
597 return TRUE;
600 static HRESULT WINAPI cost_manager_GetDataPlanStatus(
601 INetworkCostManager *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus,
602 NLM_SOCKADDR *pDestIPAddr)
604 DWORD ret, index;
605 NET_LUID luid;
606 SOCKADDR *dst = (SOCKADDR *)pDestIPAddr;
607 SOCKADDR_IN addr4, *dst4;
609 FIXME( "%p, %p, %p\n", iface, pDataPlanStatus, pDestIPAddr );
611 if (!pDataPlanStatus) return E_POINTER;
613 if (dst && ((dst->sa_family == AF_INET && (dst4 = (SOCKADDR_IN *)dst)) ||
614 ((dst->sa_family == AF_INET6 && map_address_6to4( (const SOCKADDR_IN6 *)dst, &addr4 )
615 && (dst4 = &addr4)))))
617 if ((ret = GetBestInterface( dst4->sin_addr.S_un.S_addr, &index )))
618 return HRESULT_FROM_WIN32( ret );
620 if ((ret = ConvertInterfaceIndexToLuid( index, &luid )))
621 return HRESULT_FROM_WIN32( ret );
623 if ((ret = ConvertInterfaceLuidToGuid( &luid, &pDataPlanStatus->InterfaceGuid )))
624 return HRESULT_FROM_WIN32( ret );
626 else
628 FIXME( "interface guid not found\n" );
629 memset( &pDataPlanStatus->InterfaceGuid, 0, sizeof(pDataPlanStatus->InterfaceGuid) );
632 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
633 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
634 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
635 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
636 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
637 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
638 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
639 pDataPlanStatus->Reserved = 0;
641 return S_OK;
644 static HRESULT WINAPI cost_manager_SetDestinationAddresses(
645 INetworkCostManager *iface, UINT32 length, NLM_SOCKADDR *pDestIPAddrList,
646 VARIANT_BOOL bAppend)
648 FIXME( "%p, %u, %p, %x\n", iface, length, pDestIPAddrList, bAppend );
649 return E_NOTIMPL;
652 static const INetworkCostManagerVtbl cost_manager_vtbl =
654 cost_manager_QueryInterface,
655 cost_manager_AddRef,
656 cost_manager_Release,
657 cost_manager_GetCost,
658 cost_manager_GetDataPlanStatus,
659 cost_manager_SetDestinationAddresses
662 struct networks_enum
664 IEnumNetworks IEnumNetworks_iface;
665 LONG refs;
666 struct list_manager *mgr;
667 struct list *cursor;
670 static inline struct networks_enum *impl_from_IEnumNetworks(
671 IEnumNetworks *iface )
673 return CONTAINING_RECORD( iface, struct networks_enum, IEnumNetworks_iface );
676 static HRESULT WINAPI networks_enum_QueryInterface(
677 IEnumNetworks *iface, REFIID riid, void **obj )
679 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
681 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
683 if (IsEqualIID( riid, &IID_IEnumNetworks ) ||
684 IsEqualIID( riid, &IID_IDispatch ) ||
685 IsEqualIID( riid, &IID_IUnknown ))
687 *obj = iface;
688 IEnumNetworks_AddRef( iface );
689 return S_OK;
691 else
693 WARN( "interface not supported %s\n", debugstr_guid(riid) );
694 *obj = NULL;
695 return E_NOINTERFACE;
699 static ULONG WINAPI networks_enum_AddRef(
700 IEnumNetworks *iface )
702 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
704 TRACE( "%p\n", iter );
705 return InterlockedIncrement( &iter->refs );
708 static ULONG WINAPI networks_enum_Release(
709 IEnumNetworks *iface )
711 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
712 LONG refs;
714 TRACE( "%p\n", iter );
716 if (!(refs = InterlockedDecrement( &iter->refs )))
718 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
719 heap_free( iter );
721 return refs;
724 static HRESULT WINAPI networks_enum_GetTypeInfoCount(
725 IEnumNetworks *iface,
726 UINT *count )
728 FIXME("\n");
729 return E_NOTIMPL;
732 static HRESULT WINAPI networks_enum_GetTypeInfo(
733 IEnumNetworks *iface,
734 UINT index,
735 LCID lcid,
736 ITypeInfo **info )
738 FIXME("\n");
739 return E_NOTIMPL;
742 static HRESULT WINAPI networks_enum_GetIDsOfNames(
743 IEnumNetworks *iface,
744 REFIID riid,
745 LPOLESTR *names,
746 UINT count,
747 LCID lcid,
748 DISPID *dispid )
750 FIXME("\n");
751 return E_NOTIMPL;
754 static HRESULT WINAPI networks_enum_Invoke(
755 IEnumNetworks *iface,
756 DISPID member,
757 REFIID riid,
758 LCID lcid,
759 WORD flags,
760 DISPPARAMS *params,
761 VARIANT *result,
762 EXCEPINFO *excep_info,
763 UINT *arg_err )
765 FIXME("\n");
766 return E_NOTIMPL;
769 static HRESULT WINAPI networks_enum_get__NewEnum(
770 IEnumNetworks *iface, IEnumVARIANT **ppEnumVar )
772 FIXME("\n");
773 return E_NOTIMPL;
776 static HRESULT WINAPI networks_enum_Next(
777 IEnumNetworks *iface, ULONG count, INetwork **ret, ULONG *fetched )
779 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
780 ULONG i = 0;
782 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
784 if (fetched) *fetched = 0;
785 if (!count) return S_OK;
787 while (iter->cursor && i < count)
789 struct network *network = LIST_ENTRY( iter->cursor, struct network, entry );
790 ret[i] = &network->INetwork_iface;
791 INetwork_AddRef( ret[i] );
792 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
793 i++;
795 if (fetched) *fetched = i;
797 return i < count ? S_FALSE : S_OK;
800 static HRESULT WINAPI networks_enum_Skip(
801 IEnumNetworks *iface, ULONG count )
803 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
805 TRACE( "%p, %u\n", iter, count);
807 if (!count) return S_OK;
808 if (!iter->cursor) return S_FALSE;
810 while (count--)
812 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
813 if (!iter->cursor) break;
816 return count ? S_FALSE : S_OK;
819 static HRESULT WINAPI networks_enum_Reset(
820 IEnumNetworks *iface )
822 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
824 TRACE( "%p\n", iter );
826 iter->cursor = list_head( &iter->mgr->networks );
827 return S_OK;
830 static HRESULT create_networks_enum(
831 struct list_manager *, IEnumNetworks** );
833 static HRESULT WINAPI networks_enum_Clone(
834 IEnumNetworks *iface, IEnumNetworks **ret )
836 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
838 TRACE( "%p, %p\n", iter, ret );
839 return create_networks_enum( iter->mgr, ret );
842 static const IEnumNetworksVtbl networks_enum_vtbl =
844 networks_enum_QueryInterface,
845 networks_enum_AddRef,
846 networks_enum_Release,
847 networks_enum_GetTypeInfoCount,
848 networks_enum_GetTypeInfo,
849 networks_enum_GetIDsOfNames,
850 networks_enum_Invoke,
851 networks_enum_get__NewEnum,
852 networks_enum_Next,
853 networks_enum_Skip,
854 networks_enum_Reset,
855 networks_enum_Clone
858 static HRESULT create_networks_enum(
859 struct list_manager *mgr, IEnumNetworks **ret )
861 struct networks_enum *iter;
863 *ret = NULL;
864 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
866 iter->IEnumNetworks_iface.lpVtbl = &networks_enum_vtbl;
867 iter->cursor = list_head( &mgr->networks );
868 iter->mgr = mgr;
869 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
870 iter->refs = 1;
872 *ret = &iter->IEnumNetworks_iface;
873 return S_OK;
876 static inline struct list_manager *impl_from_INetworkListManager(
877 INetworkListManager *iface )
879 return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface );
882 struct connections_enum
884 IEnumNetworkConnections IEnumNetworkConnections_iface;
885 LONG refs;
886 struct list_manager *mgr;
887 struct list *cursor;
890 static inline struct connections_enum *impl_from_IEnumNetworkConnections(
891 IEnumNetworkConnections *iface )
893 return CONTAINING_RECORD( iface, struct connections_enum, IEnumNetworkConnections_iface );
896 static HRESULT WINAPI connections_enum_QueryInterface(
897 IEnumNetworkConnections *iface, REFIID riid, void **obj )
899 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
901 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
903 if (IsEqualIID( riid, &IID_IEnumNetworkConnections ) ||
904 IsEqualIID( riid, &IID_IDispatch ) ||
905 IsEqualIID( riid, &IID_IUnknown ))
907 *obj = iface;
908 IEnumNetworkConnections_AddRef( iface );
909 return S_OK;
911 else
913 WARN( "interface not supported %s\n", debugstr_guid(riid) );
914 *obj = NULL;
915 return E_NOINTERFACE;
919 static ULONG WINAPI connections_enum_AddRef(
920 IEnumNetworkConnections *iface )
922 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
924 TRACE( "%p\n", iter );
925 return InterlockedIncrement( &iter->refs );
928 static ULONG WINAPI connections_enum_Release(
929 IEnumNetworkConnections *iface )
931 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
932 LONG refs;
934 TRACE( "%p\n", iter );
936 if (!(refs = InterlockedDecrement( &iter->refs )))
938 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
939 heap_free( iter );
941 return refs;
944 static HRESULT WINAPI connections_enum_GetTypeInfoCount(
945 IEnumNetworkConnections *iface,
946 UINT *count )
948 FIXME("\n");
949 return E_NOTIMPL;
952 static HRESULT WINAPI connections_enum_GetTypeInfo(
953 IEnumNetworkConnections *iface,
954 UINT index,
955 LCID lcid,
956 ITypeInfo **info )
958 FIXME("\n");
959 return E_NOTIMPL;
962 static HRESULT WINAPI connections_enum_GetIDsOfNames(
963 IEnumNetworkConnections *iface,
964 REFIID riid,
965 LPOLESTR *names,
966 UINT count,
967 LCID lcid,
968 DISPID *dispid )
970 FIXME("\n");
971 return E_NOTIMPL;
974 static HRESULT WINAPI connections_enum_Invoke(
975 IEnumNetworkConnections *iface,
976 DISPID member,
977 REFIID riid,
978 LCID lcid,
979 WORD flags,
980 DISPPARAMS *params,
981 VARIANT *result,
982 EXCEPINFO *excep_info,
983 UINT *arg_err )
985 FIXME("\n");
986 return E_NOTIMPL;
989 static HRESULT WINAPI connections_enum_get__NewEnum(
990 IEnumNetworkConnections *iface, IEnumVARIANT **ppEnumVar )
992 FIXME("\n");
993 return E_NOTIMPL;
996 static HRESULT WINAPI connections_enum_Next(
997 IEnumNetworkConnections *iface, ULONG count, INetworkConnection **ret, ULONG *fetched )
999 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1000 ULONG i = 0;
1002 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
1004 if (fetched) *fetched = 0;
1005 if (!count) return S_OK;
1007 while (iter->cursor && i < count)
1009 struct connection *connection = LIST_ENTRY( iter->cursor, struct connection, entry );
1010 ret[i] = &connection->INetworkConnection_iface;
1011 INetworkConnection_AddRef( ret[i] );
1012 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1013 i++;
1015 if (fetched) *fetched = i;
1017 return i < count ? S_FALSE : S_OK;
1020 static HRESULT WINAPI connections_enum_Skip(
1021 IEnumNetworkConnections *iface, ULONG count )
1023 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1025 TRACE( "%p, %u\n", iter, count);
1027 if (!count) return S_OK;
1028 if (!iter->cursor) return S_FALSE;
1030 while (count--)
1032 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1033 if (!iter->cursor) break;
1036 return count ? S_FALSE : S_OK;
1039 static HRESULT WINAPI connections_enum_Reset(
1040 IEnumNetworkConnections *iface )
1042 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1044 TRACE( "%p\n", iter );
1046 iter->cursor = list_head( &iter->mgr->connections );
1047 return S_OK;
1050 static HRESULT create_connections_enum(
1051 struct list_manager *, IEnumNetworkConnections** );
1053 static HRESULT WINAPI connections_enum_Clone(
1054 IEnumNetworkConnections *iface, IEnumNetworkConnections **ret )
1056 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1058 TRACE( "%p, %p\n", iter, ret );
1059 return create_connections_enum( iter->mgr, ret );
1062 static const IEnumNetworkConnectionsVtbl connections_enum_vtbl =
1064 connections_enum_QueryInterface,
1065 connections_enum_AddRef,
1066 connections_enum_Release,
1067 connections_enum_GetTypeInfoCount,
1068 connections_enum_GetTypeInfo,
1069 connections_enum_GetIDsOfNames,
1070 connections_enum_Invoke,
1071 connections_enum_get__NewEnum,
1072 connections_enum_Next,
1073 connections_enum_Skip,
1074 connections_enum_Reset,
1075 connections_enum_Clone
1078 static HRESULT create_connections_enum(
1079 struct list_manager *mgr, IEnumNetworkConnections **ret )
1081 struct connections_enum *iter;
1083 *ret = NULL;
1084 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
1086 iter->IEnumNetworkConnections_iface.lpVtbl = &connections_enum_vtbl;
1087 iter->mgr = mgr;
1088 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
1089 iter->cursor = list_head( &iter->mgr->connections );
1090 iter->refs = 1;
1092 *ret = &iter->IEnumNetworkConnections_iface;
1093 return S_OK;
1096 static ULONG WINAPI list_manager_AddRef(
1097 INetworkListManager *iface )
1099 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1100 return InterlockedIncrement( &mgr->refs );
1103 static ULONG WINAPI list_manager_Release(
1104 INetworkListManager *iface )
1106 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1107 LONG refs = InterlockedDecrement( &mgr->refs );
1108 if (!refs)
1110 struct list *ptr;
1112 TRACE( "destroying %p\n", mgr );
1114 connection_point_release( &mgr->events_cp );
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 if (IsEqualGUID( riid, &IID_INetworkEvents))
1400 ret = &This->events_cp;
1401 else
1403 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1404 *cp = NULL;
1405 return E_NOINTERFACE;
1408 IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface );
1409 return S_OK;
1412 static const struct IConnectionPointContainerVtbl cpc_vtbl =
1414 ConnectionPointContainer_QueryInterface,
1415 ConnectionPointContainer_AddRef,
1416 ConnectionPointContainer_Release,
1417 ConnectionPointContainer_EnumConnectionPoints,
1418 ConnectionPointContainer_FindConnectionPoint
1421 static inline struct connection *impl_from_INetworkConnection(
1422 INetworkConnection *iface )
1424 return CONTAINING_RECORD( iface, struct connection, INetworkConnection_iface );
1427 static HRESULT WINAPI connection_QueryInterface(
1428 INetworkConnection *iface, REFIID riid, void **obj )
1430 struct connection *connection = impl_from_INetworkConnection( iface );
1432 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
1434 if (IsEqualIID( riid, &IID_INetworkConnection ) ||
1435 IsEqualIID( riid, &IID_IDispatch ) ||
1436 IsEqualIID( riid, &IID_IUnknown ))
1438 *obj = iface;
1440 else if (IsEqualIID( riid, &IID_INetworkConnectionCost ))
1442 *obj = &connection->INetworkConnectionCost_iface;
1444 else
1446 WARN( "interface not supported %s\n", debugstr_guid(riid) );
1447 *obj = NULL;
1448 return E_NOINTERFACE;
1450 INetworkConnection_AddRef( iface );
1451 return S_OK;
1454 static ULONG WINAPI connection_AddRef(
1455 INetworkConnection *iface )
1457 struct connection *connection = impl_from_INetworkConnection( iface );
1459 TRACE( "%p\n", connection );
1460 return InterlockedIncrement( &connection->refs );
1463 static ULONG WINAPI connection_Release(
1464 INetworkConnection *iface )
1466 struct connection *connection = impl_from_INetworkConnection( iface );
1467 LONG refs;
1469 TRACE( "%p\n", connection );
1471 if (!(refs = InterlockedDecrement( &connection->refs )))
1473 INetwork_Release( connection->network );
1474 list_remove( &connection->entry );
1475 heap_free( connection );
1477 return refs;
1480 static HRESULT WINAPI connection_GetTypeInfoCount(
1481 INetworkConnection *iface,
1482 UINT *count )
1484 FIXME("\n");
1485 return E_NOTIMPL;
1488 static HRESULT WINAPI connection_GetTypeInfo(
1489 INetworkConnection *iface,
1490 UINT index,
1491 LCID lcid,
1492 ITypeInfo **info )
1494 FIXME("\n");
1495 return E_NOTIMPL;
1498 static HRESULT WINAPI connection_GetIDsOfNames(
1499 INetworkConnection *iface,
1500 REFIID riid,
1501 LPOLESTR *names,
1502 UINT count,
1503 LCID lcid,
1504 DISPID *dispid )
1506 FIXME("\n");
1507 return E_NOTIMPL;
1510 static HRESULT WINAPI connection_Invoke(
1511 INetworkConnection *iface,
1512 DISPID member,
1513 REFIID riid,
1514 LCID lcid,
1515 WORD flags,
1516 DISPPARAMS *params,
1517 VARIANT *result,
1518 EXCEPINFO *excep_info,
1519 UINT *arg_err )
1521 FIXME("\n");
1522 return E_NOTIMPL;
1525 static HRESULT WINAPI connection_GetNetwork(
1526 INetworkConnection *iface,
1527 INetwork **ppNetwork )
1529 struct connection *connection = impl_from_INetworkConnection( iface );
1531 TRACE( "%p, %p\n", iface, ppNetwork );
1533 *ppNetwork = connection->network;
1534 INetwork_AddRef( *ppNetwork );
1535 return S_OK;
1538 static HRESULT WINAPI connection_get_IsConnectedToInternet(
1539 INetworkConnection *iface,
1540 VARIANT_BOOL *pbIsConnected )
1542 struct connection *connection = impl_from_INetworkConnection( iface );
1544 TRACE( "%p, %p\n", iface, pbIsConnected );
1546 *pbIsConnected = connection->connected_to_internet;
1547 return S_OK;
1550 static HRESULT WINAPI connection_get_IsConnected(
1551 INetworkConnection *iface,
1552 VARIANT_BOOL *pbIsConnected )
1554 struct connection *connection = impl_from_INetworkConnection( iface );
1556 TRACE( "%p, %p\n", iface, pbIsConnected );
1558 *pbIsConnected = connection->connected;
1559 return S_OK;
1562 static HRESULT WINAPI connection_GetConnectivity(
1563 INetworkConnection *iface,
1564 NLM_CONNECTIVITY *pConnectivity )
1566 FIXME( "%p, %p\n", iface, pConnectivity );
1568 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1569 return S_OK;
1572 static HRESULT WINAPI connection_GetConnectionId(
1573 INetworkConnection *iface,
1574 GUID *pgdConnectionId )
1576 struct connection *connection = impl_from_INetworkConnection( iface );
1578 TRACE( "%p, %p\n", iface, pgdConnectionId );
1580 *pgdConnectionId = connection->id;
1581 return S_OK;
1584 static HRESULT WINAPI connection_GetAdapterId(
1585 INetworkConnection *iface,
1586 GUID *pgdAdapterId )
1588 struct connection *connection = impl_from_INetworkConnection( iface );
1590 FIXME( "%p, %p\n", iface, pgdAdapterId );
1592 *pgdAdapterId = connection->id;
1593 return S_OK;
1596 static HRESULT WINAPI connection_GetDomainType(
1597 INetworkConnection *iface,
1598 NLM_DOMAIN_TYPE *pDomainType )
1600 FIXME( "%p, %p\n", iface, pDomainType );
1602 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
1603 return S_OK;
1606 static const struct INetworkConnectionVtbl connection_vtbl =
1608 connection_QueryInterface,
1609 connection_AddRef,
1610 connection_Release,
1611 connection_GetTypeInfoCount,
1612 connection_GetTypeInfo,
1613 connection_GetIDsOfNames,
1614 connection_Invoke,
1615 connection_GetNetwork,
1616 connection_get_IsConnectedToInternet,
1617 connection_get_IsConnected,
1618 connection_GetConnectivity,
1619 connection_GetConnectionId,
1620 connection_GetAdapterId,
1621 connection_GetDomainType
1624 static inline struct connection *impl_from_INetworkConnectionCost(
1625 INetworkConnectionCost *iface )
1627 return CONTAINING_RECORD( iface, struct connection, INetworkConnectionCost_iface );
1630 static HRESULT WINAPI connection_cost_QueryInterface(
1631 INetworkConnectionCost *iface,
1632 REFIID riid,
1633 void **obj )
1635 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1636 return INetworkConnection_QueryInterface( &conn->INetworkConnection_iface, riid, obj );
1639 static ULONG WINAPI connection_cost_AddRef(
1640 INetworkConnectionCost *iface )
1642 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1643 return INetworkConnection_AddRef( &conn->INetworkConnection_iface );
1646 static ULONG WINAPI connection_cost_Release(
1647 INetworkConnectionCost *iface )
1649 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1650 return INetworkConnection_Release( &conn->INetworkConnection_iface );
1653 static HRESULT WINAPI connection_cost_GetCost(
1654 INetworkConnectionCost *iface, DWORD *pCost )
1656 FIXME( "%p, %p\n", iface, pCost );
1658 if (!pCost) return E_POINTER;
1660 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
1661 return S_OK;
1664 static HRESULT WINAPI connection_cost_GetDataPlanStatus(
1665 INetworkConnectionCost *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus )
1667 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1669 FIXME( "%p, %p\n", iface, pDataPlanStatus );
1671 if (!pDataPlanStatus) return E_POINTER;
1673 memcpy( &pDataPlanStatus->InterfaceGuid, &conn->id, sizeof(conn->id) );
1674 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1675 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
1676 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1677 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1678 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1679 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
1680 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1681 pDataPlanStatus->Reserved = 0;
1683 return S_OK;
1686 static const INetworkConnectionCostVtbl connection_cost_vtbl =
1688 connection_cost_QueryInterface,
1689 connection_cost_AddRef,
1690 connection_cost_Release,
1691 connection_cost_GetCost,
1692 connection_cost_GetDataPlanStatus
1695 static struct connection *create_connection( const GUID *id )
1697 struct connection *ret;
1699 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
1701 ret->INetworkConnection_iface.lpVtbl = &connection_vtbl;
1702 ret->INetworkConnectionCost_iface.lpVtbl = &connection_cost_vtbl;
1703 ret->refs = 1;
1704 ret->id = *id;
1705 ret->network = NULL;
1706 ret->connected = VARIANT_FALSE;
1707 ret->connected_to_internet = VARIANT_FALSE;
1708 list_init( &ret->entry );
1710 return ret;
1713 static void init_networks( struct list_manager *mgr )
1715 DWORD size = 0;
1716 IP_ADAPTER_ADDRESSES *buf, *aa;
1717 GUID id;
1718 ULONG ret, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
1719 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_GATEWAYS;
1721 list_init( &mgr->networks );
1722 list_init( &mgr->connections );
1724 ret = GetAdaptersAddresses( AF_UNSPEC, flags, NULL, NULL, &size );
1725 if (ret != ERROR_BUFFER_OVERFLOW) return;
1727 if (!(buf = heap_alloc( size ))) return;
1728 if (GetAdaptersAddresses( AF_UNSPEC, flags, NULL, buf, &size ))
1730 heap_free( buf );
1731 return;
1734 memset( &id, 0, sizeof(id) );
1735 for (aa = buf; aa; aa = aa->Next)
1737 struct network *network;
1738 struct connection *connection;
1740 id.Data1 = aa->u.s.IfIndex;
1742 /* assume a one-to-one mapping between networks and connections */
1743 if (!(network = create_network( &id ))) goto done;
1744 if (!(connection = create_connection( &id )))
1746 INetwork_Release( &network->INetwork_iface );
1747 goto done;
1750 if (aa->FirstUnicastAddress)
1752 network->connected = VARIANT_TRUE;
1753 connection->connected = VARIANT_TRUE;
1755 if (aa->FirstGatewayAddress)
1757 network->connected_to_internet = VARIANT_TRUE;
1758 connection->connected_to_internet = VARIANT_TRUE;
1761 connection->network = &network->INetwork_iface;
1762 INetwork_AddRef( connection->network );
1764 list_add_tail( &mgr->networks, &network->entry );
1765 list_add_tail( &mgr->connections, &connection->entry );
1768 done:
1769 heap_free( buf );
1772 HRESULT list_manager_create( void **obj )
1774 struct list_manager *mgr;
1776 TRACE( "%p\n", obj );
1778 if (!(mgr = heap_alloc( sizeof(*mgr) ))) return E_OUTOFMEMORY;
1779 mgr->INetworkListManager_iface.lpVtbl = &list_manager_vtbl;
1780 mgr->INetworkCostManager_iface.lpVtbl = &cost_manager_vtbl;
1781 mgr->IConnectionPointContainer_iface.lpVtbl = &cpc_vtbl;
1782 init_networks( mgr );
1783 mgr->refs = 1;
1785 connection_point_init( &mgr->list_mgr_cp, &IID_INetworkListManagerEvents,
1786 &mgr->IConnectionPointContainer_iface );
1787 connection_point_init( &mgr->cost_mgr_cp, &IID_INetworkCostManagerEvents,
1788 &mgr->IConnectionPointContainer_iface);
1789 connection_point_init( &mgr->conn_mgr_cp, &IID_INetworkConnectionEvents,
1790 &mgr->IConnectionPointContainer_iface );
1791 connection_point_init( &mgr->events_cp, &IID_INetworkEvents,
1792 &mgr->IConnectionPointContainer_iface );
1794 *obj = &mgr->INetworkListManager_iface;
1795 TRACE( "returning iface %p\n", *obj );
1796 return S_OK;