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