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