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 } 694