3 typedef struct tagINetConnectionItem
5 struct tagINetConnectionItem
* Next
;
7 NETCON_PROPERTIES Props
;
8 }INetConnectionItem
, *PINetConnectionItem
;
12 const INetConnectionManagerVtbl
* lpVtbl
;
13 const IEnumNetConnectionVtbl
* lpVtblNetConnection
;
15 PINetConnectionItem pHead
;
16 PINetConnectionItem pCurrent
;
18 } INetConnectionManagerImpl
, *LPINetConnectionManagerImpl
;
22 const INetConnectionVtbl
* lpVtbl
;
24 NETCON_PROPERTIES Props
;
26 } INetConnectionImpl
, *LPINetConnectionImpl
;
29 static __inline LPINetConnectionManagerImpl
impl_from_EnumNetConnection(IEnumNetConnection
*iface
)
31 return (LPINetConnectionManagerImpl
)((char *)iface
- FIELD_OFFSET(INetConnectionManagerImpl
, lpVtblNetConnection
));
34 VOID
NormalizeOperStatus(MIB_IFROW
*IfEntry
, NETCON_PROPERTIES
* Props
);
39 INetConnectionManager_fnQueryInterface(
40 INetConnectionManager
* iface
,
44 INetConnectionManagerImpl
* This
= (INetConnectionManagerImpl
*)iface
;
47 if (IsEqualIID (iid
, &IID_IUnknown
) ||
48 IsEqualIID (iid
, &IID_INetConnectionManager
))
51 INetConnectionManager_AddRef(iface
);
61 INetConnectionManager_fnAddRef(
62 INetConnectionManager
* iface
)
64 INetConnectionManagerImpl
* This
= (INetConnectionManagerImpl
*)iface
;
65 ULONG refCount
= InterlockedIncrement(&This
->ref
);
73 INetConnectionManager_fnRelease(
74 INetConnectionManager
* iface
)
76 INetConnectionManagerImpl
* This
= (INetConnectionManagerImpl
*)iface
;
77 ULONG refCount
= InterlockedDecrement(&This
->ref
);
89 INetConnectionManager_fnEnumConnections(
90 INetConnectionManager
* iface
,
91 NETCONMGR_ENUM_FLAGS Flags
,
92 IEnumNetConnection
**ppEnum
)
94 INetConnectionManagerImpl
* This
= (INetConnectionManagerImpl
*)iface
;
99 if (Flags
!= NCME_DEFAULT
)
102 *ppEnum
= (IEnumNetConnection
*)&This
->lpVtblNetConnection
;
103 INetConnectionManager_AddRef(iface
);
107 static const INetConnectionManagerVtbl vt_NetConnectionManager
=
109 INetConnectionManager_fnQueryInterface
,
110 INetConnectionManager_fnAddRef
,
111 INetConnectionManager_fnRelease
,
112 INetConnectionManager_fnEnumConnections
,
115 /***************************************************************
116 * INetConnection Interface
122 INetConnection_fnQueryInterface(
123 INetConnection
* iface
,
127 INetConnectionImpl
* This
= (INetConnectionImpl
*)iface
;
130 if (IsEqualIID (iid
, &IID_IUnknown
) ||
131 IsEqualIID (iid
, &IID_INetConnection
))
134 INetConnection_AddRef(iface
);
138 return E_NOINTERFACE
;
144 INetConnection_fnAddRef(
145 INetConnection
* iface
)
147 INetConnectionImpl
* This
= (INetConnectionImpl
*)iface
;
148 ULONG refCount
= InterlockedIncrement(&This
->ref
);
156 INetConnection_fnRelease(
157 INetConnection
* iface
)
159 INetConnectionImpl
* This
= (INetConnectionImpl
*)iface
;
160 ULONG refCount
= InterlockedDecrement(&This
->ref
);
164 CoTaskMemFree(This
->Props
.pszwName
);
165 CoTaskMemFree(This
->Props
.pszwDeviceName
);
174 INetConnection_fnConnect(
175 INetConnection
* iface
)
183 INetConnection_fnDisconnect(
184 INetConnection
* iface
)
193 INetConnection_fnDelete(
194 INetConnection
* iface
)
202 INetConnection_fnDuplicate(
203 INetConnection
* iface
,
204 LPCWSTR pszwDuplicateName
,
205 INetConnection
**ppCon
)
213 INetConnection_fnGetProperties(
214 INetConnection
* iface
,
215 NETCON_PROPERTIES
**ppProps
)
221 DWORD dwShowIcon
, dwType
, dwSize
;
222 NETCON_PROPERTIES
* pProperties
;
225 INetConnectionImpl
* This
= (INetConnectionImpl
*)iface
;
230 pProperties
= CoTaskMemAlloc(sizeof(NETCON_PROPERTIES
));
232 return E_OUTOFMEMORY
;
235 CopyMemory(pProperties
, &This
->Props
, sizeof(NETCON_PROPERTIES
));
236 pProperties
->pszwName
= NULL
;
238 if (This
->Props
.pszwDeviceName
)
240 pProperties
->pszwDeviceName
= CoTaskMemAlloc((wcslen(This
->Props
.pszwDeviceName
)+1)*sizeof(WCHAR
));
241 if (pProperties
->pszwDeviceName
)
242 wcscpy(pProperties
->pszwDeviceName
, This
->Props
.pszwDeviceName
);
245 *ppProps
= pProperties
;
247 /* get updated adapter characteristics */
248 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
249 IfEntry
.dwIndex
= This
->dwAdapterIndex
;
250 if(GetIfEntry(&IfEntry
) != NO_ERROR
)
253 NormalizeOperStatus(&IfEntry
, pProperties
);
256 hr
= StringFromCLSID(&This
->Props
.guidId
, &pStr
);
259 wcscpy(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
260 wcscat(szName
, pStr
);
261 wcscat(szName
, L
"\\Connection");
263 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
265 dwSize
= sizeof(dwShowIcon
);
266 if (RegQueryValueExW(hKey
, L
"ShowIcon", NULL
, &dwType
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
&& dwType
== REG_DWORD
)
269 pProperties
->dwCharacter
|= NCCF_SHOW_ICON
;
271 pProperties
->dwCharacter
&= ~NCCF_SHOW_ICON
;
273 dwSize
= sizeof(szName
);
274 if (RegQueryValueExW(hKey
, L
"Name", NULL
, &dwType
, (LPBYTE
)szName
, &dwSize
) == ERROR_SUCCESS
)
276 /* use updated name */
277 dwSize
= wcslen(szName
) + 1;
278 pProperties
->pszwName
= CoTaskMemAlloc(dwSize
* sizeof(WCHAR
));
279 if (pProperties
->pszwName
)
280 CopyMemory(pProperties
->pszwName
, szName
, dwSize
* sizeof(WCHAR
));
284 /* use cached name */
285 if (This
->Props
.pszwName
)
287 pProperties
->pszwName
= CoTaskMemAlloc((wcslen(This
->Props
.pszwName
)+1)*sizeof(WCHAR
));
288 if (pProperties
->pszwName
)
289 wcscpy(pProperties
->pszwName
, This
->Props
.pszwName
);
304 INetConnection_fnGetUiObjectClassId(
305 INetConnection
* iface
,
309 INetConnectionImpl
* This
= (INetConnectionImpl
*)iface
;
311 if (This
->Props
.MediaType
== NCM_LAN
)
313 CopyMemory(pclsid
, &CLSID_LANConnectUI
, sizeof(CLSID
));
323 INetConnection_fnRename(
324 INetConnection
* iface
,
325 LPCWSTR pszwDuplicateName
)
331 static const INetConnectionVtbl vt_NetConnection
=
333 INetConnection_fnQueryInterface
,
334 INetConnection_fnAddRef
,
335 INetConnection_fnRelease
,
336 INetConnection_fnConnect
,
337 INetConnection_fnDisconnect
,
338 INetConnection_fnDelete
,
339 INetConnection_fnDuplicate
,
340 INetConnection_fnGetProperties
,
341 INetConnection_fnGetUiObjectClassId
,
342 INetConnection_fnRename
345 HRESULT WINAPI
IConnection_Constructor (INetConnection
**ppv
, PINetConnectionItem pItem
)
347 INetConnectionImpl
*This
;
352 This
= (INetConnectionImpl
*) CoTaskMemAlloc(sizeof (INetConnectionImpl
));
354 return E_OUTOFMEMORY
;
357 This
->lpVtbl
= &vt_NetConnection
;
358 This
->dwAdapterIndex
= pItem
->dwAdapterIndex
;
359 CopyMemory(&This
->Props
, &pItem
->Props
, sizeof(NETCON_PROPERTIES
));
361 if (pItem
->Props
.pszwName
)
363 This
->Props
.pszwName
= CoTaskMemAlloc((wcslen(pItem
->Props
.pszwName
)+1)*sizeof(WCHAR
));
364 if (This
->Props
.pszwName
)
365 wcscpy(This
->Props
.pszwName
, pItem
->Props
.pszwName
);
368 if (pItem
->Props
.pszwDeviceName
)
370 This
->Props
.pszwDeviceName
= CoTaskMemAlloc((wcslen(pItem
->Props
.pszwDeviceName
)+1)*sizeof(WCHAR
));
371 if (This
->Props
.pszwDeviceName
)
372 wcscpy(This
->Props
.pszwDeviceName
, pItem
->Props
.pszwDeviceName
);
375 *ppv
= (INetConnection
*)This
;
382 /***************************************************************
383 * IEnumNetConnection Interface
389 IEnumNetConnection_fnQueryInterface(
390 IEnumNetConnection
* iface
,
394 INetConnectionManagerImpl
* This
= impl_from_EnumNetConnection(iface
);
397 if (IsEqualIID (iid
, &IID_IUnknown
) ||
398 IsEqualIID (iid
, &IID_INetConnectionManager
))
401 INetConnectionManager_AddRef(iface
);
405 return E_NOINTERFACE
;
411 IEnumNetConnection_fnAddRef(
412 IEnumNetConnection
* iface
)
414 INetConnectionManagerImpl
* This
= impl_from_EnumNetConnection(iface
);
415 ULONG refCount
= InterlockedIncrement(&This
->ref
);
423 IEnumNetConnection_fnRelease(
424 IEnumNetConnection
* iface
)
426 INetConnectionManagerImpl
* This
= impl_from_EnumNetConnection(iface
);
427 ULONG refCount
= InterlockedDecrement(&This
->ref
);
431 CoTaskMemFree (This
);
439 IEnumNetConnection_fnNext(
440 IEnumNetConnection
* iface
,
442 INetConnection
**rgelt
,
445 INetConnectionManagerImpl
* This
= impl_from_EnumNetConnection(iface
);
448 if (!pceltFetched
|| !rgelt
)
457 hr
= IConnection_Constructor(rgelt
, This
->pCurrent
);
458 This
->pCurrent
= This
->pCurrent
->Next
;
466 IEnumNetConnection_fnSkip(
467 IEnumNetConnection
* iface
,
470 INetConnectionManagerImpl
* This
= impl_from_EnumNetConnection(iface
);
472 while(This
->pCurrent
&& celt
-- > 0)
473 This
->pCurrent
= This
->pCurrent
->Next
;
485 IEnumNetConnection_fnReset(
486 IEnumNetConnection
* iface
)
488 INetConnectionManagerImpl
* This
= impl_from_EnumNetConnection(iface
);
490 This
->pCurrent
= This
->pHead
;
497 IEnumNetConnection_fnClone(
498 IEnumNetConnection
* iface
,
499 IEnumNetConnection
**ppenum
)
504 static const IEnumNetConnectionVtbl vt_EnumNetConnection
=
506 IEnumNetConnection_fnQueryInterface
,
507 IEnumNetConnection_fnAddRef
,
508 IEnumNetConnection_fnRelease
,
509 IEnumNetConnection_fnNext
,
510 IEnumNetConnection_fnSkip
,
511 IEnumNetConnection_fnReset
,
512 IEnumNetConnection_fnClone
517 GetAdapterIndexFromNetCfgInstanceId(PIP_ADAPTER_INFO pAdapterInfo
, LPWSTR szNetCfg
, PDWORD pIndex
)
520 IP_ADAPTER_INFO
* pCurrentAdapter
;
522 pCurrentAdapter
= pAdapterInfo
;
523 while(pCurrentAdapter
)
526 if (MultiByteToWideChar(CP_ACP
, 0, pCurrentAdapter
->AdapterName
, -1, szBuffer
, sizeof(szBuffer
)/sizeof(szBuffer
[0])))
528 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
530 if (!_wcsicmp(szBuffer
, szNetCfg
))
532 *pIndex
= pCurrentAdapter
->Index
;
535 pCurrentAdapter
= pCurrentAdapter
->Next
;
543 NETCON_PROPERTIES
* Props
)
545 switch(IfEntry
->dwOperStatus
)
547 case MIB_IF_OPER_STATUS_NON_OPERATIONAL
:
548 Props
->Status
= NCS_HARDWARE_DISABLED
;
550 case MIB_IF_OPER_STATUS_UNREACHABLE
:
551 Props
->Status
= NCS_DISCONNECTED
;
553 case MIB_IF_OPER_STATUS_DISCONNECTED
:
554 Props
->Status
= NCS_MEDIA_DISCONNECTED
;
556 case MIB_IF_OPER_STATUS_CONNECTING
:
557 Props
->Status
= NCS_CONNECTING
;
559 case MIB_IF_OPER_STATUS_CONNECTED
:
560 Props
->Status
= NCS_CONNECTED
;
562 case MIB_IF_OPER_STATUS_OPERATIONAL
:
563 Props
->Status
= NCS_CONNECTED
;
573 EnumerateINetConnections(INetConnectionManagerImpl
*This
)
575 DWORD dwSize
, dwResult
, dwIndex
, dwAdapterIndex
, dwShowIcon
;
576 MIB_IFTABLE
*pIfTable
;
578 IP_ADAPTER_INFO
* pAdapterInfo
;
580 SP_DEVINFO_DATA DevInfo
;
583 WCHAR szAdapterNetCfg
[50];
584 WCHAR szDetail
[200] = L
"SYSTEM\\CurrentControlSet\\Control\\Class\\";
585 WCHAR szName
[130] = L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
586 PINetConnectionItem pNew
;
587 PINetConnectionItem pCurrent
= NULL
;
589 /* get the IfTable */
591 if (GetIfTable(NULL
, &dwSize
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
)
594 pIfTable
= (PMIB_IFTABLE
)CoTaskMemAlloc(dwSize
);
598 dwResult
= GetIfTable(pIfTable
, &dwSize
, TRUE
);
599 if (dwResult
!= NO_ERROR
)
601 CoTaskMemFree(pIfTable
);
606 dwResult
= GetAdaptersInfo(NULL
, &dwSize
);
607 if (dwResult
!= ERROR_BUFFER_OVERFLOW
)
609 CoTaskMemFree(pIfTable
);
613 pAdapterInfo
= (PIP_ADAPTER_INFO
)CoTaskMemAlloc(dwSize
);
616 CoTaskMemFree(pIfTable
);
620 if (GetAdaptersInfo(pAdapterInfo
, &dwSize
) != NO_ERROR
)
622 CoTaskMemFree(pIfTable
);
623 CoTaskMemFree(pAdapterInfo
);
628 hInfo
= SetupDiGetClassDevs(&GUID_DEVCLASS_NET
, NULL
, NULL
, DIGCF_PRESENT
);
631 CoTaskMemFree(pIfTable
);
632 CoTaskMemFree(pAdapterInfo
);
640 ZeroMemory(&DevInfo
, sizeof(SP_DEVINFO_DATA
));
641 DevInfo
.cbSize
= sizeof(DevInfo
);
643 /* get device info */
644 if (!SetupDiEnumDeviceInfo(hInfo
, dwIndex
++, &DevInfo
))
647 /* get device software registry path */
648 if (!SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DRIVER
, NULL
, (LPBYTE
)&szDetail
[39], sizeof(szDetail
)/sizeof(WCHAR
) - 40, &dwSize
))
651 /* open device registry key */
652 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szDetail
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
655 /* query NetCfgInstanceId for current device */
656 dwSize
= sizeof(szNetCfg
);
657 if (RegQueryValueExW(hSubKey
, L
"NetCfgInstanceId", NULL
, NULL
, (LPBYTE
)szNetCfg
, &dwSize
) != ERROR_SUCCESS
)
659 RegCloseKey(hSubKey
);
662 RegCloseKey(hSubKey
);
664 /* get the current adapter index from NetCfgInstanceId */
665 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo
, szNetCfg
, &dwAdapterIndex
))
668 /* get detailed adapter info */
669 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
670 IfEntry
.dwIndex
= dwAdapterIndex
;
671 if(GetIfEntry(&IfEntry
) != NO_ERROR
)
674 /* allocate new INetConnectionItem */
675 pNew
= CoTaskMemAlloc(sizeof(INetConnectionItem
));
679 ZeroMemory(pNew
, sizeof(INetConnectionItem
));
680 pNew
->dwAdapterIndex
= dwAdapterIndex
;
681 /* store NetCfgInstanceId */
682 CLSIDFromString(szNetCfg
, &pNew
->Props
.guidId
);
683 NormalizeOperStatus(&IfEntry
, &pNew
->Props
);
685 switch(IfEntry
.dwType
)
687 case IF_TYPE_ETHERNET_CSMACD
:
688 pNew
->Props
.MediaType
= NCM_LAN
;
690 case IF_TYPE_IEEE80211
:
691 pNew
->Props
.MediaType
= NCM_SHAREDACCESSHOST_RAS
;
696 /* open network connections details */
697 wcscpy(&szName
[80], szNetCfg
);
698 wcscpy(&szName
[118], L
"\\Connection");
700 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
702 /* retrieve name of connection */
703 dwSize
= sizeof(szAdapterNetCfg
);
704 if (RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
706 pNew
->Props
.pszwName
= CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
707 if (pNew
->Props
.pszwName
)
708 wcscpy(pNew
->Props
.pszwName
, szAdapterNetCfg
);
710 dwSize
= sizeof(dwShowIcon
);
711 if (RegQueryValueExW(hSubKey
, L
"ShowIcon", NULL
, NULL
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
)
714 pNew
->Props
.dwCharacter
|= NCCF_SHOW_ICON
;
716 RegCloseKey(hSubKey
);
718 if (SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, (PBYTE
)szNetCfg
, sizeof(szNetCfg
)/sizeof(WCHAR
), &dwSize
))
720 szNetCfg
[(sizeof(szNetCfg
)/sizeof(WCHAR
))-1] = L
'\0';
721 pNew
->Props
.pszwDeviceName
= CoTaskMemAlloc((wcslen(szNetCfg
)+1) * sizeof(WCHAR
));
722 if (pNew
->Props
.pszwDeviceName
)
723 wcscpy(pNew
->Props
.pszwDeviceName
, szNetCfg
);
727 pCurrent
->Next
= pNew
;
734 CoTaskMemFree(pIfTable
);
735 CoTaskMemFree(pAdapterInfo
);
736 SetupDiDestroyDeviceInfoList(hInfo
);
738 This
->pCurrent
= This
->pHead
;
742 HRESULT WINAPI
INetConnectionManager_Constructor (IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
744 INetConnectionManagerImpl
*sf
;
749 return CLASS_E_NOAGGREGATION
;
751 sf
= (INetConnectionManagerImpl
*) CoTaskMemAlloc(sizeof (INetConnectionManagerImpl
));
753 return E_OUTOFMEMORY
;
756 sf
->lpVtbl
= &vt_NetConnectionManager
;
757 sf
->lpVtblNetConnection
= &vt_EnumNetConnection
;
762 if (!SUCCEEDED (INetConnectionManager_QueryInterface ((INetConnectionManager
*)sf
, riid
, ppv
)))
764 INetConnectionManager_Release((INetConnectionManager
*)sf
);
765 return E_NOINTERFACE
;
768 INetConnectionManager_Release((INetConnectionManager
*)sf
);
769 EnumerateINetConnections(sf
);