3 WINE_DEFAULT_DEBUG_CHANNEL (shell
);
5 typedef struct tagINetConnectionItem
7 struct tagINetConnectionItem
* Next
;
9 NETCON_PROPERTIES Props
;
10 } INetConnectionItem
, *PINetConnectionItem
;
12 class CNetConnectionManager
:
13 public INetConnectionManager
,
14 public IEnumNetConnection
17 CNetConnectionManager();
18 BOOL
EnumerateINetConnections();
21 virtual HRESULT WINAPI
QueryInterface(REFIID riid
, LPVOID
*ppvOut
);
22 virtual ULONG WINAPI
AddRef();
23 virtual ULONG WINAPI
Release();
25 // INetConnectionManager
26 virtual HRESULT WINAPI
EnumConnections(NETCONMGR_ENUM_FLAGS Flags
, IEnumNetConnection
**ppEnum
);
29 virtual HRESULT WINAPI
Next(ULONG celt
, INetConnection
**rgelt
, ULONG
*pceltFetched
);
30 virtual HRESULT WINAPI
Skip(ULONG celt
);
31 virtual HRESULT WINAPI
Reset();
32 virtual HRESULT WINAPI
Clone(IEnumNetConnection
**ppenum
);
36 PINetConnectionItem pHead
;
37 PINetConnectionItem pCurrent
;
44 CNetConnection(PINetConnectionItem pItem
);
47 virtual HRESULT WINAPI
QueryInterface(REFIID riid
, LPVOID
*ppvOut
);
48 virtual ULONG WINAPI
AddRef();
49 virtual ULONG WINAPI
Release();
52 HRESULT WINAPI
Connect();
53 HRESULT WINAPI
Disconnect();
54 HRESULT WINAPI
Delete();
55 HRESULT WINAPI
Duplicate(LPCWSTR pszwDuplicateName
, INetConnection
**ppCon
);
56 HRESULT WINAPI
GetProperties(NETCON_PROPERTIES
**ppProps
);
57 HRESULT WINAPI
GetUiObjectClassId(CLSID
*pclsid
);
58 HRESULT WINAPI
Rename(LPCWSTR pszwDuplicateName
);
62 NETCON_PROPERTIES Props
;
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
= (INetConnectionManager
*)this;
96 CNetConnectionManager::AddRef()
98 ULONG refCount
= InterlockedIncrement(&ref
);
105 CNetConnectionManager::Release()
107 ULONG refCount
= InterlockedDecrement(&ref
);
117 CNetConnectionManager::EnumConnections(
118 NETCONMGR_ENUM_FLAGS Flags
,
119 IEnumNetConnection
**ppEnum
)
121 TRACE("EnumConnections\n");
126 if (Flags
!= NCME_DEFAULT
)
129 *ppEnum
= (IEnumNetConnection
*)this;
134 /***************************************************************
135 * INetConnection Interface
138 CNetConnection::CNetConnection(PINetConnectionItem pItem
)
141 dwAdapterIndex
= pItem
->dwAdapterIndex
;
142 CopyMemory(&Props
, &pItem
->Props
, sizeof(NETCON_PROPERTIES
));
144 if (pItem
->Props
.pszwName
)
146 Props
.pszwName
= (LPWSTR
)CoTaskMemAlloc((wcslen(pItem
->Props
.pszwName
)+1)*sizeof(WCHAR
));
148 wcscpy(Props
.pszwName
, pItem
->Props
.pszwName
);
151 if (pItem
->Props
.pszwDeviceName
)
153 Props
.pszwDeviceName
= (LPWSTR
)CoTaskMemAlloc((wcslen(pItem
->Props
.pszwDeviceName
)+1)*sizeof(WCHAR
));
154 if (Props
.pszwDeviceName
)
155 wcscpy(Props
.pszwDeviceName
, pItem
->Props
.pszwDeviceName
);
161 CNetConnection::QueryInterface(
167 if (IsEqualIID(iid
, IID_IUnknown
) ||
168 IsEqualIID(iid
, IID_INetConnection
))
175 return E_NOINTERFACE
;
180 CNetConnection::AddRef()
182 ULONG refCount
= InterlockedIncrement(&ref
);
189 CNetConnection::Release()
191 ULONG refCount
= InterlockedDecrement(&ref
);
195 CoTaskMemFree(Props
.pszwName
);
196 CoTaskMemFree(Props
.pszwDeviceName
);
205 CNetConnection::Connect()
212 CNetConnection::Disconnect()
219 CNetConnection::Delete()
226 CNetConnection::Duplicate(
227 LPCWSTR pszwDuplicateName
,
228 INetConnection
**ppCon
)
235 CNetConnection::GetProperties(NETCON_PROPERTIES
**ppProps
)
241 DWORD dwShowIcon
, dwType
, dwSize
;
242 NETCON_PROPERTIES
* pProperties
;
248 pProperties
= (NETCON_PROPERTIES
*)CoTaskMemAlloc(sizeof(NETCON_PROPERTIES
));
250 return E_OUTOFMEMORY
;
252 CopyMemory(pProperties
, &Props
, sizeof(NETCON_PROPERTIES
));
253 pProperties
->pszwName
= NULL
;
255 if (Props
.pszwDeviceName
)
257 pProperties
->pszwDeviceName
= (LPWSTR
)CoTaskMemAlloc((wcslen(Props
.pszwDeviceName
)+1)*sizeof(WCHAR
));
258 if (pProperties
->pszwDeviceName
)
259 wcscpy(pProperties
->pszwDeviceName
, Props
.pszwDeviceName
);
262 *ppProps
= pProperties
;
264 /* get updated adapter characteristics */
265 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
266 IfEntry
.dwIndex
= dwAdapterIndex
;
267 if(GetIfEntry(&IfEntry
) != NO_ERROR
)
270 NormalizeOperStatus(&IfEntry
, pProperties
);
273 hr
= StringFromCLSID((CLSID
)Props
.guidId
, &pStr
);
276 wcscpy(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
277 wcscat(szName
, pStr
);
278 wcscat(szName
, L
"\\Connection");
280 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
282 dwSize
= sizeof(dwShowIcon
);
283 if (RegQueryValueExW(hKey
, L
"ShowIcon", NULL
, &dwType
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
&& dwType
== REG_DWORD
)
286 pProperties
->dwCharacter
|= NCCF_SHOW_ICON
;
288 pProperties
->dwCharacter
&= ~NCCF_SHOW_ICON
;
290 dwSize
= sizeof(szName
);
291 if (RegQueryValueExW(hKey
, L
"Name", NULL
, &dwType
, (LPBYTE
)szName
, &dwSize
) == ERROR_SUCCESS
)
293 /* use updated name */
294 dwSize
= wcslen(szName
) + 1;
295 pProperties
->pszwName
= (LPWSTR
)CoTaskMemAlloc(dwSize
* sizeof(WCHAR
));
296 if (pProperties
->pszwName
)
297 CopyMemory(pProperties
->pszwName
, szName
, dwSize
* sizeof(WCHAR
));
301 /* use cached name */
304 pProperties
->pszwName
= (LPWSTR
)CoTaskMemAlloc((wcslen(Props
.pszwName
)+1)*sizeof(WCHAR
));
305 if (pProperties
->pszwName
)
306 wcscpy(pProperties
->pszwName
, Props
.pszwName
);
319 CNetConnection::GetUiObjectClassId(CLSID
*pclsid
)
321 if (Props
.MediaType
== NCM_LAN
)
323 CopyMemory(pclsid
, &CLSID_LANConnectUI
, sizeof(CLSID
));
332 CNetConnection::Rename(LPCWSTR pszwDuplicateName
)
337 HRESULT WINAPI
IConnection_Constructor(INetConnection
**ppv
, PINetConnectionItem pItem
)
342 CNetConnection
*pConnection
= new CNetConnection(pItem
);
344 return E_OUTOFMEMORY
;
346 pConnection
->AddRef();
347 *ppv
= (INetConnection
*)pConnection
;
353 /***************************************************************
354 * IEnumNetConnection Interface
359 CNetConnectionManager::Next(
361 INetConnection
**rgelt
,
366 if (!pceltFetched
|| !rgelt
)
375 hr
= IConnection_Constructor(rgelt
, pCurrent
);
376 pCurrent
= pCurrent
->Next
;
383 CNetConnectionManager::Skip(ULONG celt
)
385 while(pCurrent
&& celt
-- > 0)
386 pCurrent
= pCurrent
->Next
;
397 CNetConnectionManager::Reset()
405 CNetConnectionManager::Clone(IEnumNetConnection
**ppenum
)
411 GetAdapterIndexFromNetCfgInstanceId(PIP_ADAPTER_INFO pAdapterInfo
, LPWSTR szNetCfg
, PDWORD pIndex
)
414 IP_ADAPTER_INFO
* pCurrentAdapter
;
416 pCurrentAdapter
= pAdapterInfo
;
417 while(pCurrentAdapter
)
420 if (MultiByteToWideChar(CP_ACP
, 0, pCurrentAdapter
->AdapterName
, -1, szBuffer
, sizeof(szBuffer
)/sizeof(szBuffer
[0])))
422 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
424 if (!_wcsicmp(szBuffer
, szNetCfg
))
426 *pIndex
= pCurrentAdapter
->Index
;
429 pCurrentAdapter
= pCurrentAdapter
->Next
;
437 NETCON_PROPERTIES
* Props
)
439 switch(IfEntry
->dwOperStatus
)
441 case MIB_IF_OPER_STATUS_NON_OPERATIONAL
:
442 Props
->Status
= NCS_HARDWARE_DISABLED
;
444 case MIB_IF_OPER_STATUS_UNREACHABLE
:
445 Props
->Status
= NCS_DISCONNECTED
;
447 case MIB_IF_OPER_STATUS_DISCONNECTED
:
448 Props
->Status
= NCS_MEDIA_DISCONNECTED
;
450 case MIB_IF_OPER_STATUS_CONNECTING
:
451 Props
->Status
= NCS_CONNECTING
;
453 case MIB_IF_OPER_STATUS_CONNECTED
:
454 Props
->Status
= NCS_CONNECTED
;
456 case MIB_IF_OPER_STATUS_OPERATIONAL
:
457 Props
->Status
= NCS_CONNECTED
;
465 CNetConnectionManager::EnumerateINetConnections()
467 DWORD dwSize
, dwResult
, dwIndex
, dwAdapterIndex
, dwShowIcon
;
468 MIB_IFTABLE
*pIfTable
;
470 IP_ADAPTER_INFO
* pAdapterInfo
;
472 SP_DEVINFO_DATA DevInfo
;
475 WCHAR szAdapterNetCfg
[50];
476 WCHAR szDetail
[200] = L
"SYSTEM\\CurrentControlSet\\Control\\Class\\";
477 WCHAR szName
[130] = L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
478 PINetConnectionItem pCurrent
= NULL
;
480 /* get the IfTable */
482 if (GetIfTable(NULL
, &dwSize
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
)
485 pIfTable
= (PMIB_IFTABLE
)CoTaskMemAlloc(dwSize
);
489 dwResult
= GetIfTable(pIfTable
, &dwSize
, TRUE
);
490 if (dwResult
!= NO_ERROR
)
492 CoTaskMemFree(pIfTable
);
497 dwResult
= GetAdaptersInfo(NULL
, &dwSize
);
498 if (dwResult
!= ERROR_BUFFER_OVERFLOW
)
500 CoTaskMemFree(pIfTable
);
504 pAdapterInfo
= (PIP_ADAPTER_INFO
)CoTaskMemAlloc(dwSize
);
507 CoTaskMemFree(pIfTable
);
511 if (GetAdaptersInfo(pAdapterInfo
, &dwSize
) != NO_ERROR
)
513 CoTaskMemFree(pIfTable
);
514 CoTaskMemFree(pAdapterInfo
);
518 hInfo
= SetupDiGetClassDevs(&GUID_DEVCLASS_NET
, NULL
, NULL
, DIGCF_PRESENT
);
521 CoTaskMemFree(pIfTable
);
522 CoTaskMemFree(pAdapterInfo
);
529 ZeroMemory(&DevInfo
, sizeof(SP_DEVINFO_DATA
));
530 DevInfo
.cbSize
= sizeof(DevInfo
);
532 /* get device info */
533 if (!SetupDiEnumDeviceInfo(hInfo
, dwIndex
++, &DevInfo
))
536 /* get device software registry path */
537 if (!SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DRIVER
, NULL
, (LPBYTE
)&szDetail
[39], sizeof(szDetail
)/sizeof(WCHAR
) - 40, &dwSize
))
540 /* open device registry key */
541 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szDetail
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
544 /* query NetCfgInstanceId for current device */
545 dwSize
= sizeof(szNetCfg
);
546 if (RegQueryValueExW(hSubKey
, L
"NetCfgInstanceId", NULL
, NULL
, (LPBYTE
)szNetCfg
, &dwSize
) != ERROR_SUCCESS
)
548 RegCloseKey(hSubKey
);
551 RegCloseKey(hSubKey
);
553 /* get the current adapter index from NetCfgInstanceId */
554 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo
, szNetCfg
, &dwAdapterIndex
))
557 /* get detailed adapter info */
558 ZeroMemory(&IfEntry
, sizeof(IfEntry
));
559 IfEntry
.dwIndex
= dwAdapterIndex
;
560 if(GetIfEntry(&IfEntry
) != NO_ERROR
)
563 /* allocate new INetConnectionItem */
564 PINetConnectionItem pNew
= (PINetConnectionItem
)CoTaskMemAlloc(sizeof(INetConnectionItem
));
568 ZeroMemory(pNew
, sizeof(INetConnectionItem
));
569 pNew
->dwAdapterIndex
= dwAdapterIndex
;
570 /* store NetCfgInstanceId */
571 CLSIDFromString(szNetCfg
, &pNew
->Props
.guidId
);
572 NormalizeOperStatus(&IfEntry
, &pNew
->Props
);
574 switch(IfEntry
.dwType
)
576 case IF_TYPE_ETHERNET_CSMACD
:
577 pNew
->Props
.MediaType
= NCM_LAN
;
579 case IF_TYPE_IEEE80211
:
580 pNew
->Props
.MediaType
= NCM_SHAREDACCESSHOST_RAS
;
585 /* open network connections details */
586 wcscpy(&szName
[80], szNetCfg
);
587 wcscpy(&szName
[118], L
"\\Connection");
589 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
591 /* retrieve name of connection */
592 dwSize
= sizeof(szAdapterNetCfg
);
593 if (RegQueryValueExW(hSubKey
, L
"Name", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
595 pNew
->Props
.pszwName
= (LPWSTR
)CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
596 if (pNew
->Props
.pszwName
)
597 wcscpy(pNew
->Props
.pszwName
, szAdapterNetCfg
);
599 dwSize
= sizeof(dwShowIcon
);
600 if (RegQueryValueExW(hSubKey
, L
"ShowIcon", NULL
, NULL
, (LPBYTE
)&dwShowIcon
, &dwSize
) == ERROR_SUCCESS
)
603 pNew
->Props
.dwCharacter
|= NCCF_SHOW_ICON
;
605 RegCloseKey(hSubKey
);
607 if (SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, (PBYTE
)szNetCfg
, sizeof(szNetCfg
)/sizeof(WCHAR
), &dwSize
))
609 szNetCfg
[(sizeof(szNetCfg
)/sizeof(WCHAR
))-1] = L
'\0';
610 pNew
->Props
.pszwDeviceName
= (LPWSTR
)CoTaskMemAlloc((wcslen(szNetCfg
)+1) * sizeof(WCHAR
));
611 if (pNew
->Props
.pszwDeviceName
)
612 wcscpy(pNew
->Props
.pszwDeviceName
, szNetCfg
);
616 pCurrent
->Next
= pNew
;
623 CoTaskMemFree(pIfTable
);
624 CoTaskMemFree(pAdapterInfo
);
625 SetupDiDestroyDeviceInfoList(hInfo
);
627 this->pCurrent
= pHead
;
631 HRESULT WINAPI
INetConnectionManager_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
633 TRACE("INetConnectionManager_Constructor\n");
638 return CLASS_E_NOAGGREGATION
;
640 CNetConnectionManager
*pConnectionMgr
= new CNetConnectionManager
;
642 return E_OUTOFMEMORY
;
644 pConnectionMgr
->AddRef();
645 HRESULT hr
= pConnectionMgr
->QueryInterface(riid
, ppv
);
648 pConnectionMgr
->EnumerateINetConnections();
650 pConnectionMgr
->Release();