Reactos
1/*
2 * PROJECT: ReactOS Shell
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: CNetConnectionManager class
5 * COPYRIGHT: Copyright 2008 Johannes Anderwald (johannes.anderwald@reactos.org)
6 */
7
8#include "precomp.h"
9
10VOID NormalizeOperStatus(MIB_IFROW *IfEntry, NETCON_PROPERTIES * Props);
11
12/***************************************************************
13 * INetConnection Interface
14 */
15
16HRESULT
17WINAPI
18CNetConnection::Initialize(PINetConnectionItem pItem)
19{
20 m_Props = pItem->Props;
21 m_dwAdapterIndex = pItem->dwAdapterIndex;
22
23 if (pItem->Props.pszwName)
24 {
25 m_Props.pszwName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(pItem->Props.pszwName)+1)*sizeof(WCHAR)));
26 if (m_Props.pszwName)
27 wcscpy(m_Props.pszwName, pItem->Props.pszwName);
28 }
29
30 if (pItem->Props.pszwDeviceName)
31 {
32 m_Props.pszwDeviceName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(pItem->Props.pszwDeviceName)+1)*sizeof(WCHAR)));
33 if (m_Props.pszwDeviceName)
34 wcscpy(m_Props.pszwDeviceName, pItem->Props.pszwDeviceName);
35 }
36
37 return S_OK;
38}
39
40CNetConnection::~CNetConnection()
41{
42 CoTaskMemFree(m_Props.pszwName);
43 CoTaskMemFree(m_Props.pszwDeviceName);
44}
45
46HRESULT
47WINAPI
48CNetConnection::Connect()
49{
50 return E_NOTIMPL;
51}
52
53BOOL
54FindNetworkAdapter(HDEVINFO hInfo, SP_DEVINFO_DATA *pDevInfo, LPWSTR pGuid)
55{
56 DWORD dwIndex, dwSize;
57 HKEY hSubKey;
58 WCHAR szNetCfg[50];
59 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\";
60
61 dwIndex = 0;
62 do
63 {
64 ZeroMemory(pDevInfo, sizeof(SP_DEVINFO_DATA));
65 pDevInfo->cbSize = sizeof(SP_DEVINFO_DATA);
66
67 /* get device info */
68 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, pDevInfo))
69 break;
70
71 /* get device software registry path */
72 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, pDevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize))
73 break;
74
75 /* open device registry key */
76 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
77 break;
78
79 /* query NetCfgInstanceId for current device */
80 dwSize = sizeof(szNetCfg);
81 if (RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS)
82 {
83 RegCloseKey(hSubKey);
84 break;
85 }
86 RegCloseKey(hSubKey);
87 if (!_wcsicmp(pGuid, szNetCfg))
88 {
89 return TRUE;
90 }
91 } while (TRUE);
92
93 return FALSE;
94}
95
96HRESULT
97WINAPI
98CNetConnection::Disconnect()
99{
100 HKEY hKey;
101 NETCON_PROPERTIES * pProperties;
102 LPOLESTR pDisplayName;
103 WCHAR szPath[200];
104 DWORD dwSize, dwType;
105 LPWSTR pPnp;
106 HDEVINFO hInfo;
107 SP_DEVINFO_DATA DevInfo;
108 SP_PROPCHANGE_PARAMS PropChangeParams;
109 HRESULT hr;
110
111 hr = GetProperties(&pProperties);
112 if (FAILED_UNEXPECTEDLY(hr))
113 return hr;
114
115 hInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT );
116 if (!hInfo)
117 {
118 NcFreeNetconProperties(pProperties);
119 return E_FAIL;
120 }
121
122 if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pDisplayName)))
123 {
124 NcFreeNetconProperties(pProperties);
125 SetupDiDestroyDeviceInfoList(hInfo);
126 return E_FAIL;
127 }
128 NcFreeNetconProperties(pProperties);
129
130 if (FindNetworkAdapter(hInfo, &DevInfo, pDisplayName))
131 {
132 PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
133 PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; //;
134 PropChangeParams.StateChange = DICS_DISABLE;
135 PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
136 PropChangeParams.HwProfile = 0;
137
138 if (!SetupDiSetClassInstallParams(hInfo, &DevInfo, &PropChangeParams.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS)) ||
139 !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hInfo, &DevInfo))
140 {
141 hr = HRESULT_FROM_WIN32(GetLastError());
142 }
143 }
144 SetupDiDestroyDeviceInfoList(hInfo);
145
146 swprintf(szPath, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", pDisplayName);
147 CoTaskMemFree(pDisplayName);
148
149 if (FAILED_UNEXPECTEDLY(hr))
150 return hr;
151
152 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
153 return E_FAIL;
154
155 dwSize = 0;
156 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_SZ)
157 {
158 RegCloseKey(hKey);
159 return E_FAIL;
160 }
161
162 pPnp = static_cast<PWSTR>(CoTaskMemAlloc(dwSize));
163 if (!pPnp)
164 {
165 RegCloseKey(hKey);
166 return E_FAIL;
167 }
168
169 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, (LPBYTE)pPnp, &dwSize) != ERROR_SUCCESS)
170 {
171 CoTaskMemFree(pPnp);
172 RegCloseKey(hKey);
173 return E_FAIL;
174 }
175 RegCloseKey(hKey);
176
177 swprintf(szPath, L"System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Enum\\%s", pPnp);
178 CoTaskMemFree(pPnp);
179
180 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
181 return E_FAIL;
182
183 dwSize = 1; /* enable = 0, disable = 1 */
184 RegSetValueExW(hKey, L"CSConfigFlags", 0, REG_DWORD, (LPBYTE)&dwSize, sizeof(DWORD));
185 RegCloseKey(hKey);
186
187 return S_OK;
188}
189
190HRESULT
191WINAPI
192CNetConnection::Delete()
193{
194 return E_NOTIMPL;
195}
196
197HRESULT
198WINAPI
199CNetConnection::Duplicate(
200 LPCWSTR pszwDuplicateName,
201 INetConnection **ppCon)
202{
203 return E_NOTIMPL;
204}
205
206HRESULT
207WINAPI
208CNetConnection::GetProperties(NETCON_PROPERTIES **ppProps)
209{
210 MIB_IFROW IfEntry;
211 HKEY hKey;
212 LPOLESTR pStr;
213 WCHAR szName[140];
214 DWORD dwShowIcon, dwNotifyDisconnect, dwType, dwSize;
215 NETCON_PROPERTIES * pProperties;
216 HRESULT hr;
217
218 if (!ppProps)
219 return E_POINTER;
220
221 pProperties = static_cast<NETCON_PROPERTIES*>(CoTaskMemAlloc(sizeof(NETCON_PROPERTIES)));
222 if (!pProperties)
223 return E_OUTOFMEMORY;
224
225 CopyMemory(pProperties, &m_Props, sizeof(NETCON_PROPERTIES));
226 pProperties->pszwName = NULL;
227
228 if (m_Props.pszwDeviceName)
229 {
230 pProperties->pszwDeviceName = static_cast<LPWSTR>(CoTaskMemAlloc((wcslen(m_Props.pszwDeviceName)+1)*sizeof(WCHAR)));
231 if (pProperties->pszwDeviceName)
232 wcscpy(pProperties->pszwDeviceName, m_Props.pszwDeviceName);
233 }
234
235 *ppProps = pProperties;
236
237 /* get updated adapter characteristics */
238 ZeroMemory(&IfEntry, sizeof(IfEntry));
239 IfEntry.dwIndex = m_dwAdapterIndex;
240 if (GetIfEntry(&IfEntry) != NO_ERROR)
241 return NOERROR;
242
243 NormalizeOperStatus(&IfEntry, pProperties);
244
245
246 hr = StringFromCLSID((CLSID)m_Props.guidId, &pStr);
247 if (SUCCEEDED(hr))
248 {
249 wcscpy(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
250 wcscat(szName, pStr);
251 wcscat(szName, L"\\Connection");
252
253 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
254 {
255 dwSize = sizeof(dwShowIcon);
256 if (RegQueryValueExW(hKey, L"ShowIcon", NULL, &dwType, (LPBYTE)&dwShowIcon, &dwSize) == ERROR_SUCCESS && dwType == REG_DWORD)
257 {
258 if (dwShowIcon)
259 pProperties->dwCharacter |= NCCF_SHOW_ICON;
260 else
261 pProperties->dwCharacter &= ~NCCF_SHOW_ICON;
262 }
263
264 dwSize = sizeof(dwNotifyDisconnect);
265 if (RegQueryValueExW(hKey, L"IpCheckingEnabled", NULL, &dwType, (LPBYTE)&dwNotifyDisconnect, &dwSize) == ERROR_SUCCESS && dwType == REG_DWORD)
266 {
267 if (dwNotifyDisconnect)
268 pProperties->dwCharacter |= NCCF_NOTIFY_DISCONNECTED;
269 else
270 pProperties->dwCharacter &= ~NCCF_NOTIFY_DISCONNECTED;
271 }
272
273 dwSize = sizeof(szName);
274 if (RegQueryValueExW(hKey, L"Name", NULL, &dwType, (LPBYTE)szName, &dwSize) == ERROR_SUCCESS)
275 {
276 /* use updated name */
277 dwSize = wcslen(szName) + 1;
278 pProperties->pszwName = static_cast<PWSTR>(CoTaskMemAlloc(dwSize * sizeof(WCHAR)));
279 if (pProperties->pszwName)
280 CopyMemory(pProperties->pszwName, szName, dwSize * sizeof(WCHAR));
281 }
282 else
283 {
284 /* use cached name */
285 if (m_Props.pszwName)
286 {
287 pProperties->pszwName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(m_Props.pszwName)+1)*sizeof(WCHAR)));
288 if (pProperties->pszwName)
289 wcscpy(pProperties->pszwName, m_Props.pszwName);
290 }
291 }
292 RegCloseKey(hKey);
293 }
294 CoTaskMemFree(pStr);
295 }
296
297 /* Enable 'Rename' and 'Delete' for Adminstrators only */
298 if (IsUserAdmin())
299 {
300 pProperties->dwCharacter |= NCCF_ALLOW_RENAME;
301
302 /* Virtual network interfaces can be deleted */
303 if (IfEntry.dwType == IF_TYPE_TUNNEL)
304 {
305 pProperties->dwCharacter |= NCCF_ALLOW_REMOVAL;
306 }
307 }
308 else
309 {
310 pProperties->dwCharacter &= ~(NCCF_ALLOW_RENAME | NCCF_ALLOW_REMOVAL);
311 }
312
313 return S_OK;
314}
315
316HRESULT
317WINAPI
318CNetConnection::GetUiObjectClassId(CLSID *pclsid)
319{
320 if (m_Props.MediaType == NCM_LAN)
321 {
322 CopyMemory(pclsid, &CLSID_LanConnectionUi, sizeof(CLSID));
323 return S_OK;
324 }
325
326 return E_NOTIMPL;
327}
328
329HRESULT
330WINAPI
331CNetConnection::Rename(LPCWSTR pszwDuplicateName)
332{
333 WCHAR szName[140];
334 LPOLESTR pStr;
335 DWORD dwSize;
336 HKEY hKey;
337 HRESULT hr;
338
339 if (pszwDuplicateName == NULL || wcslen(pszwDuplicateName) == 0)
340 return S_OK;
341
342 if (m_Props.pszwName)
343 {
344 CoTaskMemFree(m_Props.pszwName);
345 m_Props.pszwName = NULL;
346 }
347
348 dwSize = (wcslen(pszwDuplicateName) + 1) * sizeof(WCHAR);
349 m_Props.pszwName = static_cast<PWSTR>(CoTaskMemAlloc(dwSize));
350 if (m_Props.pszwName == NULL)
351 return E_OUTOFMEMORY;
352
353 wcscpy(m_Props.pszwName, pszwDuplicateName);
354
355 hr = StringFromCLSID((CLSID)m_Props.guidId, &pStr);
356 if (SUCCEEDED(hr))
357 {
358 wcscpy(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
359 wcscat(szName, pStr);
360 wcscat(szName, L"\\Connection");
361
362 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
363 {
364 RegSetValueExW(hKey, L"Name", NULL, REG_SZ, (LPBYTE)m_Props.pszwName, dwSize);
365 RegCloseKey(hKey);
366 }
367
368 CoTaskMemFree(pStr);
369 }
370
371 return hr;
372}
373
374HRESULT WINAPI CNetConnection_CreateInstance(PINetConnectionItem pItem, REFIID riid, LPVOID * ppv)
375{
376 return ShellObjectCreatorInit<CNetConnection>(pItem, riid, ppv);
377}
378
379
380
381CNetConnectionManager::CNetConnectionManager() :
382 m_pHead(NULL),
383 m_pCurrent(NULL)
384{
385}
386
387HRESULT
388WINAPI
389CNetConnectionManager::EnumConnections(
390 NETCONMGR_ENUM_FLAGS Flags,
391 IEnumNetConnection **ppEnum)
392{
393 TRACE("EnumConnections\n");
394
395 if (!ppEnum)
396 return E_POINTER;
397
398 if (Flags != NCME_DEFAULT)
399 return E_FAIL;
400
401 *ppEnum = static_cast<IEnumNetConnection*>(this);
402 AddRef();
403 return S_OK;
404}
405
406/***************************************************************
407 * IEnumNetConnection Interface
408 */
409
410HRESULT
411WINAPI
412CNetConnectionManager::Next(
413 ULONG celt,
414 INetConnection **rgelt,
415 ULONG *pceltFetched)
416{
417 HRESULT hr;
418
419 if (!pceltFetched || !rgelt)
420 return E_POINTER;
421
422 if (celt != 1)
423 return E_FAIL;
424
425 if (!m_pCurrent)
426 return S_FALSE;
427
428 hr = CNetConnection_CreateInstance(m_pCurrent, IID_PPV_ARG(INetConnection, rgelt));
429 m_pCurrent = m_pCurrent->Next;
430
431 return hr;
432}
433
434HRESULT
435WINAPI
436CNetConnectionManager::Skip(ULONG celt)
437{
438 while (m_pCurrent && celt-- > 0)
439 m_pCurrent = m_pCurrent->Next;
440
441 if (celt)
442 return S_FALSE;
443 else
444 return S_OK;
445
446}
447
448HRESULT
449WINAPI
450CNetConnectionManager::Reset()
451{
452 m_pCurrent = m_pHead;
453 return S_OK;
454}
455
456HRESULT
457WINAPI
458CNetConnectionManager::Clone(IEnumNetConnection **ppenum)
459{
460 return E_NOTIMPL;
461}
462
463BOOL
464GetAdapterIndexFromNetCfgInstanceId(PIP_ADAPTER_INFO pAdapterInfo, LPWSTR szNetCfg, PDWORD pIndex)
465{
466 WCHAR szBuffer[50];
467 IP_ADAPTER_INFO * pCurrentAdapter;
468
469 pCurrentAdapter = pAdapterInfo;
470 while (pCurrentAdapter)
471 {
472 szBuffer[0] = L'\0';
473 if (MultiByteToWideChar(CP_ACP, 0, pCurrentAdapter->AdapterName, -1, szBuffer, sizeof(szBuffer)/sizeof(szBuffer[0])))
474 {
475 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
476 }
477 if (!_wcsicmp(szBuffer, szNetCfg))
478 {
479 *pIndex = pCurrentAdapter->Index;
480 return TRUE;
481 }
482 pCurrentAdapter = pCurrentAdapter->Next;
483 }
484 return FALSE;
485}
486
487VOID
488NormalizeOperStatus(
489 MIB_IFROW *IfEntry,
490 NETCON_PROPERTIES * Props)
491{
492 switch (IfEntry->dwOperStatus)
493 {
494 case MIB_IF_OPER_STATUS_NON_OPERATIONAL:
495 Props->Status = NCS_HARDWARE_DISABLED;
496 break;
497 case MIB_IF_OPER_STATUS_UNREACHABLE:
498 Props->Status = NCS_DISCONNECTED;
499 break;
500 case MIB_IF_OPER_STATUS_DISCONNECTED:
501 Props->Status = NCS_MEDIA_DISCONNECTED;
502 break;
503 case MIB_IF_OPER_STATUS_CONNECTING:
504 Props->Status = NCS_CONNECTING;
505 break;
506 case MIB_IF_OPER_STATUS_CONNECTED:
507 Props->Status = NCS_CONNECTED;
508 break;
509 case MIB_IF_OPER_STATUS_OPERATIONAL:
510 Props->Status = NCS_CONNECTED;
511 break;
512 default:
513 break;
514 }
515}
516
517HRESULT
518CNetConnectionManager::EnumerateINetConnections()
519{
520 DWORD dwSize, dwResult, dwIndex, dwAdapterIndex, dwShowIcon, dwNotifyDisconnect;
521 MIB_IFTABLE *pIfTable;
522 MIB_IFROW IfEntry;
523 IP_ADAPTER_INFO * pAdapterInfo;
524 HDEVINFO hInfo;
525 SP_DEVINFO_DATA DevInfo;
526 HKEY hSubKey;
527 WCHAR szNetCfg[50];
528 WCHAR szAdapterNetCfg[50];
529 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\";
530 WCHAR szName[130] = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
531 PINetConnectionItem pCurrent = NULL;
532
533 /* get the IfTable */
534 dwSize = 0;
535 if (GetIfTable(NULL, &dwSize, TRUE) != ERROR_INSUFFICIENT_BUFFER)
536 return E_FAIL;
537
538 pIfTable = static_cast<PMIB_IFTABLE>(CoTaskMemAlloc(dwSize));
539 if (!pIfTable)
540 return E_OUTOFMEMORY;
541
542 dwResult = GetIfTable(pIfTable, &dwSize, TRUE);
543 if (dwResult != NO_ERROR)
544 {
545 CoTaskMemFree(pIfTable);
546 return HRESULT_FROM_WIN32(dwResult);
547 }
548
549 dwSize = 0;
550 dwResult = GetAdaptersInfo(NULL, &dwSize);
551 if (dwResult!= ERROR_BUFFER_OVERFLOW)
552 {
553 CoTaskMemFree(pIfTable);
554 return HRESULT_FROM_WIN32(dwResult);
555 }
556
557 pAdapterInfo = static_cast<PIP_ADAPTER_INFO>(CoTaskMemAlloc(dwSize));
558 if (!pAdapterInfo)
559 {
560 CoTaskMemFree(pIfTable);
561 return E_OUTOFMEMORY;
562 }
563
564 dwResult = GetAdaptersInfo(pAdapterInfo, &dwSize);
565 if (dwResult != NO_ERROR)
566 {
567 CoTaskMemFree(pIfTable);
568 CoTaskMemFree(pAdapterInfo);
569 return HRESULT_FROM_WIN32(dwResult);
570 }
571
572 hInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT );
573 if (!hInfo)
574 {
575 CoTaskMemFree(pIfTable);
576 CoTaskMemFree(pAdapterInfo);
577 return E_FAIL;
578 }
579
580 dwIndex = 0;
581 do
582 {
583 ZeroMemory(&DevInfo, sizeof(SP_DEVINFO_DATA));
584 DevInfo.cbSize = sizeof(DevInfo);
585
586 /* get device info */
587 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, &DevInfo))
588 break;
589
590 /* get device software registry path */
591 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize))
592 break;
593
594 /* open device registry key */
595 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
596 break;
597
598 /* query NetCfgInstanceId for current device */
599 dwSize = sizeof(szNetCfg);
600 if (RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS)
601 {
602 RegCloseKey(hSubKey);
603 break;
604 }
605 RegCloseKey(hSubKey);
606
607 /* get the current adapter index from NetCfgInstanceId */
608 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo, szNetCfg, &dwAdapterIndex))
609 continue;
610
611 /* get detailed adapter info */
612 ZeroMemory(&IfEntry, sizeof(IfEntry));
613 IfEntry.dwIndex = dwAdapterIndex;
614 if (GetIfEntry(&IfEntry) != NO_ERROR)
615 break;
616
617 /* allocate new INetConnectionItem */
618 PINetConnectionItem pNew = static_cast<PINetConnectionItem>(CoTaskMemAlloc(sizeof(INetConnectionItem)));
619 if (!pNew)
620 break;
621
622 ZeroMemory(pNew, sizeof(INetConnectionItem));
623 pNew->dwAdapterIndex = dwAdapterIndex;
624 /* store NetCfgInstanceId */
625 CLSIDFromString(szNetCfg, &pNew->Props.guidId);
626 NormalizeOperStatus(&IfEntry, &pNew->Props);
627
628 switch (IfEntry.dwType)
629 {
630 case IF_TYPE_ETHERNET_CSMACD:
631 pNew->Props.MediaType = NCM_LAN;
632 break;
633 case IF_TYPE_IEEE80211:
634 pNew->Props.MediaType = NCM_SHAREDACCESSHOST_RAS;
635 break;
636 default:
637 break;
638 }
639 /* open network connections details */
640 wcscpy(&szName[80], szNetCfg);
641 wcscpy(&szName[118], L"\\Connection");
642
643 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS)
644 {
645 /* retrieve name of connection */
646 dwSize = sizeof(szAdapterNetCfg);
647 if (RegQueryValueExW(hSubKey, L"Name", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS)
648 {
649 pNew->Props.pszwName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR)));
650 if (pNew->Props.pszwName)
651 wcscpy(pNew->Props.pszwName, szAdapterNetCfg);
652 }
653 dwSize = sizeof(dwShowIcon);
654 if (RegQueryValueExW(hSubKey, L"ShowIcon", NULL, NULL, (LPBYTE)&dwShowIcon, &dwSize) == ERROR_SUCCESS)
655 {
656 if (dwShowIcon)
657 pNew->Props.dwCharacter |= NCCF_SHOW_ICON;
658 }
659 dwSize = sizeof(dwNotifyDisconnect);
660 if (RegQueryValueExW(hSubKey, L"IpCheckingEnabled", NULL, NULL, (LPBYTE)&dwNotifyDisconnect, &dwSize) == ERROR_SUCCESS)
661 {
662 if (dwNotifyDisconnect)
663 pNew->Props.dwCharacter |= NCCF_NOTIFY_DISCONNECTED;
664 }
665 RegCloseKey(hSubKey);
666 }
667
668 /* Get the adapter device description */
669 dwSize = 0;
670 SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, NULL, 0, &dwSize);
671 if (dwSize != 0)
672 {
673 pNew->Props.pszwDeviceName = static_cast<PWSTR>(CoTaskMemAlloc(dwSize));
674 if (pNew->Props.pszwDeviceName)
675 SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, (PBYTE)pNew->Props.pszwDeviceName, dwSize, &dwSize);
676 }
677
678 if (pCurrent)
679 pCurrent->Next = pNew;
680 else
681 m_pHead = pNew;
682
683 pCurrent = pNew;
684 } while (TRUE);
685
686 CoTaskMemFree(pIfTable);
687 CoTaskMemFree(pAdapterInfo);
688 SetupDiDestroyDeviceInfoList(hInfo);
689
690 m_pCurrent = m_pHead;
691 return (m_pHead != NULL ? S_OK : S_FALSE);
692}
693
694HRESULT CNetConnectionManager::Initialize()
695{
696 HRESULT hr = EnumerateINetConnections();
697 if (FAILED_UNEXPECTEDLY(hr))
698 {
699 /* If something went wrong during the enumeration print an error don't enumerate anything */
700 m_pCurrent = m_pHead = NULL;
701 return S_FALSE;
702 }
703 return S_OK;
704}
705
706HRESULT WINAPI CNetConnectionManager_CreateInstance(REFIID riid, LPVOID * ppv)
707{
708#if USE_CUSTOM_CONMGR
709 return ShellObjectCreatorInit<CNetConnectionManager>(riid, ppv);
710#else
711 return CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_ALL, riid, ppv);
712#endif
713}