dbghelp: Remove DMT_ entries for .DBG and .PDB files.
[wine.git] / dlls / netprofm / list.c
blobcb65484485bd12106664dc248b78c5f0be804720
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
22 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winsock2.h"
26 #include "ws2ipdef.h"
27 #include "iphlpapi.h"
28 #include "ifdef.h"
29 #include "netioapi.h"
30 #include "initguid.h"
31 #include "objbase.h"
32 #include "ocidl.h"
33 #include "netlistmgr.h"
34 #include "olectl.h"
36 #include "wine/debug.h"
37 #include "wine/list.h"
38 #include "netprofm_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(netprofm);
42 struct network
44 INetwork INetwork_iface;
45 LONG refs;
46 struct list entry;
47 GUID id;
48 INetworkListManager *mgr;
49 VARIANT_BOOL connected_to_internet;
50 VARIANT_BOOL connected;
53 struct connection
55 INetworkConnection INetworkConnection_iface;
56 INetworkConnectionCost INetworkConnectionCost_iface;
57 LONG refs;
58 struct list entry;
59 GUID id;
60 INetwork *network;
61 VARIANT_BOOL connected_to_internet;
62 VARIANT_BOOL connected;
65 struct connection_point
67 IConnectionPoint IConnectionPoint_iface;
68 IConnectionPointContainer *container;
69 IID iid;
70 struct list sinks;
71 DWORD cookie;
74 struct list_manager
76 INetworkListManager INetworkListManager_iface;
77 INetworkCostManager INetworkCostManager_iface;
78 IConnectionPointContainer IConnectionPointContainer_iface;
79 LONG refs;
80 struct list networks;
81 struct list connections;
82 struct connection_point list_mgr_cp;
83 struct connection_point cost_mgr_cp;
84 struct connection_point conn_mgr_cp;
85 struct connection_point events_cp;
88 struct sink_entry
90 struct list entry;
91 DWORD cookie;
92 IUnknown *unk;
95 static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
97 return CONTAINING_RECORD(iface, struct list_manager, IConnectionPointContainer_iface);
100 static inline struct list_manager *impl_from_INetworkCostManager(
101 INetworkCostManager *iface )
103 return CONTAINING_RECORD( iface, struct list_manager, INetworkCostManager_iface );
106 static inline struct connection_point *impl_from_IConnectionPoint(
107 IConnectionPoint *iface )
109 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
112 static HRESULT WINAPI connection_point_QueryInterface(
113 IConnectionPoint *iface,
114 REFIID riid,
115 void **obj )
117 struct connection_point *cp = impl_from_IConnectionPoint( iface );
118 TRACE( "%p, %s, %p\n", cp, debugstr_guid(riid), obj );
120 if (IsEqualGUID( riid, &IID_IConnectionPoint ) ||
121 IsEqualGUID( riid, &IID_IUnknown ))
123 *obj = iface;
125 else
127 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
128 *obj = NULL;
129 return E_NOINTERFACE;
131 IConnectionPoint_AddRef( iface );
132 return S_OK;
135 static ULONG WINAPI connection_point_AddRef(
136 IConnectionPoint *iface )
138 struct connection_point *cp = impl_from_IConnectionPoint( iface );
139 return IConnectionPointContainer_AddRef( cp->container );
142 static ULONG WINAPI connection_point_Release(
143 IConnectionPoint *iface )
145 struct connection_point *cp = impl_from_IConnectionPoint( iface );
146 return IConnectionPointContainer_Release( cp->container );
149 static HRESULT WINAPI connection_point_GetConnectionInterface(
150 IConnectionPoint *iface,
151 IID *iid )
153 struct connection_point *cp = impl_from_IConnectionPoint( iface );
154 TRACE( "%p, %p\n", cp, iid );
156 if (!iid)
157 return E_POINTER;
159 memcpy( iid, &cp->iid, sizeof(*iid) );
160 return S_OK;
163 static HRESULT WINAPI connection_point_GetConnectionPointContainer(
164 IConnectionPoint *iface,
165 IConnectionPointContainer **container )
167 struct connection_point *cp = impl_from_IConnectionPoint( iface );
168 TRACE( "%p, %p\n", cp, container );
170 if (!container)
171 return E_POINTER;
173 IConnectionPointContainer_AddRef( cp->container );
174 *container = cp->container;
175 return S_OK;
178 static HRESULT WINAPI connection_point_Advise(
179 IConnectionPoint *iface,
180 IUnknown *sink,
181 DWORD *cookie )
183 struct connection_point *cp = impl_from_IConnectionPoint( iface );
184 struct sink_entry *sink_entry;
185 IUnknown *unk;
186 HRESULT hr;
188 FIXME( "%p, %p, %p - semi-stub\n", cp, sink, cookie );
190 if (!sink || !cookie)
191 return E_POINTER;
193 hr = IUnknown_QueryInterface( sink, &cp->iid, (void**)&unk );
194 if (FAILED(hr))
196 WARN( "iface %s not implemented by sink\n", debugstr_guid(&cp->iid) );
197 return CO_E_FAILEDTOOPENTHREADTOKEN;
200 sink_entry = malloc( sizeof(*sink_entry) );
201 if (!sink_entry)
203 IUnknown_Release( unk );
204 return E_OUTOFMEMORY;
207 sink_entry->unk = unk;
208 *cookie = sink_entry->cookie = ++cp->cookie;
209 list_add_tail( &cp->sinks, &sink_entry->entry );
210 return S_OK;
213 static void sink_entry_release( struct sink_entry *entry )
215 list_remove( &entry->entry );
216 IUnknown_Release( entry->unk );
217 free( entry );
220 static HRESULT WINAPI connection_point_Unadvise(
221 IConnectionPoint *iface,
222 DWORD cookie )
224 struct connection_point *cp = impl_from_IConnectionPoint( iface );
225 struct sink_entry *iter;
227 TRACE( "%p, %ld\n", cp, cookie );
229 LIST_FOR_EACH_ENTRY( iter, &cp->sinks, struct sink_entry, entry )
231 if (iter->cookie != cookie) continue;
232 sink_entry_release( iter );
233 return S_OK;
236 WARN( "invalid cookie\n" );
237 return OLE_E_NOCONNECTION;
240 static HRESULT WINAPI connection_point_EnumConnections(
241 IConnectionPoint *iface,
242 IEnumConnections **connections )
244 struct connection_point *cp = impl_from_IConnectionPoint( iface );
245 FIXME( "%p, %p - stub\n", cp, connections );
247 return E_NOTIMPL;
250 static const IConnectionPointVtbl connection_point_vtbl =
252 connection_point_QueryInterface,
253 connection_point_AddRef,
254 connection_point_Release,
255 connection_point_GetConnectionInterface,
256 connection_point_GetConnectionPointContainer,
257 connection_point_Advise,
258 connection_point_Unadvise,
259 connection_point_EnumConnections
262 static void connection_point_init(
263 struct connection_point *cp,
264 REFIID riid,
265 IConnectionPointContainer *container )
267 cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
268 cp->container = container;
269 cp->cookie = 0;
270 cp->iid = *riid;
271 list_init( &cp->sinks );
274 static void connection_point_release( struct connection_point *cp )
276 while (!list_empty( &cp->sinks ))
277 sink_entry_release( LIST_ENTRY( list_head( &cp->sinks ), struct sink_entry, entry ) );
280 static inline struct network *impl_from_INetwork(
281 INetwork *iface )
283 return CONTAINING_RECORD( iface, struct network, INetwork_iface );
286 static HRESULT WINAPI network_QueryInterface(
287 INetwork *iface, REFIID riid, void **obj )
289 struct network *network = impl_from_INetwork( iface );
291 TRACE( "%p, %s, %p\n", network, debugstr_guid(riid), obj );
293 if (IsEqualIID( riid, &IID_INetwork ) ||
294 IsEqualIID( riid, &IID_IDispatch ) ||
295 IsEqualIID( riid, &IID_IUnknown ))
297 *obj = iface;
298 INetwork_AddRef( iface );
299 return S_OK;
301 else
303 WARN( "interface not supported %s\n", debugstr_guid(riid) );
304 *obj = NULL;
305 return E_NOINTERFACE;
309 static ULONG WINAPI network_AddRef(
310 INetwork *iface )
312 struct network *network = impl_from_INetwork( iface );
314 TRACE( "%p\n", network );
315 return InterlockedIncrement( &network->refs );
318 static ULONG WINAPI network_Release(
319 INetwork *iface )
321 struct network *network = impl_from_INetwork( iface );
322 LONG refs;
324 TRACE( "%p\n", network );
326 if (!(refs = InterlockedDecrement( &network->refs )))
328 list_remove( &network->entry );
329 INetworkListManager_Release( network->mgr );
330 free( network );
332 return refs;
335 static HRESULT WINAPI network_GetTypeInfoCount(
336 INetwork *iface,
337 UINT *count )
339 FIXME("\n");
340 return E_NOTIMPL;
343 static HRESULT WINAPI network_GetTypeInfo(
344 INetwork *iface,
345 UINT index,
346 LCID lcid,
347 ITypeInfo **info )
349 FIXME("\n");
350 return E_NOTIMPL;
353 static HRESULT WINAPI network_GetIDsOfNames(
354 INetwork *iface,
355 REFIID riid,
356 LPOLESTR *names,
357 UINT count,
358 LCID lcid,
359 DISPID *dispid )
361 FIXME("\n");
362 return E_NOTIMPL;
365 static HRESULT WINAPI network_Invoke(
366 INetwork *iface,
367 DISPID member,
368 REFIID riid,
369 LCID lcid,
370 WORD flags,
371 DISPPARAMS *params,
372 VARIANT *result,
373 EXCEPINFO *excep_info,
374 UINT *arg_err )
376 FIXME("\n");
377 return E_NOTIMPL;
380 static HRESULT WINAPI network_GetName(
381 INetwork *iface,
382 BSTR *pszNetworkName )
384 FIXME( "%p, %p\n", iface, pszNetworkName );
385 return E_NOTIMPL;
388 static HRESULT WINAPI network_SetName(
389 INetwork *iface,
390 BSTR szNetworkNewName )
392 FIXME( "%p, %s\n", iface, debugstr_w(szNetworkNewName) );
393 return E_NOTIMPL;
396 static HRESULT WINAPI network_GetDescription(
397 INetwork *iface,
398 BSTR *pszDescription )
400 FIXME( "%p, %p\n", iface, pszDescription );
401 return E_NOTIMPL;
404 static HRESULT WINAPI network_SetDescription(
405 INetwork *iface,
406 BSTR szDescription )
408 FIXME( "%p, %s\n", iface, debugstr_w(szDescription) );
409 return E_NOTIMPL;
412 static HRESULT WINAPI network_GetNetworkId(
413 INetwork *iface,
414 GUID *pgdGuidNetworkId )
416 struct network *network = impl_from_INetwork( iface );
418 TRACE( "%p, %p\n", iface, pgdGuidNetworkId );
420 *pgdGuidNetworkId = network->id;
421 return S_OK;
424 static HRESULT WINAPI network_GetDomainType(
425 INetwork *iface,
426 NLM_DOMAIN_TYPE *pDomainType )
428 FIXME( "%p, %p\n", iface, pDomainType );
430 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
431 return S_OK;
434 static inline struct list_manager *impl_from_INetworkListManager(
435 INetworkListManager *iface )
437 return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface );
440 static HRESULT create_connections_enum(
441 struct list_manager *, IEnumNetworkConnections** );
443 static HRESULT WINAPI network_GetNetworkConnections(
444 INetwork *iface,
445 IEnumNetworkConnections **ppEnum )
447 struct network *network = impl_from_INetwork( iface );
448 struct list_manager *mgr = impl_from_INetworkListManager( network->mgr );
450 TRACE( "%p, %p\n", iface, ppEnum );
451 return create_connections_enum( mgr, ppEnum );
454 static HRESULT WINAPI network_GetTimeCreatedAndConnected(
455 INetwork *iface,
456 DWORD *pdwLowDateTimeCreated,
457 DWORD *pdwHighDateTimeCreated,
458 DWORD *pdwLowDateTimeConnected,
459 DWORD *pdwHighDateTimeConnected )
461 FIXME( "%p, %p, %p, %p, %p\n", iface, pdwLowDateTimeCreated, pdwHighDateTimeCreated,
462 pdwLowDateTimeConnected, pdwHighDateTimeConnected );
463 return E_NOTIMPL;
466 static HRESULT WINAPI network_get_IsConnectedToInternet(
467 INetwork *iface,
468 VARIANT_BOOL *pbIsConnected )
470 struct network *network = impl_from_INetwork( iface );
472 TRACE( "%p, %p\n", iface, pbIsConnected );
474 *pbIsConnected = network->connected_to_internet;
475 return S_OK;
478 static HRESULT WINAPI network_get_IsConnected(
479 INetwork *iface,
480 VARIANT_BOOL *pbIsConnected )
482 struct network *network = impl_from_INetwork( iface );
484 TRACE( "%p, %p\n", iface, pbIsConnected );
486 *pbIsConnected = network->connected;
487 return S_OK;
490 static HRESULT WINAPI network_GetConnectivity(
491 INetwork *iface,
492 NLM_CONNECTIVITY *pConnectivity )
494 struct network *network = impl_from_INetwork( iface );
496 FIXME( "%p, %p\n", iface, pConnectivity );
498 *pConnectivity = NLM_CONNECTIVITY_DISCONNECTED;
500 if (network->connected_to_internet)
501 *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET;
502 else if (network->connected)
503 *pConnectivity |= NLM_CONNECTIVITY_IPV4_LOCALNETWORK;
505 return S_OK;
508 static HRESULT WINAPI network_GetCategory(
509 INetwork *iface,
510 NLM_NETWORK_CATEGORY *pCategory )
512 FIXME( "%p, %p\n", iface, pCategory );
514 *pCategory = NLM_NETWORK_CATEGORY_PUBLIC;
515 return S_OK;
518 static HRESULT WINAPI network_SetCategory(
519 INetwork *iface,
520 NLM_NETWORK_CATEGORY NewCategory )
522 FIXME( "%p, %u\n", iface, NewCategory );
523 return E_NOTIMPL;
526 static const struct INetworkVtbl network_vtbl =
528 network_QueryInterface,
529 network_AddRef,
530 network_Release,
531 network_GetTypeInfoCount,
532 network_GetTypeInfo,
533 network_GetIDsOfNames,
534 network_Invoke,
535 network_GetName,
536 network_SetName,
537 network_GetDescription,
538 network_SetDescription,
539 network_GetNetworkId,
540 network_GetDomainType,
541 network_GetNetworkConnections,
542 network_GetTimeCreatedAndConnected,
543 network_get_IsConnectedToInternet,
544 network_get_IsConnected,
545 network_GetConnectivity,
546 network_GetCategory,
547 network_SetCategory
550 static struct network *create_network( const GUID *id )
552 struct network *ret;
554 if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL;
556 ret->INetwork_iface.lpVtbl = &network_vtbl;
557 ret->refs = 1;
558 ret->id = *id;
559 ret->connected = VARIANT_FALSE;
560 ret->connected_to_internet = VARIANT_FALSE;
561 list_init( &ret->entry );
563 return ret;
566 static HRESULT WINAPI cost_manager_QueryInterface(
567 INetworkCostManager *iface,
568 REFIID riid,
569 void **obj )
571 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
572 return INetworkListManager_QueryInterface( &mgr->INetworkListManager_iface, riid, obj );
575 static ULONG WINAPI cost_manager_AddRef(
576 INetworkCostManager *iface )
578 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
579 return INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
582 static ULONG WINAPI cost_manager_Release(
583 INetworkCostManager *iface )
585 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
586 return INetworkListManager_Release( &mgr->INetworkListManager_iface );
589 static HRESULT WINAPI cost_manager_GetCost(
590 INetworkCostManager *iface, DWORD *pCost, NLM_SOCKADDR *pDestIPAddr)
592 FIXME( "%p, %p, %p\n", iface, pCost, pDestIPAddr );
594 if (!pCost) return E_POINTER;
596 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
597 return S_OK;
600 static BOOL map_address_6to4( const SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
602 ULONG i;
604 if (addr6->sin6_family != AF_INET6) return FALSE;
606 for (i = 0; i < 5; i++)
607 if (addr6->sin6_addr.u.Word[i]) return FALSE;
609 if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
611 addr4->sin_family = AF_INET;
612 addr4->sin_port = addr6->sin6_port;
613 addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
614 memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
616 return TRUE;
619 static HRESULT WINAPI cost_manager_GetDataPlanStatus(
620 INetworkCostManager *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus,
621 NLM_SOCKADDR *pDestIPAddr)
623 DWORD ret, index;
624 NET_LUID luid;
625 SOCKADDR *dst = (SOCKADDR *)pDestIPAddr;
626 SOCKADDR_IN addr4, *dst4;
628 FIXME( "%p, %p, %p\n", iface, pDataPlanStatus, pDestIPAddr );
630 if (!pDataPlanStatus) return E_POINTER;
632 if (dst && ((dst->sa_family == AF_INET && (dst4 = (SOCKADDR_IN *)dst)) ||
633 ((dst->sa_family == AF_INET6 && map_address_6to4( (const SOCKADDR_IN6 *)dst, &addr4 )
634 && (dst4 = &addr4)))))
636 if ((ret = GetBestInterface( dst4->sin_addr.S_un.S_addr, &index )))
637 return HRESULT_FROM_WIN32( ret );
639 if ((ret = ConvertInterfaceIndexToLuid( index, &luid )))
640 return HRESULT_FROM_WIN32( ret );
642 if ((ret = ConvertInterfaceLuidToGuid( &luid, &pDataPlanStatus->InterfaceGuid )))
643 return HRESULT_FROM_WIN32( ret );
645 else
647 FIXME( "interface guid not found\n" );
648 memset( &pDataPlanStatus->InterfaceGuid, 0, sizeof(pDataPlanStatus->InterfaceGuid) );
651 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
652 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
653 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
654 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
655 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
656 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
657 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
658 pDataPlanStatus->Reserved = 0;
660 return S_OK;
663 static HRESULT WINAPI cost_manager_SetDestinationAddresses(
664 INetworkCostManager *iface, UINT32 length, NLM_SOCKADDR *pDestIPAddrList,
665 VARIANT_BOOL bAppend)
667 FIXME( "%p, %u, %p, %x\n", iface, length, pDestIPAddrList, bAppend );
668 return E_NOTIMPL;
671 static const INetworkCostManagerVtbl cost_manager_vtbl =
673 cost_manager_QueryInterface,
674 cost_manager_AddRef,
675 cost_manager_Release,
676 cost_manager_GetCost,
677 cost_manager_GetDataPlanStatus,
678 cost_manager_SetDestinationAddresses
681 struct networks_enum
683 IEnumNetworks IEnumNetworks_iface;
684 LONG refs;
685 struct list_manager *mgr;
686 struct list *cursor;
689 static inline struct networks_enum *impl_from_IEnumNetworks(
690 IEnumNetworks *iface )
692 return CONTAINING_RECORD( iface, struct networks_enum, IEnumNetworks_iface );
695 static HRESULT WINAPI networks_enum_QueryInterface(
696 IEnumNetworks *iface, REFIID riid, void **obj )
698 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
700 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
702 if (IsEqualIID( riid, &IID_IEnumNetworks ) ||
703 IsEqualIID( riid, &IID_IDispatch ) ||
704 IsEqualIID( riid, &IID_IUnknown ))
706 *obj = iface;
707 IEnumNetworks_AddRef( iface );
708 return S_OK;
710 else
712 WARN( "interface not supported %s\n", debugstr_guid(riid) );
713 *obj = NULL;
714 return E_NOINTERFACE;
718 static ULONG WINAPI networks_enum_AddRef(
719 IEnumNetworks *iface )
721 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
723 TRACE( "%p\n", iter );
724 return InterlockedIncrement( &iter->refs );
727 static ULONG WINAPI networks_enum_Release(
728 IEnumNetworks *iface )
730 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
731 LONG refs;
733 TRACE( "%p\n", iter );
735 if (!(refs = InterlockedDecrement( &iter->refs )))
737 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
738 free( iter );
740 return refs;
743 static HRESULT WINAPI networks_enum_GetTypeInfoCount(
744 IEnumNetworks *iface,
745 UINT *count )
747 FIXME("\n");
748 return E_NOTIMPL;
751 static HRESULT WINAPI networks_enum_GetTypeInfo(
752 IEnumNetworks *iface,
753 UINT index,
754 LCID lcid,
755 ITypeInfo **info )
757 FIXME("\n");
758 return E_NOTIMPL;
761 static HRESULT WINAPI networks_enum_GetIDsOfNames(
762 IEnumNetworks *iface,
763 REFIID riid,
764 LPOLESTR *names,
765 UINT count,
766 LCID lcid,
767 DISPID *dispid )
769 FIXME("\n");
770 return E_NOTIMPL;
773 static HRESULT WINAPI networks_enum_Invoke(
774 IEnumNetworks *iface,
775 DISPID member,
776 REFIID riid,
777 LCID lcid,
778 WORD flags,
779 DISPPARAMS *params,
780 VARIANT *result,
781 EXCEPINFO *excep_info,
782 UINT *arg_err )
784 FIXME("\n");
785 return E_NOTIMPL;
788 static HRESULT WINAPI networks_enum_get__NewEnum(
789 IEnumNetworks *iface, IEnumVARIANT **ppEnumVar )
791 FIXME("\n");
792 return E_NOTIMPL;
795 static HRESULT WINAPI networks_enum_Next(
796 IEnumNetworks *iface, ULONG count, INetwork **ret, ULONG *fetched )
798 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
799 ULONG i = 0;
801 TRACE( "%p, %lu %p %p\n", iter, count, ret, fetched );
803 if (fetched) *fetched = 0;
804 if (!count) return S_OK;
806 while (iter->cursor && i < count)
808 struct network *network = LIST_ENTRY( iter->cursor, struct network, entry );
809 ret[i] = &network->INetwork_iface;
810 INetwork_AddRef( ret[i] );
811 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
812 i++;
814 if (fetched) *fetched = i;
816 return i < count ? S_FALSE : S_OK;
819 static HRESULT WINAPI networks_enum_Skip(
820 IEnumNetworks *iface, ULONG count )
822 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
824 TRACE( "%p, %lu\n", iter, count);
826 if (!count) return S_OK;
827 if (!iter->cursor) return S_FALSE;
829 while (count--)
831 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
832 if (!iter->cursor) break;
835 return count ? S_FALSE : S_OK;
838 static HRESULT WINAPI networks_enum_Reset(
839 IEnumNetworks *iface )
841 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
843 TRACE( "%p\n", iter );
845 iter->cursor = list_head( &iter->mgr->networks );
846 return S_OK;
849 static HRESULT create_networks_enum(
850 struct list_manager *, IEnumNetworks** );
852 static HRESULT WINAPI networks_enum_Clone(
853 IEnumNetworks *iface, IEnumNetworks **ret )
855 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
857 TRACE( "%p, %p\n", iter, ret );
858 return create_networks_enum( iter->mgr, ret );
861 static const IEnumNetworksVtbl networks_enum_vtbl =
863 networks_enum_QueryInterface,
864 networks_enum_AddRef,
865 networks_enum_Release,
866 networks_enum_GetTypeInfoCount,
867 networks_enum_GetTypeInfo,
868 networks_enum_GetIDsOfNames,
869 networks_enum_Invoke,
870 networks_enum_get__NewEnum,
871 networks_enum_Next,
872 networks_enum_Skip,
873 networks_enum_Reset,
874 networks_enum_Clone
877 static HRESULT create_networks_enum(
878 struct list_manager *mgr, IEnumNetworks **ret )
880 struct networks_enum *iter;
882 *ret = NULL;
883 if (!(iter = calloc( 1, sizeof(*iter) ))) return E_OUTOFMEMORY;
885 iter->IEnumNetworks_iface.lpVtbl = &networks_enum_vtbl;
886 iter->cursor = list_head( &mgr->networks );
887 iter->mgr = mgr;
888 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
889 iter->refs = 1;
891 *ret = &iter->IEnumNetworks_iface;
892 return S_OK;
895 struct connections_enum
897 IEnumNetworkConnections IEnumNetworkConnections_iface;
898 LONG refs;
899 struct list_manager *mgr;
900 struct list *cursor;
903 static inline struct connections_enum *impl_from_IEnumNetworkConnections(
904 IEnumNetworkConnections *iface )
906 return CONTAINING_RECORD( iface, struct connections_enum, IEnumNetworkConnections_iface );
909 static HRESULT WINAPI connections_enum_QueryInterface(
910 IEnumNetworkConnections *iface, REFIID riid, void **obj )
912 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
914 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
916 if (IsEqualIID( riid, &IID_IEnumNetworkConnections ) ||
917 IsEqualIID( riid, &IID_IDispatch ) ||
918 IsEqualIID( riid, &IID_IUnknown ))
920 *obj = iface;
921 IEnumNetworkConnections_AddRef( iface );
922 return S_OK;
924 else
926 WARN( "interface not supported %s\n", debugstr_guid(riid) );
927 *obj = NULL;
928 return E_NOINTERFACE;
932 static ULONG WINAPI connections_enum_AddRef(
933 IEnumNetworkConnections *iface )
935 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
937 TRACE( "%p\n", iter );
938 return InterlockedIncrement( &iter->refs );
941 static ULONG WINAPI connections_enum_Release(
942 IEnumNetworkConnections *iface )
944 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
945 LONG refs;
947 TRACE( "%p\n", iter );
949 if (!(refs = InterlockedDecrement( &iter->refs )))
951 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
952 free( iter );
954 return refs;
957 static HRESULT WINAPI connections_enum_GetTypeInfoCount(
958 IEnumNetworkConnections *iface,
959 UINT *count )
961 FIXME("\n");
962 return E_NOTIMPL;
965 static HRESULT WINAPI connections_enum_GetTypeInfo(
966 IEnumNetworkConnections *iface,
967 UINT index,
968 LCID lcid,
969 ITypeInfo **info )
971 FIXME("\n");
972 return E_NOTIMPL;
975 static HRESULT WINAPI connections_enum_GetIDsOfNames(
976 IEnumNetworkConnections *iface,
977 REFIID riid,
978 LPOLESTR *names,
979 UINT count,
980 LCID lcid,
981 DISPID *dispid )
983 FIXME("\n");
984 return E_NOTIMPL;
987 static HRESULT WINAPI connections_enum_Invoke(
988 IEnumNetworkConnections *iface,
989 DISPID member,
990 REFIID riid,
991 LCID lcid,
992 WORD flags,
993 DISPPARAMS *params,
994 VARIANT *result,
995 EXCEPINFO *excep_info,
996 UINT *arg_err )
998 FIXME("\n");
999 return E_NOTIMPL;
1002 static HRESULT WINAPI connections_enum_get__NewEnum(
1003 IEnumNetworkConnections *iface, IEnumVARIANT **ppEnumVar )
1005 FIXME("\n");
1006 return E_NOTIMPL;
1009 static HRESULT WINAPI connections_enum_Next(
1010 IEnumNetworkConnections *iface, ULONG count, INetworkConnection **ret, ULONG *fetched )
1012 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1013 ULONG i = 0;
1015 TRACE( "%p, %lu %p %p\n", iter, count, ret, fetched );
1017 if (!ret) return E_POINTER;
1018 *ret = NULL;
1019 if (fetched) *fetched = 0;
1020 if (!count) return S_OK;
1022 while (iter->cursor && i < count)
1024 struct connection *connection = LIST_ENTRY( iter->cursor, struct connection, entry );
1025 ret[i] = &connection->INetworkConnection_iface;
1026 INetworkConnection_AddRef( ret[i] );
1027 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1028 i++;
1030 if (fetched) *fetched = i;
1032 return i < count ? S_FALSE : S_OK;
1035 static HRESULT WINAPI connections_enum_Skip(
1036 IEnumNetworkConnections *iface, ULONG count )
1038 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1040 TRACE( "%p, %lu\n", iter, count);
1042 if (!count) return S_OK;
1043 if (!iter->cursor) return S_FALSE;
1045 while (count--)
1047 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1048 if (!iter->cursor) break;
1051 return count ? S_FALSE : S_OK;
1054 static HRESULT WINAPI connections_enum_Reset(
1055 IEnumNetworkConnections *iface )
1057 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1059 TRACE( "%p\n", iter );
1061 iter->cursor = list_head( &iter->mgr->connections );
1062 return S_OK;
1065 static HRESULT WINAPI connections_enum_Clone(
1066 IEnumNetworkConnections *iface, IEnumNetworkConnections **ret )
1068 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1070 TRACE( "%p, %p\n", iter, ret );
1071 return create_connections_enum( iter->mgr, ret );
1074 static const IEnumNetworkConnectionsVtbl connections_enum_vtbl =
1076 connections_enum_QueryInterface,
1077 connections_enum_AddRef,
1078 connections_enum_Release,
1079 connections_enum_GetTypeInfoCount,
1080 connections_enum_GetTypeInfo,
1081 connections_enum_GetIDsOfNames,
1082 connections_enum_Invoke,
1083 connections_enum_get__NewEnum,
1084 connections_enum_Next,
1085 connections_enum_Skip,
1086 connections_enum_Reset,
1087 connections_enum_Clone
1090 static HRESULT create_connections_enum(
1091 struct list_manager *mgr, IEnumNetworkConnections **ret )
1093 struct connections_enum *iter;
1095 *ret = NULL;
1096 if (!(iter = calloc( 1, sizeof(*iter) ))) return E_OUTOFMEMORY;
1098 iter->IEnumNetworkConnections_iface.lpVtbl = &connections_enum_vtbl;
1099 iter->mgr = mgr;
1100 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
1101 iter->cursor = list_head( &iter->mgr->connections );
1102 iter->refs = 1;
1104 *ret = &iter->IEnumNetworkConnections_iface;
1105 return S_OK;
1108 static ULONG WINAPI list_manager_AddRef(
1109 INetworkListManager *iface )
1111 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1112 return InterlockedIncrement( &mgr->refs );
1115 static ULONG WINAPI list_manager_Release(
1116 INetworkListManager *iface )
1118 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1119 LONG refs = InterlockedDecrement( &mgr->refs );
1120 if (!refs)
1122 struct network *network, *next_network;
1123 struct connection *connection, *next_connection;
1125 TRACE( "destroying %p\n", mgr );
1127 connection_point_release( &mgr->events_cp );
1128 connection_point_release( &mgr->conn_mgr_cp );
1129 connection_point_release( &mgr->cost_mgr_cp );
1130 connection_point_release( &mgr->list_mgr_cp );
1131 LIST_FOR_EACH_ENTRY_SAFE( connection, next_connection, &mgr->connections, struct connection, entry )
1133 INetworkConnection_Release( &connection->INetworkConnection_iface );
1135 LIST_FOR_EACH_ENTRY_SAFE( network, next_network, &mgr->networks, struct network, entry )
1137 INetwork_Release( &network->INetwork_iface );
1139 free( mgr );
1141 return refs;
1144 static HRESULT WINAPI list_manager_QueryInterface(
1145 INetworkListManager *iface,
1146 REFIID riid,
1147 void **obj )
1149 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1151 TRACE( "%p, %s, %p\n", mgr, debugstr_guid(riid), obj );
1153 if (IsEqualGUID( riid, &IID_INetworkListManager ) ||
1154 IsEqualGUID( riid, &IID_IDispatch ) ||
1155 IsEqualGUID( riid, &IID_IUnknown ))
1157 *obj = iface;
1159 else if (IsEqualGUID( riid, &IID_INetworkCostManager ))
1161 *obj = &mgr->INetworkCostManager_iface;
1163 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
1165 *obj = &mgr->IConnectionPointContainer_iface;
1167 else
1169 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1170 *obj = NULL;
1171 return E_NOINTERFACE;
1173 INetworkListManager_AddRef( iface );
1174 return S_OK;
1177 static HRESULT WINAPI list_manager_GetTypeInfoCount(
1178 INetworkListManager *iface,
1179 UINT *count )
1181 FIXME("\n");
1182 return E_NOTIMPL;
1185 static HRESULT WINAPI list_manager_GetTypeInfo(
1186 INetworkListManager *iface,
1187 UINT index,
1188 LCID lcid,
1189 ITypeInfo **info )
1191 FIXME("\n");
1192 return E_NOTIMPL;
1195 static HRESULT WINAPI list_manager_GetIDsOfNames(
1196 INetworkListManager *iface,
1197 REFIID riid,
1198 LPOLESTR *names,
1199 UINT count,
1200 LCID lcid,
1201 DISPID *dispid )
1203 FIXME("\n");
1204 return E_NOTIMPL;
1207 static HRESULT WINAPI list_manager_Invoke(
1208 INetworkListManager *iface,
1209 DISPID member,
1210 REFIID riid,
1211 LCID lcid,
1212 WORD flags,
1213 DISPPARAMS *params,
1214 VARIANT *result,
1215 EXCEPINFO *excep_info,
1216 UINT *arg_err )
1218 FIXME("\n");
1219 return E_NOTIMPL;
1222 static HRESULT WINAPI list_manager_GetNetworks(
1223 INetworkListManager *iface,
1224 NLM_ENUM_NETWORK Flags,
1225 IEnumNetworks **ppEnumNetwork )
1227 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1229 TRACE( "%p, %x, %p\n", iface, Flags, ppEnumNetwork );
1230 if (Flags) FIXME( "flags %08x not supported\n", Flags );
1232 return create_networks_enum( mgr, ppEnumNetwork );
1235 static HRESULT WINAPI list_manager_GetNetwork(
1236 INetworkListManager *iface,
1237 GUID gdNetworkId,
1238 INetwork **ppNetwork )
1240 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1241 struct network *network;
1243 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkId), ppNetwork );
1245 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1247 if (IsEqualGUID( &network->id, &gdNetworkId ))
1249 *ppNetwork = &network->INetwork_iface;
1250 INetwork_AddRef( *ppNetwork );
1251 return S_OK;
1255 return S_FALSE;
1258 static HRESULT WINAPI list_manager_GetNetworkConnections(
1259 INetworkListManager *iface,
1260 IEnumNetworkConnections **ppEnum )
1262 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1264 TRACE( "%p, %p\n", iface, ppEnum );
1265 return create_connections_enum( mgr, ppEnum );
1268 static HRESULT WINAPI list_manager_GetNetworkConnection(
1269 INetworkListManager *iface,
1270 GUID gdNetworkConnectionId,
1271 INetworkConnection **ppNetworkConnection )
1273 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1274 struct connection *connection;
1276 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkConnectionId),
1277 ppNetworkConnection );
1279 LIST_FOR_EACH_ENTRY( connection, &mgr->connections, struct connection, entry )
1281 if (IsEqualGUID( &connection->id, &gdNetworkConnectionId ))
1283 *ppNetworkConnection = &connection->INetworkConnection_iface;
1284 INetworkConnection_AddRef( *ppNetworkConnection );
1285 return S_OK;
1289 return S_FALSE;
1292 static HRESULT WINAPI list_manager_IsConnectedToInternet(
1293 INetworkListManager *iface,
1294 VARIANT_BOOL *pbIsConnected )
1296 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1297 struct network *network;
1299 TRACE( "%p, %p\n", iface, pbIsConnected );
1301 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1303 if (network->connected_to_internet)
1305 *pbIsConnected = VARIANT_TRUE;
1306 return S_OK;
1310 *pbIsConnected = VARIANT_FALSE;
1311 return S_OK;
1314 static HRESULT WINAPI list_manager_IsConnected(
1315 INetworkListManager *iface,
1316 VARIANT_BOOL *pbIsConnected )
1318 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1319 struct network *network;
1321 TRACE( "%p, %p\n", iface, pbIsConnected );
1323 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1325 if (network->connected)
1327 *pbIsConnected = VARIANT_TRUE;
1328 return S_OK;
1332 *pbIsConnected = VARIANT_FALSE;
1333 return S_OK;
1336 static HRESULT WINAPI list_manager_GetConnectivity(
1337 INetworkListManager *iface,
1338 NLM_CONNECTIVITY *pConnectivity )
1340 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1341 struct network *network;
1343 FIXME( "%p, %p\n", iface, pConnectivity );
1345 *pConnectivity = NLM_CONNECTIVITY_DISCONNECTED;
1347 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1349 if (network->connected_to_internet)
1350 *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET;
1351 else if (network->connected)
1352 *pConnectivity |= NLM_CONNECTIVITY_IPV4_LOCALNETWORK;
1355 return S_OK;
1358 static const INetworkListManagerVtbl list_manager_vtbl =
1360 list_manager_QueryInterface,
1361 list_manager_AddRef,
1362 list_manager_Release,
1363 list_manager_GetTypeInfoCount,
1364 list_manager_GetTypeInfo,
1365 list_manager_GetIDsOfNames,
1366 list_manager_Invoke,
1367 list_manager_GetNetworks,
1368 list_manager_GetNetwork,
1369 list_manager_GetNetworkConnections,
1370 list_manager_GetNetworkConnection,
1371 list_manager_IsConnectedToInternet,
1372 list_manager_IsConnected,
1373 list_manager_GetConnectivity
1376 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
1377 REFIID riid, void **ppv)
1379 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1380 return INetworkListManager_QueryInterface(&This->INetworkListManager_iface, riid, ppv);
1383 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
1385 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1386 return INetworkListManager_AddRef(&This->INetworkListManager_iface);
1389 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
1391 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1392 return INetworkListManager_Release(&This->INetworkListManager_iface);
1395 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
1396 IEnumConnectionPoints **ppEnum)
1398 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1399 FIXME("(%p)->(%p): stub\n", This, ppEnum);
1400 return E_NOTIMPL;
1403 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
1404 REFIID riid, IConnectionPoint **cp)
1406 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1407 struct connection_point *ret;
1409 TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
1411 if (!riid || !cp)
1412 return E_POINTER;
1414 if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ))
1415 ret = &This->list_mgr_cp;
1416 else if (IsEqualGUID( riid, &IID_INetworkCostManagerEvents ))
1417 ret = &This->cost_mgr_cp;
1418 else if (IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
1419 ret = &This->conn_mgr_cp;
1420 else if (IsEqualGUID( riid, &IID_INetworkEvents))
1421 ret = &This->events_cp;
1422 else
1424 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1425 *cp = NULL;
1426 return E_NOINTERFACE;
1429 IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface );
1430 return S_OK;
1433 static const struct IConnectionPointContainerVtbl cpc_vtbl =
1435 ConnectionPointContainer_QueryInterface,
1436 ConnectionPointContainer_AddRef,
1437 ConnectionPointContainer_Release,
1438 ConnectionPointContainer_EnumConnectionPoints,
1439 ConnectionPointContainer_FindConnectionPoint
1442 static inline struct connection *impl_from_INetworkConnection(
1443 INetworkConnection *iface )
1445 return CONTAINING_RECORD( iface, struct connection, INetworkConnection_iface );
1448 static HRESULT WINAPI connection_QueryInterface(
1449 INetworkConnection *iface, REFIID riid, void **obj )
1451 struct connection *connection = impl_from_INetworkConnection( iface );
1453 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
1455 if (IsEqualIID( riid, &IID_INetworkConnection ) ||
1456 IsEqualIID( riid, &IID_IDispatch ) ||
1457 IsEqualIID( riid, &IID_IUnknown ))
1459 *obj = iface;
1461 else if (IsEqualIID( riid, &IID_INetworkConnectionCost ))
1463 *obj = &connection->INetworkConnectionCost_iface;
1465 else
1467 WARN( "interface not supported %s\n", debugstr_guid(riid) );
1468 *obj = NULL;
1469 return E_NOINTERFACE;
1471 INetworkConnection_AddRef( iface );
1472 return S_OK;
1475 static ULONG WINAPI connection_AddRef(
1476 INetworkConnection *iface )
1478 struct connection *connection = impl_from_INetworkConnection( iface );
1480 TRACE( "%p\n", connection );
1481 return InterlockedIncrement( &connection->refs );
1484 static ULONG WINAPI connection_Release(
1485 INetworkConnection *iface )
1487 struct connection *connection = impl_from_INetworkConnection( iface );
1488 LONG refs;
1490 TRACE( "%p\n", connection );
1492 if (!(refs = InterlockedDecrement( &connection->refs )))
1494 list_remove( &connection->entry );
1495 INetwork_Release( connection->network );
1496 free( connection );
1498 return refs;
1501 static HRESULT WINAPI connection_GetTypeInfoCount(
1502 INetworkConnection *iface,
1503 UINT *count )
1505 FIXME("\n");
1506 return E_NOTIMPL;
1509 static HRESULT WINAPI connection_GetTypeInfo(
1510 INetworkConnection *iface,
1511 UINT index,
1512 LCID lcid,
1513 ITypeInfo **info )
1515 FIXME("\n");
1516 return E_NOTIMPL;
1519 static HRESULT WINAPI connection_GetIDsOfNames(
1520 INetworkConnection *iface,
1521 REFIID riid,
1522 LPOLESTR *names,
1523 UINT count,
1524 LCID lcid,
1525 DISPID *dispid )
1527 FIXME("\n");
1528 return E_NOTIMPL;
1531 static HRESULT WINAPI connection_Invoke(
1532 INetworkConnection *iface,
1533 DISPID member,
1534 REFIID riid,
1535 LCID lcid,
1536 WORD flags,
1537 DISPPARAMS *params,
1538 VARIANT *result,
1539 EXCEPINFO *excep_info,
1540 UINT *arg_err )
1542 FIXME("\n");
1543 return E_NOTIMPL;
1546 static HRESULT WINAPI connection_GetNetwork(
1547 INetworkConnection *iface,
1548 INetwork **ppNetwork )
1550 struct connection *connection = impl_from_INetworkConnection( iface );
1552 TRACE( "%p, %p\n", iface, ppNetwork );
1554 *ppNetwork = connection->network;
1555 INetwork_AddRef( *ppNetwork );
1556 return S_OK;
1559 static HRESULT WINAPI connection_get_IsConnectedToInternet(
1560 INetworkConnection *iface,
1561 VARIANT_BOOL *pbIsConnected )
1563 struct connection *connection = impl_from_INetworkConnection( iface );
1565 TRACE( "%p, %p\n", iface, pbIsConnected );
1567 *pbIsConnected = connection->connected_to_internet;
1568 return S_OK;
1571 static HRESULT WINAPI connection_get_IsConnected(
1572 INetworkConnection *iface,
1573 VARIANT_BOOL *pbIsConnected )
1575 struct connection *connection = impl_from_INetworkConnection( iface );
1577 TRACE( "%p, %p\n", iface, pbIsConnected );
1579 *pbIsConnected = connection->connected;
1580 return S_OK;
1583 static HRESULT WINAPI connection_GetConnectivity(
1584 INetworkConnection *iface,
1585 NLM_CONNECTIVITY *pConnectivity )
1587 struct connection *connection = impl_from_INetworkConnection( iface );
1589 FIXME( "%p, %p\n", iface, pConnectivity );
1591 *pConnectivity = NLM_CONNECTIVITY_DISCONNECTED;
1593 if (connection->connected_to_internet)
1594 *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET;
1595 else if (connection->connected)
1596 *pConnectivity |= NLM_CONNECTIVITY_IPV4_LOCALNETWORK;
1598 return S_OK;
1601 static HRESULT WINAPI connection_GetConnectionId(
1602 INetworkConnection *iface,
1603 GUID *pgdConnectionId )
1605 struct connection *connection = impl_from_INetworkConnection( iface );
1607 TRACE( "%p, %p\n", iface, pgdConnectionId );
1609 *pgdConnectionId = connection->id;
1610 return S_OK;
1613 static HRESULT WINAPI connection_GetAdapterId(
1614 INetworkConnection *iface,
1615 GUID *pgdAdapterId )
1617 struct connection *connection = impl_from_INetworkConnection( iface );
1619 FIXME( "%p, %p\n", iface, pgdAdapterId );
1621 *pgdAdapterId = connection->id;
1622 return S_OK;
1625 static HRESULT WINAPI connection_GetDomainType(
1626 INetworkConnection *iface,
1627 NLM_DOMAIN_TYPE *pDomainType )
1629 FIXME( "%p, %p\n", iface, pDomainType );
1631 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
1632 return S_OK;
1635 static const struct INetworkConnectionVtbl connection_vtbl =
1637 connection_QueryInterface,
1638 connection_AddRef,
1639 connection_Release,
1640 connection_GetTypeInfoCount,
1641 connection_GetTypeInfo,
1642 connection_GetIDsOfNames,
1643 connection_Invoke,
1644 connection_GetNetwork,
1645 connection_get_IsConnectedToInternet,
1646 connection_get_IsConnected,
1647 connection_GetConnectivity,
1648 connection_GetConnectionId,
1649 connection_GetAdapterId,
1650 connection_GetDomainType
1653 static inline struct connection *impl_from_INetworkConnectionCost(
1654 INetworkConnectionCost *iface )
1656 return CONTAINING_RECORD( iface, struct connection, INetworkConnectionCost_iface );
1659 static HRESULT WINAPI connection_cost_QueryInterface(
1660 INetworkConnectionCost *iface,
1661 REFIID riid,
1662 void **obj )
1664 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1665 return INetworkConnection_QueryInterface( &conn->INetworkConnection_iface, riid, obj );
1668 static ULONG WINAPI connection_cost_AddRef(
1669 INetworkConnectionCost *iface )
1671 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1672 return INetworkConnection_AddRef( &conn->INetworkConnection_iface );
1675 static ULONG WINAPI connection_cost_Release(
1676 INetworkConnectionCost *iface )
1678 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1679 return INetworkConnection_Release( &conn->INetworkConnection_iface );
1682 static HRESULT WINAPI connection_cost_GetCost(
1683 INetworkConnectionCost *iface, DWORD *pCost )
1685 FIXME( "%p, %p\n", iface, pCost );
1687 if (!pCost) return E_POINTER;
1689 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
1690 return S_OK;
1693 static HRESULT WINAPI connection_cost_GetDataPlanStatus(
1694 INetworkConnectionCost *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus )
1696 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1698 FIXME( "%p, %p\n", iface, pDataPlanStatus );
1700 if (!pDataPlanStatus) return E_POINTER;
1702 memcpy( &pDataPlanStatus->InterfaceGuid, &conn->id, sizeof(conn->id) );
1703 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1704 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
1705 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1706 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1707 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1708 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
1709 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1710 pDataPlanStatus->Reserved = 0;
1712 return S_OK;
1715 static const INetworkConnectionCostVtbl connection_cost_vtbl =
1717 connection_cost_QueryInterface,
1718 connection_cost_AddRef,
1719 connection_cost_Release,
1720 connection_cost_GetCost,
1721 connection_cost_GetDataPlanStatus
1724 static struct connection *create_connection( const GUID *id )
1726 struct connection *ret;
1728 if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL;
1730 ret->INetworkConnection_iface.lpVtbl = &connection_vtbl;
1731 ret->INetworkConnectionCost_iface.lpVtbl = &connection_cost_vtbl;
1732 ret->refs = 1;
1733 ret->id = *id;
1734 ret->network = NULL;
1735 ret->connected = VARIANT_FALSE;
1736 ret->connected_to_internet = VARIANT_FALSE;
1737 list_init( &ret->entry );
1739 return ret;
1742 static IP_ADAPTER_ADDRESSES *get_network_adapters(void)
1744 ULONG err, size = 4096, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
1745 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_GATEWAYS;
1746 IP_ADAPTER_ADDRESSES *tmp, *ret;
1748 if (!(ret = malloc( size ))) return NULL;
1749 err = GetAdaptersAddresses( AF_UNSPEC, flags, NULL, ret, &size );
1750 while (err == ERROR_BUFFER_OVERFLOW)
1752 if (!(tmp = realloc( ret, size ))) break;
1753 ret = tmp;
1754 err = GetAdaptersAddresses( AF_UNSPEC, flags, NULL, ret, &size );
1756 if (err == ERROR_SUCCESS) return ret;
1757 free( ret );
1758 return NULL;
1761 static void init_networks( struct list_manager *mgr )
1763 IP_ADAPTER_ADDRESSES *buf, *aa;
1764 GUID id;
1766 list_init( &mgr->networks );
1767 list_init( &mgr->connections );
1769 if (!(buf = get_network_adapters())) return;
1771 memset( &id, 0, sizeof(id) );
1772 for (aa = buf; aa; aa = aa->Next)
1774 struct network *network;
1775 struct connection *connection;
1776 NET_LUID luid;
1778 ConvertInterfaceIndexToLuid(aa->IfIndex, &luid);
1779 ConvertInterfaceLuidToGuid(&luid, &id);
1781 /* assume a one-to-one mapping between networks and connections */
1782 if (!(network = create_network( &id ))) goto done;
1783 if (!(connection = create_connection( &id )))
1785 INetwork_Release( &network->INetwork_iface );
1786 goto done;
1789 if (aa->FirstUnicastAddress)
1791 network->connected = VARIANT_TRUE;
1792 connection->connected = VARIANT_TRUE;
1794 if (aa->FirstGatewayAddress)
1796 network->connected_to_internet = VARIANT_TRUE;
1797 connection->connected_to_internet = VARIANT_TRUE;
1800 network->mgr = &mgr->INetworkListManager_iface;
1801 INetworkListManager_AddRef( network->mgr );
1802 connection->network = &network->INetwork_iface;
1803 INetwork_AddRef( connection->network );
1805 list_add_tail( &mgr->networks, &network->entry );
1806 list_add_tail( &mgr->connections, &connection->entry );
1809 done:
1810 free( buf );
1813 HRESULT list_manager_create( void **obj )
1815 struct list_manager *mgr;
1817 TRACE( "%p\n", obj );
1819 if (!(mgr = calloc( 1, sizeof(*mgr) ))) return E_OUTOFMEMORY;
1820 mgr->INetworkListManager_iface.lpVtbl = &list_manager_vtbl;
1821 mgr->INetworkCostManager_iface.lpVtbl = &cost_manager_vtbl;
1822 mgr->IConnectionPointContainer_iface.lpVtbl = &cpc_vtbl;
1823 init_networks( mgr );
1824 mgr->refs = 1;
1826 connection_point_init( &mgr->list_mgr_cp, &IID_INetworkListManagerEvents,
1827 &mgr->IConnectionPointContainer_iface );
1828 connection_point_init( &mgr->cost_mgr_cp, &IID_INetworkCostManagerEvents,
1829 &mgr->IConnectionPointContainer_iface);
1830 connection_point_init( &mgr->conn_mgr_cp, &IID_INetworkConnectionEvents,
1831 &mgr->IConnectionPointContainer_iface );
1832 connection_point_init( &mgr->events_cp, &IID_INetworkEvents,
1833 &mgr->IConnectionPointContainer_iface );
1835 *obj = &mgr->INetworkListManager_iface;
1836 TRACE( "returning iface %p\n", *obj );
1837 return S_OK;