netprofm: Implement connection points as the same object as their container.
[wine.git] / dlls / netprofm / list.c
blob3f572841f963ceb1ef8abd207b1947cdd2d54f6a
1 /*
2 * Copyright 2014 Hans Leidekker for CodeWeavers
3 * Copyright 2015 Michael Müller
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define COBJMACROS
21 #define NONAMELESSUNION
22 #define NONAMELESSSTRUCT
24 #include "config.h"
25 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #define USE_WS_PREFIX
29 #include "winsock2.h"
30 #include "ws2ipdef.h"
31 #include "iphlpapi.h"
32 #include "ifdef.h"
33 #include "netioapi.h"
34 #include "initguid.h"
35 #include "objbase.h"
36 #include "ocidl.h"
37 #include "netlistmgr.h"
38 #include "olectl.h"
40 #include "wine/debug.h"
41 #include "wine/list.h"
42 #include "netprofm_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(netprofm);
46 static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t size)
48 return HeapAlloc(GetProcessHeap(), 0, size);
51 static inline BOOL heap_free(void *mem)
53 return HeapFree(GetProcessHeap(), 0, mem);
56 struct network
58 INetwork INetwork_iface;
59 LONG refs;
60 struct list entry;
61 GUID id;
62 VARIANT_BOOL connected_to_internet;
63 VARIANT_BOOL connected;
66 struct connection
68 INetworkConnection INetworkConnection_iface;
69 INetworkConnectionCost INetworkConnectionCost_iface;
70 LONG refs;
71 struct list entry;
72 GUID id;
73 INetwork *network;
74 VARIANT_BOOL connected_to_internet;
75 VARIANT_BOOL connected;
78 struct connection_point
80 IConnectionPoint IConnectionPoint_iface;
81 IConnectionPointContainer *container;
82 IID iid;
83 struct list sinks;
84 DWORD cookie;
87 struct list_manager
89 INetworkListManager INetworkListManager_iface;
90 INetworkCostManager INetworkCostManager_iface;
91 IConnectionPointContainer IConnectionPointContainer_iface;
92 LONG refs;
93 struct list networks;
94 struct list connections;
95 struct connection_point list_mgr_cp;
96 struct connection_point cost_mgr_cp;
97 struct connection_point conn_mgr_cp;
100 struct sink_entry
102 struct list entry;
103 DWORD cookie;
104 IUnknown *unk;
107 static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
109 return CONTAINING_RECORD(iface, struct list_manager, IConnectionPointContainer_iface);
112 static inline struct list_manager *impl_from_INetworkCostManager(
113 INetworkCostManager *iface )
115 return CONTAINING_RECORD( iface, struct list_manager, INetworkCostManager_iface );
118 static inline struct connection_point *impl_from_IConnectionPoint(
119 IConnectionPoint *iface )
121 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
124 static HRESULT WINAPI connection_point_QueryInterface(
125 IConnectionPoint *iface,
126 REFIID riid,
127 void **obj )
129 struct connection_point *cp = impl_from_IConnectionPoint( iface );
130 TRACE( "%p, %s, %p\n", cp, debugstr_guid(riid), obj );
132 if (IsEqualGUID( riid, &IID_IConnectionPoint ) ||
133 IsEqualGUID( riid, &IID_IUnknown ))
135 *obj = iface;
137 else
139 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
140 *obj = NULL;
141 return E_NOINTERFACE;
143 IConnectionPoint_AddRef( iface );
144 return S_OK;
147 static ULONG WINAPI connection_point_AddRef(
148 IConnectionPoint *iface )
150 struct connection_point *cp = impl_from_IConnectionPoint( iface );
151 return IConnectionPointContainer_AddRef( cp->container );
154 static ULONG WINAPI connection_point_Release(
155 IConnectionPoint *iface )
157 struct connection_point *cp = impl_from_IConnectionPoint( iface );
158 return IConnectionPointContainer_Release( cp->container );
161 static HRESULT WINAPI connection_point_GetConnectionInterface(
162 IConnectionPoint *iface,
163 IID *iid )
165 struct connection_point *cp = impl_from_IConnectionPoint( iface );
166 TRACE( "%p, %p\n", cp, iid );
168 if (!iid)
169 return E_POINTER;
171 memcpy( iid, &cp->iid, sizeof(*iid) );
172 return S_OK;
175 static HRESULT WINAPI connection_point_GetConnectionPointContainer(
176 IConnectionPoint *iface,
177 IConnectionPointContainer **container )
179 struct connection_point *cp = impl_from_IConnectionPoint( iface );
180 TRACE( "%p, %p\n", cp, container );
182 if (!container)
183 return E_POINTER;
185 IConnectionPointContainer_AddRef( cp->container );
186 *container = cp->container;
187 return S_OK;
190 static HRESULT WINAPI connection_point_Advise(
191 IConnectionPoint *iface,
192 IUnknown *sink,
193 DWORD *cookie )
195 struct connection_point *cp = impl_from_IConnectionPoint( iface );
196 struct sink_entry *sink_entry;
197 IUnknown *unk;
198 HRESULT hr;
200 FIXME( "%p, %p, %p - semi-stub\n", cp, sink, cookie );
202 if (!sink || !cookie)
203 return E_POINTER;
205 hr = IUnknown_QueryInterface( sink, &cp->iid, (void**)&unk );
206 if (FAILED(hr))
208 WARN( "iface %s not implemented by sink\n", debugstr_guid(&cp->iid) );
209 return CO_E_FAILEDTOOPENTHREADTOKEN;
212 sink_entry = heap_alloc( sizeof(*sink_entry) );
213 if (!sink_entry)
215 IUnknown_Release( unk );
216 return E_OUTOFMEMORY;
219 sink_entry->unk = unk;
220 *cookie = sink_entry->cookie = ++cp->cookie;
221 list_add_tail( &cp->sinks, &sink_entry->entry );
222 return S_OK;
225 static HRESULT WINAPI connection_point_Unadvise(
226 IConnectionPoint *iface,
227 DWORD cookie )
229 struct connection_point *cp = impl_from_IConnectionPoint( iface );
230 struct sink_entry *iter;
232 TRACE( "%p, %d\n", cp, cookie );
234 LIST_FOR_EACH_ENTRY( iter, &cp->sinks, struct sink_entry, entry )
236 if (iter->cookie != cookie) continue;
237 list_remove( &iter->entry );
238 IUnknown_Release( iter->unk );
239 heap_free( iter );
240 return S_OK;
243 WARN( "invalid cookie\n" );
244 return OLE_E_NOCONNECTION;
247 static HRESULT WINAPI connection_point_EnumConnections(
248 IConnectionPoint *iface,
249 IEnumConnections **connections )
251 struct connection_point *cp = impl_from_IConnectionPoint( iface );
252 FIXME( "%p, %p - stub\n", cp, connections );
254 return E_NOTIMPL;
257 static const IConnectionPointVtbl connection_point_vtbl =
259 connection_point_QueryInterface,
260 connection_point_AddRef,
261 connection_point_Release,
262 connection_point_GetConnectionInterface,
263 connection_point_GetConnectionPointContainer,
264 connection_point_Advise,
265 connection_point_Unadvise,
266 connection_point_EnumConnections
269 static void connection_point_init(
270 struct connection_point *cp,
271 REFIID riid,
272 IConnectionPointContainer *container )
274 cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
275 cp->container = container;
276 cp->cookie = 0;
277 cp->iid = *riid;
278 list_init( &cp->sinks );
281 static inline struct network *impl_from_INetwork(
282 INetwork *iface )
284 return CONTAINING_RECORD( iface, struct network, INetwork_iface );
287 static HRESULT WINAPI network_QueryInterface(
288 INetwork *iface, REFIID riid, void **obj )
290 struct network *network = impl_from_INetwork( iface );
292 TRACE( "%p, %s, %p\n", network, debugstr_guid(riid), obj );
294 if (IsEqualIID( riid, &IID_INetwork ) ||
295 IsEqualIID( riid, &IID_IDispatch ) ||
296 IsEqualIID( riid, &IID_IUnknown ))
298 *obj = iface;
299 INetwork_AddRef( iface );
300 return S_OK;
302 else
304 WARN( "interface not supported %s\n", debugstr_guid(riid) );
305 *obj = NULL;
306 return E_NOINTERFACE;
310 static ULONG WINAPI network_AddRef(
311 INetwork *iface )
313 struct network *network = impl_from_INetwork( iface );
315 TRACE( "%p\n", network );
316 return InterlockedIncrement( &network->refs );
319 static ULONG WINAPI network_Release(
320 INetwork *iface )
322 struct network *network = impl_from_INetwork( iface );
323 LONG refs;
325 TRACE( "%p\n", network );
327 if (!(refs = InterlockedDecrement( &network->refs )))
329 list_remove( &network->entry );
330 heap_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 HRESULT WINAPI network_GetNetworkConnections(
435 INetwork *iface,
436 IEnumNetworkConnections **ppEnumNetworkConnection )
438 FIXME( "%p, %p\n", iface, ppEnumNetworkConnection );
439 return E_NOTIMPL;
442 static HRESULT WINAPI network_GetTimeCreatedAndConnected(
443 INetwork *iface,
444 DWORD *pdwLowDateTimeCreated,
445 DWORD *pdwHighDateTimeCreated,
446 DWORD *pdwLowDateTimeConnected,
447 DWORD *pdwHighDateTimeConnected )
449 FIXME( "%p, %p, %p, %p, %p\n", iface, pdwLowDateTimeCreated, pdwHighDateTimeCreated,
450 pdwLowDateTimeConnected, pdwHighDateTimeConnected );
451 return E_NOTIMPL;
454 static HRESULT WINAPI network_get_IsConnectedToInternet(
455 INetwork *iface,
456 VARIANT_BOOL *pbIsConnected )
458 struct network *network = impl_from_INetwork( iface );
460 TRACE( "%p, %p\n", iface, pbIsConnected );
462 *pbIsConnected = network->connected_to_internet;
463 return S_OK;
466 static HRESULT WINAPI network_get_IsConnected(
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;
475 return S_OK;
478 static HRESULT WINAPI network_GetConnectivity(
479 INetwork *iface,
480 NLM_CONNECTIVITY *pConnectivity )
482 FIXME( "%p, %p\n", iface, pConnectivity );
484 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
485 return S_OK;
488 static HRESULT WINAPI network_GetCategory(
489 INetwork *iface,
490 NLM_NETWORK_CATEGORY *pCategory )
492 FIXME( "%p, %p\n", iface, pCategory );
494 *pCategory = NLM_NETWORK_CATEGORY_PUBLIC;
495 return S_OK;
498 static HRESULT WINAPI network_SetCategory(
499 INetwork *iface,
500 NLM_NETWORK_CATEGORY NewCategory )
502 FIXME( "%p, %u\n", iface, NewCategory );
503 return E_NOTIMPL;
506 static const struct INetworkVtbl network_vtbl =
508 network_QueryInterface,
509 network_AddRef,
510 network_Release,
511 network_GetTypeInfoCount,
512 network_GetTypeInfo,
513 network_GetIDsOfNames,
514 network_Invoke,
515 network_GetName,
516 network_SetName,
517 network_GetDescription,
518 network_SetDescription,
519 network_GetNetworkId,
520 network_GetDomainType,
521 network_GetNetworkConnections,
522 network_GetTimeCreatedAndConnected,
523 network_get_IsConnectedToInternet,
524 network_get_IsConnected,
525 network_GetConnectivity,
526 network_GetCategory,
527 network_SetCategory
530 static struct network *create_network( const GUID *id )
532 struct network *ret;
534 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
536 ret->INetwork_iface.lpVtbl = &network_vtbl;
537 ret->refs = 1;
538 ret->id = *id;
539 ret->connected = VARIANT_FALSE;
540 ret->connected_to_internet = VARIANT_FALSE;
541 list_init( &ret->entry );
543 return ret;
546 static HRESULT WINAPI cost_manager_QueryInterface(
547 INetworkCostManager *iface,
548 REFIID riid,
549 void **obj )
551 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
552 return INetworkListManager_QueryInterface( &mgr->INetworkListManager_iface, riid, obj );
555 static ULONG WINAPI cost_manager_AddRef(
556 INetworkCostManager *iface )
558 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
559 return INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
562 static ULONG WINAPI cost_manager_Release(
563 INetworkCostManager *iface )
565 struct list_manager *mgr = impl_from_INetworkCostManager( iface );
566 return INetworkListManager_Release( &mgr->INetworkListManager_iface );
569 static HRESULT WINAPI cost_manager_GetCost(
570 INetworkCostManager *iface, DWORD *pCost, NLM_SOCKADDR *pDestIPAddr)
572 FIXME( "%p, %p, %p\n", iface, pCost, pDestIPAddr );
574 if (!pCost) return E_POINTER;
576 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
577 return S_OK;
580 static BOOL map_address_6to4( const SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
582 ULONG i;
584 if (addr6->sin6_family != WS_AF_INET6) return FALSE;
586 for (i = 0; i < 5; i++)
587 if (addr6->sin6_addr.u.Word[i]) return FALSE;
589 if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
591 addr4->sin_family = WS_AF_INET;
592 addr4->sin_port = addr6->sin6_port;
593 addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
594 memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
596 return TRUE;
599 static HRESULT WINAPI cost_manager_GetDataPlanStatus(
600 INetworkCostManager *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus,
601 NLM_SOCKADDR *pDestIPAddr)
603 DWORD ret, index;
604 NET_LUID luid;
605 SOCKADDR *dst = (SOCKADDR *)pDestIPAddr;
606 SOCKADDR_IN addr4, *dst4;
608 FIXME( "%p, %p, %p\n", iface, pDataPlanStatus, pDestIPAddr );
610 if (!pDataPlanStatus) return E_POINTER;
612 if (dst && ((dst->sa_family == WS_AF_INET && (dst4 = (SOCKADDR_IN *)dst)) ||
613 ((dst->sa_family == WS_AF_INET6 && map_address_6to4( (const SOCKADDR_IN6 *)dst, &addr4 )
614 && (dst4 = &addr4)))))
616 if ((ret = GetBestInterface( dst4->sin_addr.S_un.S_addr, &index )))
617 return HRESULT_FROM_WIN32( ret );
619 if ((ret = ConvertInterfaceIndexToLuid( index, &luid )))
620 return HRESULT_FROM_WIN32( ret );
622 if ((ret = ConvertInterfaceLuidToGuid( &luid, &pDataPlanStatus->InterfaceGuid )))
623 return HRESULT_FROM_WIN32( ret );
625 else
627 FIXME( "interface guid not found\n" );
628 memset( &pDataPlanStatus->InterfaceGuid, 0, sizeof(pDataPlanStatus->InterfaceGuid) );
631 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
632 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
633 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
634 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
635 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
636 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
637 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
638 pDataPlanStatus->Reserved = 0;
640 return S_OK;
643 static HRESULT WINAPI cost_manager_SetDestinationAddresses(
644 INetworkCostManager *iface, UINT32 length, NLM_SOCKADDR *pDestIPAddrList,
645 VARIANT_BOOL bAppend)
647 FIXME( "%p, %u, %p, %x\n", iface, length, pDestIPAddrList, bAppend );
648 return E_NOTIMPL;
651 static const INetworkCostManagerVtbl cost_manager_vtbl =
653 cost_manager_QueryInterface,
654 cost_manager_AddRef,
655 cost_manager_Release,
656 cost_manager_GetCost,
657 cost_manager_GetDataPlanStatus,
658 cost_manager_SetDestinationAddresses
661 struct networks_enum
663 IEnumNetworks IEnumNetworks_iface;
664 LONG refs;
665 struct list_manager *mgr;
666 struct list *cursor;
669 static inline struct networks_enum *impl_from_IEnumNetworks(
670 IEnumNetworks *iface )
672 return CONTAINING_RECORD( iface, struct networks_enum, IEnumNetworks_iface );
675 static HRESULT WINAPI networks_enum_QueryInterface(
676 IEnumNetworks *iface, REFIID riid, void **obj )
678 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
680 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
682 if (IsEqualIID( riid, &IID_IEnumNetworks ) ||
683 IsEqualIID( riid, &IID_IDispatch ) ||
684 IsEqualIID( riid, &IID_IUnknown ))
686 *obj = iface;
687 IEnumNetworks_AddRef( iface );
688 return S_OK;
690 else
692 WARN( "interface not supported %s\n", debugstr_guid(riid) );
693 *obj = NULL;
694 return E_NOINTERFACE;
698 static ULONG WINAPI networks_enum_AddRef(
699 IEnumNetworks *iface )
701 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
703 TRACE( "%p\n", iter );
704 return InterlockedIncrement( &iter->refs );
707 static ULONG WINAPI networks_enum_Release(
708 IEnumNetworks *iface )
710 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
711 LONG refs;
713 TRACE( "%p\n", iter );
715 if (!(refs = InterlockedDecrement( &iter->refs )))
717 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
718 heap_free( iter );
720 return refs;
723 static HRESULT WINAPI networks_enum_GetTypeInfoCount(
724 IEnumNetworks *iface,
725 UINT *count )
727 FIXME("\n");
728 return E_NOTIMPL;
731 static HRESULT WINAPI networks_enum_GetTypeInfo(
732 IEnumNetworks *iface,
733 UINT index,
734 LCID lcid,
735 ITypeInfo **info )
737 FIXME("\n");
738 return E_NOTIMPL;
741 static HRESULT WINAPI networks_enum_GetIDsOfNames(
742 IEnumNetworks *iface,
743 REFIID riid,
744 LPOLESTR *names,
745 UINT count,
746 LCID lcid,
747 DISPID *dispid )
749 FIXME("\n");
750 return E_NOTIMPL;
753 static HRESULT WINAPI networks_enum_Invoke(
754 IEnumNetworks *iface,
755 DISPID member,
756 REFIID riid,
757 LCID lcid,
758 WORD flags,
759 DISPPARAMS *params,
760 VARIANT *result,
761 EXCEPINFO *excep_info,
762 UINT *arg_err )
764 FIXME("\n");
765 return E_NOTIMPL;
768 static HRESULT WINAPI networks_enum_get__NewEnum(
769 IEnumNetworks *iface, IEnumVARIANT **ppEnumVar )
771 FIXME("\n");
772 return E_NOTIMPL;
775 static HRESULT WINAPI networks_enum_Next(
776 IEnumNetworks *iface, ULONG count, INetwork **ret, ULONG *fetched )
778 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
779 ULONG i = 0;
781 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
783 if (fetched) *fetched = 0;
784 if (!count) return S_OK;
786 while (iter->cursor && i < count)
788 struct network *network = LIST_ENTRY( iter->cursor, struct network, entry );
789 ret[i] = &network->INetwork_iface;
790 INetwork_AddRef( ret[i] );
791 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
792 i++;
794 if (fetched) *fetched = i;
796 return i < count ? S_FALSE : S_OK;
799 static HRESULT WINAPI networks_enum_Skip(
800 IEnumNetworks *iface, ULONG count )
802 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
804 TRACE( "%p, %u\n", iter, count);
806 if (!count) return S_OK;
807 if (!iter->cursor) return S_FALSE;
809 while (count--)
811 iter->cursor = list_next( &iter->mgr->networks, iter->cursor );
812 if (!iter->cursor) break;
815 return count ? S_FALSE : S_OK;
818 static HRESULT WINAPI networks_enum_Reset(
819 IEnumNetworks *iface )
821 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
823 TRACE( "%p\n", iter );
825 iter->cursor = list_head( &iter->mgr->networks );
826 return S_OK;
829 static HRESULT create_networks_enum(
830 struct list_manager *, IEnumNetworks** );
832 static HRESULT WINAPI networks_enum_Clone(
833 IEnumNetworks *iface, IEnumNetworks **ret )
835 struct networks_enum *iter = impl_from_IEnumNetworks( iface );
837 TRACE( "%p, %p\n", iter, ret );
838 return create_networks_enum( iter->mgr, ret );
841 static const IEnumNetworksVtbl networks_enum_vtbl =
843 networks_enum_QueryInterface,
844 networks_enum_AddRef,
845 networks_enum_Release,
846 networks_enum_GetTypeInfoCount,
847 networks_enum_GetTypeInfo,
848 networks_enum_GetIDsOfNames,
849 networks_enum_Invoke,
850 networks_enum_get__NewEnum,
851 networks_enum_Next,
852 networks_enum_Skip,
853 networks_enum_Reset,
854 networks_enum_Clone
857 static HRESULT create_networks_enum(
858 struct list_manager *mgr, IEnumNetworks **ret )
860 struct networks_enum *iter;
862 *ret = NULL;
863 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
865 iter->IEnumNetworks_iface.lpVtbl = &networks_enum_vtbl;
866 iter->cursor = list_head( &mgr->networks );
867 iter->mgr = mgr;
868 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
869 iter->refs = 1;
871 *ret = &iter->IEnumNetworks_iface;
872 return S_OK;
875 static inline struct list_manager *impl_from_INetworkListManager(
876 INetworkListManager *iface )
878 return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface );
881 struct connections_enum
883 IEnumNetworkConnections IEnumNetworkConnections_iface;
884 LONG refs;
885 struct list_manager *mgr;
886 struct list *cursor;
889 static inline struct connections_enum *impl_from_IEnumNetworkConnections(
890 IEnumNetworkConnections *iface )
892 return CONTAINING_RECORD( iface, struct connections_enum, IEnumNetworkConnections_iface );
895 static HRESULT WINAPI connections_enum_QueryInterface(
896 IEnumNetworkConnections *iface, REFIID riid, void **obj )
898 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
900 TRACE( "%p, %s, %p\n", iter, debugstr_guid(riid), obj );
902 if (IsEqualIID( riid, &IID_IEnumNetworkConnections ) ||
903 IsEqualIID( riid, &IID_IDispatch ) ||
904 IsEqualIID( riid, &IID_IUnknown ))
906 *obj = iface;
907 IEnumNetworkConnections_AddRef( iface );
908 return S_OK;
910 else
912 WARN( "interface not supported %s\n", debugstr_guid(riid) );
913 *obj = NULL;
914 return E_NOINTERFACE;
918 static ULONG WINAPI connections_enum_AddRef(
919 IEnumNetworkConnections *iface )
921 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
923 TRACE( "%p\n", iter );
924 return InterlockedIncrement( &iter->refs );
927 static ULONG WINAPI connections_enum_Release(
928 IEnumNetworkConnections *iface )
930 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
931 LONG refs;
933 TRACE( "%p\n", iter );
935 if (!(refs = InterlockedDecrement( &iter->refs )))
937 INetworkListManager_Release( &iter->mgr->INetworkListManager_iface );
938 heap_free( iter );
940 return refs;
943 static HRESULT WINAPI connections_enum_GetTypeInfoCount(
944 IEnumNetworkConnections *iface,
945 UINT *count )
947 FIXME("\n");
948 return E_NOTIMPL;
951 static HRESULT WINAPI connections_enum_GetTypeInfo(
952 IEnumNetworkConnections *iface,
953 UINT index,
954 LCID lcid,
955 ITypeInfo **info )
957 FIXME("\n");
958 return E_NOTIMPL;
961 static HRESULT WINAPI connections_enum_GetIDsOfNames(
962 IEnumNetworkConnections *iface,
963 REFIID riid,
964 LPOLESTR *names,
965 UINT count,
966 LCID lcid,
967 DISPID *dispid )
969 FIXME("\n");
970 return E_NOTIMPL;
973 static HRESULT WINAPI connections_enum_Invoke(
974 IEnumNetworkConnections *iface,
975 DISPID member,
976 REFIID riid,
977 LCID lcid,
978 WORD flags,
979 DISPPARAMS *params,
980 VARIANT *result,
981 EXCEPINFO *excep_info,
982 UINT *arg_err )
984 FIXME("\n");
985 return E_NOTIMPL;
988 static HRESULT WINAPI connections_enum_get__NewEnum(
989 IEnumNetworkConnections *iface, IEnumVARIANT **ppEnumVar )
991 FIXME("\n");
992 return E_NOTIMPL;
995 static HRESULT WINAPI connections_enum_Next(
996 IEnumNetworkConnections *iface, ULONG count, INetworkConnection **ret, ULONG *fetched )
998 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
999 ULONG i = 0;
1001 TRACE( "%p, %u %p %p\n", iter, count, ret, fetched );
1003 if (fetched) *fetched = 0;
1004 if (!count) return S_OK;
1006 while (iter->cursor && i < count)
1008 struct connection *connection = LIST_ENTRY( iter->cursor, struct connection, entry );
1009 ret[i] = &connection->INetworkConnection_iface;
1010 INetworkConnection_AddRef( ret[i] );
1011 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1012 i++;
1014 if (fetched) *fetched = i;
1016 return i < count ? S_FALSE : S_OK;
1019 static HRESULT WINAPI connections_enum_Skip(
1020 IEnumNetworkConnections *iface, ULONG count )
1022 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1024 TRACE( "%p, %u\n", iter, count);
1026 if (!count) return S_OK;
1027 if (!iter->cursor) return S_FALSE;
1029 while (count--)
1031 iter->cursor = list_next( &iter->mgr->connections, iter->cursor );
1032 if (!iter->cursor) break;
1035 return count ? S_FALSE : S_OK;
1038 static HRESULT WINAPI connections_enum_Reset(
1039 IEnumNetworkConnections *iface )
1041 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1043 TRACE( "%p\n", iter );
1045 iter->cursor = list_head( &iter->mgr->connections );
1046 return S_OK;
1049 static HRESULT create_connections_enum(
1050 struct list_manager *, IEnumNetworkConnections** );
1052 static HRESULT WINAPI connections_enum_Clone(
1053 IEnumNetworkConnections *iface, IEnumNetworkConnections **ret )
1055 struct connections_enum *iter = impl_from_IEnumNetworkConnections( iface );
1057 TRACE( "%p, %p\n", iter, ret );
1058 return create_connections_enum( iter->mgr, ret );
1061 static const IEnumNetworkConnectionsVtbl connections_enum_vtbl =
1063 connections_enum_QueryInterface,
1064 connections_enum_AddRef,
1065 connections_enum_Release,
1066 connections_enum_GetTypeInfoCount,
1067 connections_enum_GetTypeInfo,
1068 connections_enum_GetIDsOfNames,
1069 connections_enum_Invoke,
1070 connections_enum_get__NewEnum,
1071 connections_enum_Next,
1072 connections_enum_Skip,
1073 connections_enum_Reset,
1074 connections_enum_Clone
1077 static HRESULT create_connections_enum(
1078 struct list_manager *mgr, IEnumNetworkConnections **ret )
1080 struct connections_enum *iter;
1082 *ret = NULL;
1083 if (!(iter = heap_alloc( sizeof(*iter) ))) return E_OUTOFMEMORY;
1085 iter->IEnumNetworkConnections_iface.lpVtbl = &connections_enum_vtbl;
1086 iter->mgr = mgr;
1087 INetworkListManager_AddRef( &mgr->INetworkListManager_iface );
1088 iter->cursor = list_head( &iter->mgr->connections );
1089 iter->refs = 1;
1091 *ret = &iter->IEnumNetworkConnections_iface;
1092 return S_OK;
1095 static ULONG WINAPI list_manager_AddRef(
1096 INetworkListManager *iface )
1098 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1099 return InterlockedIncrement( &mgr->refs );
1102 static ULONG WINAPI list_manager_Release(
1103 INetworkListManager *iface )
1105 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1106 LONG refs = InterlockedDecrement( &mgr->refs );
1107 if (!refs)
1109 struct list *ptr;
1111 TRACE( "destroying %p\n", mgr );
1113 while ((ptr = list_head( &mgr->networks )))
1115 struct network *network = LIST_ENTRY( ptr, struct network, entry );
1116 list_remove( &network->entry );
1117 INetwork_Release( &network->INetwork_iface );
1119 while ((ptr = list_head( &mgr->connections )))
1121 struct connection *connection = LIST_ENTRY( ptr, struct connection, entry );
1122 list_remove( &connection->entry );
1123 INetworkConnection_Release( &connection->INetworkConnection_iface );
1125 heap_free( mgr );
1127 return refs;
1130 static HRESULT WINAPI list_manager_QueryInterface(
1131 INetworkListManager *iface,
1132 REFIID riid,
1133 void **obj )
1135 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1137 TRACE( "%p, %s, %p\n", mgr, debugstr_guid(riid), obj );
1139 if (IsEqualGUID( riid, &IID_INetworkListManager ) ||
1140 IsEqualGUID( riid, &IID_IDispatch ) ||
1141 IsEqualGUID( riid, &IID_IUnknown ))
1143 *obj = iface;
1145 else if (IsEqualGUID( riid, &IID_INetworkCostManager ))
1147 *obj = &mgr->INetworkCostManager_iface;
1149 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
1151 *obj = &mgr->IConnectionPointContainer_iface;
1153 else
1155 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1156 *obj = NULL;
1157 return E_NOINTERFACE;
1159 INetworkListManager_AddRef( iface );
1160 return S_OK;
1163 static HRESULT WINAPI list_manager_GetTypeInfoCount(
1164 INetworkListManager *iface,
1165 UINT *count )
1167 FIXME("\n");
1168 return E_NOTIMPL;
1171 static HRESULT WINAPI list_manager_GetTypeInfo(
1172 INetworkListManager *iface,
1173 UINT index,
1174 LCID lcid,
1175 ITypeInfo **info )
1177 FIXME("\n");
1178 return E_NOTIMPL;
1181 static HRESULT WINAPI list_manager_GetIDsOfNames(
1182 INetworkListManager *iface,
1183 REFIID riid,
1184 LPOLESTR *names,
1185 UINT count,
1186 LCID lcid,
1187 DISPID *dispid )
1189 FIXME("\n");
1190 return E_NOTIMPL;
1193 static HRESULT WINAPI list_manager_Invoke(
1194 INetworkListManager *iface,
1195 DISPID member,
1196 REFIID riid,
1197 LCID lcid,
1198 WORD flags,
1199 DISPPARAMS *params,
1200 VARIANT *result,
1201 EXCEPINFO *excep_info,
1202 UINT *arg_err )
1204 FIXME("\n");
1205 return E_NOTIMPL;
1208 static HRESULT WINAPI list_manager_GetNetworks(
1209 INetworkListManager *iface,
1210 NLM_ENUM_NETWORK Flags,
1211 IEnumNetworks **ppEnumNetwork )
1213 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1215 TRACE( "%p, %x, %p\n", iface, Flags, ppEnumNetwork );
1216 if (Flags) FIXME( "flags %08x not supported\n", Flags );
1218 return create_networks_enum( mgr, ppEnumNetwork );
1221 static HRESULT WINAPI list_manager_GetNetwork(
1222 INetworkListManager *iface,
1223 GUID gdNetworkId,
1224 INetwork **ppNetwork )
1226 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1227 struct network *network;
1229 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkId), ppNetwork );
1231 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1233 if (IsEqualGUID( &network->id, &gdNetworkId ))
1235 *ppNetwork = &network->INetwork_iface;
1236 INetwork_AddRef( *ppNetwork );
1237 return S_OK;
1241 return S_FALSE;
1244 static HRESULT WINAPI list_manager_GetNetworkConnections(
1245 INetworkListManager *iface,
1246 IEnumNetworkConnections **ppEnum )
1248 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1250 TRACE( "%p, %p\n", iface, ppEnum );
1251 return create_connections_enum( mgr, ppEnum );
1254 static HRESULT WINAPI list_manager_GetNetworkConnection(
1255 INetworkListManager *iface,
1256 GUID gdNetworkConnectionId,
1257 INetworkConnection **ppNetworkConnection )
1259 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1260 struct connection *connection;
1262 TRACE( "%p, %s, %p\n", iface, debugstr_guid(&gdNetworkConnectionId),
1263 ppNetworkConnection );
1265 LIST_FOR_EACH_ENTRY( connection, &mgr->connections, struct connection, entry )
1267 if (IsEqualGUID( &connection->id, &gdNetworkConnectionId ))
1269 *ppNetworkConnection = &connection->INetworkConnection_iface;
1270 INetworkConnection_AddRef( *ppNetworkConnection );
1271 return S_OK;
1275 return S_FALSE;
1278 static HRESULT WINAPI list_manager_IsConnectedToInternet(
1279 INetworkListManager *iface,
1280 VARIANT_BOOL *pbIsConnected )
1282 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1283 struct network *network;
1285 TRACE( "%p, %p\n", iface, pbIsConnected );
1287 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1289 if (network->connected_to_internet)
1291 *pbIsConnected = VARIANT_TRUE;
1292 return S_OK;
1296 *pbIsConnected = VARIANT_FALSE;
1297 return S_OK;
1300 static HRESULT WINAPI list_manager_IsConnected(
1301 INetworkListManager *iface,
1302 VARIANT_BOOL *pbIsConnected )
1304 struct list_manager *mgr = impl_from_INetworkListManager( iface );
1305 struct network *network;
1307 TRACE( "%p, %p\n", iface, pbIsConnected );
1309 LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry )
1311 if (network->connected)
1313 *pbIsConnected = VARIANT_TRUE;
1314 return S_OK;
1318 *pbIsConnected = VARIANT_FALSE;
1319 return S_OK;
1322 static HRESULT WINAPI list_manager_GetConnectivity(
1323 INetworkListManager *iface,
1324 NLM_CONNECTIVITY *pConnectivity )
1326 FIXME( "%p, %p\n", iface, pConnectivity );
1328 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1329 return S_OK;
1332 static const INetworkListManagerVtbl list_manager_vtbl =
1334 list_manager_QueryInterface,
1335 list_manager_AddRef,
1336 list_manager_Release,
1337 list_manager_GetTypeInfoCount,
1338 list_manager_GetTypeInfo,
1339 list_manager_GetIDsOfNames,
1340 list_manager_Invoke,
1341 list_manager_GetNetworks,
1342 list_manager_GetNetwork,
1343 list_manager_GetNetworkConnections,
1344 list_manager_GetNetworkConnection,
1345 list_manager_IsConnectedToInternet,
1346 list_manager_IsConnected,
1347 list_manager_GetConnectivity
1350 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
1351 REFIID riid, void **ppv)
1353 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1354 return INetworkListManager_QueryInterface(&This->INetworkListManager_iface, riid, ppv);
1357 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
1359 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1360 return INetworkListManager_AddRef(&This->INetworkListManager_iface);
1363 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
1365 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1366 return INetworkListManager_Release(&This->INetworkListManager_iface);
1369 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
1370 IEnumConnectionPoints **ppEnum)
1372 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1373 FIXME("(%p)->(%p): stub\n", This, ppEnum);
1374 return E_NOTIMPL;
1377 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
1378 REFIID riid, IConnectionPoint **cp)
1380 struct list_manager *This = impl_from_IConnectionPointContainer( iface );
1381 struct connection_point *ret;
1383 TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
1385 if (!riid || !cp)
1386 return E_POINTER;
1388 if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ))
1389 ret = &This->list_mgr_cp;
1390 else if (IsEqualGUID( riid, &IID_INetworkCostManagerEvents ))
1391 ret = &This->cost_mgr_cp;
1392 else if (IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
1393 ret = &This->conn_mgr_cp;
1394 else
1396 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1397 *cp = NULL;
1398 return E_NOINTERFACE;
1401 IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface );
1402 return S_OK;
1405 static const struct IConnectionPointContainerVtbl cpc_vtbl =
1407 ConnectionPointContainer_QueryInterface,
1408 ConnectionPointContainer_AddRef,
1409 ConnectionPointContainer_Release,
1410 ConnectionPointContainer_EnumConnectionPoints,
1411 ConnectionPointContainer_FindConnectionPoint
1414 static inline struct connection *impl_from_INetworkConnection(
1415 INetworkConnection *iface )
1417 return CONTAINING_RECORD( iface, struct connection, INetworkConnection_iface );
1420 static HRESULT WINAPI connection_QueryInterface(
1421 INetworkConnection *iface, REFIID riid, void **obj )
1423 struct connection *connection = impl_from_INetworkConnection( iface );
1425 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
1427 if (IsEqualIID( riid, &IID_INetworkConnection ) ||
1428 IsEqualIID( riid, &IID_IDispatch ) ||
1429 IsEqualIID( riid, &IID_IUnknown ))
1431 *obj = iface;
1433 else if (IsEqualIID( riid, &IID_INetworkConnectionCost ))
1435 *obj = &connection->INetworkConnectionCost_iface;
1437 else
1439 WARN( "interface not supported %s\n", debugstr_guid(riid) );
1440 *obj = NULL;
1441 return E_NOINTERFACE;
1443 INetworkConnection_AddRef( iface );
1444 return S_OK;
1447 static ULONG WINAPI connection_AddRef(
1448 INetworkConnection *iface )
1450 struct connection *connection = impl_from_INetworkConnection( iface );
1452 TRACE( "%p\n", connection );
1453 return InterlockedIncrement( &connection->refs );
1456 static ULONG WINAPI connection_Release(
1457 INetworkConnection *iface )
1459 struct connection *connection = impl_from_INetworkConnection( iface );
1460 LONG refs;
1462 TRACE( "%p\n", connection );
1464 if (!(refs = InterlockedDecrement( &connection->refs )))
1466 INetwork_Release( connection->network );
1467 list_remove( &connection->entry );
1468 heap_free( connection );
1470 return refs;
1473 static HRESULT WINAPI connection_GetTypeInfoCount(
1474 INetworkConnection *iface,
1475 UINT *count )
1477 FIXME("\n");
1478 return E_NOTIMPL;
1481 static HRESULT WINAPI connection_GetTypeInfo(
1482 INetworkConnection *iface,
1483 UINT index,
1484 LCID lcid,
1485 ITypeInfo **info )
1487 FIXME("\n");
1488 return E_NOTIMPL;
1491 static HRESULT WINAPI connection_GetIDsOfNames(
1492 INetworkConnection *iface,
1493 REFIID riid,
1494 LPOLESTR *names,
1495 UINT count,
1496 LCID lcid,
1497 DISPID *dispid )
1499 FIXME("\n");
1500 return E_NOTIMPL;
1503 static HRESULT WINAPI connection_Invoke(
1504 INetworkConnection *iface,
1505 DISPID member,
1506 REFIID riid,
1507 LCID lcid,
1508 WORD flags,
1509 DISPPARAMS *params,
1510 VARIANT *result,
1511 EXCEPINFO *excep_info,
1512 UINT *arg_err )
1514 FIXME("\n");
1515 return E_NOTIMPL;
1518 static HRESULT WINAPI connection_GetNetwork(
1519 INetworkConnection *iface,
1520 INetwork **ppNetwork )
1522 struct connection *connection = impl_from_INetworkConnection( iface );
1524 TRACE( "%p, %p\n", iface, ppNetwork );
1526 *ppNetwork = connection->network;
1527 INetwork_AddRef( *ppNetwork );
1528 return S_OK;
1531 static HRESULT WINAPI connection_get_IsConnectedToInternet(
1532 INetworkConnection *iface,
1533 VARIANT_BOOL *pbIsConnected )
1535 struct connection *connection = impl_from_INetworkConnection( iface );
1537 TRACE( "%p, %p\n", iface, pbIsConnected );
1539 *pbIsConnected = connection->connected_to_internet;
1540 return S_OK;
1543 static HRESULT WINAPI connection_get_IsConnected(
1544 INetworkConnection *iface,
1545 VARIANT_BOOL *pbIsConnected )
1547 struct connection *connection = impl_from_INetworkConnection( iface );
1549 TRACE( "%p, %p\n", iface, pbIsConnected );
1551 *pbIsConnected = connection->connected;
1552 return S_OK;
1555 static HRESULT WINAPI connection_GetConnectivity(
1556 INetworkConnection *iface,
1557 NLM_CONNECTIVITY *pConnectivity )
1559 FIXME( "%p, %p\n", iface, pConnectivity );
1561 *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET;
1562 return S_OK;
1565 static HRESULT WINAPI connection_GetConnectionId(
1566 INetworkConnection *iface,
1567 GUID *pgdConnectionId )
1569 struct connection *connection = impl_from_INetworkConnection( iface );
1571 TRACE( "%p, %p\n", iface, pgdConnectionId );
1573 *pgdConnectionId = connection->id;
1574 return S_OK;
1577 static HRESULT WINAPI connection_GetAdapterId(
1578 INetworkConnection *iface,
1579 GUID *pgdAdapterId )
1581 struct connection *connection = impl_from_INetworkConnection( iface );
1583 FIXME( "%p, %p\n", iface, pgdAdapterId );
1585 *pgdAdapterId = connection->id;
1586 return S_OK;
1589 static HRESULT WINAPI connection_GetDomainType(
1590 INetworkConnection *iface,
1591 NLM_DOMAIN_TYPE *pDomainType )
1593 FIXME( "%p, %p\n", iface, pDomainType );
1595 *pDomainType = NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK;
1596 return S_OK;
1599 static const struct INetworkConnectionVtbl connection_vtbl =
1601 connection_QueryInterface,
1602 connection_AddRef,
1603 connection_Release,
1604 connection_GetTypeInfoCount,
1605 connection_GetTypeInfo,
1606 connection_GetIDsOfNames,
1607 connection_Invoke,
1608 connection_GetNetwork,
1609 connection_get_IsConnectedToInternet,
1610 connection_get_IsConnected,
1611 connection_GetConnectivity,
1612 connection_GetConnectionId,
1613 connection_GetAdapterId,
1614 connection_GetDomainType
1617 static inline struct connection *impl_from_INetworkConnectionCost(
1618 INetworkConnectionCost *iface )
1620 return CONTAINING_RECORD( iface, struct connection, INetworkConnectionCost_iface );
1623 static HRESULT WINAPI connection_cost_QueryInterface(
1624 INetworkConnectionCost *iface,
1625 REFIID riid,
1626 void **obj )
1628 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1629 return INetworkConnection_QueryInterface( &conn->INetworkConnection_iface, riid, obj );
1632 static ULONG WINAPI connection_cost_AddRef(
1633 INetworkConnectionCost *iface )
1635 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1636 return INetworkConnection_AddRef( &conn->INetworkConnection_iface );
1639 static ULONG WINAPI connection_cost_Release(
1640 INetworkConnectionCost *iface )
1642 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1643 return INetworkConnection_Release( &conn->INetworkConnection_iface );
1646 static HRESULT WINAPI connection_cost_GetCost(
1647 INetworkConnectionCost *iface, DWORD *pCost )
1649 FIXME( "%p, %p\n", iface, pCost );
1651 if (!pCost) return E_POINTER;
1653 *pCost = NLM_CONNECTION_COST_UNRESTRICTED;
1654 return S_OK;
1657 static HRESULT WINAPI connection_cost_GetDataPlanStatus(
1658 INetworkConnectionCost *iface, NLM_DATAPLAN_STATUS *pDataPlanStatus )
1660 struct connection *conn = impl_from_INetworkConnectionCost( iface );
1662 FIXME( "%p, %p\n", iface, pDataPlanStatus );
1664 if (!pDataPlanStatus) return E_POINTER;
1666 memcpy( &pDataPlanStatus->InterfaceGuid, &conn->id, sizeof(conn->id) );
1667 pDataPlanStatus->UsageData.UsageInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1668 memset( &pDataPlanStatus->UsageData.LastSyncTime, 0, sizeof(pDataPlanStatus->UsageData.LastSyncTime) );
1669 pDataPlanStatus->DataLimitInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1670 pDataPlanStatus->InboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1671 pDataPlanStatus->OutboundBandwidthInKbps = NLM_UNKNOWN_DATAPLAN_STATUS;
1672 memset( &pDataPlanStatus->NextBillingCycle, 0, sizeof(pDataPlanStatus->NextBillingCycle) );
1673 pDataPlanStatus->MaxTransferSizeInMegabytes = NLM_UNKNOWN_DATAPLAN_STATUS;
1674 pDataPlanStatus->Reserved = 0;
1676 return S_OK;
1679 static const INetworkConnectionCostVtbl connection_cost_vtbl =
1681 connection_cost_QueryInterface,
1682 connection_cost_AddRef,
1683 connection_cost_Release,
1684 connection_cost_GetCost,
1685 connection_cost_GetDataPlanStatus
1688 static struct connection *create_connection( const GUID *id )
1690 struct connection *ret;
1692 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
1694 ret->INetworkConnection_iface.lpVtbl = &connection_vtbl;
1695 ret->INetworkConnectionCost_iface.lpVtbl = &connection_cost_vtbl;
1696 ret->refs = 1;
1697 ret->id = *id;
1698 ret->network = NULL;
1699 ret->connected = VARIANT_FALSE;
1700 ret->connected_to_internet = VARIANT_FALSE;
1701 list_init( &ret->entry );
1703 return ret;
1706 static void init_networks( struct list_manager *mgr )
1708 DWORD size = 0;
1709 IP_ADAPTER_ADDRESSES *buf, *aa;
1710 GUID id;
1711 ULONG ret, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
1712 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_GATEWAYS;
1714 list_init( &mgr->networks );
1715 list_init( &mgr->connections );
1717 ret = GetAdaptersAddresses( WS_AF_UNSPEC, flags, NULL, NULL, &size );
1718 if (ret != ERROR_BUFFER_OVERFLOW) return;
1720 if (!(buf = heap_alloc( size ))) return;
1721 if (GetAdaptersAddresses( WS_AF_UNSPEC, flags, NULL, buf, &size ))
1723 heap_free( buf );
1724 return;
1727 memset( &id, 0, sizeof(id) );
1728 for (aa = buf; aa; aa = aa->Next)
1730 struct network *network;
1731 struct connection *connection;
1733 id.Data1 = aa->u.s.IfIndex;
1735 /* assume a one-to-one mapping between networks and connections */
1736 if (!(network = create_network( &id ))) goto done;
1737 if (!(connection = create_connection( &id )))
1739 INetwork_Release( &network->INetwork_iface );
1740 goto done;
1743 if (aa->FirstUnicastAddress)
1745 network->connected = VARIANT_TRUE;
1746 connection->connected = VARIANT_TRUE;
1748 if (aa->FirstGatewayAddress)
1750 network->connected_to_internet = VARIANT_TRUE;
1751 connection->connected_to_internet = VARIANT_TRUE;
1754 connection->network = &network->INetwork_iface;
1755 INetwork_AddRef( connection->network );
1757 list_add_tail( &mgr->networks, &network->entry );
1758 list_add_tail( &mgr->connections, &connection->entry );
1761 done:
1762 heap_free( buf );
1765 HRESULT list_manager_create( void **obj )
1767 struct list_manager *mgr;
1769 TRACE( "%p\n", obj );
1771 if (!(mgr = heap_alloc( sizeof(*mgr) ))) return E_OUTOFMEMORY;
1772 mgr->INetworkListManager_iface.lpVtbl = &list_manager_vtbl;
1773 mgr->INetworkCostManager_iface.lpVtbl = &cost_manager_vtbl;
1774 mgr->IConnectionPointContainer_iface.lpVtbl = &cpc_vtbl;
1775 init_networks( mgr );
1776 mgr->refs = 1;
1778 connection_point_init( &mgr->list_mgr_cp, &IID_INetworkListManagerEvents,
1779 &mgr->IConnectionPointContainer_iface );
1780 connection_point_init( &mgr->cost_mgr_cp, &IID_INetworkCostManagerEvents,
1781 &mgr->IConnectionPointContainer_iface);
1782 connection_point_init( &mgr->conn_mgr_cp, &IID_INetworkConnectionEvents,
1783 &mgr->IConnectionPointContainer_iface );
1785 *obj = &mgr->INetworkListManager_iface;
1786 TRACE( "returning iface %p\n", *obj );
1787 return S_OK;