kernel32/tests/pipe: Enable compilation with long types.
[wine.git] / dlls / netprofm / list.c
blob254cf60c263bcebc795943ea7f101dbf99693e0b
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, %ld\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, %lu %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, %lu\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, %lu %p %p\n", iter, count, ret, fetched );
1004 if (!ret) return E_POINTER;
1005 *ret = NULL;
1006 if (fetched) *fetched = 0;
1007 if (!count) return S_OK;
1009 while (iter->cursor && i < count)
1011 struct connection *connection = LIST_ENTRY( iter->cursor, struct connection, entry );
1012 ret[i] = &connection->INetworkConnection_iface;
1013 INetworkConnection_AddRef( ret[i] );
1014 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1015 i++;
1017 if (fetched) *fetched = i;
1019 return i < count ? S_FALSE : S_OK;
1022 static HRESULT WINAPI connections_enum_Skip(
1023 IEnumNetworkConnections *iface, ULONG count )
1025 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1027 TRACE( "%p, %lu\n", iter, count);
1029 if (!count) return S_OK;
1030 if (!iter->cursor) return S_FALSE;
1032 while (count--)
1034 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1035 if (!iter->cursor) break;
1038 return count ? S_FALSE : S_OK;
1041 static HRESULT WINAPI connections_enum_Reset(
1042 IEnumNetworkConnections *iface )
1044 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1046 TRACE( "%p\n", iter );
1048 iter->cursor = list_head( &iter->mgr->connections );
1049 return S_OK;
1052 static HRESULT create_connections_enum(
1053 struct list_manager *, IEnumNetworkConnections** );
1055 static HRESULT WINAPI connections_enum_Clone(
1056 IEnumNetworkConnections *iface, IEnumNetworkConnections **ret )
1058 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1060 TRACE( "%p, %p\n", iter, ret );
1061 return create_connections_enum( iter->mgr, ret );
1064 static const IEnumNetworkConnectionsVtbl connections_enum_vtbl =
1066 connections_enum_QueryInterface,
1067 connections_enum_AddRef,
1068 connections_enum_Release,
1069 connections_enum_GetTypeInfoCount,
1070 connections_enum_GetTypeInfo,
1071 connections_enum_GetIDsOfNames,
1072 connections_enum_Invoke,
1073 connections_enum_get__NewEnum,
1074 connections_enum_Next,
1075 connections_enum_Skip,
1076 connections_enum_Reset,
1077 connections_enum_Clone
1080 static HRESULT create_connections_enum(
1081 struct list_manager *mgr, IEnumNetworkConnections **ret )
1083 struct connections_enum *iter;
1085 *ret = NULL;
1086 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
1088 iter->IEnumNetworkConnections_iface.lpVtbl = &connections_enum_vtbl;
1089 iter->mgr = mgr;
1090 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
1091 iter->cursor = list_head( &iter->mgr->connections );
1092 iter->refs = 1;
1094 *ret = &iter->IEnumNetworkConnections_iface;
1095 return S_OK;
1098 static ULONG WINAPI list_manager_AddRef(
1099 INetworkListManager *iface )
1101 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1102 return InterlockedIncrement( &mgr->refs );
1105 static ULONG WINAPI list_manager_Release(
1106 INetworkListManager *iface )
1108 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1109 LONG refs = InterlockedDecrement( &mgr->refs );
1110 if (!refs)
1112 struct list *ptr;
1114 TRACE( "destroying %p\n", mgr );
1116 connection_point_release( &mgr->events_cp );
1117 connection_point_release( &mgr->conn_mgr_cp );
1118 connection_point_release( &mgr->cost_mgr_cp );
1119 connection_point_release( &mgr->list_mgr_cp );
1120 while ((ptr = list_head( &mgr->networks )))
1122 struct network *network = LIST_ENTRY( ptr, struct network, entry );
1123 list_remove( &network->entry );
1124 INetwork_Release( &network->INetwork_iface );
1126 while ((ptr = list_head( &mgr->connections )))
1128 struct connection *connection = LIST_ENTRY( ptr, struct connection, entry );
1129 list_remove( &connection->entry );
1130 INetworkConnection_Release( &connection->INetworkConnection_iface );
1132 heap_free( mgr );
1134 return refs;
1137 static HRESULT WINAPI list_manager_QueryInterface(
1138 INetworkListManager *iface,
1139 REFIID riid,
1140 void **obj )
1142 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1144 TRACE( "%p, %s, %p\n", mgr, debugstr_guid(riid), obj );
1146 if (IsEqualGUID( riid, &IID_INetworkListManager ) ||
1147 IsEqualGUID( riid, &IID_IDispatch ) ||
1148 IsEqualGUID( riid, &IID_IUnknown ))
1150 *obj = iface;
1152 else if (IsEqualGUID( riid, &IID_INetworkCostManager ))
1154 *obj = &mgr->INetworkCostManager_iface;
1156 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
1158 *obj = &mgr->IConnectionPointContainer_iface;
1160 else
1162 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1163 *obj = NULL;
1164 return E_NOINTERFACE;
1166 INetworkListManager_AddRef( iface );
1167 return S_OK;
1170 static HRESULT WINAPI list_manager_GetTypeInfoCount(
1171 INetworkListManager *iface,
1172 UINT *count )
1174 FIXME("\n");
1175 return E_NOTIMPL;
1178 static HRESULT WINAPI list_manager_GetTypeInfo(
1179 INetworkListManager *iface,
1180 UINT index,
1181 LCID lcid,
1182 ITypeInfo **info )
1184 FIXME("\n");
1185 return E_NOTIMPL;
1188 static HRESULT WINAPI list_manager_GetIDsOfNames(
1189 INetworkListManager *iface,
1190 REFIID riid,
1191 LPOLESTR *names,
1192 UINT count,
1193 LCID lcid,
1194 DISPID *dispid )
1196 FIXME("\n");
1197 return E_NOTIMPL;
1200 static HRESULT WINAPI list_manager_Invoke(
1201 INetworkListManager *iface,
1202 DISPID member,
1203 REFIID riid,
1204 LCID lcid,
1205 WORD flags,
1206 DISPPARAMS *params,
1207 VARIANT *result,
1208 EXCEPINFO *excep_info,
1209 UINT *arg_err )
1211 FIXME("\n");
1212 return E_NOTIMPL;
1215 static HRESULT WINAPI list_manager_GetNetworks(
1216 INetworkListManager *iface,
1217 NLM_ENUM_NETWORK Flags,
1218 IEnumNetworks **ppEnumNetwork )
1220 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1222 TRACE( "%p, %x, %p\n", iface, Flags, ppEnumNetwork );
1223 if (Flags) FIXME( "flags %08x not supported\n", Flags );
1225 return create_networks_enum( mgr, ppEnumNetwork );
1228 static HRESULT WINAPI list_manager_GetNetwork(
1229 INetworkListManager *iface,
1230 GUID gdNetworkId,
1231 INetwork **ppNetwork )
1233 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1234 struct network *network;
1236 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkId), ppNetwork );
1238 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1240 if (IsEqualGUID( &network->id, &gdNetworkId ))
1242 *ppNetwork = &network->INetwork_iface;
1243 INetwork_AddRef( *ppNetwork );
1244 return S_OK;
1248 return S_FALSE;
1251 static HRESULT WINAPI list_manager_GetNetworkConnections(
1252 INetworkListManager *iface,
1253 IEnumNetworkConnections **ppEnum )
1255 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1257 TRACE( "%p, %p\n", iface, ppEnum );
1258 return create_connections_enum( mgr, ppEnum );
1261 static HRESULT WINAPI list_manager_GetNetworkConnection(
1262 INetworkListManager *iface,
1263 GUID gdNetworkConnectionId,
1264 INetworkConnection **ppNetworkConnection )
1266 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1267 struct connection *connection;
1269 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkConnectionId),
1270 ppNetworkConnection );
1272 LIST_FOR_EACH_ENTRY( connection, &mgr->connections, struct connection, entry )
1274 if (IsEqualGUID( &connection->id, &gdNetworkConnectionId ))
1276 *ppNetworkConnection = &connection->INetworkConnection_iface;
1277 INetworkConnection_AddRef( *ppNetworkConnection );
1278 return S_OK;
1282 return S_FALSE;
1285 static HRESULT WINAPI list_manager_IsConnectedToInternet(
1286 INetworkListManager *iface,
1287 VARIANT_BOOL *pbIsConnected )
1289 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1290 struct network *network;
1292 TRACE( "%p, %p\n", iface, pbIsConnected );
1294 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1296 if (network->connected_to_internet)
1298 *pbIsConnected = VARIANT_TRUE;
1299 return S_OK;
1303 *pbIsConnected = VARIANT_FALSE;
1304 return S_OK;
1307 static HRESULT WINAPI list_manager_IsConnected(
1308 INetworkListManager *iface,
1309 VARIANT_BOOL *pbIsConnected )
1311 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1312 struct network *network;
1314 TRACE( "%p, %p\n", iface, pbIsConnected );
1316 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1318 if (network->connected)
1320 *pbIsConnected = VARIANT_TRUE;
1321 return S_OK;
1325 *pbIsConnected = VARIANT_FALSE;
1326 return S_OK;
1329 static HRESULT WINAPI list_manager_GetConnectivity(
1330 INetworkListManager *iface,
1331 NLM_CONNECTIVITY *pConnectivity )
1333 FIXME( "%p, %p\n", iface, pConnectivity );
1335 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1336 return S_OK;
1339 static const INetworkListManagerVtbl list_manager_vtbl =
1341 list_manager_QueryInterface,
1342 list_manager_AddRef,
1343 list_manager_Release,
1344 list_manager_GetTypeInfoCount,
1345 list_manager_GetTypeInfo,
1346 list_manager_GetIDsOfNames,
1347 list_manager_Invoke,
1348 list_manager_GetNetworks,
1349 list_manager_GetNetwork,
1350 list_manager_GetNetworkConnections,
1351 list_manager_GetNetworkConnection,
1352 list_manager_IsConnectedToInternet,
1353 list_manager_IsConnected,
1354 list_manager_GetConnectivity
1357 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
1358 REFIID riid, void **ppv)
1360 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1361 return INetworkListManager_QueryInterface(&This->INetworkListManager_iface, riid, ppv);
1364 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
1366 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1367 return INetworkListManager_AddRef(&This->INetworkListManager_iface);
1370 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
1372 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1373 return INetworkListManager_Release(&This->INetworkListManager_iface);
1376 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
1377 IEnumConnectionPoints **ppEnum)
1379 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1380 FIXME("(%p)->(%p): stub\n", This, ppEnum);
1381 return E_NOTIMPL;
1384 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
1385 REFIID riid, IConnectionPoint **cp)
1387 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1388 struct connection_point *ret;
1390 TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
1392 if (!riid || !cp)
1393 return E_POINTER;
1395 if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ))
1396 ret = &This->list_mgr_cp;
1397 else if (IsEqualGUID( riid, &IID_INetworkCostManagerEvents ))
1398 ret = &This->cost_mgr_cp;
1399 else if (IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
1400 ret = &This->conn_mgr_cp;
1401 else if (IsEqualGUID( riid, &IID_INetworkEvents))
1402 ret = &This->events_cp;
1403 else
1405 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1406 *cp = NULL;
1407 return E_NOINTERFACE;
1410 IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface );
1411 return S_OK;
1414 static const struct IConnectionPointContainerVtbl cpc_vtbl =
1416 ConnectionPointContainer_QueryInterface,
1417 ConnectionPointContainer_AddRef,
1418 ConnectionPointContainer_Release,
1419 ConnectionPointContainer_EnumConnectionPoints,
1420 ConnectionPointContainer_FindConnectionPoint
1423 static inline struct connection *impl_from_INetworkConnection(
1424 INetworkConnection *iface )
1426 return CONTAINING_RECORD( iface, struct connection, INetworkConnection_iface );
1429 static HRESULT WINAPI connection_QueryInterface(
1430 INetworkConnection *iface, REFIID riid, void **obj )
1432 struct connection *connection = impl_from_INetworkConnection( iface );
1434 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
1436 if (IsEqualIID( riid, &IID_INetworkConnection ) ||
1437 IsEqualIID( riid, &IID_IDispatch ) ||
1438 IsEqualIID( riid, &IID_IUnknown ))
1440 *obj = iface;
1442 else if (IsEqualIID( riid, &IID_INetworkConnectionCost ))
1444 *obj = &connection->INetworkConnectionCost_iface;
1446 else
1448 WARN( "interface not supported %s\n", debugstr_guid(riid) );
1449 *obj = NULL;
1450 return E_NOINTERFACE;
1452 INetworkConnection_AddRef( iface );
1453 return S_OK;
1456 static ULONG WINAPI connection_AddRef(
1457 INetworkConnection *iface )
1459 struct connection *connection = impl_from_INetworkConnection( iface );
1461 TRACE( "%p\n", connection );
1462 return InterlockedIncrement( &connection->refs );
1465 static ULONG WINAPI connection_Release(
1466 INetworkConnection *iface )
1468 struct connection *connection = impl_from_INetworkConnection( iface );
1469 LONG refs;
1471 TRACE( "%p\n", connection );
1473 if (!(refs = InterlockedDecrement( &connection->refs )))
1475 INetwork_Release( connection->network );
1476 list_remove( &connection->entry );
1477 heap_free( connection );
1479 return refs;
1482 static HRESULT WINAPI connection_GetTypeInfoCount(
1483 INetworkConnection *iface,
1484 UINT *count )
1486 FIXME("\n");
1487 return E_NOTIMPL;
1490 static HRESULT WINAPI connection_GetTypeInfo(
1491 INetworkConnection *iface,
1492 UINT index,
1493 LCID lcid,
1494 ITypeInfo **info )
1496 FIXME("\n");
1497 return E_NOTIMPL;
1500 static HRESULT WINAPI connection_GetIDsOfNames(
1501 INetworkConnection *iface,
1502 REFIID riid,
1503 LPOLESTR *names,
1504 UINT count,
1505 LCID lcid,
1506 DISPID *dispid )
1508 FIXME("\n");
1509 return E_NOTIMPL;
1512 static HRESULT WINAPI connection_Invoke(
1513 INetworkConnection *iface,
1514 DISPID member,
1515 REFIID riid,
1516 LCID lcid,
1517 WORD flags,
1518 DISPPARAMS *params,
1519 VARIANT *result,
1520 EXCEPINFO *excep_info,
1521 UINT *arg_err )
1523 FIXME("\n");
1524 return E_NOTIMPL;
1527 static HRESULT WINAPI connection_GetNetwork(
1528 INetworkConnection *iface,
1529 INetwork **ppNetwork )
1531 struct connection *connection = impl_from_INetworkConnection( iface );
1533 TRACE( "%p, %p\n", iface, ppNetwork );
1535 *ppNetwork = connection->network;
1536 INetwork_AddRef( *ppNetwork );
1537 return S_OK;
1540 static HRESULT WINAPI connection_get_IsConnectedToInternet(
1541 INetworkConnection *iface,
1542 VARIANT_BOOL *pbIsConnected )
1544 struct connection *connection = impl_from_INetworkConnection( iface );
1546 TRACE( "%p, %p\n", iface, pbIsConnected );
1548 *pbIsConnected = connection->connected_to_internet;
1549 return S_OK;
1552 static HRESULT WINAPI connection_get_IsConnected(
1553 INetworkConnection *iface,
1554 VARIANT_BOOL *pbIsConnected )
1556 struct connection *connection = impl_from_INetworkConnection( iface );
1558 TRACE( "%p, %p\n", iface, pbIsConnected );
1560 *pbIsConnected = connection->connected;
1561 return S_OK;
1564 static HRESULT WINAPI connection_GetConnectivity(
1565 INetworkConnection *iface,
1566 NLM_CONNECTIVITY *pConnectivity )
1568 FIXME( "%p, %p\n", iface, pConnectivity );
1570 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1571 return S_OK;
1574 static HRESULT WINAPI connection_GetConnectionId(
1575 INetworkConnection *iface,
1576 GUID *pgdConnectionId )
1578 struct connection *connection = impl_from_INetworkConnection( iface );
1580 TRACE( "%p, %p\n", iface, pgdConnectionId );
1582 *pgdConnectionId = connection->id;
1583 return S_OK;
1586 static HRESULT WINAPI connection_GetAdapterId(
1587 INetworkConnection *iface,
1588 GUID *pgdAdapterId )
1590 struct connection *connection = impl_from_INetworkConnection( iface );
1592 FIXME( "%p, %p\n", iface, pgdAdapterId );
1594 *pgdAdapterId = connection->id;
1595 return S_OK;
1598 static HRESULT WINAPI connection_GetDomainType(
1599 INetworkConnection *iface,
1600 NLM_DOMAIN_TYPE *pDomainType )
1602 FIXME( "%p, %p\n", iface, pDomainType );
1604 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
1605 return S_OK;
1608 static const struct INetworkConnectionVtbl connection_vtbl =
1610 connection_QueryInterface,
1611 connection_AddRef,
1612 connection_Release,
1613 connection_GetTypeInfoCount,
1614 connection_GetTypeInfo,
1615 connection_GetIDsOfNames,
1616 connection_Invoke,
1617 connection_GetNetwork,
1618 connection_get_IsConnectedToInternet,
1619 connection_get_IsConnected,
1620 connection_GetConnectivity,
1621 connection_GetConnectionId,
1622 connection_GetAdapterId,
1623 connection_GetDomainType
1626 static inline struct connection *impl_from_INetworkConnectionCost(
1627 INetworkConnectionCost *iface )
1629 return CONTAINING_RECORD( iface, struct connection, INetworkConnectionCost_iface );
1632 static HRESULT WINAPI connection_cost_QueryInterface(
1633 INetworkConnectionCost *iface,
1634 REFIID riid,
1635 void **obj )
1637 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1638 return INetworkConnection_QueryInterface( &conn->INetworkConnection_iface, riid, obj );
1641 static ULONG WINAPI connection_cost_AddRef(
1642 INetworkConnectionCost *iface )
1644 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1645 return INetworkConnection_AddRef( &conn->INetworkConnection_iface );
1648 static ULONG WINAPI connection_cost_Release(
1649 INetworkConnectionCost *iface )
1651 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1652 return INetworkConnection_Release( &conn->INetworkConnection_iface );
1655 static HRESULT WINAPI connection_cost_GetCost(
1656 INetworkConnectionCost *iface, DWORD *pCost )
1658 FIXME( "%p, %p\n", iface, pCost );
1660 if (!pCost) return E_POINTER;
1662 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
1663 return S_OK;
1666 static HRESULT WINAPI connection_cost_GetDataPlanStatus(
1667 INetworkConnectionCost *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus )
1669 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1671 FIXME( "%p, %p\n", iface, pDataPlanStatus );
1673 if (!pDataPlanStatus) return E_POINTER;
1675 memcpy( &pDataPlanStatus->InterfaceGuid, &conn->id, sizeof(conn->id) );
1676 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1677 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
1678 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1679 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1680 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1681 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
1682 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1683 pDataPlanStatus->Reserved = 0;
1685 return S_OK;
1688 static const INetworkConnectionCostVtbl connection_cost_vtbl =
1690 connection_cost_QueryInterface,
1691 connection_cost_AddRef,
1692 connection_cost_Release,
1693 connection_cost_GetCost,
1694 connection_cost_GetDataPlanStatus
1697 static struct connection *create_connection( const GUID *id )
1699 struct connection *ret;
1701 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
1703 ret->INetworkConnection_iface.lpVtbl = &connection_vtbl;
1704 ret->INetworkConnectionCost_iface.lpVtbl = &connection_cost_vtbl;
1705 ret->refs = 1;
1706 ret->id = *id;
1707 ret->network = NULL;
1708 ret->connected = VARIANT_FALSE;
1709 ret->connected_to_internet = VARIANT_FALSE;
1710 list_init( &ret->entry );
1712 return ret;
1715 static void init_networks( struct list_manager *mgr )
1717 DWORD size = 0;
1718 IP_ADAPTER_ADDRESSES *buf, *aa;
1719 GUID id;
1720 ULONG ret, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
1721 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_GATEWAYS;
1723 list_init( &mgr->networks );
1724 list_init( &mgr->connections );
1726 ret = GetAdaptersAddresses( AF_UNSPEC, flags, NULL, NULL, &size );
1727 if (ret != ERROR_BUFFER_OVERFLOW) return;
1729 if (!(buf = heap_alloc( size ))) return;
1730 if (GetAdaptersAddresses( AF_UNSPEC, flags, NULL, buf, &size ))
1732 heap_free( buf );
1733 return;
1736 memset( &id, 0, sizeof(id) );
1737 for (aa = buf; aa; aa = aa->Next)
1739 struct network *network;
1740 struct connection *connection;
1741 NET_LUID luid;
1743 ConvertInterfaceIndexToLuid(aa->u.s.IfIndex, &luid);
1744 ConvertInterfaceLuidToGuid(&luid, &id);
1746 /* assume a one-to-one mapping between networks and connections */
1747 if (!(network = create_network( &id ))) goto done;
1748 if (!(connection = create_connection( &id )))
1750 INetwork_Release( &network->INetwork_iface );
1751 goto done;
1754 if (aa->FirstUnicastAddress)
1756 network->connected = VARIANT_TRUE;
1757 connection->connected = VARIANT_TRUE;
1759 if (aa->FirstGatewayAddress)
1761 network->connected_to_internet = VARIANT_TRUE;
1762 connection->connected_to_internet = VARIANT_TRUE;
1765 connection->network = &network->INetwork_iface;
1766 INetwork_AddRef( connection->network );
1768 list_add_tail( &mgr->networks, &network->entry );
1769 list_add_tail( &mgr->connections, &connection->entry );
1772 done:
1773 heap_free( buf );
1776 HRESULT list_manager_create( void **obj )
1778 struct list_manager *mgr;
1780 TRACE( "%p\n", obj );
1782 if (!(mgr = heap_alloc( sizeof(*mgr) ))) return E_OUTOFMEMORY;
1783 mgr->INetworkListManager_iface.lpVtbl = &list_manager_vtbl;
1784 mgr->INetworkCostManager_iface.lpVtbl = &cost_manager_vtbl;
1785 mgr->IConnectionPointContainer_iface.lpVtbl = &cpc_vtbl;
1786 init_networks( mgr );
1787 mgr->refs = 1;
1789 connection_point_init( &mgr->list_mgr_cp, &IID_INetworkListManagerEvents,
1790 &mgr->IConnectionPointContainer_iface );
1791 connection_point_init( &mgr->cost_mgr_cp, &IID_INetworkCostManagerEvents,
1792 &mgr->IConnectionPointContainer_iface);
1793 connection_point_init( &mgr->conn_mgr_cp, &IID_INetworkConnectionEvents,
1794 &mgr->IConnectionPointContainer_iface );
1795 connection_point_init( &mgr->events_cp, &IID_INetworkEvents,
1796 &mgr->IConnectionPointContainer_iface );
1798 *obj = &mgr->INetworkListManager_iface;
1799 TRACE( "returning iface %p\n", *obj );
1800 return S_OK;