VirtualBox

Changeset 87826 in vbox


Ignore:
Timestamp:
Feb 21, 2021 11:08:44 PM (4 years ago)
Author:
vboxsync
Message:

NAT/Net: Finally get disinherited from VBoxNetBaseService that was a
strange chimera. Use new IntNetIf class to talk to the intnet and
manage our receive and event pumps ourselves. Seems to pass the smoke
test. bugref:9929.

Location:
trunk/src/VBox/NetworkServices/NAT
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/NAT/Makefile.kmk

    r87743 r87826  
    9393VBoxNetNAT_SOURCES = \
    9494        VBoxNetLwipNAT.cpp \
    95         ../NetLib/VBoxNetBaseService.cpp \
     95        ../NetLib/IntNetIf.cpp \
    9696        ../NetLib/VBoxNetPortForwardString.cpp \
    97         ../NetLib/VBoxNetIntIf.cpp \
    98         ../NetLib/VBoxNetUDP.cpp \
    99         ../NetLib/VBoxNetARP.cpp \
    10097        $(addprefix ../../Devices/Network/lwip-new/,$(LWIP_SOURCES)) \
    10198        proxy_pollmgr.c \
  • trunk/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp

    r87798 r87826  
    3030#include <VBox/com/errorprint.h>
    3131#include <VBox/com/VirtualBox.h>
     32#include <VBox/com/NativeEventQueue.h>
    3233
    3334#include <iprt/net.h>
     
    8182#include <stdio.h>
    8283
    83 #include "../NetLib/VBoxNetBaseService.h"
     84#include "../NetLib/IntNetIf.h"
    8485#include "../NetLib/VBoxPortForwardString.h"
    8586
     
    127128
    128129class VBoxNetLwipNAT
    129   : public VBoxNetBaseService
    130 {
     130{
     131    static RTGETOPTDEF s_aGetOptDef[];
     132
     133    com::Utf8Str m_strNetworkName;
     134    int m_uVerbosity;
     135
     136    ComPtr<IVirtualBoxClient> virtualboxClient;
     137    ComPtr<IVirtualBox> virtualbox;
     138    ComPtr<IHost> m_host;
     139    ComPtr<INATNetwork> m_net;
     140
     141    RTMAC m_MacAddress;
     142    IntNetIf m_IntNetIf;
     143    RTTHREAD m_hThrRecv;
     144
    131145    /** Home folder location; used as default directory for several paths. */
    132146    com::Utf8Str m_strHome;
     
    144158    netif m_LwipNetIf;
    145159
    146     /* Our NAT network descriptor in Main */
    147     ComPtr<INATNetwork> m_net;
    148     ComPtr<IHost> m_host;
    149 
    150160    VECNATSERVICEPF m_vecPortForwardRule4;
    151161    VECNATSERVICEPF m_vecPortForwardRule6;
     
    177187    Listener m_ListenerVBoxClient;
    178188
    179     static INTNETSEG aXmitSeg[64];
    180 
    181     static RTGETOPTDEF s_aGetOptDef[];
    182 
    183189public:
    184190    VBoxNetLwipNAT();
    185     virtual ~VBoxNetLwipNAT();
     191    ~VBoxNetLwipNAT();
    186192
    187193    RTEXITCODE parseArgs(int argc, char *argv[]);
    188194
    189     virtual int init();
    190     virtual int run();
     195    int init();
     196    int run();
     197    void shutdown();
    191198
    192199private:
    193     virtual int parseOpt(int c, const RTGETOPTUNION &Value);
    194     virtual void usage();
    195 
    196     virtual bool isMainNeeded() const { return true; }
     200    RTEXITCODE usage();
    197201
    198202    int initCom();
     
    220224    static DECLCALLBACK(void) onLwipTcpIpInit(void *arg);
    221225    static DECLCALLBACK(void) onLwipTcpIpFini(void *arg);
    222     static err_t netifInit(netif *pNetif) RT_NOTHROW_PROTO;
    223 
    224     virtual HRESULT HandleEvent(VBoxEventType_T aEventType, IEvent *pEvent);
     226    static DECLCALLBACK(err_t) netifInit(netif *pNetif) RT_NOTHROW_PROTO;
     227
     228    HRESULT HandleEvent(VBoxEventType_T aEventType, IEvent *pEvent);
    225229
    226230    const char **getHostNameservers();
     
    230234    static int natServicePfRegister(NATSERVICEPORTFORWARDRULE &natServicePf);
    231235
     236    static DECLCALLBACK(int) receiveThread(RTTHREAD hThreadSelf, void *pvUser);
     237
    232238    /* input from intnet */
    233     virtual int processFrame(void *, size_t);
    234     virtual int processGSO(PCPDMNETWORKGSO, size_t);
    235     virtual int processUDP(void *, size_t) { return VERR_IGNORED; }
     239    static DECLCALLBACK(void) processFrame(void *pvUser, void *pvFrame, uint32_t cbFrame);
    236240
    237241    /* output to intnet */
    238     static err_t netifLinkoutput(netif *pNetif, pbuf *pBuf) RT_NOTHROW_PROTO;
     242    static DECLCALLBACK(err_t) netifLinkoutput(netif *pNetif, pbuf *pBuf) RT_NOTHROW_PROTO;
    239243};
    240244
    241 INTNETSEG VBoxNetLwipNAT::aXmitSeg[64];
    242 
    243245
    244246
    245247VBoxNetLwipNAT::VBoxNetLwipNAT()
    246   : VBoxNetBaseService("VBoxNetNAT", "")
     248  : m_uVerbosity(0),
     249    m_hThrRecv(NIL_RTTHREAD)
    247250{
    248251    LogFlowFuncEnter();
     
    272275    m_LwipNetIf.name[1] = 'T';
    273276
    274     RTMAC mac;
    275     mac.au8[0] = 0x52;
    276     mac.au8[1] = 0x54;
    277     mac.au8[2] = 0;
    278     mac.au8[3] = 0x12;
    279     mac.au8[4] = 0x35;
    280     mac.au8[5] = 0;
    281     setMacAddress(mac);
    282 
     277    m_MacAddress.au8[0] = 0x52;
     278    m_MacAddress.au8[1] = 0x54;
     279    m_MacAddress.au8[2] = 0;
     280    m_MacAddress.au8[3] = 0x12;
     281    m_MacAddress.au8[4] = 0x35;
     282    m_MacAddress.au8[5] = 0;
     283
     284    RT_ZERO(m_lo2off);
    283285    m_loOptDescriptor.lomap = NULL;
    284286    m_loOptDescriptor.num_lomap = 0;
     
    311313/**
    312314 * Command line options.
    313  *
    314  * @note This class is currently in transition away from being
    315  * inheritted from VBoxNetBaseService, so it no longer calls its
    316  * getopt code and has its own parseArgs() instead.
    317315 */
    318316RTGETOPTDEF VBoxNetLwipNAT::s_aGetOptDef[] =
     
    326324#define RTEXITCODE_DONE RTEXITCODE_32BIT_HACK
    327325
    328 void
     326RTEXITCODE
    329327VBoxNetLwipNAT::usage()
    330328{
     
    340338    for (size_t i = 0; i < RT_ELEMENTS(s_aGetOptDef); ++i)
    341339        RTPrintf("    -%c, %s\n", s_aGetOptDef[i].iShort, s_aGetOptDef[i].pszLong);
     340
     341    return RTEXITCODE_DONE;
    342342}
    343343
     
    361361        {
    362362            case 'n':           /* --network */
    363                 if (!getNetworkName().empty())
     363                if (m_strNetworkName.isNotEmpty())
    364364                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "multiple --network options");
    365                 setNetworkName(Val.psz);
     365                m_strNetworkName = Val.psz;
    366366                break;
    367367
     
    380380
    381381            case 'h':           /* --help */
    382                 usage();
    383                 return RTEXITCODE_DONE;
     382                return usage();
    384383
    385384            case VINF_GETOPT_NOT_OPTION:
     
    391390    }
    392391
    393     if (getNetworkName().empty())
     392    if (m_strNetworkName.isEmpty())
    394393        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "missing --network option");
    395394
    396     /* tell the base class while we're still joined at the hip */
    397     setVerbosityLevel((int32_t)uVerbosity);
    398 
     395    m_uVerbosity = uVerbosity;
    399396    return RTEXITCODE_SUCCESS;
    400 }
    401 
    402 
    403 /**
    404  * @note This class is currently in transition away from being
    405  * inheritted from VBoxNetBaseService, so it no longer calls its
    406  * getopt code and has its own parseArgs() instead.
    407  */
    408 int VBoxNetLwipNAT::parseOpt(int c, const RTGETOPTUNION &Value)
    409 {
    410     RT_NOREF(c, Value);
    411     return VERR_NOT_FOUND;      /* not recognized */
    412397}
    413398
     
    438423     * API object to get the rest of the configuration from.
    439424     */
    440     const std::string &networkName = getNetworkName();
    441     hrc = virtualbox->FindNATNetworkByName(com::Bstr(networkName.c_str()).raw(),
     425    hrc = virtualbox->FindNATNetworkByName(com::Bstr(m_strNetworkName).raw(),
    442426                                           m_net.asOutParam());
    443427    if (FAILED(hrc))
     
    491475
    492476    /* connect to the intnet */
    493     rc = tryGoOnline();
     477    rc = m_IntNetIf.init(m_strNetworkName);
    494478    if (RT_FAILURE(rc))
    495479        return rc;
    496 
    497     /* start the LWIP thread */
    498     vboxLwipCoreInitialize(VBoxNetLwipNAT::onLwipTcpIpInit, this);
    499480
    500481    LogFlowFuncLeaveRC(rc);
     
    641622    Addr4.u = Net4.u | RT_H2N_U32_C(0x00000001);
    642623
    643     /* Transitional: check that old and new ways agree */
    644     const RTNETADDRIPV4 &CmdLineAddr4 = getIpv4Address();
    645     AssertReturn(CmdLineAddr4.u == 0 || CmdLineAddr4.u == Addr4.u,
    646                  VERR_INVALID_PARAMETER);
    647 
    648     const RTNETADDRIPV4 &CmdLineMask4 = getIpv4Netmask();
    649     AssertReturn(CmdLineMask4.u == 0 || CmdLineMask4.u == Mask4.u,
    650                  VERR_INVALID_PARAMETER);
    651 
    652     /*
    653      * Transitional: tell the base class just in case, though it's not
    654      * used as far as I can tell.
    655      */
    656     if (CmdLineAddr4.u == 0)
    657     {
    658         setIpv4Address(Addr4);
    659         setIpv4Netmask(Mask4);
    660     }
    661 
    662624    memcpy(&m_ProxyOptions.ipv4_addr, &Addr4, sizeof(ip_addr));
    663625    memcpy(&m_ProxyOptions.ipv4_mask, &Mask4, sizeof(ip_addr));
     
    768730
    769731    /* netmask in host order, to verify the offsets */
    770     uint32_t uMask = RT_N2H_U32(getIpv4Netmask().u);
     732    uint32_t uMask = RT_N2H_U32(ip4_addr_get_u32(&m_ProxyOptions.ipv4_mask));
    771733
    772734
     
    13151277 * the exact details.
    13161278 */
    1317 /* static */
    1318 err_t VBoxNetLwipNAT::netifInit(netif *pNetif) RT_NOTHROW_DEF
     1279/* static */ DECLCALLBACK(err_t)
     1280VBoxNetLwipNAT::netifInit(netif *pNetif) RT_NOTHROW_DEF
    13191281{
    13201282    err_t rcLwip = ERR_OK;
     
    13321294
    13331295    pNetif->hwaddr_len = sizeof(RTMAC);
    1334     RTMAC mac = self->getMacAddress();
    1335     memcpy(pNetif->hwaddr, &mac, sizeof(RTMAC));
     1296    memcpy(pNetif->hwaddr, &self->m_MacAddress, sizeof(RTMAC));
    13361297
    13371298    self->m_u16Mtu = 1500; // XXX: FIXME
     
    13731334 * feeds them to lwIP.  Enter COM event loop here, on the main thread.
    13741335 */
    1375 int VBoxNetLwipNAT::run()
    1376 {
    1377     VBoxNetBaseService::run();
    1378 
    1379     /* event pump was told to shut down, we are done ... */
     1336int
     1337VBoxNetLwipNAT::run()
     1338{
     1339    int rc;
     1340
     1341    AssertReturn(m_hThrRecv == NIL_RTTHREAD, VERR_INVALID_STATE);
     1342
     1343    /* spawn the lwIP tcpip thread */
     1344    vboxLwipCoreInitialize(VBoxNetLwipNAT::onLwipTcpIpInit, this);
     1345
     1346    /* spawn intnet input pump */
     1347    rc = RTThreadCreate(&m_hThrRecv,
     1348             VBoxNetLwipNAT::receiveThread, this,
     1349             0, /* :cbStack */
     1350             RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE,
     1351             "RECV");
     1352    AssertRCReturn(rc, rc);
     1353
     1354    /* main thread will run the API event queue pump */
     1355    com::NativeEventQueue *pQueue = com::NativeEventQueue::getMainEventQueue();
     1356    if (pQueue == NULL)
     1357    {
     1358        LogRel(("run: getMainEventQueue() == NULL\n"));
     1359        return VERR_GENERAL_FAILURE;
     1360    }
     1361
     1362    /* dispatch API events to our listeners */
     1363    for (;;)
     1364    {
     1365        rc = pQueue->processEventQueue(RT_INDEFINITE_WAIT);
     1366        if (rc == VERR_INTERRUPTED)
     1367        {
     1368            LogRel(("run: shutdown\n"));
     1369            break;
     1370        }
     1371        else if (rc != VINF_SUCCESS)
     1372        {
     1373            /* note any unexpected rc */
     1374            LogRel(("run: processEventQueue: %Rrc\n", rc));
     1375        }
     1376    }
     1377
     1378    /*
     1379     * We are out of the event loop, so we were told to shut down.
     1380     * Tell other threads to wrap up.
     1381     */
     1382
     1383    /* tell the intnet input pump to terminate */
     1384    m_IntNetIf.ifAbort();
     1385
     1386    /* tell the lwIP tcpip thread to terminate */
    13801387    vboxLwipCoreFinalize(VBoxNetLwipNAT::onLwipTcpIpFini, this);
    13811388
    1382     m_vecPortForwardRule4.clear();
    1383     m_vecPortForwardRule6.clear();
    1384 
     1389    rc = RTThreadWait(m_hThrRecv, 5000, NULL);
     1390    m_hThrRecv = NIL_RTTHREAD;
     1391
     1392    return VINF_SUCCESS;
     1393}
     1394
     1395
     1396void
     1397VBoxNetLwipNAT::shutdown()
     1398{
     1399    int rc;
     1400
     1401    com::NativeEventQueue *pQueue = com::NativeEventQueue::getMainEventQueue();
     1402    if (pQueue == NULL)
     1403    {
     1404        LogRel(("shutdown: getMainEventQueue() == NULL\n"));
     1405        return;
     1406    }
     1407
     1408    /* unregister listeners */
    13851409    m_ListenerNATNet.unlisten();
    13861410    m_ListenerVirtualBox.unlisten();
    13871411    m_ListenerVBoxClient.unlisten();
    13881412
    1389     return VINF_SUCCESS;
     1413    /* tell the event loop in run() to stop */
     1414    rc = pQueue->interruptEventQueueProcessing();
     1415    if (RT_FAILURE(rc))
     1416        LogRel(("shutdown: interruptEventQueueProcessing: %Rrc\n", rc));
    13901417}
    13911418
     
    14221449            hrc = pSettingsEvent->COMGETTER(NetworkName)(networkName.asOutParam());
    14231450            AssertComRCReturn(hrc, hrc);
    1424             if (networkName.compare(getNetworkName().c_str()))
     1451            if (networkName != m_strNetworkName)
    14251452                break; /* change not for our network */
    14261453
     
    14481475            hrc = pForwardEvent->COMGETTER(NetworkName)(networkName.asOutParam());
    14491476            AssertComRCReturn(hrc, hrc);
    1450             if (networkName.compare(getNetworkName().c_str()))
     1477            if (networkName != m_strNetworkName)
    14511478                break; /* change not for our network */
    14521479
     
    16061633            hrc = pStartStopEvent->COMGETTER(NetworkName)(networkName.asOutParam());
    16071634            AssertComRCReturn(hrc, hrc);
    1608             if (networkName.compare(getNetworkName().c_str()))
     1635            if (networkName != m_strNetworkName)
    16091636                break; /* change not for our network */
    16101637
     
    18091836
    18101837/**
     1838 * IntNetIf receive thread.  Runs intnet pump with our processFrame()
     1839 * as input callback.
     1840 */
     1841/* static */ DECLCALLBACK(int)
     1842VBoxNetLwipNAT::receiveThread(RTTHREAD hThreadSelf, void *pvUser)
     1843{
     1844    HRESULT hrc;
     1845    int rc;
     1846
     1847    RT_NOREF(hThreadSelf);
     1848
     1849    AssertReturn(pvUser != NULL, VERR_INVALID_PARAMETER);
     1850    VBoxNetLwipNAT *self = static_cast<VBoxNetLwipNAT *>(pvUser);
     1851
     1852    /* do we relaly need to init com on this thread? */
     1853    hrc = com::Initialize();
     1854    if (FAILED(hrc))
     1855        return VERR_GENERAL_FAILURE;
     1856
     1857    rc = self->m_IntNetIf.setInputCallback(VBoxNetLwipNAT::processFrame, self);
     1858    AssertRCReturn(rc, rc);
     1859
     1860    rc = self->m_IntNetIf.ifPump();
     1861    if (rc == VERR_SEM_DESTROYED)
     1862        return VINF_SUCCESS;
     1863
     1864    LogRel(("receiveThread: ifPump: unexpected %Rrc\n", rc));
     1865    return VERR_INVALID_STATE;
     1866}
     1867
     1868
     1869/**
    18111870 * Process an incoming frame received from the intnet.
    18121871 */
    1813 int VBoxNetLwipNAT::processFrame(void *pvFrame, size_t cbFrame)
    1814 {
    1815     AssertPtrReturn(pvFrame, VERR_INVALID_PARAMETER);
    1816     AssertReturn(cbFrame != 0, VERR_INVALID_PARAMETER);
     1872/* static */ DECLCALLBACK(void)
     1873VBoxNetLwipNAT::processFrame(void *pvUser, void *pvFrame, uint32_t cbFrame)
     1874{
     1875    AssertReturnVoid(pvFrame != NULL);
     1876    AssertReturnVoid(cbFrame != 0);
     1877    AssertReturnVoid(cbFrame <= 1522); /* include .1Q and FCS */
     1878
     1879    AssertReturnVoid(pvUser != NULL);
     1880    VBoxNetLwipNAT *self = static_cast<VBoxNetLwipNAT *>(pvUser);
    18171881
    18181882    struct pbuf *p = pbuf_alloc(PBUF_RAW, (u16_t)cbFrame + ETH_PAD_SIZE, PBUF_POOL);
    18191883    if (RT_UNLIKELY(p == NULL))
    1820         return VERR_NO_MEMORY;
     1884        return;
    18211885
    18221886    /*
     
    18451909    } while (RT_UNLIKELY(q != NULL));
    18461910
    1847     m_LwipNetIf.input(p, &m_LwipNetIf);
    1848     return VINF_SUCCESS;
    1849 }
    1850 
    1851 
    1852 /**
    1853  * Process an incoming GSO frame received from the intnet.
    1854  */
    1855 int VBoxNetLwipNAT::processGSO(PCPDMNETWORKGSO pGso, size_t cbFrame)
    1856 {
    1857     if (!PDMNetGsoIsValid(pGso, cbFrame, cbFrame - sizeof(PDMNETWORKGSO)))
    1858         return VERR_INVALID_PARAMETER;
    1859 
    1860     cbFrame -= sizeof(PDMNETWORKGSO);
    1861     uint8_t         abHdrScratch[256];
    1862     uint32_t const  cSegs = PDMNetGsoCalcSegmentCount(pGso,
    1863                                                       cbFrame);
    1864     for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
    1865     {
    1866         uint32_t cbSegFrame;
    1867         void    *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso,
    1868                                                       (uint8_t *)(pGso + 1),
    1869                                                       cbFrame,
    1870                                                       abHdrScratch,
    1871                                                       iSeg,
    1872                                                       cSegs,
    1873                                                       &cbSegFrame);
    1874 
    1875         int rc = processFrame(pvSegFrame, cbSegFrame);
    1876         if (RT_FAILURE(rc))
    1877         {
    1878             return rc;
    1879         }
    1880     }
    1881 
    1882     return VINF_SUCCESS;
     1911    /* pass input to lwIP: netif input funcion tcpip_input() */
     1912    self->m_LwipNetIf.input(p, &self->m_LwipNetIf);
    18831913}
    18841914
     
    18871917 * Send an outgoing frame from lwIP to intnet.
    18881918 */
    1889 /* static */
    1890 err_t VBoxNetLwipNAT::netifLinkoutput(netif *pNetif, pbuf *pPBuf) RT_NOTHROW_DEF
    1891 {
     1919/* static */ DECLCALLBACK(err_t)
     1920VBoxNetLwipNAT::netifLinkoutput(netif *pNetif, pbuf *pPBuf) RT_NOTHROW_DEF
     1921{
     1922    int rc;
     1923
    18921924    AssertPtrReturn(pNetif, ERR_ARG);
    18931925    AssertPtrReturn(pPBuf, ERR_ARG);
     
    19031935                 pPBuf));
    19041936
    1905     RT_ZERO(VBoxNetLwipNAT::aXmitSeg);
    1906 
    1907     size_t idx = 0;
    1908     for (struct pbuf *q = pPBuf; q != NULL; q = q->next, ++idx)
    1909     {
    1910         AssertReturn(idx < RT_ELEMENTS(VBoxNetLwipNAT::aXmitSeg), ERR_MEM);
    1911 
    1912 #if ETH_PAD_SIZE
    1913         if (q == pPBuf)
    1914         {
    1915             VBoxNetLwipNAT::aXmitSeg[idx].pv = (uint8_t *)q->payload + ETH_PAD_SIZE;
    1916             VBoxNetLwipNAT::aXmitSeg[idx].cb = q->len - ETH_PAD_SIZE;
    1917         }
    1918         else
    1919 #endif
    1920         {
    1921             VBoxNetLwipNAT::aXmitSeg[idx].pv = q->payload;
    1922             VBoxNetLwipNAT::aXmitSeg[idx].cb = q->len;
    1923         }
    1924     }
    1925 
    1926     int rc = self->sendBufferOnWire(VBoxNetLwipNAT::aXmitSeg, idx,
    1927                                     pPBuf->tot_len - ETH_PAD_SIZE);
    1928     AssertRCReturn(rc, ERR_IF);
    1929 
    1930     self->flushWire();
     1937    if (pPBuf->tot_len < sizeof(struct eth_hdr)) /* includes ETH_PAD_SIZE */
     1938        return ERR_ARG;
     1939
     1940    size_t cbFrame = (size_t)pPBuf->tot_len - ETH_PAD_SIZE;
     1941    IntNetIf::Frame frame;
     1942    rc = self->m_IntNetIf.getOutputFrame(frame, cbFrame);
     1943    if (RT_FAILURE(rc))
     1944        return ERR_MEM;
     1945
     1946    pbuf_copy_partial(pPBuf, frame.pvFrame, cbFrame, ETH_PAD_SIZE);
     1947    rc = self->m_IntNetIf.ifOutput(frame);
     1948    if (RT_FAILURE(rc))
     1949        return ERR_IF;
    19311950
    19321951    LogFlowFunc(("LEAVE: %d\n", ERR_OK));
     
    19431962
    19441963    AssertReturn(!virtualbox.isNull(), E_FAIL);
    1945     AssertReturn(!getNetworkName().empty(), E_FAIL);
     1964    AssertReturn(m_strNetworkName.isNotEmpty(), E_FAIL);
    19461965    AssertReturn(pcszKey != NULL, E_FAIL);
    19471966    AssertReturn(*pcszKey != '\0', E_FAIL);
    19481967
    1949     com::BstrFmt bstrKey("NAT/%s/%s", getNetworkName().c_str(), pcszKey);
     1968    com::BstrFmt bstrKey("NAT/%s/%s", m_strNetworkName.c_str(), pcszKey);
    19501969    com::Bstr bstrValue;
    19511970    hrc = virtualbox->GetExtraData(bstrKey.raw(), bstrValue.asOutParam());
     
    20872106    int rc;
    20882107
    2089     const std::string &strNetworkName = getNetworkName();
    2090     if (strNetworkName.empty())
     2108    if (m_strNetworkName.isEmpty())
    20912109        return VERR_MISSING;
    20922110
    20932111    char szNetwork[RTPATH_MAX];
    2094     rc = RTStrCopy(szNetwork, sizeof(szNetwork), strNetworkName.c_str());
     2112    rc = RTStrCopy(szNetwork, sizeof(szNetwork), m_strNetworkName.c_str());
    20952113    if (RT_FAILURE(rc))
    20962114        return rc;
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