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
)
338 if (pszwDuplicateName
== NULL
|| wcslen(pszwDuplicateName
) == 0)
343 CoTaskMemFree(Props
.pszwName
);
344 Props
.pszwName
= NULL
;
347 dwSize
= (wcslen(pszwDuplicateName
) + 1) * sizeof(WCHAR
);
348 Props
.pszwName
= (LPWSTR
)CoTaskMemAlloc(dwSize
);
349 if (Props
.pszwName
== NULL
)
350 return E_OUTOFMEMORY
;
352 wcscpy(Props
.pszwName
, pszwDuplicateName
);
354 hr
= StringFromCLSID((CLSID
)Props
.guidId
, &pStr
);
357 wcscpy(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
358 wcscat(szName
, pStr
);
359 wcscat(szName
, L
"\\Connection");
361 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_WRITE
, &hKey
) == ERROR_SUCCESS
)
363 RegSetValueExW(hKey
, L
"Name", NULL
, REG_SZ
, (LPBYTE
)Props
.pszwName
, dwSize
);
373 HRESULT WINAPI
IConnection_Constructor(INetConnection
**ppv
, PINetConnectionItem pItem
)
378 CNetConnection
*pConnection
= new CNetConnection(pItem
);
380 return E_OUTOFMEMORY
;
382 pConnection
->AddRef();
383 *ppv
= (INetConnection
*)pConnection
;
389 /***************************************************************
390 * IEnumNetConnection Interface
395 CNetConnectionManager::Next(
397 INetConnection
**rgelt
,
402 if (!pceltFetched
|| !rgelt
)
411 hr
= IConnection_Constructor(rgelt
, pCurrent
);
412 pCurrent
= pCurrent
->Next
;
419 CNetConnectionManager::Skip(ULONG celt
)
421 while(pCurrent
&& celt
-- > 0)
422 pCurrent
= pCurrent
->Next
;
433 CNetConnectionManager::Reset()
441 CNetConnectionManager::Clone(IEnumNetConnection
**ppenum
)
447 GetAdapterIndexFromNetCfgInstanceId(PIP_ADAPTER_INFO pAdapterInfo
, LPWSTR szNetCfg
, PDWORD pIndex
)
450 IP_ADAPTER_INFO
* pCurrentAdapter
;
452 pCurrentAdapter
= pAdapterInfo
;
453 while(pCurrentAdapter
)
456 if (MultiByteToWideChar(CP_ACP
, 0, pCurrentAdapter
->AdapterName
, -1, szBuffer
, sizeof(szBuffer
)/sizeof(szBuffer
[0])))
458 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
460 if (!_wcsicmp(szBuffer
, szNetCfg
))
462 *pIndex
= pCurrentAdapter
->Index
;
465 pCurrentAdapter
= pCurrentAdapter
->Next
;
473 NETCON_PROPERTIES
* Props
)
475 switch(IfEntry
->dwOperStatus
)
477 case MIB_IF_OPER_STATUS_NON_OPERATIONAL
:
478 Props
->Status
= NCS_HARDWARE_DISABLED
;
480 case MIB_IF_OPER_STATUS_UNREACHABLE
:
481 Props
->Status
= NCS_DISCONNECTED
;
483 case MIB_IF_OPER_STATUS_DISCONNECTED
:
484 Props
->Status
= NCS_MEDIA_DISCONNECTED
;
486 case MIB_IF_OPER_STATUS_CONNECTING
:
487 Props
->Status
= NCS_CONNECTING
;
489 case MIB_IF_OPER_STATUS_CONNECTED
:
490 Props
->Status
= NCS_CONNECTED
;
492 case MIB_IF_OPER_STATUS_OPERATIONAL
:
493 Props
->Status
= NCS_CONNECTED
;
501 CNetConnectionManager::EnumerateINetConnections()
503 DWORD dwSize
, dwResult
, dwIndex
, dwAdapterIndex
, dwShowIcon
;
504 MIB_IFTABLE
*pIfTable
;
506 IP_ADAPTER_INFO
* pAdapterInfo
;
508 SP_DEVINFO_DATA DevInfo
;
511 WCHAR szAdapterNetCfg
[50];
512 WCHAR szDetail
[200] = L
"SYSTEM\\CurrentControlSet\\Control\\Class\\";
513 WCHAR szName
[130] = L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
514 PINetConnectionItem pCurrent
= NULL
;
516 /* get the IfTable */
518 if (GetIfTable(NULL
, &dwSize
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
)
521 pIfTable
= (PMIB_IFTABLE
)CoTaskMemAlloc(dwSize
);
525 dwResult
= GetIfTable(pIfTable
, &dwSize
, TRUE
);
526 if (dwResult
!= NO_ERROR
)
528 CoTaskMemFree(pIfTable
);
533 dwResult
= GetAdaptersInfo(NULL
, &dwSize
);
534 if (dwResult
!= ERROR_BUFFER_OVERFLOW
)
536 CoTaskMemFree(pIfTable
);
540 pAdapterInfo
= (PIP_ADAPTER_INFO
)CoTaskMemAlloc(dwSize
);
543 CoTaskMemFree(pIfTable
);
547 if (GetAdaptersInfo(pAdapterInfo
, &dwSize
) != NO_ERROR
)
549 CoTaskMemFree(pIfTable
);
550 CoTaskMemFree(pAdapterInfo
);
554 hInfo
= SetupDiGetClassDevs(&GUID_DEVCLASS_NET
, NULL
, NULL
, DIGCF_PRESENT
);
557 CoTaskMemFree(pIfTable
);
558 CoTaskMemFree(pAdapterInfo
);
565 ZeroMemory(&DevInfo
, sizeof(SP_DEVINFO_DATA
));
566 DevInfo
.cbSize
= sizeof(DevInfo
);
568 /* get device info */
569 if (!SetupDiEnumDeviceInfo(hInfo
, dwIndex
++, &DevInfo
))
572 /* get device software registry path */
573 if (!SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DRIVER
, NULL
, (LPBYTE
)&szDetail
[39], sizeof(szDetail
)/sizeof(WCHAR
) - 40, &dwSize
))
576 /* open device registry key */
577 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szDetail
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
580 /* query NetCfgInstanceId for current device */
581 dwSize
= sizeof(szNetCfg
);
582 if (RegQueryValueExW(hSubKey
, L
"NetCfgInstanceId", NULL
, NULL
, (LPBYTE
)szNetCfg
, &dwSize
) != ERROR_SUCCESS
)
584 RegCloseKey(hSubKey
);
587 RegCloseKey(hSubKey
);
589 /* get the current adapter index from NetCfgInstanceId */
590 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo
, szNetCfg
, &dwAdapterIndex
))
593 /* get detailed adapter info */
594 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
595 IfEntry
.dwIndex
= dwAdapterIndex
;
596 if(GetIfEntry(&IfEntry
) != NO_ERROR
)
599 /* allocate new INetConnectionItem */
600 PINetConnectionItem pNew
= (PINetConnectionItem
)CoTaskMemAlloc(sizeof(INetConnectionItem
));
604 ZeroMemory(pNew
, sizeof(INetConnectionItem
));
605 pNew
->dwAdapterIndex
= dwAdapterIndex
;
606 /* store NetCfgInstanceId */
607 CLSIDFromString(szNetCfg
, &pNew
->Props
.guidId
);
608 NormalizeOperStatus(&IfEntry
, &pNew
->Props
);
610 switch(IfEntry
.dwType
)
612 case IF_TYPE_ETHERNET_CSMACD
:
613 pNew
->Props
.MediaType
= NCM_LAN
;
615 case IF_TYPE_IEEE80211
:
616 pNew
->Props
.MediaType
= NCM_SHAREDACCESSHOST_RAS
;
621 /* open network connections details */
622 wcscpy(&szName
[80], szNetCfg
);
623 wcscpy(&szName
[118], L
"\\Connection");
625 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
627 /* retrieve name of connection */
628 dwSize
= sizeof(szAdapterNetCfg
);
629 if (RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
631 pNew
->Props
.pszwName
= (LPWSTR
)CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
632 if (pNew
->Props
.pszwName
)
633 wcscpy(pNew
->Props
.pszwName
, szAdapterNetCfg
);
635 dwSize
= sizeof(dwShowIcon
);
636 if (RegQueryValueExW(hSubKey
, L
"ShowIcon", NULL
, NULL
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
)
639 pNew
->Props
.dwCharacter
|= NCCF_SHOW_ICON
;
641 RegCloseKey(hSubKey
);
644 /* Get the adapter device description */
646 SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, NULL
, 0, &dwSize
);
649 pNew
->Props
.pszwDeviceName
= (LPWSTR
)CoTaskMemAlloc(dwSize
);
650 if (pNew
->Props
.pszwDeviceName
)
651 SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, (PBYTE
)pNew
->Props
.pszwDeviceName
, dwSize
, &dwSize
);
655 pCurrent
->Next
= pNew
;
662 CoTaskMemFree(pIfTable
);
663 CoTaskMemFree(pAdapterInfo
);
664 SetupDiDestroyDeviceInfoList(hInfo
);
666 this->pCurrent
= pHead
;
670 HRESULT WINAPI
INetConnectionManager_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
672 TRACE("INetConnectionManager_Constructor\n");
677 return CLASS_E_NOAGGREGATION
;
679 CNetConnectionManager
*pConnectionMgr
= new CNetConnectionManager
;
681 return E_OUTOFMEMORY
;
683 pConnectionMgr
->AddRef();
684 HRESULT hr
= pConnectionMgr
->QueryInterface(riid
, ppv
);
687 pConnectionMgr
->EnumerateINetConnections();
689 pConnectionMgr
->Release();