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 pHead
;
35 PINetConnectionItem 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
);
60 NETCON_PROPERTIES Props
;
64 VOID
NormalizeOperStatus(MIB_IFROW
*IfEntry
, NETCON_PROPERTIES
* Props
);
66 CNetConnectionManager::CNetConnectionManager()
75 CNetConnectionManager::QueryInterface(
81 if (IsEqualIID(iid
, IID_IUnknown
) ||
82 IsEqualIID(iid
, IID_INetConnectionManager
))
84 *ppvObj
= (INetConnectionManager
*)this;
94 CNetConnectionManager::AddRef()
96 ULONG refCount
= InterlockedIncrement(&ref
);
103 CNetConnectionManager::Release()
105 ULONG refCount
= InterlockedDecrement(&ref
);
115 CNetConnectionManager::EnumConnections(
116 NETCONMGR_ENUM_FLAGS Flags
,
117 IEnumNetConnection
**ppEnum
)
119 TRACE("EnumConnections\n");
124 if (Flags
!= NCME_DEFAULT
)
127 *ppEnum
= (IEnumNetConnection
*)this;
132 /***************************************************************
133 * INetConnection Interface
136 CNetConnection::CNetConnection(PINetConnectionItem pItem
)
139 dwAdapterIndex
= pItem
->dwAdapterIndex
;
140 CopyMemory(&Props
, &pItem
->Props
, sizeof(NETCON_PROPERTIES
));
142 if (pItem
->Props
.pszwName
)
144 Props
.pszwName
= (LPWSTR
)CoTaskMemAlloc((wcslen(pItem
->Props
.pszwName
)+1)*sizeof(WCHAR
));
146 wcscpy(Props
.pszwName
, pItem
->Props
.pszwName
);
149 if (pItem
->Props
.pszwDeviceName
)
151 Props
.pszwDeviceName
= (LPWSTR
)CoTaskMemAlloc((wcslen(pItem
->Props
.pszwDeviceName
)+1)*sizeof(WCHAR
));
152 if (Props
.pszwDeviceName
)
153 wcscpy(Props
.pszwDeviceName
, pItem
->Props
.pszwDeviceName
);
159 CNetConnection::QueryInterface(
165 if (IsEqualIID(iid
, IID_IUnknown
) ||
166 IsEqualIID(iid
, IID_INetConnection
))
173 return E_NOINTERFACE
;
178 CNetConnection::AddRef()
180 ULONG refCount
= InterlockedIncrement(&ref
);
187 CNetConnection::Release()
189 ULONG refCount
= InterlockedDecrement(&ref
);
193 CoTaskMemFree(Props
.pszwName
);
194 CoTaskMemFree(Props
.pszwDeviceName
);
203 CNetConnection::Connect()
210 CNetConnection::Disconnect()
217 CNetConnection::Delete()
224 CNetConnection::Duplicate(
225 LPCWSTR pszwDuplicateName
,
226 INetConnection
**ppCon
)
233 CNetConnection::GetProperties(NETCON_PROPERTIES
**ppProps
)
239 DWORD dwShowIcon
, dwType
, dwSize
;
240 NETCON_PROPERTIES
* pProperties
;
246 pProperties
= (NETCON_PROPERTIES
*)CoTaskMemAlloc(sizeof(NETCON_PROPERTIES
));
248 return E_OUTOFMEMORY
;
250 CopyMemory(pProperties
, &Props
, sizeof(NETCON_PROPERTIES
));
251 pProperties
->pszwName
= NULL
;
253 if (Props
.pszwDeviceName
)
255 pProperties
->pszwDeviceName
= (LPWSTR
)CoTaskMemAlloc((wcslen(Props
.pszwDeviceName
)+1)*sizeof(WCHAR
));
256 if (pProperties
->pszwDeviceName
)
257 wcscpy(pProperties
->pszwDeviceName
, Props
.pszwDeviceName
);
260 *ppProps
= pProperties
;
262 /* get updated adapter characteristics */
263 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
264 IfEntry
.dwIndex
= dwAdapterIndex
;
265 if(GetIfEntry(&IfEntry
) != NO_ERROR
)
268 NormalizeOperStatus(&IfEntry
, pProperties
);
271 hr
= StringFromCLSID((CLSID
)Props
.guidId
, &pStr
);
274 wcscpy(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
275 wcscat(szName
, pStr
);
276 wcscat(szName
, L
"\\Connection");
278 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
280 dwSize
= sizeof(dwShowIcon
);
281 if (RegQueryValueExW(hKey
, L
"ShowIcon", NULL
, &dwType
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
&& dwType
== REG_DWORD
)
284 pProperties
->dwCharacter
|= NCCF_SHOW_ICON
;
286 pProperties
->dwCharacter
&= ~NCCF_SHOW_ICON
;
288 dwSize
= sizeof(szName
);
289 if (RegQueryValueExW(hKey
, L
"Name", NULL
, &dwType
, (LPBYTE
)szName
, &dwSize
) == ERROR_SUCCESS
)
291 /* use updated name */
292 dwSize
= wcslen(szName
) + 1;
293 pProperties
->pszwName
= (LPWSTR
)CoTaskMemAlloc(dwSize
* sizeof(WCHAR
));
294 if (pProperties
->pszwName
)
295 CopyMemory(pProperties
->pszwName
, szName
, dwSize
* sizeof(WCHAR
));
299 /* use cached name */
302 pProperties
->pszwName
= (LPWSTR
)CoTaskMemAlloc((wcslen(Props
.pszwName
)+1)*sizeof(WCHAR
));
303 if (pProperties
->pszwName
)
304 wcscpy(pProperties
->pszwName
, Props
.pszwName
);
317 CNetConnection::GetUiObjectClassId(CLSID
*pclsid
)
319 if (Props
.MediaType
== NCM_LAN
)
321 CopyMemory(pclsid
, &CLSID_LANConnectUI
, sizeof(CLSID
));
330 CNetConnection::Rename(LPCWSTR pszwDuplicateName
)
335 HRESULT WINAPI
IConnection_Constructor(INetConnection
**ppv
, PINetConnectionItem pItem
)
340 CNetConnection
*pConnection
= new CNetConnection(pItem
);
342 return E_OUTOFMEMORY
;
344 pConnection
->AddRef();
345 *ppv
= (INetConnection
*)pConnection
;
351 /***************************************************************
352 * IEnumNetConnection Interface
357 CNetConnectionManager::Next(
359 INetConnection
**rgelt
,
364 if (!pceltFetched
|| !rgelt
)
373 hr
= IConnection_Constructor(rgelt
, pCurrent
);
374 pCurrent
= pCurrent
->Next
;
381 CNetConnectionManager::Skip(ULONG celt
)
383 while(pCurrent
&& celt
-- > 0)
384 pCurrent
= pCurrent
->Next
;
395 CNetConnectionManager::Reset()
403 CNetConnectionManager::Clone(IEnumNetConnection
**ppenum
)
409 GetAdapterIndexFromNetCfgInstanceId(PIP_ADAPTER_INFO pAdapterInfo
, LPWSTR szNetCfg
, PDWORD pIndex
)
412 IP_ADAPTER_INFO
* pCurrentAdapter
;
414 pCurrentAdapter
= pAdapterInfo
;
415 while(pCurrentAdapter
)
418 if (MultiByteToWideChar(CP_ACP
, 0, pCurrentAdapter
->AdapterName
, -1, szBuffer
, sizeof(szBuffer
)/sizeof(szBuffer
[0])))
420 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
422 if (!_wcsicmp(szBuffer
, szNetCfg
))
424 *pIndex
= pCurrentAdapter
->Index
;
427 pCurrentAdapter
= pCurrentAdapter
->Next
;
435 NETCON_PROPERTIES
* Props
)
437 switch(IfEntry
->dwOperStatus
)
439 case MIB_IF_OPER_STATUS_NON_OPERATIONAL
:
440 Props
->Status
= NCS_HARDWARE_DISABLED
;
442 case MIB_IF_OPER_STATUS_UNREACHABLE
:
443 Props
->Status
= NCS_DISCONNECTED
;
445 case MIB_IF_OPER_STATUS_DISCONNECTED
:
446 Props
->Status
= NCS_MEDIA_DISCONNECTED
;
448 case MIB_IF_OPER_STATUS_CONNECTING
:
449 Props
->Status
= NCS_CONNECTING
;
451 case MIB_IF_OPER_STATUS_CONNECTED
:
452 Props
->Status
= NCS_CONNECTED
;
454 case MIB_IF_OPER_STATUS_OPERATIONAL
:
455 Props
->Status
= NCS_CONNECTED
;
463 CNetConnectionManager::EnumerateINetConnections()
465 DWORD dwSize
, dwResult
, dwIndex
, dwAdapterIndex
, dwShowIcon
;
466 MIB_IFTABLE
*pIfTable
;
468 IP_ADAPTER_INFO
* pAdapterInfo
;
470 SP_DEVINFO_DATA DevInfo
;
473 WCHAR szAdapterNetCfg
[50];
474 WCHAR szDetail
[200] = L
"SYSTEM\\CurrentControlSet\\Control\\Class\\";
475 WCHAR szName
[130] = L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
476 PINetConnectionItem pCurrent
= NULL
;
478 /* get the IfTable */
480 if (GetIfTable(NULL
, &dwSize
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
)
483 pIfTable
= (PMIB_IFTABLE
)CoTaskMemAlloc(dwSize
);
487 dwResult
= GetIfTable(pIfTable
, &dwSize
, TRUE
);
488 if (dwResult
!= NO_ERROR
)
490 CoTaskMemFree(pIfTable
);
495 dwResult
= GetAdaptersInfo(NULL
, &dwSize
);
496 if (dwResult
!= ERROR_BUFFER_OVERFLOW
)
498 CoTaskMemFree(pIfTable
);
502 pAdapterInfo
= (PIP_ADAPTER_INFO
)CoTaskMemAlloc(dwSize
);
505 CoTaskMemFree(pIfTable
);
509 if (GetAdaptersInfo(pAdapterInfo
, &dwSize
) != NO_ERROR
)
511 CoTaskMemFree(pIfTable
);
512 CoTaskMemFree(pAdapterInfo
);
516 hInfo
= SetupDiGetClassDevs(&GUID_DEVCLASS_NET
, NULL
, NULL
, DIGCF_PRESENT
);
519 CoTaskMemFree(pIfTable
);
520 CoTaskMemFree(pAdapterInfo
);
527 ZeroMemory(&DevInfo
, sizeof(SP_DEVINFO_DATA
));
528 DevInfo
.cbSize
= sizeof(DevInfo
);
530 /* get device info */
531 if (!SetupDiEnumDeviceInfo(hInfo
, dwIndex
++, &DevInfo
))
534 /* get device software registry path */
535 if (!SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DRIVER
, NULL
, (LPBYTE
)&szDetail
[39], sizeof(szDetail
)/sizeof(WCHAR
) - 40, &dwSize
))
538 /* open device registry key */
539 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szDetail
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
542 /* query NetCfgInstanceId for current device */
543 dwSize
= sizeof(szNetCfg
);
544 if (RegQueryValueExW(hSubKey
, L
"NetCfgInstanceId", NULL
, NULL
, (LPBYTE
)szNetCfg
, &dwSize
) != ERROR_SUCCESS
)
546 RegCloseKey(hSubKey
);
549 RegCloseKey(hSubKey
);
551 /* get the current adapter index from NetCfgInstanceId */
552 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo
, szNetCfg
, &dwAdapterIndex
))
555 /* get detailed adapter info */
556 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
557 IfEntry
.dwIndex
= dwAdapterIndex
;
558 if(GetIfEntry(&IfEntry
) != NO_ERROR
)
561 /* allocate new INetConnectionItem */
562 PINetConnectionItem pNew
= (PINetConnectionItem
)CoTaskMemAlloc(sizeof(INetConnectionItem
));
566 ZeroMemory(pNew
, sizeof(INetConnectionItem
));
567 pNew
->dwAdapterIndex
= dwAdapterIndex
;
568 /* store NetCfgInstanceId */
569 CLSIDFromString(szNetCfg
, &pNew
->Props
.guidId
);
570 NormalizeOperStatus(&IfEntry
, &pNew
->Props
);
572 switch(IfEntry
.dwType
)
574 case IF_TYPE_ETHERNET_CSMACD
:
575 pNew
->Props
.MediaType
= NCM_LAN
;
577 case IF_TYPE_IEEE80211
:
578 pNew
->Props
.MediaType
= NCM_SHAREDACCESSHOST_RAS
;
583 /* open network connections details */
584 wcscpy(&szName
[80], szNetCfg
);
585 wcscpy(&szName
[118], L
"\\Connection");
587 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
589 /* retrieve name of connection */
590 dwSize
= sizeof(szAdapterNetCfg
);
591 if (RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
593 pNew
->Props
.pszwName
= (LPWSTR
)CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
594 if (pNew
->Props
.pszwName
)
595 wcscpy(pNew
->Props
.pszwName
, szAdapterNetCfg
);
597 dwSize
= sizeof(dwShowIcon
);
598 if (RegQueryValueExW(hSubKey
, L
"ShowIcon", NULL
, NULL
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
)
601 pNew
->Props
.dwCharacter
|= NCCF_SHOW_ICON
;
603 RegCloseKey(hSubKey
);
606 /* Get the adapter device description */
608 SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, NULL
, 0, &dwSize
);
611 pNew
->Props
.pszwDeviceName
= (LPWSTR
)CoTaskMemAlloc(dwSize
);
612 if (pNew
->Props
.pszwDeviceName
)
613 SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, (PBYTE
)pNew
->Props
.pszwDeviceName
, dwSize
, &dwSize
);
617 pCurrent
->Next
= pNew
;
624 CoTaskMemFree(pIfTable
);
625 CoTaskMemFree(pAdapterInfo
);
626 SetupDiDestroyDeviceInfoList(hInfo
);
628 this->pCurrent
= pHead
;
632 HRESULT WINAPI
INetConnectionManager_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
634 TRACE("INetConnectionManager_Constructor\n");
639 return CLASS_E_NOAGGREGATION
;
641 CNetConnectionManager
*pConnectionMgr
= new CNetConnectionManager
;
643 return E_OUTOFMEMORY
;
645 pConnectionMgr
->AddRef();
646 HRESULT hr
= pConnectionMgr
->QueryInterface(riid
, ppv
);
649 pConnectionMgr
->EnumerateINetConnections();
651 pConnectionMgr
->Release();