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 !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 190 HRESULT 191 WINAPI 192 CNetConnection::Delete() 193 { 194 return E_NOTIMPL; 195 } 196 197 HRESULT 198 WINAPI 199 CNetConnection::Duplicate( 200 LPCWSTR pszwDuplicateName, 201 INetConnection **ppCon) 202 { 203 return E_NOTIMPL; 204 } 205 206 HRESULT 207 WINAPI 208 CNetConnection::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 316 HRESULT 317 WINAPI 318 CNetConnection::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 329 HRESULT 330 WINAPI 331 CNetConnection::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 374 HRESULT WINAPI CNetConnection_CreateInstance(PINetConnectionItem pItem, REFIID riid, LPVOID * ppv) 375 { 376 return ShellObjectCreatorInit<CNetConnection>(pItem, riid, ppv); 377 } 378 379 380 381 CNetConnectionManager::CNetConnectionManager() : 382 m_pHead(NULL), 383 m_pCurrent(NULL) 384 { 385 } 386 387 HRESULT 388 WINAPI 389 CNetConnectionManager::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 410 HRESULT 411 WINAPI 412 CNetConnectionManager::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 434 HRESULT 435 WINAPI 436 CNetConnectionManager::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 448 HRESULT 449 WINAPI 450 CNetConnectionManager::Reset() 451 { 452 m_pCurrent = m_pHead; 453 return S_OK; 454 } 455 456 HRESULT 457 WINAPI 458 CNetConnectionManager::Clone(IEnumNetConnection **ppenum) 459 { 460 return E_NOTIMPL; 461 } 462 463 BOOL 464 GetAdapterIndexFromNetCfgInstanceId(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 487 VOID 488 NormalizeOperStatus( 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 517 HRESULT 518 CNetConnectionManager::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 694 HRESULT 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 706 HRESULT 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 } 714