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 /* Enable 'Rename' and 'Delete' for Adminstrators only */ 294 if (IsUserAdmin()) 295 { 296 pProperties->dwCharacter |= NCCF_ALLOW_RENAME; 297 298 /* Virtual network interfaces can be deleted */ 299 if (IfEntry.dwType == IF_TYPE_TUNNEL) 300 { 301 pProperties->dwCharacter |= NCCF_ALLOW_REMOVAL; 302 } 303 } 304 else 305 { 306 pProperties->dwCharacter &= ~(NCCF_ALLOW_RENAME | NCCF_ALLOW_REMOVAL); 307 } 308 309 return S_OK; 310 } 311 312 HRESULT 313 WINAPI 314 CNetConnection::GetUiObjectClassId(CLSID *pclsid) 315 { 316 if (m_Props.MediaType == NCM_LAN) 317 { 318 CopyMemory(pclsid, &CLSID_LanConnectionUi, sizeof(CLSID)); 319 return S_OK; 320 } 321 322 return E_NOTIMPL; 323 } 324 325 HRESULT 326 WINAPI 327 CNetConnection::Rename(LPCWSTR pszwDuplicateName) 328 { 329 WCHAR szName[140]; 330 LPOLESTR pStr; 331 DWORD dwSize; 332 HKEY hKey; 333 HRESULT hr; 334 335 if (pszwDuplicateName == NULL || wcslen(pszwDuplicateName) == 0) 336 return S_OK; 337 338 if (m_Props.pszwName) 339 { 340 CoTaskMemFree(m_Props.pszwName); 341 m_Props.pszwName = NULL; 342 } 343 344 dwSize = (wcslen(pszwDuplicateName) + 1) * sizeof(WCHAR); 345 m_Props.pszwName = static_cast<PWSTR>(CoTaskMemAlloc(dwSize)); 346 if (m_Props.pszwName == NULL) 347 return E_OUTOFMEMORY; 348 349 wcscpy(m_Props.pszwName, pszwDuplicateName); 350 351 hr = StringFromCLSID((CLSID)m_Props.guidId, &pStr); 352 if (SUCCEEDED(hr)) 353 { 354 wcscpy(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"); 355 wcscat(szName, pStr); 356 wcscat(szName, L"\\Connection"); 357 358 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) 359 { 360 RegSetValueExW(hKey, L"Name", NULL, REG_SZ, (LPBYTE)m_Props.pszwName, dwSize); 361 RegCloseKey(hKey); 362 } 363 364 CoTaskMemFree(pStr); 365 } 366 367 return hr; 368 } 369 370 HRESULT WINAPI CNetConnection_CreateInstance(PINetConnectionItem pItem, REFIID riid, LPVOID * ppv) 371 { 372 return ShellObjectCreatorInit<CNetConnection>(pItem, riid, ppv); 373 } 374 375 376 377 CNetConnectionManager::CNetConnectionManager() : 378 m_pHead(NULL), 379 m_pCurrent(NULL) 380 { 381 } 382 383 HRESULT 384 WINAPI 385 CNetConnectionManager::EnumConnections( 386 NETCONMGR_ENUM_FLAGS Flags, 387 IEnumNetConnection **ppEnum) 388 { 389 TRACE("EnumConnections\n"); 390 391 if (!ppEnum) 392 return E_POINTER; 393 394 if (Flags != NCME_DEFAULT) 395 return E_FAIL; 396 397 *ppEnum = static_cast<IEnumNetConnection*>(this); 398 AddRef(); 399 return S_OK; 400 } 401 402 /*************************************************************** 403 * IEnumNetConnection Interface 404 */ 405 406 HRESULT 407 WINAPI 408 CNetConnectionManager::Next( 409 ULONG celt, 410 INetConnection **rgelt, 411 ULONG *pceltFetched) 412 { 413 HRESULT hr; 414 415 if (!pceltFetched || !rgelt) 416 return E_POINTER; 417 418 if (celt != 1) 419 return E_FAIL; 420 421 if (!m_pCurrent) 422 return S_FALSE; 423 424 hr = CNetConnection_CreateInstance(m_pCurrent, IID_PPV_ARG(INetConnection, rgelt)); 425 m_pCurrent = m_pCurrent->Next; 426 427 return hr; 428 } 429 430 HRESULT 431 WINAPI 432 CNetConnectionManager::Skip(ULONG celt) 433 { 434 while (m_pCurrent && celt-- > 0) 435 m_pCurrent = m_pCurrent->Next; 436 437 if (celt) 438 return S_FALSE; 439 else 440 return S_OK; 441 442 } 443 444 HRESULT 445 WINAPI 446 CNetConnectionManager::Reset() 447 { 448 m_pCurrent = m_pHead; 449 return S_OK; 450 } 451 452 HRESULT 453 WINAPI 454 CNetConnectionManager::Clone(IEnumNetConnection **ppenum) 455 { 456 return E_NOTIMPL; 457 } 458 459 BOOL 460 GetAdapterIndexFromNetCfgInstanceId(PIP_ADAPTER_INFO pAdapterInfo, LPWSTR szNetCfg, PDWORD pIndex) 461 { 462 WCHAR szBuffer[50]; 463 IP_ADAPTER_INFO * pCurrentAdapter; 464 465 pCurrentAdapter = pAdapterInfo; 466 while (pCurrentAdapter) 467 { 468 szBuffer[0] = L'\0'; 469 if (MultiByteToWideChar(CP_ACP, 0, pCurrentAdapter->AdapterName, -1, szBuffer, sizeof(szBuffer)/sizeof(szBuffer[0]))) 470 { 471 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0'; 472 } 473 if (!_wcsicmp(szBuffer, szNetCfg)) 474 { 475 *pIndex = pCurrentAdapter->Index; 476 return TRUE; 477 } 478 pCurrentAdapter = pCurrentAdapter->Next; 479 } 480 return FALSE; 481 } 482 483 VOID 484 NormalizeOperStatus( 485 MIB_IFROW *IfEntry, 486 NETCON_PROPERTIES * Props) 487 { 488 switch (IfEntry->dwOperStatus) 489 { 490 case MIB_IF_OPER_STATUS_NON_OPERATIONAL: 491 Props->Status = NCS_HARDWARE_DISABLED; 492 break; 493 case MIB_IF_OPER_STATUS_UNREACHABLE: 494 Props->Status = NCS_DISCONNECTED; 495 break; 496 case MIB_IF_OPER_STATUS_DISCONNECTED: 497 Props->Status = NCS_MEDIA_DISCONNECTED; 498 break; 499 case MIB_IF_OPER_STATUS_CONNECTING: 500 Props->Status = NCS_CONNECTING; 501 break; 502 case MIB_IF_OPER_STATUS_CONNECTED: 503 Props->Status = NCS_CONNECTED; 504 break; 505 case MIB_IF_OPER_STATUS_OPERATIONAL: 506 Props->Status = NCS_CONNECTED; 507 break; 508 default: 509 break; 510 } 511 } 512 513 HRESULT 514 CNetConnectionManager::EnumerateINetConnections() 515 { 516 DWORD dwSize, dwResult, dwIndex, dwAdapterIndex, dwShowIcon, dwNotifyDisconnect; 517 MIB_IFTABLE *pIfTable; 518 MIB_IFROW IfEntry; 519 IP_ADAPTER_INFO * pAdapterInfo; 520 HDEVINFO hInfo; 521 SP_DEVINFO_DATA DevInfo; 522 HKEY hSubKey; 523 WCHAR szNetCfg[50]; 524 WCHAR szAdapterNetCfg[50]; 525 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\"; 526 WCHAR szName[130] = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; 527 PINetConnectionItem pCurrent = NULL; 528 529 /* get the IfTable */ 530 dwSize = 0; 531 if (GetIfTable(NULL, &dwSize, TRUE) != ERROR_INSUFFICIENT_BUFFER) 532 return E_FAIL; 533 534 pIfTable = static_cast<PMIB_IFTABLE>(CoTaskMemAlloc(dwSize)); 535 if (!pIfTable) 536 return E_OUTOFMEMORY; 537 538 dwResult = GetIfTable(pIfTable, &dwSize, TRUE); 539 if (dwResult != NO_ERROR) 540 { 541 CoTaskMemFree(pIfTable); 542 return HRESULT_FROM_WIN32(dwResult); 543 } 544 545 dwSize = 0; 546 dwResult = GetAdaptersInfo(NULL, &dwSize); 547 if (dwResult!= ERROR_BUFFER_OVERFLOW) 548 { 549 CoTaskMemFree(pIfTable); 550 return HRESULT_FROM_WIN32(dwResult); 551 } 552 553 pAdapterInfo = static_cast<PIP_ADAPTER_INFO>(CoTaskMemAlloc(dwSize)); 554 if (!pAdapterInfo) 555 { 556 CoTaskMemFree(pIfTable); 557 return E_OUTOFMEMORY; 558 } 559 560 dwResult = GetAdaptersInfo(pAdapterInfo, &dwSize); 561 if (dwResult != NO_ERROR) 562 { 563 CoTaskMemFree(pIfTable); 564 CoTaskMemFree(pAdapterInfo); 565 return HRESULT_FROM_WIN32(dwResult); 566 } 567 568 hInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT ); 569 if (!hInfo) 570 { 571 CoTaskMemFree(pIfTable); 572 CoTaskMemFree(pAdapterInfo); 573 return E_FAIL; 574 } 575 576 dwIndex = 0; 577 do 578 { 579 ZeroMemory(&DevInfo, sizeof(SP_DEVINFO_DATA)); 580 DevInfo.cbSize = sizeof(DevInfo); 581 582 /* get device info */ 583 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, &DevInfo)) 584 break; 585 586 /* get device software registry path */ 587 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize)) 588 break; 589 590 /* open device registry key */ 591 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS) 592 break; 593 594 /* query NetCfgInstanceId for current device */ 595 dwSize = sizeof(szNetCfg); 596 if (RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS) 597 { 598 RegCloseKey(hSubKey); 599 break; 600 } 601 RegCloseKey(hSubKey); 602 603 /* get the current adapter index from NetCfgInstanceId */ 604 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo, szNetCfg, &dwAdapterIndex)) 605 continue; 606 607 /* get detailed adapter info */ 608 ZeroMemory(&IfEntry, sizeof(IfEntry)); 609 IfEntry.dwIndex = dwAdapterIndex; 610 if (GetIfEntry(&IfEntry) != NO_ERROR) 611 break; 612 613 /* allocate new INetConnectionItem */ 614 PINetConnectionItem pNew = static_cast<PINetConnectionItem>(CoTaskMemAlloc(sizeof(INetConnectionItem))); 615 if (!pNew) 616 break; 617 618 ZeroMemory(pNew, sizeof(INetConnectionItem)); 619 pNew->dwAdapterIndex = dwAdapterIndex; 620 /* store NetCfgInstanceId */ 621 CLSIDFromString(szNetCfg, &pNew->Props.guidId); 622 NormalizeOperStatus(&IfEntry, &pNew->Props); 623 624 switch (IfEntry.dwType) 625 { 626 case IF_TYPE_ETHERNET_CSMACD: 627 pNew->Props.MediaType = NCM_LAN; 628 break; 629 case IF_TYPE_IEEE80211: 630 pNew->Props.MediaType = NCM_SHAREDACCESSHOST_RAS; 631 break; 632 default: 633 break; 634 } 635 /* open network connections details */ 636 wcscpy(&szName[80], szNetCfg); 637 wcscpy(&szName[118], L"\\Connection"); 638 639 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) 640 { 641 /* retrieve name of connection */ 642 dwSize = sizeof(szAdapterNetCfg); 643 if (RegQueryValueExW(hSubKey, L"Name", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS) 644 { 645 pNew->Props.pszwName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR))); 646 if (pNew->Props.pszwName) 647 wcscpy(pNew->Props.pszwName, szAdapterNetCfg); 648 } 649 dwSize = sizeof(dwShowIcon); 650 if (RegQueryValueExW(hSubKey, L"ShowIcon", NULL, NULL, (LPBYTE)&dwShowIcon, &dwSize) == ERROR_SUCCESS) 651 { 652 if (dwShowIcon) 653 pNew->Props.dwCharacter |= NCCF_SHOW_ICON; 654 } 655 dwSize = sizeof(dwNotifyDisconnect); 656 if (RegQueryValueExW(hSubKey, L"IpCheckingEnabled", NULL, NULL, (LPBYTE)&dwNotifyDisconnect, &dwSize) == ERROR_SUCCESS) 657 { 658 if (dwNotifyDisconnect) 659 pNew->Props.dwCharacter |= NCCF_NOTIFY_DISCONNECTED; 660 } 661 RegCloseKey(hSubKey); 662 } 663 664 /* Get the adapter device description */ 665 dwSize = 0; 666 SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, NULL, 0, &dwSize); 667 if (dwSize != 0) 668 { 669 pNew->Props.pszwDeviceName = static_cast<PWSTR>(CoTaskMemAlloc(dwSize)); 670 if (pNew->Props.pszwDeviceName) 671 SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, (PBYTE)pNew->Props.pszwDeviceName, dwSize, &dwSize); 672 } 673 674 if (pCurrent) 675 pCurrent->Next = pNew; 676 else 677 m_pHead = pNew; 678 679 pCurrent = pNew; 680 } while (TRUE); 681 682 CoTaskMemFree(pIfTable); 683 CoTaskMemFree(pAdapterInfo); 684 SetupDiDestroyDeviceInfoList(hInfo); 685 686 m_pCurrent = m_pHead; 687 return (m_pHead != NULL ? S_OK : S_FALSE); 688 } 689 690 HRESULT CNetConnectionManager::Initialize() 691 { 692 HRESULT hr = EnumerateINetConnections(); 693 if (FAILED_UNEXPECTEDLY(hr)) 694 { 695 /* If something went wrong during the enumeration print an error don't enumerate anything */ 696 m_pCurrent = m_pHead = NULL; 697 return S_FALSE; 698 } 699 return S_OK; 700 } 701 702 HRESULT WINAPI CNetConnectionManager_CreateInstance(REFIID riid, LPVOID * ppv) 703 { 704 #if USE_CUSTOM_CONMGR 705 return ShellObjectCreatorInit<CNetConnectionManager>(riid, ppv); 706 #else 707 return CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_ALL, riid, ppv); 708 #endif 709 } 710