VirtualBox

Changeset 58874 in vbox


Ignore:
Timestamp:
Nov 26, 2015 6:51:52 AM (9 years ago)
Author:
vboxsync
Message:

Main/Network: adapter enumeration re-worked to use INetCfg with minimum amount of other API calls (Vista+), extra release logging enabled, delayed renaming re-enabled (#7973)

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxNetCfg-win.h

    r58795 r58874  
    3535 * still being 'committed' by the network setup engine.
    3636 */
    37 //#define VBOXNETCFG_DELAYEDRENAME
     37#define VBOXNETCFG_DELAYEDRENAME
    3838
    3939#include <winsock2.h>
  • trunk/src/VBox/Main/Makefile.kmk

    r58383 r58874  
    302302endif
    303303VBoxSVC_DEFS.win += VBOX_COM_OUTOFPROC_MODULE
    304 VBoxSVC_DEFS.win += _WIN32_WINNT=0x0510
     304VBoxSVC_DEFS.win += _WIN32_WINNT=0x0600
    305305# Try to load and use libhal at runtime for probing removable media
    306306# VBoxSVC_DEFS.linux += VBOX_USE_LIBHAL
  • trunk/src/VBox/Main/src-server/win/NetIf-win.cpp

    r58794 r58874  
    14731473}
    14741474
    1475 #ifndef NETIF_WITHOUT_NETCFG
    1476 int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
    1477 {
    1478 #ifndef VBOX_WITH_NETFLT
    1479     return VERR_NOT_IMPLEMENTED;
    1480 #else /* #  if defined VBOX_WITH_NETFLT */
    1481     INetCfg              *pNc = NULL;
    1482     INetCfgComponent     *pMpNcc;
    1483     INetCfgComponent     *pTcpIpNcc;
     1475
     1476#define netIfLog LogRel
     1477
     1478struct BoundAdapter
     1479{
     1480    LPWSTR                pName;
     1481    LPWSTR                pHwId;
     1482    RTUUID                guid;
     1483    PIP_ADAPTER_ADDRESSES pAdapter;
     1484};
     1485
     1486static HRESULT netIfGetBoundAdapters(std::list<BoundAdapter> &boundAdapters)
     1487{
     1488    INetCfg              *pNetCfg = NULL;
     1489    INetCfgComponent     *pFilter;
    14841490    LPWSTR               lpszApp;
    14851491    HRESULT              hr;
    1486     IEnumNetCfgBindingPath      *pEnumBp;
    1487     INetCfgBindingPath          *pBp;
    1488     IEnumNetCfgBindingInterface *pEnumBi;
    1489     INetCfgBindingInterface *pBi;
    1490     int                  iDefault = getDefaultInterfaceIndex();
    1491 
    1492     Log(("NetIfList: building the list of interfaces\n"));
     1492
     1493    netIfLog(("netIfGetBoundAdapters: building the list of interfaces\n"));
    14931494    /* we are using the INetCfg API for getting the list of miniports */
    1494     hr = VBoxNetCfgWinQueryINetCfg(&pNc, FALSE,
     1495    hr = VBoxNetCfgWinQueryINetCfg(&pNetCfg, FALSE,
    14951496                       VBOX_APP_NAME,
    14961497                       10000,
     
    14991500    if (hr != S_OK)
    15001501    {
    1501         if (pNc)
    1502             pNc->Release();
    1503         pNc = NULL;
    1504         LogRel(("NetIfList: failed to acquire INetCfg interface (0x%x), trying CoCreateInstance...\n", hr));
    1505         hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (PVOID*)&pNc);
    1506         if (SUCCEEDED(hr))
    1507         {
    1508             hr = pNc->Initialize(NULL);
    1509             if (FAILED(hr))
    1510             {
    1511                 LogRel(("NetIfList: INetCfg::Initialize failed with 0x%x\n", hr));
    1512                 if (pNc)
    1513                     pNc->Release();
    1514                 pNc = NULL;
    1515             }
    1516         }
     1502        netIfLog(("netIfGetBoundAdapters: failed to query INetCfg (0x%x)\n", hr));
     1503        return hr;
     1504    }
     1505
     1506    if ((hr = pNetCfg->FindComponent(L"oracle_VBoxNetLwf", &pFilter)) != S_OK)
     1507        netIfLog(("netIfGetBoundAdapters: could not find 'oracle_VBoxNetLwf' component (0x%x)\n", hr));
     1508    else
     1509    {
     1510        INetCfgComponentBindings *pFilterBindings;
     1511        if ((pFilter->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pFilterBindings)) != S_OK)
     1512            netIfLog(("netIfGetBoundAdapters: failed to query INetCfgComponentBindings (0x%x)\n", hr));
    15171513        else
    1518             LogRel(("NetIfList: CoCreateInstance failed with 0x%x\n", hr));
    1519     }
    1520 
    1521     if (hr == S_OK)
    1522     {
    1523 # ifdef VBOX_NETFLT_ONDEMAND_BIND
    1524         /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
    1525         hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
    1526 # else
    1527         /* for the filter-based approach we get all miniports our filter (oracle_VBoxNetLwf)is bound to */
    1528         hr = pNc->FindComponent(L"oracle_VBoxNetLwf", &pTcpIpNcc);
    1529         if (hr != S_OK)
    1530         {
    1531             LogRel(("NetIfList: could not find VBoxNetLwf component (error 0x%x), trying VBoxNetFlt instead\n", hr));
    1532             /* fall back to NDIS5 miniport lookup (sun_VBoxNetFlt) */
    1533             hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
    1534         }
    1535 #  ifndef VBOX_WITH_HARDENING
    1536         if (hr != S_OK)
    1537         {
    1538             /* TODO: try to install the netflt from here */
    1539         }
    1540 #  endif
    1541 
    1542 # endif
    1543 
    1544         if (hr == S_OK)
    1545         {
    1546             INetCfgComponentBindings *pBindings;
    1547             hr = pTcpIpNcc->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pBindings);
    1548             Assert(hr == S_OK);
    1549             if (hr == S_OK)
    1550             {
    1551                 hr = pBindings->EnumBindingPaths(EBP_BELOW, &pEnumBp);
    1552                 Assert(hr == S_OK);
    1553                 if (hr == S_OK)
    1554                 {
    1555                     hr = pEnumBp->Reset();
    1556                     Assert(hr == S_OK);
    1557                     if (hr == S_OK)
    1558                     {
    1559                         while ((hr = pEnumBp->Next(1, &pBp, NULL)) == S_OK)
     1514        {
     1515            IEnumNetCfgBindingPath *pEnumBp;
     1516            INetCfgBindingPath     *pBp;
     1517            if ((pFilterBindings->EnumBindingPaths(EBP_BELOW, &pEnumBp)) != S_OK)
     1518                netIfLog(("netIfGetBoundAdapters: failed to enumerate binding paths (0x%x)\n", hr));
     1519            else
     1520            {
     1521                pEnumBp->Reset();
     1522                while ((hr = pEnumBp->Next(1, &pBp, NULL)) == S_OK)
     1523                {
     1524                    IEnumNetCfgBindingInterface *pEnumBi;
     1525                    INetCfgBindingInterface     *pBi;
     1526                    if (pBp->IsEnabled() != S_OK)
     1527                    {
     1528                        /* @todo some id of disabled path could be useful. */
     1529                        netIfLog(("netIfGetBoundAdapters: INetCfgBindingPath is disabled (0x%x)\n", hr));
     1530                        pBp->Release();
     1531                        continue;
     1532                    }
     1533                    if ((pBp->EnumBindingInterfaces(&pEnumBi)) != S_OK)
     1534                        netIfLog(("netIfGetBoundAdapters: failed to enumerate binding interfaces (0x%x)\n", hr));
     1535                    else
     1536                    {
     1537                        hr = pEnumBi->Reset();
     1538                        while ((hr = pEnumBi->Next(1, &pBi, NULL)) == S_OK)
    15601539                        {
    1561                             Log(("NetIfList: fetched INetCfgBindingPath interface\n"));
    1562                             /* S_OK == enabled, S_FALSE == disabled */
    1563                             if (pBp->IsEnabled() == S_OK)
     1540                            INetCfgComponent *pAdapter;
     1541                            if ((hr = pBi->GetLowerComponent(&pAdapter)) != S_OK)
     1542                                netIfLog(("netIfGetBoundAdapters: failed to get lower component (0x%x)\n", hr));
     1543                            else
    15641544                            {
    1565                                 hr = pBp->EnumBindingInterfaces(&pEnumBi);
    1566                                 Assert(hr == S_OK);
    1567                                 if (hr == S_OK)
     1545                                LPWSTR pwszName = NULL;
     1546                                if ((hr = pAdapter->GetDisplayName(&pwszName)) != S_OK)
     1547                                    netIfLog(("netIfGetBoundAdapters: failed to get display name (0x%x)\n", hr));
     1548                                else
    15681549                                {
    1569                                     hr = pEnumBi->Reset();
    1570                                     Assert(hr == S_OK);
    1571                                     if (hr == S_OK)
     1550                                    ULONG uStatus;
     1551                                    DWORD dwChars;
     1552                                    if ((hr = pAdapter->GetDeviceStatus(&uStatus)) != S_OK)
     1553                                        netIfLog(("netIfGetBoundAdapters: %ls: failed to get device status (0x%x)\n",
     1554                                                  pwszName, hr));
     1555                                    else if ((hr = pAdapter->GetCharacteristics(&dwChars)) != S_OK)
     1556                                        netIfLog(("netIfGetBoundAdapters: %ls: failed to get device characteristics (0x%x)\n",
     1557                                                  pwszName, hr));
     1558                                    else if (uStatus != 0)
     1559                                        netIfLog(("netIfGetBoundAdapters: %ls: wrong status 0x%x\n",
     1560                                                  pwszName, uStatus));
     1561                                    else if ((dwChars & NCF_HIDDEN) || !(dwChars & (NCF_VIRTUAL | NCF_PHYSICAL)))
     1562                                        netIfLog(("netIfGetBoundAdapters: %ls: wrong characteristics 0x%x\n",
     1563                                                  pwszName, dwChars));
     1564                                    else
    15721565                                    {
    1573                                         while ((hr = pEnumBi->Next(1, &pBi, NULL)) == S_OK)
     1566                                        GUID guid;
     1567                                        LPWSTR pwszHwId = NULL;
     1568                                        if ((hr = pAdapter->GetId(&pwszHwId)) != S_OK)
     1569                                            netIfLog(("netIfGetBoundAdapters: %ls: failed to get hardware id (0x%x)\n",
     1570                                                      pwszName, hr));
     1571                                        else if ((hr = pAdapter->GetInstanceGuid(&guid)) != S_OK)
     1572                                            netIfLog(("netIfGetBoundAdapters: %ls: failed to get instance GUID (0x%x)\n",
     1573                                                      pwszName, hr));
     1574                                        else
    15741575                                        {
    1575                                             Log(("NetIfList: fetched INetCfgBindingInterface interface\n"));
    1576                                             hr = pBi->GetLowerComponent(&pMpNcc);
    1577                                             Assert(hr == S_OK);
    1578                                             if (hr == S_OK)
    1579                                             {
    1580                                                 LPWSTR pwszName;
    1581                                                 ULONG uComponentStatus;
    1582                                                 hr = pMpNcc->GetDisplayName(&pwszName);
    1583                                                 if (hr == S_OK)
    1584                                                     Log(("NetIfList: got %ls\n", pwszName));
    1585                                                 else
    1586                                                     LogRel(("NetIfList: failed to get device display name (0x%x)\n", hr));
    1587                                                 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
    1588                                                 if (hr == S_OK)
    1589                                                 {
    1590                                                     if (uComponentStatus == 0)
    1591                                                     {
    1592                                                         LPWSTR pId;
    1593                                                         hr = pMpNcc->GetId(&pId);
    1594                                                         Assert(hr == S_OK);
    1595                                                         if (hr == S_OK)
    1596                                                         {
    1597                                                             Log(("NetIfList: fetched network adapter id: %.80ls\n", pId));
    1598                                                             /*
    1599                                                              * Host-only interfaces are ignored here and included into the list
    1600                                                              * later in netIfListHostAdapters()
    1601                                                              */
    1602                                                             if (_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
    1603                                                             {
    1604                                                                 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged,
    1605                                                                                        iDefault);
    1606                                                             }
    1607                                                             CoTaskMemFree(pId);
    1608                                                         }
    1609                                                         else
    1610                                                             LogRel(("NetIfList: failed to get device id (0x%x)\n", hr));
    1611                                                     }
    1612                                                     else
    1613                                                         LogRel(("NetIfList: wrong device status (0x%x)\n", uComponentStatus));
    1614                                                 }
    1615                                                 else
    1616                                                     LogRel(("NetIfList: failed to get device status (0x%x)\n", hr));
    1617                                                 pMpNcc->Release();
    1618                                             }
    1619                                             else
    1620                                                 LogRel(("NetIfList: failed to get lower component (0x%x)\n", hr));
    1621                                             pBi->Release();
     1576                                            struct BoundAdapter adapter;
     1577                                            adapter.pName    = pwszName;
     1578                                            adapter.pHwId    = pwszHwId;
     1579                                            adapter.guid     = *(Guid(guid).raw());
     1580                                            adapter.pAdapter = NULL;
     1581                                            netIfLog(("netIfGetBoundAdapters: guid=%RTuuid, name=%ls, hwid=%ls, status=%x, chars=%x\n",
     1582                                                      &adapter.guid, pwszName, pwszHwId, uStatus, dwChars));
     1583                                            boundAdapters.push_back(adapter);
     1584                                            pwszName = pwszHwId = NULL; /* do not free, will be done later */
    16221585                                        }
    1623                                         Assert(hr == S_OK || hr == S_FALSE);
     1586                                        if (pwszHwId)
     1587                                            CoTaskMemFree(pwszHwId);
    16241588                                    }
    1625                                     else
    1626                                         LogRel(("NetIfList: IEnumNetCfgBindingInterface::Reset failed (0x%x)\n", hr));
    1627                                     pEnumBi->Release();
     1589                                    if (pwszName)
     1590                                        CoTaskMemFree(pwszName);
    16281591                                }
    1629                                 else
    1630                                     LogRel(("NetIfList: failed to enumerate binding interfaces (0x%x)\n", hr));
     1592
     1593                                pAdapter->Release();
    16311594                            }
    1632                             else
    1633                                 LogRel(("NetIfList: INetCfgBindingPath is disabled\n"));
    1634                             pBp->Release();
     1595                            pBi->Release();
    16351596                        }
    1636                         Assert(hr == S_OK || hr == S_FALSE);
    1637                     }
     1597                        pEnumBi->Release();
     1598                    }
     1599                    pBp->Release();
     1600                }
     1601                pEnumBp->Release();
     1602            }
     1603            pFilterBindings->Release();
     1604        }
     1605        pFilter->Release();
     1606    }
     1607    VBoxNetCfgWinReleaseINetCfg(pNetCfg, FALSE);
     1608
     1609    return S_OK;
     1610}
     1611
     1612#if 0
     1613static HRESULT netIfGetBoundAdaptersFallback(std::list<BoundAdapter> &boundAdapters)
     1614{
     1615    return CO_E_NOT_SUPPORTED;
     1616}
     1617#endif
     1618
     1619static void netIfFillInfoWithAddresses(PNETIFINFO pInfo, PIP_ADAPTER_ADDRESSES pAdapter)
     1620{
     1621    PIP_ADAPTER_UNICAST_ADDRESS pAddr;
     1622
     1623    if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
     1624        netIfLog(("netIfFillInfoWithAddresses: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
     1625    else
     1626        memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
     1627
     1628    bool fIPFound = false;
     1629    bool fIPv6Found = false;
     1630    for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
     1631    {
     1632        switch (pAddr->Address.lpSockaddr->sa_family)
     1633        {
     1634            case AF_INET:
     1635                if (!fIPFound)
     1636                {
     1637                    fIPFound = true;
     1638                    memcpy(&pInfo->IPAddress,
     1639                           &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
     1640                           sizeof(pInfo->IPAddress));
     1641                    if (pAddr->OnLinkPrefixLength > 32)
     1642                        netIfLog(("netIfFillInfoWithAddresses: Invalid IPv4 prefix length of %d\n", pAddr->OnLinkPrefixLength));
    16381643                    else
    1639                         LogRel(("NetIfList: IEnumNetCfgBindingPath::Reset failed (0x%x)\n", hr));
    1640                     pEnumBp->Release();
    1641                 }
    1642                 else
    1643                     LogRel(("NetIfList: EnumBindingPaths failed (0x%x)\n", hr));
    1644                 pBindings->Release();
    1645             }
    1646             else
    1647                 LogRel(("NetIfList: failed to acquire INetCfgComponentBindings interface\n"));
    1648             pTcpIpNcc->Release();
    1649         }
    1650         else
    1651         {
    1652             LogRel(("failed to get the oracle_VBoxNetLwf(sun_VBoxNetFlt) component, error (0x%x)\n", hr));
    1653         }
    1654 
    1655         /* Add host-only adapters to the list */
    1656         netIfListHostAdapters(pNc, list);
    1657 
    1658         VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
    1659     }
    1660 
    1661     return VINF_SUCCESS;
    1662 #endif /* #  if defined VBOX_WITH_NETFLT */
    1663 }
    1664 
    1665 #else /* !NETIF_WITHOUT_NETCFG */
    1666 
    1667 static void getTypeAndName(PIP_ADAPTER_ADDRESSES pAdapter, HostNetworkInterfaceType *enmType, PWCHAR pwszName, int cbName)
    1668 {
    1669     /* In case we fail to get the right values we initialize them with best-effort defaults. */
    1670     *enmType = wcsncmp(pAdapter->Description, L"VirtualBox", 10) == 0
    1671                        ? HostNetworkInterfaceType_HostOnly
    1672                        : HostNetworkInterfaceType_Bridged;
    1673     wcscpy_s(pwszName, cbName / sizeof(*pwszName), pAdapter->Description);
    1674 
    1675     char szKeyName[256];
    1676     sprintf_s(szKeyName, sizeof(szKeyName),
    1677               "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",
    1678               pAdapter->AdapterName);
    1679     HKEY hkeyConnection;
    1680     LONG status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_READ, &hkeyConnection);
    1681     if (status != ERROR_SUCCESS)
    1682     {
    1683         LogRel(("NetIf: Failed to find connection key in registry for %ls at %s\n",
    1684                 pAdapter->Description, szKeyName));
    1685     }
    1686     else
    1687     {
    1688         WCHAR wszId[256];
    1689         DWORD dwLen = sizeof(wszId);
    1690         status = RegQueryValueExW(hkeyConnection, L"PnPInstanceID", NULL, NULL, (LPBYTE)wszId, &dwLen);
    1691         if (status != ERROR_SUCCESS)
    1692         {
    1693             LogRel(("NetIf: Failed to get PnPInstanceID from registry for %ls\n", pAdapter->Description));
    1694         }
    1695         else
    1696         {
    1697             HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_NET, NULL);
    1698             if (hDevInfo != INVALID_HANDLE_VALUE)
    1699             {
    1700                 SP_DEVINFO_DATA DevInfoData;
    1701                
    1702                 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    1703                 if (SetupDiOpenDeviceInfo(hDevInfo, wszId, NULL, 0, &DevInfoData))
    1704                 {
    1705                     if (SetupDiGetDeviceRegistryPropertyW(hDevInfo, &DevInfoData,
    1706                                                           SPDRP_HARDWAREID, NULL,
    1707                                                           (PBYTE)wszId, sizeof(wszId), NULL))
    1708                     {
    1709                         /*
    1710                          * We do not care for multiple strings that may have been
    1711                          * returned since our host-only adapter has a single id.
    1712                          */
    1713                         if (_wcsnicmp(wszId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
    1714                             *enmType = HostNetworkInterfaceType_Bridged;
    1715                         else
    1716                             *enmType = HostNetworkInterfaceType_HostOnly;
    1717                     }
    1718                     SetupDiGetDeviceRegistryPropertyW(hDevInfo, &DevInfoData,
    1719                                                       SPDRP_FRIENDLYNAME, NULL,
    1720                                                       (PBYTE)pwszName, cbName, NULL);
    1721                 }
    1722                 SetupDiDestroyDeviceInfoList(hDevInfo);
    1723             }
    1724             LogRel(("PnP ID: %ls\n", wszId));
    1725         }
    1726         RegCloseKey(hkeyConnection);
     1644                        ASMBitSetRange(&pInfo->IPNetMask, 0, pAddr->OnLinkPrefixLength);
     1645                }
     1646                break;
     1647            case AF_INET6:
     1648                if (!fIPv6Found)
     1649                {
     1650                    fIPv6Found = true;
     1651                    memcpy(&pInfo->IPv6Address,
     1652                           ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
     1653                           sizeof(pInfo->IPv6Address));
     1654                    if (pAddr->OnLinkPrefixLength > 128)
     1655                        netIfLog(("netIfFillInfoWithAddresses: Invalid IPv6 prefix length of %d\n", pAddr->OnLinkPrefixLength));
     1656                    else
     1657                        ASMBitSetRange(&pInfo->IPv6NetMask, 0, pAddr->OnLinkPrefixLength);
     1658                }
     1659                break;
     1660        }
    17271661    }
    17281662}
     
    17301664int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
    17311665{
    1732     DWORD dwRc;
    1733     int rc = VINF_SUCCESS;
     1666    HRESULT hr = S_OK;
    17341667    int iDefault = getDefaultInterfaceIndex();
    1735     /*
    1736      * Most of the hosts probably have less than 10 adapters,
    1737      * so we'll mostly succeed from the first attempt.
    1738      */
    1739     ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
     1668    /* MSDN recommends to pre-allocate a 15KB buffer. */
     1669    ULONG uBufLen = 15 * 1024;
    17401670    PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
    17411671    if (!pAddresses)
    1742         return VERR_NO_MEMORY;
    1743     dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
    1744     if (dwRc == ERROR_BUFFER_OVERFLOW)
    1745     {
    1746         /* Impressive! More than 10 adapters! Get more memory and try again. */
    1747         RTMemFree(pAddresses);
     1672        return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
     1673    DWORD dwRc = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &uBufLen);
     1674    for (int tries = 0; tries < 3 && dwRc == ERROR_BUFFER_OVERFLOW; ++tries)
     1675    {
     1676        /* Get more memory and try again. */
     1677        free(pAddresses);
    17481678        pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
    17491679        if (!pAddresses)
    1750             return VERR_NO_MEMORY;
    1751         dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
    1752     }
    1753     if (dwRc == NO_ERROR)
    1754     {
    1755         PIP_ADAPTER_ADDRESSES pAdapter;
    1756         for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
    1757         {
    1758             Log(("Enumerating %s\n", pAdapter->AdapterName));
    1759             /* Vista+ systems introduced separate type for wireless adapters */
    1760             if (pAdapter->IfType != IF_TYPE_ETHERNET_CSMACD && pAdapter->IfType != IF_TYPE_IEEE80211)
    1761             {
    1762                 LogRel(("Skipped non-Ethernet '%ls'\n", pAdapter->FriendlyName));
    1763                 continue;
    1764             }
    1765 
    1766             NETIFINFO Info;
    1767             RT_ZERO(Info);
    1768 
    1769             if (pAdapter->AdapterName[0] == '{')
    1770             {
    1771                 bool fIPv4Found, fIPv6Found;
    1772                 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
    1773                 fIPv4Found = fIPv6Found = false;
    1774                 for (pAddr = pAdapter->FirstUnicastAddress;
    1775                      pAddr && !(fIPv4Found && fIPv6Found);
    1776                      pAddr = pAddr->Next)
    1777                 {
    1778                     switch (pAddr->Address.lpSockaddr->sa_family)
    1779                     {
    1780                         case AF_INET:
    1781                             if (!fIPv4Found)
    1782                             {
    1783                                 fIPv4Found = true;
    1784                                 memcpy(&Info.IPAddress,
    1785                                        &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
    1786                                        sizeof(Info.IPAddress));
    1787                             }
     1680            return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
     1681        dwRc = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &uBufLen);
     1682    }
     1683    if (dwRc != NO_ERROR)
     1684    {
     1685        netIfLog(("NetIfList: GetAdaptersAddresses failed (0x%x)\n", dwRc));
     1686        hr = HRESULT_FROM_WIN32(dwRc);
     1687    }
     1688    else
     1689    {
     1690        std::list<BoundAdapter> boundAdapters;
     1691        HRESULT hr = netIfGetBoundAdapters(boundAdapters);
     1692#if 0
     1693        if (hr != S_OK)
     1694            hr = netIfGetBoundAdaptersFallback(boundAdapters);
     1695#endif
     1696        if (hr != S_OK)
     1697            netIfLog(("NetIfList: netIfGetBoundAdapters failed (0x%x)\n", hr));
     1698        else
     1699        {
     1700            PIP_ADAPTER_ADDRESSES pAdapter;
     1701
     1702            for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
     1703            {
     1704                char *pszUuid = RTStrDup(pAdapter->AdapterName);
     1705                if (!pszUuid)
     1706                {
     1707                    netIfLog(("NetIfList: out of memory\n"));
     1708                    break;
     1709                }
     1710                size_t len = strlen(pszUuid) - 1;
     1711                if (pszUuid[0] != '{' || pszUuid[len] != '}')
     1712                    netIfLog(("NetIfList: ignoring invalid GUID %s\n", pAdapter->AdapterName));
     1713                else
     1714                {
     1715                    std::list<BoundAdapter>::iterator it;
     1716                    pszUuid[len] = 0;
     1717                    for (it = boundAdapters.begin(); it != boundAdapters.end(); ++it)
     1718                    {
     1719                        if (!RTUuidCompareStr(Guid((*it).guid).raw(), pszUuid + 1))
     1720                        {
     1721                            (*it).pAdapter = pAdapter;
    17881722                            break;
    1789                         case AF_INET6:
    1790                             if (!fIPv6Found)
    1791                             {
    1792                                 fIPv6Found = true;
    1793                                 memcpy(&Info.IPv6Address,
    1794                                        ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
    1795                                        sizeof(Info.IPv6Address));
    1796                             }
    1797                             break;
    1798                     }
    1799                 }
    1800                 PIP_ADAPTER_PREFIX pPrefix;
    1801                 fIPv4Found = fIPv6Found = false;
    1802                 for (pPrefix = pAdapter->FirstPrefix;
    1803                      pPrefix && !(fIPv4Found && fIPv6Found);
    1804                      pPrefix = pPrefix->Next)
    1805                 {
    1806                     switch (pPrefix->Address.lpSockaddr->sa_family)
    1807                     {
    1808                         case AF_INET:
    1809                             if (!fIPv4Found)
    1810                             {
    1811                                 if (pPrefix->PrefixLength <= sizeof(Info.IPNetMask) * 8)
    1812                                 {
    1813                                     fIPv4Found = true;
    1814                                     ASMBitSetRange(&Info.IPNetMask, 0, pPrefix->PrefixLength);
    1815                                 }
    1816                                 else
    1817                                     LogRel(("NetIfList: Unexpected IPv4 prefix length of %d\n",
    1818                                             pPrefix->PrefixLength));
    1819                             }
    1820                             break;
    1821                         case AF_INET6:
    1822                             if (!fIPv6Found)
    1823                             {
    1824                                 if (pPrefix->PrefixLength <= sizeof(Info.IPv6NetMask) * 8)
    1825                                 {
    1826                                     fIPv6Found = true;
    1827                                     ASMBitSetRange(&Info.IPv6NetMask, 0, pPrefix->PrefixLength);
    1828                                 }
    1829                                 else
    1830                                     LogRel(("NetIfList: Unexpected IPv6 prefix length of %d\n",
    1831                                             pPrefix->PrefixLength));
    1832                             }
    1833                             break;
    1834                     }
    1835                 }
    1836                 if (sizeof(Info.MACAddress) != pAdapter->PhysicalAddressLength)
    1837                     LogRel(("NetIfList: Unexpected physical address length: %u\n",
    1838                             pAdapter->PhysicalAddressLength));
     1723                        }
     1724                    }
     1725                }
     1726                RTStrFree(pszUuid);
     1727            }
     1728            std::list<BoundAdapter>::iterator it;
     1729            for (it = boundAdapters.begin(); it != boundAdapters.end(); ++it)
     1730            {
     1731                NETIFINFO info;
     1732                memset(&info, 0, sizeof(info));
     1733                info.Uuid = (*it).guid;
     1734                info.enmMediumType = NETIF_T_ETHERNET;
     1735                pAdapter = (*it).pAdapter;
     1736                if (pAdapter)
     1737                {
     1738                    info.enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
     1739                    info.bIsDefault = (pAdapter->IfIndex == iDefault);
     1740                    info.bDhcpEnabled = pAdapter->Flags & IP_ADAPTER_DHCP_ENABLED;
     1741                    netIfFillInfoWithAddresses(&info, pAdapter);
     1742                }
    18391743                else
    1840                     memcpy(Info.MACAddress.au8, pAdapter->PhysicalAddress, sizeof(Info.MACAddress));
    1841                 Info.enmMediumType = NETIF_T_ETHERNET;
    1842                 Info.enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
    1843                 Info.bDhcpEnabled = !!(pAdapter->Flags & IP_ADAPTER_DHCP_ENABLED);
    1844                 Info.bIsDefault = (pAdapter->IfIndex == iDefault);
    1845 
    1846                 HostNetworkInterfaceType enmType;
    1847                 WCHAR wszName[256];
    1848                 /* Try to get name and type via Setup API */
    1849                 getTypeAndName(pAdapter, &enmType, wszName, sizeof(wszName));
    1850 
    1851                 char *pszUuid = pAdapter->AdapterName + 1;
    1852                 size_t len = strlen(pszUuid) - 1;
    1853                 if (pszUuid[len] != '}')
    1854                 {
    1855                     LogRel(("%s is not a valid UUID!\n", pAdapter->AdapterName));
    1856                     continue;
    1857                 }
    1858                 pszUuid[len] = 0;
    1859                 rc = RTUuidFromStr(&Info.Uuid, pszUuid);
    1860                 if (RT_FAILURE(rc))
    1861                 {
    1862                     LogRel(("NetIfList: Failed to convert %s to UUID (%Rrc)\n", pszUuid, rc));
    1863                     continue;
    1864                 }
    1865                 LogRel(("Adding %ls as %s\n", pAdapter->Description,
    1866                         enmType == HostNetworkInterfaceType_Bridged ? "bridged" :
    1867                         enmType == HostNetworkInterfaceType_HostOnly ? "host-only" : "unknown"));
     1744                    info.enmStatus = NETIF_S_DOWN;
    18681745                /* create a new object and add it to the list */
    18691746                ComObjPtr<HostNetworkInterface> iface;
    18701747                iface.createObject();
    1871                 /* remove the curly bracket at the end */
    1872                 rc = iface->init(wszName, enmType, &Info);
    1873                 if (SUCCEEDED(rc))
    1874                 {
    1875                     if (Info.bIsDefault)
     1748                HostNetworkInterfaceType enmType =
     1749                    _wcsnicmp((*it).pHwId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2) ?
     1750                    HostNetworkInterfaceType_Bridged : HostNetworkInterfaceType_HostOnly;
     1751                netIfLog(("Adding %ls as %s\n", (*it).pName,
     1752                        enmType == HostNetworkInterfaceType_Bridged ? "bridged" :
     1753                        enmType == HostNetworkInterfaceType_HostOnly ? "host-only" : "unknown"));
     1754                int rc = iface->init((*it).pName, enmType, &info);
     1755                if (FAILED(rc))
     1756                    netIfLog(("NetIfList: HostNetworkInterface::init() -> %Rrc\n", rc));
     1757                else
     1758                {
     1759                    if (info.bIsDefault)
    18761760                        list.push_front(iface);
    18771761                    else
    18781762                        list.push_back(iface);
    18791763                }
    1880                 else
    1881                 {
    1882                     LogRel(("NetIfList: HostNetworkInterface::init() -> %Rrc\n", rc));
    1883                     Assert(0);
    1884                 }
    1885             }
    1886         }
    1887     }
    1888 
     1764                if ((*it).pHwId)
     1765                    CoTaskMemFree((*it).pHwId);
     1766                if ((*it).pName)
     1767                    CoTaskMemFree((*it).pName);
     1768            }
     1769        }
     1770    }
    18891771    RTMemFree(pAddresses);
    18901772
    1891     return VINF_SUCCESS;
    1892 }
    1893 #endif /* !NETIF_WITHOUT_NETCFG */
     1773    return hr;
     1774}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette