3 typedef struct tagINetConnectionItem
5 struct tagINetConnectionItem
* Next
;
7 NETCON_PROPERTIES Props
;
8 } INetConnectionItem
, *PINetConnectionItem
;
10 class CNetConnectionManager final
:
11 public INetConnectionManager
,
12 public IEnumNetConnection
15 CNetConnectionManager();
16 BOOL
EnumerateINetConnections();
19 virtual HRESULT WINAPI
QueryInterface(REFIID riid
, LPVOID
*ppvOut
);
20 virtual ULONG WINAPI
AddRef();
21 virtual ULONG WINAPI
Release();
23 // INetConnectionManager
24 virtual HRESULT WINAPI
EnumConnections(NETCONMGR_ENUM_FLAGS Flags
, IEnumNetConnection
**ppEnum
);
27 virtual HRESULT WINAPI
Next(ULONG celt
, INetConnection
**rgelt
, ULONG
*pceltFetched
);
28 virtual HRESULT WINAPI
Skip(ULONG celt
);
29 virtual HRESULT WINAPI
Reset();
30 virtual HRESULT WINAPI
Clone(IEnumNetConnection
**ppenum
);
34 PINetConnectionItem m_pHead
;
35 PINetConnectionItem m_pCurrent
;
38 class CNetConnection final
:
42 CNetConnection(PINetConnectionItem pItem
);
45 virtual HRESULT WINAPI
QueryInterface(REFIID riid
, LPVOID
*ppvOut
);
46 virtual ULONG WINAPI
AddRef();
47 virtual ULONG WINAPI
Release();
50 HRESULT WINAPI
Connect();
51 HRESULT WINAPI
Disconnect();
52 HRESULT WINAPI
Delete();
53 HRESULT WINAPI
Duplicate(LPCWSTR pszwDuplicateName
, INetConnection
**ppCon
);
54 HRESULT WINAPI
GetProperties(NETCON_PROPERTIES
**ppProps
);
55 HRESULT WINAPI
GetUiObjectClassId(CLSID
*pclsid
);
56 HRESULT WINAPI
Rename(LPCWSTR pszwDuplicateName
);
62 NETCON_PROPERTIES m_Props
;
63 DWORD m_dwAdapterIndex
;
66 VOID
NormalizeOperStatus(MIB_IFROW
*IfEntry
, NETCON_PROPERTIES
* Props
);
68 CNetConnectionManager::CNetConnectionManager() :
77 CNetConnectionManager::QueryInterface(
83 if (IsEqualIID(iid
, IID_IUnknown
) ||
84 IsEqualIID(iid
, IID_INetConnectionManager
))
86 *ppvObj
= static_cast<INetConnectionManager
*>(this);
96 CNetConnectionManager::AddRef()
98 ULONG refCount
= InterlockedIncrement(&m_ref
);
105 CNetConnectionManager::Release()
107 ULONG refCount
= InterlockedDecrement(&m_ref
);
117 CNetConnectionManager::EnumConnections(
118 NETCONMGR_ENUM_FLAGS Flags
,
119 IEnumNetConnection
**ppEnum
)
121 TRACE("EnumConnections\n");
126 if (Flags
!= NCME_DEFAULT
)
129 *ppEnum
= static_cast<IEnumNetConnection
*>(this);
134 /***************************************************************
135 * INetConnection Interface
138 CNetConnection::CNetConnection(PINetConnectionItem pItem
) :
140 m_Props(pItem
->Props
),
141 m_dwAdapterIndex(pItem
->dwAdapterIndex
)
143 if (pItem
->Props
.pszwName
)
145 m_Props
.pszwName
= static_cast<PWSTR
>(CoTaskMemAlloc((wcslen(pItem
->Props
.pszwName
)+1)*sizeof(WCHAR
)));
146 if (m_Props
.pszwName
)
147 wcscpy(m_Props
.pszwName
, pItem
->Props
.pszwName
);
150 if (pItem
->Props
.pszwDeviceName
)
152 m_Props
.pszwDeviceName
= static_cast<PWSTR
>(CoTaskMemAlloc((wcslen(pItem
->Props
.pszwDeviceName
)+1)*sizeof(WCHAR
)));
153 if (m_Props
.pszwDeviceName
)
154 wcscpy(m_Props
.pszwDeviceName
, pItem
->Props
.pszwDeviceName
);
158 CNetConnection::~CNetConnection()
160 CoTaskMemFree(m_Props
.pszwName
);
161 CoTaskMemFree(m_Props
.pszwDeviceName
);
166 CNetConnection::QueryInterface(
172 if (IsEqualIID(iid
, IID_IUnknown
) ||
173 IsEqualIID(iid
, IID_INetConnection
))
180 return E_NOINTERFACE
;
185 CNetConnection::AddRef()
187 ULONG refCount
= InterlockedIncrement(&m_ref
);
194 CNetConnection::Release()
196 ULONG refCount
= InterlockedDecrement(&m_ref
);
206 CNetConnection::Connect()
213 CNetConnection::Disconnect()
220 CNetConnection::Delete()
227 CNetConnection::Duplicate(
228 LPCWSTR pszwDuplicateName
,
229 INetConnection
**ppCon
)
236 CNetConnection::GetProperties(NETCON_PROPERTIES
**ppProps
)
242 DWORD dwShowIcon
, dwType
, dwSize
;
243 NETCON_PROPERTIES
* pProperties
;
249 pProperties
= static_cast<NETCON_PROPERTIES
*>(CoTaskMemAlloc(sizeof(NETCON_PROPERTIES
)));
251 return E_OUTOFMEMORY
;
253 CopyMemory(pProperties
, &m_Props
, sizeof(NETCON_PROPERTIES
));
254 pProperties
->pszwName
= NULL
;
256 if (m_Props
.pszwDeviceName
)
258 pProperties
->pszwDeviceName
= static_cast<LPWSTR
>(CoTaskMemAlloc((wcslen(m_Props
.pszwDeviceName
)+1)*sizeof(WCHAR
)));
259 if (pProperties
->pszwDeviceName
)
260 wcscpy(pProperties
->pszwDeviceName
, m_Props
.pszwDeviceName
);
263 *ppProps
= pProperties
;
265 /* get updated adapter characteristics */
266 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
267 IfEntry
.dwIndex
= m_dwAdapterIndex
;
268 if (GetIfEntry(&IfEntry
) != NO_ERROR
)
271 NormalizeOperStatus(&IfEntry
, pProperties
);
274 hr
= StringFromCLSID((CLSID
)m_Props
.guidId
, &pStr
);
277 wcscpy(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
278 wcscat(szName
, pStr
);
279 wcscat(szName
, L
"\\Connection");
281 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
283 dwSize
= sizeof(dwShowIcon
);
284 if (RegQueryValueExW(hKey
, L
"ShowIcon", NULL
, &dwType
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
&& dwType
== REG_DWORD
)
287 pProperties
->dwCharacter
|= NCCF_SHOW_ICON
;
289 pProperties
->dwCharacter
&= ~NCCF_SHOW_ICON
;
291 dwSize
= sizeof(szName
);
292 if (RegQueryValueExW(hKey
, L
"Name", NULL
, &dwType
, (LPBYTE
)szName
, &dwSize
) == ERROR_SUCCESS
)
294 /* use updated name */
295 dwSize
= wcslen(szName
) + 1;
296 pProperties
->pszwName
= static_cast<PWSTR
>(CoTaskMemAlloc(dwSize
* sizeof(WCHAR
)));
297 if (pProperties
->pszwName
)
298 CopyMemory(pProperties
->pszwName
, szName
, dwSize
* sizeof(WCHAR
));
302 /* use cached name */
303 if (m_Props
.pszwName
)
305 pProperties
->pszwName
= static_cast<PWSTR
>(CoTaskMemAlloc((wcslen(m_Props
.pszwName
)+1)*sizeof(WCHAR
)));
306 if (pProperties
->pszwName
)
307 wcscpy(pProperties
->pszwName
, m_Props
.pszwName
);
320 CNetConnection::GetUiObjectClassId(CLSID
*pclsid
)
322 if (m_Props
.MediaType
== NCM_LAN
)
324 CopyMemory(pclsid
, &CLSID_LanConnectionUi
, sizeof(CLSID
));
333 CNetConnection::Rename(LPCWSTR pszwDuplicateName
)
341 if (pszwDuplicateName
== NULL
|| wcslen(pszwDuplicateName
) == 0)
344 if (m_Props
.pszwName
)
346 CoTaskMemFree(m_Props
.pszwName
);
347 m_Props
.pszwName
= NULL
;
350 dwSize
= (wcslen(pszwDuplicateName
) + 1) * sizeof(WCHAR
);
351 m_Props
.pszwName
= static_cast<PWSTR
>(CoTaskMemAlloc(dwSize
));
352 if (m_Props
.pszwName
== NULL
)
353 return E_OUTOFMEMORY
;
355 wcscpy(m_Props
.pszwName
, pszwDuplicateName
);
357 hr
= StringFromCLSID((CLSID
)m_Props
.guidId
, &pStr
);
360 wcscpy(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
361 wcscat(szName
, pStr
);
362 wcscat(szName
, L
"\\Connection");
364 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_WRITE
, &hKey
) == ERROR_SUCCESS
)
366 RegSetValueExW(hKey
, L
"Name", NULL
, REG_SZ
, (LPBYTE
)m_Props
.pszwName
, dwSize
);
376 HRESULT WINAPI
IConnection_Constructor(INetConnection
**ppv
, PINetConnectionItem pItem
)
381 CNetConnection
*pConnection
= new CNetConnection(pItem
);
383 return E_OUTOFMEMORY
;
385 pConnection
->AddRef();
392 /***************************************************************
393 * IEnumNetConnection Interface
398 CNetConnectionManager::Next(
400 INetConnection
**rgelt
,
405 if (!pceltFetched
|| !rgelt
)
414 hr
= IConnection_Constructor(rgelt
, m_pCurrent
);
415 m_pCurrent
= m_pCurrent
->Next
;
422 CNetConnectionManager::Skip(ULONG celt
)
424 while (m_pCurrent
&& celt
-- > 0)
425 m_pCurrent
= m_pCurrent
->Next
;
436 CNetConnectionManager::Reset()
438 m_pCurrent
= m_pHead
;
444 CNetConnectionManager::Clone(IEnumNetConnection
**ppenum
)
450 GetAdapterIndexFromNetCfgInstanceId(PIP_ADAPTER_INFO pAdapterInfo
, LPWSTR szNetCfg
, PDWORD pIndex
)
453 IP_ADAPTER_INFO
* pCurrentAdapter
;
455 pCurrentAdapter
= pAdapterInfo
;
456 while (pCurrentAdapter
)
459 if (MultiByteToWideChar(CP_ACP
, 0, pCurrentAdapter
->AdapterName
, -1, szBuffer
, sizeof(szBuffer
)/sizeof(szBuffer
[0])))
461 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
463 if (!_wcsicmp(szBuffer
, szNetCfg
))
465 *pIndex
= pCurrentAdapter
->Index
;
468 pCurrentAdapter
= pCurrentAdapter
->Next
;
476 NETCON_PROPERTIES
* Props
)
478 switch (IfEntry
->dwOperStatus
)
480 case MIB_IF_OPER_STATUS_NON_OPERATIONAL
:
481 Props
->Status
= NCS_HARDWARE_DISABLED
;
483 case MIB_IF_OPER_STATUS_UNREACHABLE
:
484 Props
->Status
= NCS_DISCONNECTED
;
486 case MIB_IF_OPER_STATUS_DISCONNECTED
:
487 Props
->Status
= NCS_MEDIA_DISCONNECTED
;
489 case MIB_IF_OPER_STATUS_CONNECTING
:
490 Props
->Status
= NCS_CONNECTING
;
492 case MIB_IF_OPER_STATUS_CONNECTED
:
493 Props
->Status
= NCS_CONNECTED
;
495 case MIB_IF_OPER_STATUS_OPERATIONAL
:
496 Props
->Status
= NCS_CONNECTED
;
504 CNetConnectionManager::EnumerateINetConnections()
506 DWORD dwSize
, dwResult
, dwIndex
, dwAdapterIndex
, dwShowIcon
;
507 MIB_IFTABLE
*pIfTable
;
509 IP_ADAPTER_INFO
* pAdapterInfo
;
511 SP_DEVINFO_DATA DevInfo
;
514 WCHAR szAdapterNetCfg
[50];
515 WCHAR szDetail
[200] = L
"SYSTEM\\CurrentControlSet\\Control\\Class\\";
516 WCHAR szName
[130] = L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
517 PINetConnectionItem pCurrent
= NULL
;
519 /* get the IfTable */
521 if (GetIfTable(NULL
, &dwSize
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
)
524 pIfTable
= static_cast<PMIB_IFTABLE
>(CoTaskMemAlloc(dwSize
));
528 dwResult
= GetIfTable(pIfTable
, &dwSize
, TRUE
);
529 if (dwResult
!= NO_ERROR
)
531 CoTaskMemFree(pIfTable
);
536 dwResult
= GetAdaptersInfo(NULL
, &dwSize
);
537 if (dwResult
!= ERROR_BUFFER_OVERFLOW
)
539 CoTaskMemFree(pIfTable
);
543 pAdapterInfo
= static_cast<PIP_ADAPTER_INFO
>(CoTaskMemAlloc(dwSize
));
546 CoTaskMemFree(pIfTable
);
550 if (GetAdaptersInfo(pAdapterInfo
, &dwSize
) != NO_ERROR
)
552 CoTaskMemFree(pIfTable
);
553 CoTaskMemFree(pAdapterInfo
);
557 hInfo
= SetupDiGetClassDevs(&GUID_DEVCLASS_NET
, NULL
, NULL
, DIGCF_PRESENT
);
560 CoTaskMemFree(pIfTable
);
561 CoTaskMemFree(pAdapterInfo
);
568 ZeroMemory(&DevInfo
, sizeof(SP_DEVINFO_DATA
));
569 DevInfo
.cbSize
= sizeof(DevInfo
);
571 /* get device info */
572 if (!SetupDiEnumDeviceInfo(hInfo
, dwIndex
++, &DevInfo
))
575 /* get device software registry path */
576 if (!SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DRIVER
, NULL
, (LPBYTE
)&szDetail
[39], sizeof(szDetail
)/sizeof(WCHAR
) - 40, &dwSize
))
579 /* open device registry key */
580 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szDetail
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
583 /* query NetCfgInstanceId for current device */
584 dwSize
= sizeof(szNetCfg
);
585 if (RegQueryValueExW(hSubKey
, L
"NetCfgInstanceId", NULL
, NULL
, (LPBYTE
)szNetCfg
, &dwSize
) != ERROR_SUCCESS
)
587 RegCloseKey(hSubKey
);
590 RegCloseKey(hSubKey
);
592 /* get the current adapter index from NetCfgInstanceId */
593 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo
, szNetCfg
, &dwAdapterIndex
))
596 /* get detailed adapter info */
597 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
598 IfEntry
.dwIndex
= dwAdapterIndex
;
599 if (GetIfEntry(&IfEntry
) != NO_ERROR
)
602 /* allocate new INetConnectionItem */
603 PINetConnectionItem pNew
= static_cast<PINetConnectionItem
>(CoTaskMemAlloc(sizeof(INetConnectionItem
)));
607 ZeroMemory(pNew
, sizeof(INetConnectionItem
));
608 pNew
->dwAdapterIndex
= dwAdapterIndex
;
609 /* store NetCfgInstanceId */
610 CLSIDFromString(szNetCfg
, &pNew
->Props
.guidId
);
611 NormalizeOperStatus(&IfEntry
, &pNew
->Props
);
613 switch (IfEntry
.dwType
)
615 case IF_TYPE_ETHERNET_CSMACD
:
616 pNew
->Props
.MediaType
= NCM_LAN
;
618 case IF_TYPE_IEEE80211
:
619 pNew
->Props
.MediaType
= NCM_SHAREDACCESSHOST_RAS
;
624 /* open network connections details */
625 wcscpy(&szName
[80], szNetCfg
);
626 wcscpy(&szName
[118], L
"\\Connection");
628 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
630 /* retrieve name of connection */
631 dwSize
= sizeof(szAdapterNetCfg
);
632 if (RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
634 pNew
->Props
.pszwName
= static_cast<PWSTR
>(CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
)));
635 if (pNew
->Props
.pszwName
)
636 wcscpy(pNew
->Props
.pszwName
, szAdapterNetCfg
);
638 dwSize
= sizeof(dwShowIcon
);
639 if (RegQueryValueExW(hSubKey
, L
"ShowIcon", NULL
, NULL
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
)
642 pNew
->Props
.dwCharacter
|= NCCF_SHOW_ICON
;
644 RegCloseKey(hSubKey
);
647 /* Get the adapter device description */
649 SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, NULL
, 0, &dwSize
);
652 pNew
->Props
.pszwDeviceName
= static_cast<PWSTR
>(CoTaskMemAlloc(dwSize
));
653 if (pNew
->Props
.pszwDeviceName
)
654 SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, (PBYTE
)pNew
->Props
.pszwDeviceName
, dwSize
, &dwSize
);
658 pCurrent
->Next
= pNew
;
665 CoTaskMemFree(pIfTable
);
666 CoTaskMemFree(pAdapterInfo
);
667 SetupDiDestroyDeviceInfoList(hInfo
);
669 m_pCurrent
= m_pHead
;
673 HRESULT WINAPI
INetConnectionManager_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
675 TRACE("INetConnectionManager_Constructor\n");
680 return CLASS_E_NOAGGREGATION
;
682 CNetConnectionManager
*pConnectionMgr
= new CNetConnectionManager
;
684 return E_OUTOFMEMORY
;
686 pConnectionMgr
->AddRef();
687 HRESULT hr
= pConnectionMgr
->QueryInterface(riid
, ppv
);
690 pConnectionMgr
->EnumerateINetConnections();
692 pConnectionMgr
->Release();