VirtualBox

Changeset 20521 in vbox for trunk/src


Ignore:
Timestamp:
Jun 12, 2009 3:28:26 PM (16 years ago)
Author:
vboxsync
Message:

NetworkAttachment: Allow changing the attachment between NONE/NAT/HIF/host-only/.. dynamically #3573

Location:
trunk/src/VBox
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Makefile.kmk

    r20501 r20521  
    286286        Serial/DevSerial.cpp \
    287287        Parallel/DevParallel.cpp
     288
     289ifdef VBOX_DYNAMIC_NET_ATTACH
     290 DevicesR3_DEFS += VBOX_DYNAMIC_NET_ATTACH
     291endif
    288292
    289293ifdef VBOX_WITH_E1000
     
    466470        Parallel/DevParallel.cpp
    467471
     472ifdef VBOX_DYNAMIC_NET_ATTACH
     473 VBoxDDGC_DEFS += VBOX_DYNAMIC_NET_ATTACH
     474endif
     475
    468476ifdef VBOX_WITH_E1000
    469477 VBoxDDGC_DEFS         += VBOX_WITH_E1000
     
    548556        Serial/DevSerial.cpp \
    549557        Parallel/DevParallel.cpp
     558
     559ifdef VBOX_DYNAMIC_NET_ATTACH
     560 VBoxDDR0_DEFS += VBOX_DYNAMIC_NET_ATTACH
     561endif
    550562
    551563ifdef VBOX_WITH_E1000
  • trunk/src/VBox/Devices/Network/DevPCNet.cpp

    r20374 r20521  
    46514651
    46524652
     4653#ifdef VBOX_DYNAMIC_NET_ATTACH
     4654/**
     4655 * Detach notification.
     4656 *
     4657 * One network card at one port has been unplugged.
     4658 * The VM is suspended at this point.
     4659 *
     4660 * @param   pDevIns     The device instance.
     4661 * @param   iLUN        The logical unit which is being detached.
     4662 */
     4663static DECLCALLBACK(void) pcnetDetach(PPDMDEVINS pDevIns, unsigned iLUN)
     4664{
     4665    PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
     4666
     4667    Log(("%s:\n", __FUNCTION__));
     4668
     4669    int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
     4670    AssertReleaseRC(rc);
     4671
     4672    /* @todo: r=pritesh still need to check if i missed
     4673     * to clean something in this function
     4674     */
     4675
     4676    /*
     4677     * Zero some important members.
     4678     */
     4679    pThis->pDrvBase = NULL;
     4680    pThis->pDrv = NULL;
     4681
     4682    PDMCritSectLeave(&pThis->CritSect);
     4683}
     4684
     4685
     4686/**
     4687 * Attach the Network attachment.
     4688 *
     4689 * @returns VBox status code.
     4690 * @param   pDevIns     The device instance.
     4691 * @param   iLUN        The logical unit which is being detached.
     4692 */
     4693static DECLCALLBACK(int)  pcnetAttach(PPDMDEVINS pDevIns, unsigned iLUN)
     4694{
     4695    PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
     4696    int         rc    = VINF_SUCCESS;
     4697
     4698    Log(("%s:\n", __FUNCTION__));
     4699
     4700    rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
     4701    AssertReleaseRC(rc);
     4702
     4703    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Network Port");
     4704    if (RT_SUCCESS(rc))
     4705    {
     4706        if (rc == VINF_NAT_DNS)
     4707        {
     4708#ifdef RT_OS_LINUX
     4709            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
     4710                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
     4711#else
     4712            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
     4713                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
     4714#endif
     4715        }
     4716        pThis->pDrv = (PPDMINETWORKCONNECTOR)
     4717            pThis->pDrvBase->pfnQueryInterface(pThis->pDrvBase, PDMINTERFACE_NETWORK_CONNECTOR);
     4718        if (!pThis->pDrv)
     4719        {
     4720            AssertMsgFailed(("Failed to obtain the PDMINTERFACE_NETWORK_CONNECTOR interface!\n"));
     4721            return VERR_PDM_MISSING_INTERFACE_BELOW;
     4722        }
     4723    }
     4724    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     4725        Log(("No attached driver!\n"));
     4726    else
     4727        return rc;
     4728
     4729    /*
     4730     * Temporary set the link down if it was up so that the guest
     4731     * will know that we have change the configuration of the
     4732     * network card
     4733     */
     4734    if (pThis->fLinkUp)
     4735    {
     4736        pThis->fLinkTempDown = true;
     4737        pThis->cLinkDownReported = 0;
     4738        pThis->aCSR[0] |= RT_BIT(15) | RT_BIT(13); /* ERR | CERR (this is probably wrong) */
     4739        pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1;
     4740        TMTimerSetMillies(pThis->pTimerRestore, 20000);
     4741    }
     4742    PDMCritSectLeave(&pThis->CritSect);
     4743
     4744    return rc;
     4745
     4746}
     4747#endif /* VBOX_DYNAMIC_NET_ATTACH */
     4748
     4749
    46534750/**
    46544751 * @copydoc FNPDMDEVSUSPEND
     
    51635260    /* pfnResume */
    51645261    NULL,
     5262#ifdef VBOX_DYNAMIC_NET_ATTACH
     5263    /* pfnAttach */
     5264    pcnetAttach,
     5265    /* pfnDetach */
     5266    pcnetDetach,
     5267#else /* !VBOX_DYNAMIC_NET_ATTACH */
    51655268    /* pfnAttach */
    51665269    NULL,
    51675270    /* pfnDetach */
    51685271    NULL,
     5272#endif /* !VBOX_DYNAMIC_NET_ATTACH */
    51695273    /* pfnQueryInterface. */
    51705274    NULL,
  • trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk

    r20501 r20521  
    4747        $(if $(VBOX_WITH_HOSTNETIF_API), VBOX_WITH_HOSTNETIF_API)
    4848 VBoxManage_DEFS.win   = _WIN32_WINNT=0x0500
     49ifdef VBOX_DYNAMIC_NET_ATTACH
     50 VBoxManage_DEFS += VBOX_DYNAMIC_NET_ATTACH
     51endif
    4952ifdef VBOX_WITH_NETFLT
    5053 VBoxManage_DEFS += VBOX_WITH_NETFLT
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp

    r20313 r20521  
    751751            }
    752752        }
     753#ifdef VBOX_DYNAMIC_NET_ATTACH
     754        else if (!strncmp(a->argv[1], "nic", 3))
     755        {
     756            /* Get the number of network adapters */
     757            ULONG NetworkAdapterCount = 0;
     758            ComPtr <ISystemProperties> info;
     759            CHECK_ERROR_BREAK (a->virtualBox, COMGETTER(SystemProperties) (info.asOutParam()));
     760            CHECK_ERROR_BREAK (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount));
     761
     762            unsigned n = parseNum(&a->argv[1][3], NetworkAdapterCount, "NIC");
     763            if (!n)
     764            {
     765                rc = E_FAIL;
     766                break;
     767            }
     768            if (a->argc <= 1 + 1)
     769            {
     770                errorArgument("Missing argument to '%s'", a->argv[1]);
     771                rc = E_FAIL;
     772                break;
     773            }
     774
     775            /* get the corresponding network adapter */
     776            ComPtr<INetworkAdapter> adapter;
     777            CHECK_ERROR_BREAK (sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
     778            if (adapter)
     779            {
     780                if (!strcmp(a->argv[2], "none"))
     781                {
     782                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (FALSE), 1);
     783                }
     784                else if (!strcmp(a->argv[2], "null"))
     785                {
     786                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
     787                    CHECK_ERROR_RET(adapter, Detach(), 1);
     788                }
     789                else if (!strcmp(a->argv[2], "nat"))
     790                {
     791                    if (a->argc == 3)
     792                        CHECK_ERROR_RET(adapter, COMSETTER(NATNetwork)(Bstr(a->argv[3])), 1);
     793                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
     794                    CHECK_ERROR_RET(adapter, AttachToNAT(), 1);
     795                }
     796                else if (  !strcmp(a->argv[2], "bridged")
     797                        || !strcmp(a->argv[2], "hostif")) /* backward compatibility */
     798                {
     799                    if (a->argc <= 1 + 2)
     800                    {
     801                        errorArgument("Missing argument to '%s'", a->argv[2]);
     802                        rc = E_FAIL;
     803                        break;
     804                    }
     805                    CHECK_ERROR_RET(adapter, COMSETTER(HostInterface)(Bstr(a->argv[3])), 1);
     806                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
     807                    CHECK_ERROR_RET(adapter, AttachToBridgedInterface(), 1);
     808                }
     809                else if (!strcmp(a->argv[2], "intnet"))
     810                {
     811                    if (a->argc <= 1 + 2)
     812                    {
     813                        errorArgument("Missing argument to '%s'", a->argv[2]);
     814                        rc = E_FAIL;
     815                        break;
     816                    }
     817                    CHECK_ERROR_RET(adapter, COMSETTER(InternalNetwork)(Bstr(a->argv[3])), 1);
     818                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
     819                    CHECK_ERROR_RET(adapter, AttachToInternalNetwork(), 1);
     820                }
     821#if defined(VBOX_WITH_NETFLT)
     822                else if (!strcmp(a->argv[2], "hostonly"))
     823                {
     824                    if (a->argc <= 1 + 2)
     825                    {
     826                        errorArgument("Missing argument to '%s'", a->argv[2]);
     827                        rc = E_FAIL;
     828                        break;
     829                    }
     830                    CHECK_ERROR_RET(adapter, COMSETTER(HostInterface)(Bstr(a->argv[3])), 1);
     831                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
     832                    CHECK_ERROR_RET(adapter, AttachToHostOnlyInterface(), 1);
     833                }
     834#endif
     835                else
     836                {
     837                    errorArgument("Invalid type '%s' specfied for NIC %lu", Utf8Str(a->argv[2]).raw(), n + 1);
     838                    rc = E_FAIL;
     839                    break;
     840                }
     841            }
     842        }
     843#endif /* VBOX_DYNAMIC_NET_ATTACH */
    753844#ifdef VBOX_WITH_VRDP
    754845        else if (!strcmp(a->argv[1], "vrdp"))
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r20501 r20521  
    278278                 "                            injectnmi|\n"
    279279                 "                            setlinkstate<1-N> on|off |\n"
     280#ifdef VBOX_DYNAMIC_NET_ATTACH
     281#if defined(VBOX_WITH_NETFLT)
     282                 "                            nic<1-N> none|null|nat|bridged|intnet|hostonly\n"
     283                 "                                     [<devicename>] |\n"
     284#else /* !RT_OS_LINUX && !RT_OS_DARWIN */
     285                 "                            nic<1-N> none|null|nat|bridged|intnet\n"
     286                 "                                     [<devicename>] |\n"
     287#endif /* !RT_OS_LINUX && !RT_OS_DARWIN  */
     288#endif /* VBOX_DYNAMIC_NET_ATTACH */
    280289                 "                            usbattach <uuid>|<address> |\n"
    281290                 "                            usbdetach <uuid>|<address> |\n"
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r20384 r20521  
    3030#   include <sys/types.h>
    3131#   include <sys/wait.h>
     32#ifndef VBOX_DYNAMIC_NET_ATTACH
    3233#   include <net/if.h>
     34#endif /* !VBOX_DYNAMIC_NET_ATTACH */
    3335#   include <linux/if_tun.h>
    3436#   include <stdio.h>
     
    8991# include <VBox/com/array.h>
    9092#endif
     93
     94#ifdef VBOX_DYNAMIC_NET_ATTACH
     95#include <VBox/intnet.h>
     96
     97#if defined(RT_OS_LINUX) && defined(VBOX_WITH_NETFLT)
     98# include <unistd.h>
     99# include <sys/ioctl.h>
     100# include <sys/socket.h>
     101# include <linux/types.h>
     102# include <linux/if.h>
     103# include <linux/wireless.h>
     104#endif
     105
     106#if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
     107# include <VBox/WinNetConfig.h>
     108# include <Ntddndis.h>
     109# include <devguid.h>
     110#endif
     111
     112#if !defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
     113# include <HostNetworkInterfaceImpl.h>
     114# include <netif.h>
     115#endif
     116
     117#include "DHCPServerRunner.h"
     118#endif /* VBOX_DYNAMIC_NET_ATTACH */
    91119
    92120#include <set>
     
    249277    memset(&mapUSBLed, 0, sizeof(mapUSBLed));
    250278    memset(&mapSharedFolderLed, 0, sizeof(mapSharedFolderLed));
     279#ifdef VBOX_DYNAMIC_NET_ATTACH
     280    memset(&meAttachmentType, 0, sizeof(meAttachmentType));
     281#endif /* VBOX_DYNAMIC_NET_ATTACH */
    251282
    252283    return S_OK;
     
    31813212    CheckComRCReturnRC (autoVMCaller.rc());
    31823213
     3214#ifdef VBOX_DYNAMIC_NET_ATTACH
     3215    /* Get the current network attachment type */
     3216    HRESULT rc;
     3217    NetworkAttachmentType_T eAttachmentType;
     3218
     3219    rc = aNetworkAdapter->COMGETTER (AttachmentType) (&eAttachmentType);
     3220    ComAssertComRCRetRC (rc);
     3221#endif /* VBOX_DYNAMIC_NET_ATTACH */
     3222
    31833223    /* Get the properties we need from the adapter */
    31843224    BOOL fCableConnected;
     3225#ifdef VBOX_DYNAMIC_NET_ATTACH
     3226    rc = aNetworkAdapter->COMGETTER(CableConnected) (&fCableConnected);
     3227#else /* !VBOX_DYNAMIC_NET_ATTACH */
    31853228    HRESULT rc = aNetworkAdapter->COMGETTER(CableConnected) (&fCableConnected);
     3229#endif /* !VBOX_DYNAMIC_NET_ATTACH */
    31863230    AssertComRC(rc);
    31873231    if (SUCCEEDED(rc))
     
    32303274            }
    32313275
     3276#ifdef VBOX_DYNAMIC_NET_ATTACH
     3277            if (VBOX_SUCCESS (vrc) &&
     3278                !((eAttachmentType == meAttachmentType[ulInstance]) ||
     3279                  (eAttachmentType == NetworkAttachmentType_Null &&
     3280                   meAttachmentType[ulInstance] == NetworkAttachmentType_Null)))
     3281            {
     3282                rc = doNetworkAdapterChange(cszAdapterName,
     3283                                            ulInstance, 0,
     3284                                            eAttachmentType,
     3285                                            &meAttachmentType[ulInstance],
     3286                                            aNetworkAdapter);
     3287            }
     3288#endif /* VBOX_DYNAMIC_NET_ATTACH */
     3289
    32323290            if (VBOX_FAILURE (vrc))
    32333291                rc = E_FAIL;
     
    32463304    return rc;
    32473305}
     3306
     3307
     3308#ifdef VBOX_DYNAMIC_NET_ATTACH
     3309/**
     3310 * Process a network adaptor change.
     3311 *
     3312 * @returns COM status code.
     3313 *
     3314 * @param   pszDevice       The PDM device name.
     3315 * @param   uInstance       The PDM device instance.
     3316 * @param   uLun            The PDM LUN number of the drive.
     3317 * @param   aAttachmentType The attachment type.
     3318 *
     3319 * @note Locks this object for writing.
     3320 */
     3321HRESULT Console::doNetworkAdapterChange (const char *pszDevice, unsigned uInstance,
     3322                                         unsigned uLun, NetworkAttachmentType_T eAttachmentType,
     3323                                         NetworkAttachmentType_T *meAttachmentType,
     3324                                         INetworkAdapter *aNetworkAdapter)
     3325{
     3326    LogFlowThisFunc (("pszDevice=%p:{%s} uInstance=%u uLun=%u eAttachmentType=%d "
     3327                      "meAttachmentType=%p:{%d} aNetworkAdapter=%p\n",
     3328                      pszDevice, pszDevice, uInstance, uLun, eAttachmentType,
     3329                      meAttachmentType, *meAttachmentType, aNetworkAdapter));
     3330
     3331    AutoCaller autoCaller (this);
     3332    AssertComRCReturnRC (autoCaller.rc());
     3333
     3334    /* We will need to release the write lock before calling EMT */
     3335    AutoWriteLock alock (this);
     3336
     3337    /* protect mpVM */
     3338    AutoVMCaller autoVMCaller (this);
     3339    CheckComRCReturnRC (autoVMCaller.rc());
     3340
     3341    /*
     3342     * Call worker in EMT, that's faster and safer than doing everything
     3343     * using VM3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
     3344     * here to make requests from under the lock in order to serialize them.
     3345     */
     3346    PVMREQ pReq;
     3347    int vrc = VMR3ReqCall (mpVM, VMCPUID_ANY, &pReq, 0 /* no wait! */,
     3348                           (PFNRT) Console::changeNetworkAttachment, 7,
     3349                           this, pszDevice, uInstance, uLun, eAttachmentType,
     3350                           meAttachmentType, aNetworkAdapter);
     3351    /// @todo (r=dmik) bird, it would be nice to have a special VMR3Req method
     3352    //  for that purpose, that doesn't return useless VERR_TIMEOUT
     3353    if (vrc == VERR_TIMEOUT)
     3354        vrc = VINF_SUCCESS;
     3355
     3356    /* leave the lock before waiting for a result (EMT will call us back!) */
     3357    alock.leave();
     3358
     3359    if (VBOX_SUCCESS (vrc))
     3360    {
     3361        vrc = VMR3ReqWait (pReq, RT_INDEFINITE_WAIT);
     3362        AssertRC (vrc);
     3363        if (VBOX_SUCCESS (vrc))
     3364            vrc = pReq->iStatus;
     3365    }
     3366    VMR3ReqFree (pReq);
     3367
     3368    if (VBOX_SUCCESS (vrc))
     3369    {
     3370        LogFlowThisFunc (("Returns S_OK\n"));
     3371        return S_OK;
     3372    }
     3373
     3374    return setError (E_FAIL,
     3375        tr ("Could not change the network adaptor attachement type (%Rrc)"), vrc);
     3376}
     3377
     3378
     3379/**
     3380 * Performs the Network Adaptor change in EMT.
     3381 *
     3382 * @returns VBox status code.
     3383 *
     3384 * @param   pThis           Pointer to the Console object.
     3385 * @param   pszDevice       The PDM device name.
     3386 * @param   uInstance       The PDM device instance.
     3387 * @param   uLun            The PDM LUN number of the drive.
     3388 * @param   aAttachmentType The attachment type.
     3389 *
     3390 * @thread  EMT
     3391 * @note Locks the Console object for writing.
     3392 */
     3393DECLCALLBACK(int) Console::changeNetworkAttachment (Console *pThis, const char *pszDevice,
     3394                                                    unsigned uInstance, unsigned uLun,
     3395                                                    NetworkAttachmentType_T eAttachmentType,
     3396                                                    NetworkAttachmentType_T *meAttachmentType,
     3397                                                    INetworkAdapter *aNetworkAdapter)
     3398{
     3399    LogFlowFunc (("pThis=%p pszDevice=%p:{%s} uInstance=%u uLun=%u eAttachmentType=%d "
     3400                  "meAttachmentType=%p{%d} aNetworkAdapter=%p\n",
     3401                  pThis, pszDevice, pszDevice, uInstance, uLun, eAttachmentType,
     3402                  meAttachmentType, *meAttachmentType, aNetworkAdapter));
     3403
     3404    AssertReturn (pThis, VERR_INVALID_PARAMETER);
     3405
     3406    AssertMsg (   (!strcmp (pszDevice, "pcnet") && uLun == 0 && uInstance < 8)
     3407               || (!strcmp (pszDevice, "e1000") && uLun == 0 && uInstance < 8),
     3408               ("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
     3409    Log(("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
     3410
     3411    AutoCaller autoCaller (pThis);
     3412    AssertComRCReturn (autoCaller.rc(), VERR_ACCESS_DENIED);
     3413
     3414    /*
     3415     * Locking the object before doing VMR3* calls is quite safe here, since
     3416     * we're on EMT. Write lock is necessary because we indirectly modify the
     3417     * meAttachmentType member.
     3418     */
     3419    AutoWriteLock alock (pThis);
     3420
     3421    /* protect mpVM */
     3422    AutoVMCaller autoVMCaller (pThis);
     3423    CheckComRCReturnRC (autoVMCaller.rc());
     3424
     3425    PVM pVM = pThis->mpVM;
     3426
     3427    /*
     3428     * Suspend the VM first.
     3429     *
     3430     * The VM must not be running since it might have pending I/O to
     3431     * the drive which is being changed.
     3432     */
     3433    bool fResume;
     3434    VMSTATE enmVMState = VMR3GetState (pVM);
     3435    switch (enmVMState)
     3436    {
     3437        case VMSTATE_RESETTING:
     3438        case VMSTATE_RUNNING:
     3439        {
     3440            LogFlowFunc (("Suspending the VM...\n"));
     3441            /* disable the callback to prevent Console-level state change */
     3442            pThis->mVMStateChangeCallbackDisabled = true;
     3443            int rc = VMR3Suspend (pVM);
     3444            pThis->mVMStateChangeCallbackDisabled = false;
     3445            AssertRCReturn (rc, rc);
     3446            fResume = true;
     3447            break;
     3448        }
     3449
     3450        case VMSTATE_SUSPENDED:
     3451        case VMSTATE_CREATED:
     3452        case VMSTATE_OFF:
     3453            fResume = false;
     3454            break;
     3455
     3456        default:
     3457            AssertMsgFailedReturn (("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED);
     3458    }
     3459
     3460    int rc = VINF_SUCCESS;
     3461    int rcRet = VINF_SUCCESS;
     3462
     3463#define STR_CONV()  do { rc = RTUtf16ToUtf8(str, &psz); RC_CHECK(); } while (0)
     3464#define STR_FREE()  do { if (str) { SysFreeString(str); str = NULL; } if (psz) { RTStrFree(psz); psz = NULL; } } while (0)
     3465#define RC_CHECK()  do { if (RT_FAILURE(rc)) { AssertMsgFailed(("rc=%Rrc\n", rc)); rcRet = rc; goto rcfailed; } } while (0)
     3466#define H()         do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%#x\n", hrc)); rcRet = VERR_GENERAL_FAILURE; goto rcfailed; } } while (0)
     3467    do
     3468    {
     3469        HRESULT hrc;
     3470        ComPtr <IMachine> pMachine = pThis->machine();
     3471
     3472        ComPtr<IVirtualBox> virtualBox;
     3473        hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam());
     3474        H();
     3475
     3476        ComPtr<IHost> host;
     3477        hrc = virtualBox->COMGETTER(Host)(host.asOutParam());
     3478        H();
     3479
     3480        BSTR      str = NULL;
     3481        char     *psz = NULL;
     3482
     3483        /*
     3484         * Detach the device train for the current network attachment.
     3485         */
     3486        rc = PDMR3DeviceDetach (pVM, pszDevice, uInstance, uLun);
     3487        if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN)
     3488            rc = VINF_SUCCESS;
     3489        AssertRC (rc);
     3490
     3491        PCFGMNODE pCfg = NULL;          /* /Devices/Dev/.../Config/ */
     3492        PCFGMNODE pLunL0 = NULL;        /* /Devices/Dev/0/LUN#0/ */
     3493        PCFGMNODE pInst = CFGMR3GetChildF (CFGMR3GetRoot (pVM), "Devices/%s/%d/", pszDevice, uInstance);
     3494        AssertRelease (pInst);
     3495
     3496        /* nuke anything which might have been left behind. */
     3497        CFGMR3RemoveNode (CFGMR3GetChildF (pInst, "LUN#%d", uLun));
     3498
     3499        /*
     3500         * Enable the packet sniffer if requested.
     3501         */
     3502        BOOL fSniffer;
     3503        hrc = aNetworkAdapter->COMGETTER(TraceEnabled)(&fSniffer);
     3504        H();
     3505        if (fSniffer)
     3506        {
     3507            /* insert the sniffer filter driver. */
     3508            rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
     3509            RC_CHECK();
     3510            rc = CFGMR3InsertString(pLunL0, "Driver", "NetSniffer");
     3511            RC_CHECK();
     3512            rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
     3513            RC_CHECK();
     3514            hrc = aNetworkAdapter->COMGETTER(TraceFile)(&str);
     3515            H();
     3516            if (str) /* check convention for indicating default file. */
     3517            {
     3518                STR_CONV();
     3519                rc = CFGMR3InsertString(pCfg, "File", psz);
     3520                RC_CHECK();
     3521                STR_FREE();
     3522            }
     3523        }
     3524
     3525        Bstr networkName, trunkName, trunkType;
     3526        switch (eAttachmentType)
     3527        {
     3528            case NetworkAttachmentType_Null:
     3529                break;
     3530
     3531            case NetworkAttachmentType_NAT:
     3532            {
     3533                if (fSniffer)
     3534                {
     3535                    rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
     3536                    RC_CHECK();
     3537                }
     3538                else
     3539                {
     3540                    rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
     3541                    RC_CHECK();
     3542                }
     3543
     3544                rc = CFGMR3InsertString(pLunL0, "Driver", "NAT");
     3545                RC_CHECK();
     3546
     3547                rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
     3548                RC_CHECK();
     3549
     3550                /* Configure TFTP prefix and boot filename. */
     3551                hrc = virtualBox->COMGETTER(HomeFolder)(&str);
     3552                H();
     3553                STR_CONV();
     3554                if (psz && *psz)
     3555                {
     3556                    char *pszTFTPPrefix = NULL;
     3557                    RTStrAPrintf(&pszTFTPPrefix, "%s%c%s", psz, RTPATH_DELIMITER, "TFTP");
     3558                    rc = CFGMR3InsertString(pCfg, "TFTPPrefix", pszTFTPPrefix);
     3559                    RC_CHECK();
     3560                    RTStrFree(pszTFTPPrefix);
     3561                }
     3562                STR_FREE();
     3563                hrc = pMachine->COMGETTER(Name)(&str);
     3564                H();
     3565                STR_CONV();
     3566                char *pszBootFile = NULL;
     3567                RTStrAPrintf(&pszBootFile, "%s.pxe", psz);
     3568                STR_FREE();
     3569                rc = CFGMR3InsertString(pCfg, "BootFile", pszBootFile);
     3570                RC_CHECK();
     3571                RTStrFree(pszBootFile);
     3572
     3573                hrc = aNetworkAdapter->COMGETTER(NATNetwork)(&str);
     3574                H();
     3575                if (str)
     3576                {
     3577                    STR_CONV();
     3578                    if (psz && *psz)
     3579                    {
     3580                        rc = CFGMR3InsertString(pCfg, "Network", psz);
     3581                        RC_CHECK();
     3582                        /* NAT uses its own DHCP implementation */
     3583                        //networkName = Bstr(psz);
     3584                    }
     3585
     3586                    STR_FREE();
     3587                }
     3588                break;
     3589            }
     3590
     3591            case NetworkAttachmentType_Bridged:
     3592            {
     3593#if !defined(VBOX_WITH_NETFLT) && defined(RT_OS_LINUX)
     3594                Assert ((int)pConsole->maTapFD[ulInstance] >= 0);
     3595                if ((int)pConsole->maTapFD[ulInstance] >= 0)
     3596                {
     3597                    if (fSniffer)
     3598                    {
     3599                        rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
     3600                        RC_CHECK();
     3601                    }
     3602                    else
     3603                    {
     3604                        rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
     3605                        RC_CHECK();
     3606                    }
     3607                    rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface");
     3608                    RC_CHECK();
     3609                    rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
     3610                    RC_CHECK();
     3611                    rc = CFGMR3InsertInteger(pCfg, "FileHandle", pConsole->maTapFD[ulInstance]);
     3612                    RC_CHECK();
     3613                }
     3614#elif defined(VBOX_WITH_NETFLT)
     3615                /*
     3616                 * This is the new VBoxNetFlt+IntNet stuff.
     3617                 */
     3618                if (fSniffer)
     3619                {
     3620                    rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
     3621                    RC_CHECK();
     3622                }
     3623                else
     3624                {
     3625                    rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
     3626                    RC_CHECK();
     3627                }
     3628
     3629                Bstr HifName;
     3630                hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
     3631                if(FAILED(hrc))
     3632                {
     3633                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
     3634                    H();
     3635                }
     3636
     3637                Utf8Str HifNameUtf8(HifName);
     3638                const char *pszHifName = HifNameUtf8.raw();
     3639
     3640# if defined(RT_OS_DARWIN)
     3641                /* The name is on the form 'ifX: long name', chop it off at the colon. */
     3642                char szTrunk[8];
     3643                strncpy(szTrunk, pszHifName, sizeof(szTrunk));
     3644                char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
     3645                if (!pszColon)
     3646                {
     3647                    hrc = networkAdapter->Detach();
     3648                    H();
     3649                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     3650                                      N_("Malformed host interface networking name '%ls'"),
     3651                                      HifName.raw());
     3652                }
     3653                *pszColon = '\0';
     3654                const char *pszTrunk = szTrunk;
     3655
     3656# elif defined(RT_OS_SOLARIS)
     3657                /* The name is on the form format 'ifX[:1] - long name, chop it off at space. */
     3658                char szTrunk[256];
     3659                strlcpy(szTrunk, pszHifName, sizeof(szTrunk));
     3660                char *pszSpace = (char *)memchr(szTrunk, ' ', sizeof(szTrunk));
     3661
     3662                /*
     3663                 * Currently don't bother about malformed names here for the sake of people using
     3664                 * VBoxManage and setting only the NIC name from there. If there is a space we
     3665                 * chop it off and proceed, otherwise just use whatever we've got.
     3666                 */
     3667                if (pszSpace)
     3668                    *pszSpace = '\0';
     3669
     3670                /* Chop it off at the colon (zone naming eg: e1000g:1 we need only the e1000g) */
     3671                char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
     3672                if (pszColon)
     3673                    *pszColon = '\0';
     3674
     3675                const char *pszTrunk = szTrunk;
     3676
     3677# elif defined(RT_OS_WINDOWS)
     3678                ComPtr<IHostNetworkInterface> hostInterface;
     3679                rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
     3680                if (!SUCCEEDED(rc))
     3681                {
     3682                    AssertBreakpoint();
     3683                    LogRel(("NetworkAttachmentType_Bridged: FindByName failed, rc (0x%x)", rc));
     3684                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     3685                                      N_("Inexistent host networking interface, name '%ls'"),
     3686                                      HifName.raw());
     3687                }
     3688
     3689                HostNetworkInterfaceType_T ifType;
     3690                hrc = hostInterface->COMGETTER(InterfaceType)(&ifType);
     3691                if(FAILED(hrc))
     3692                {
     3693                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc));
     3694                    H();
     3695                }
     3696
     3697                if(ifType != HostNetworkInterfaceType_Bridged)
     3698                {
     3699                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     3700                                                          N_("Interface ('%ls') is not a Bridged Adapter interface"),
     3701                                                          HifName.raw());
     3702                }
     3703
     3704                Bstr hostIFGuid_;
     3705                hrc = hostInterface->COMGETTER(Id)(hostIFGuid_.asOutParam());
     3706                if(FAILED(hrc))
     3707                {
     3708                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(Id) failed, hrc (0x%x)", hrc));
     3709                    H();
     3710                }
     3711                Guid hostIFGuid(hostIFGuid_);
     3712
     3713                INetCfg              *pNc;
     3714                ComPtr<INetCfgComponent> pAdaptorComponent;
     3715                LPWSTR               lpszApp;
     3716                int rc = VERR_INTNET_FLT_IF_NOT_FOUND;
     3717
     3718                hrc = VBoxNetCfgWinQueryINetCfg( FALSE,
     3719                                   L"VirtualBox",
     3720                                   &pNc,
     3721                                   &lpszApp );
     3722                Assert(hrc == S_OK);
     3723                if(hrc == S_OK)
     3724                {
     3725                    /* get the adapter's INetCfgComponent*/
     3726                    hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam());
     3727                    if(hrc != S_OK)
     3728                    {
     3729                        VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
     3730                        LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
     3731                        H();
     3732                    }
     3733                }
     3734#define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
     3735                char szTrunkName[INTNET_MAX_TRUNK_NAME];
     3736                char *pszTrunkName = szTrunkName;
     3737                wchar_t * pswzBindName;
     3738                hrc = pAdaptorComponent->GetBindName(&pswzBindName);
     3739                Assert(hrc == S_OK);
     3740                if (hrc == S_OK)
     3741                {
     3742                    int cwBindName = (int)wcslen(pswzBindName) + 1;
     3743                    int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX);
     3744                    if(sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName)
     3745                    {
     3746                        strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX);
     3747                        pszTrunkName += cbFullBindNamePrefix-1;
     3748                        if(!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName,
     3749                                sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL))
     3750                        {
     3751                            Assert(0);
     3752                            DWORD err = GetLastError();
     3753                            hrc = HRESULT_FROM_WIN32(err);
     3754                            AssertMsgFailed(("%hrc=%Rhrc %#x\n", hrc, hrc));
     3755                            LogRel(("NetworkAttachmentType_Bridged: WideCharToMultiByte failed, hr=%Rhrc (0x%x)\n", hrc, hrc));
     3756                        }
     3757                    }
     3758                    else
     3759                    {
     3760                        Assert(0);
     3761                        LogRel(("NetworkAttachmentType_Bridged: insufficient szTrunkName buffer space\n"));
     3762                        /** @todo set appropriate error code */
     3763                        hrc = E_FAIL;
     3764                    }
     3765
     3766                    if(hrc != S_OK)
     3767                    {
     3768                        Assert(0);
     3769                        CoTaskMemFree(pswzBindName);
     3770                        VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
     3771                        H();
     3772                    }
     3773
     3774                    /* we're not freeing the bind name since we'll use it later for detecting wireless*/
     3775                }
     3776                else
     3777                {
     3778                    Assert(0);
     3779                    VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
     3780                    LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
     3781                    H();
     3782                }
     3783                const char *pszTrunk = szTrunkName;
     3784                /* we're not releasing the INetCfg stuff here since we use it later to figure out whether it is wireless */
     3785
     3786# elif defined(RT_OS_LINUX)
     3787                /* @todo Check for malformed names. */
     3788                const char *pszTrunk = pszHifName;
     3789
     3790# else
     3791#  error "PORTME (VBOX_WITH_NETFLT)"
     3792# endif
     3793
     3794                rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");
     3795                RC_CHECK();
     3796                rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
     3797                RC_CHECK();
     3798                rc = CFGMR3InsertString(pCfg, "Trunk", pszTrunk);
     3799                RC_CHECK();
     3800                rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);
     3801                RC_CHECK();
     3802                char szNetwork[80];
     3803                RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
     3804                rc = CFGMR3InsertString(pCfg, "Network", szNetwork);
     3805                RC_CHECK();
     3806                networkName = Bstr(szNetwork);
     3807                trunkName = Bstr(pszTrunk);
     3808                trunkType = Bstr(TRUNKTYPE_NETFLT);
     3809
     3810# if defined(RT_OS_DARWIN)
     3811                /** @todo Come up with a better deal here. Problem is that IHostNetworkInterface is completely useless here. */
     3812                if (    strstr(pszHifName, "Wireless")
     3813                    ||  strstr(pszHifName, "AirPort" ))
     3814                {
     3815                    rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);
     3816                    RC_CHECK();
     3817                }
     3818# elif defined(RT_OS_LINUX)
     3819                int iSock = socket(AF_INET, SOCK_DGRAM, 0);
     3820                if (iSock >= 0)
     3821                {
     3822                    struct iwreq WRq;
     3823
     3824                    memset(&WRq, 0, sizeof(WRq));
     3825                    strncpy(WRq.ifr_name, pszHifName, IFNAMSIZ);
     3826                    if (ioctl(iSock, SIOCGIWNAME, &WRq) >= 0)
     3827                    {
     3828                        rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);
     3829                        RC_CHECK();
     3830                        Log(("Set SharedMacOnWire\n"));
     3831                    }
     3832                    else
     3833                    {
     3834                        Log(("Failed to get wireless name\n"));
     3835                    }
     3836                    close(iSock);
     3837                }
     3838                else
     3839                {
     3840                    Log(("Failed to open wireless socket\n"));
     3841                }
     3842# elif defined(RT_OS_WINDOWS)
     3843#  define DEVNAME_PREFIX L"\\\\.\\"
     3844                /* we are getting the medium type via IOCTL_NDIS_QUERY_GLOBAL_STATS Io Control
     3845                 * there is a pretty long way till there though since we need to obtain the symbolic link name
     3846                 * for the adapter device we are going to query given the device Guid */
     3847
     3848
     3849                /* prepend the "\\\\.\\" to the bind name to obtain the link name */
     3850
     3851                wchar_t FileName[MAX_PATH];
     3852                wcscpy(FileName, DEVNAME_PREFIX);
     3853                wcscpy((wchar_t*)(((char*)FileName) + sizeof(DEVNAME_PREFIX) - sizeof(FileName[0])), pswzBindName);
     3854
     3855                /* open the device */
     3856                HANDLE hDevice = CreateFile(FileName,
     3857                                            GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
     3858                                            NULL,
     3859                                            OPEN_EXISTING,
     3860                                            FILE_ATTRIBUTE_NORMAL,
     3861                                            NULL);
     3862
     3863                if (hDevice != INVALID_HANDLE_VALUE)
     3864                {
     3865                    /* now issue the OID_GEN_PHYSICAL_MEDIUM query */
     3866                    DWORD Oid = OID_GEN_PHYSICAL_MEDIUM;
     3867                    NDIS_PHYSICAL_MEDIUM PhMedium;
     3868                    DWORD cbResult;
     3869                    if (DeviceIoControl(hDevice,
     3870                                        IOCTL_NDIS_QUERY_GLOBAL_STATS,
     3871                                        &Oid,
     3872                                        sizeof(Oid),
     3873                                        &PhMedium,
     3874                                        sizeof(PhMedium),
     3875                                        &cbResult,
     3876                                        NULL))
     3877                    {
     3878                        /* that was simple, now examine PhMedium */
     3879                        if (   PhMedium == NdisPhysicalMediumWirelessWan
     3880                            || PhMedium == NdisPhysicalMediumWirelessLan
     3881                            || PhMedium == NdisPhysicalMediumNative802_11
     3882                            || PhMedium == NdisPhysicalMediumBluetooth)
     3883                        {
     3884                            Log(("this is a wireless adapter"));
     3885                            rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);
     3886                            RC_CHECK();
     3887                            Log(("Set SharedMacOnWire\n"));
     3888                        }
     3889                        else
     3890                        {
     3891                            Log(("this is NOT a wireless adapter"));
     3892                        }
     3893                    }
     3894                    else
     3895                    {
     3896                        int winEr = GetLastError();
     3897                        LogRel(("Console::configConstructor: DeviceIoControl failed, err (0x%x), ignoring\n", winEr));
     3898                        Assert(winEr == ERROR_INVALID_PARAMETER || winEr == ERROR_NOT_SUPPORTED || winEr == ERROR_BAD_COMMAND);
     3899                    }
     3900
     3901                    CloseHandle(hDevice);
     3902                }
     3903                else
     3904                {
     3905                    int winEr = GetLastError();
     3906                    LogRel(("Console::configConstructor: CreateFile failed, err (0x%x), ignoring\n", winEr));
     3907                    AssertBreakpoint();
     3908                }
     3909
     3910                CoTaskMemFree(pswzBindName);
     3911
     3912                pAdaptorComponent.setNull();
     3913                /* release the pNc finally */
     3914                VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
     3915# else
     3916                /** @todo PORTME: wireless detection */
     3917# endif
     3918
     3919# if defined(RT_OS_SOLARIS)
     3920#  if 0 /* bird: this is a bit questionable and might cause more trouble than its worth.  */
     3921                /* Zone access restriction, don't allow snopping the global zone. */
     3922                zoneid_t ZoneId = getzoneid();
     3923                if (ZoneId != GLOBAL_ZONEID)
     3924                {
     3925                    rc = CFGMR3InsertInteger(pCfg, "IgnoreAllPromisc", true);   RC_CHECK();
     3926                }
     3927#  endif
     3928# endif
     3929
     3930#elif defined(RT_OS_WINDOWS) /* not defined NetFlt */
     3931                /* NOTHING TO DO HERE */
     3932#elif defined(RT_OS_LINUX)
     3933/// @todo aleksey: is there anything to be done here?
     3934#elif defined(RT_OS_FREEBSD)
     3935/** @todo FreeBSD: Check out this later (HIF networking). */
     3936#else
     3937# error "Port me"
     3938#endif
     3939                break;
     3940            }
     3941
     3942            case NetworkAttachmentType_Internal:
     3943            {
     3944                hrc = aNetworkAdapter->COMGETTER(InternalNetwork)(&str);
     3945                H();
     3946                if (str)
     3947                {
     3948                    STR_CONV();
     3949                    if (psz && *psz)
     3950                    {
     3951                        if (fSniffer)
     3952                        {
     3953                            rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
     3954                            RC_CHECK();
     3955                        }
     3956                        else
     3957                        {
     3958                            rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
     3959                            RC_CHECK();
     3960                        }
     3961                        rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");
     3962                        RC_CHECK();
     3963                        rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
     3964                        RC_CHECK();
     3965                        rc = CFGMR3InsertString(pCfg, "Network", psz);
     3966                        RC_CHECK();
     3967                        rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_WhateverNone);
     3968                        RC_CHECK();
     3969                        networkName = Bstr(psz);
     3970                        trunkType = Bstr(TRUNKTYPE_WHATEVER);
     3971                    }
     3972                    STR_FREE();
     3973                }
     3974                break;
     3975            }
     3976
     3977            case NetworkAttachmentType_HostOnly:
     3978            {
     3979                if (fSniffer)
     3980                {
     3981                    rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
     3982                    RC_CHECK();
     3983                }
     3984                else
     3985                {
     3986                    rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
     3987                    RC_CHECK();
     3988                }
     3989
     3990                rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");
     3991                RC_CHECK();
     3992                rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
     3993                RC_CHECK();
     3994#if defined(RT_OS_WINDOWS)
     3995# ifndef VBOX_WITH_NETFLT
     3996                hrc = E_NOTIMPL;
     3997                LogRel(("NetworkAttachmentType_HostOnly: Not Implemented"));
     3998                H();
     3999# else
     4000                Bstr HifName;
     4001                hrc = networkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
     4002                if(FAILED(hrc))
     4003                {
     4004                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
     4005                    H();
     4006                }
     4007
     4008                Utf8Str HifNameUtf8(HifName);
     4009                const char *pszHifName = HifNameUtf8.raw();
     4010                ComPtr<IHostNetworkInterface> hostInterface;
     4011                rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
     4012                if (!SUCCEEDED(rc))
     4013                {
     4014                    AssertBreakpoint();
     4015                    LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)", rc));
     4016                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     4017                                      N_("Inexistent host networking interface, name '%ls'"),
     4018                                      HifName.raw());
     4019                }
     4020
     4021                HostNetworkInterfaceType_T ifType;
     4022                hrc = hostInterface->COMGETTER(InterfaceType)(&ifType);
     4023                if(FAILED(hrc))
     4024                {
     4025                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc));
     4026                    H();
     4027                }
     4028
     4029                if(ifType != HostNetworkInterfaceType_HostOnly)
     4030                {
     4031                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     4032                                      N_("Interface ('%ls') is not a Host-Only Adapter interface"),
     4033                                      HifName.raw());
     4034                }
     4035
     4036
     4037                Bstr hostIFGuid_;
     4038                hrc = hostInterface->COMGETTER(Id)(hostIFGuid_.asOutParam());
     4039                if(FAILED(hrc))
     4040                {
     4041                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(Id) failed, hrc (0x%x)", hrc));
     4042                    H();
     4043                }
     4044                Guid hostIFGuid(hostIFGuid_);
     4045
     4046                INetCfg *pNc;
     4047                ComPtr<INetCfgComponent> pAdaptorComponent;
     4048                LPWSTR lpszApp;
     4049                int rc = VERR_INTNET_FLT_IF_NOT_FOUND;
     4050
     4051                hrc = VBoxNetCfgWinQueryINetCfg(FALSE,
     4052                                                L"VirtualBox",
     4053                                                &pNc,
     4054                                                &lpszApp);
     4055                Assert(hrc == S_OK);
     4056                if(hrc == S_OK)
     4057                {
     4058                    /* get the adapter's INetCfgComponent*/
     4059                    hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam());
     4060                    if(hrc != S_OK)
     4061                    {
     4062                        VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
     4063                        LogRel(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
     4064                        H();
     4065                    }
     4066                }
     4067#define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
     4068                char szTrunkName[INTNET_MAX_TRUNK_NAME];
     4069                char *pszTrunkName = szTrunkName;
     4070                wchar_t * pswzBindName;
     4071                hrc = pAdaptorComponent->GetBindName(&pswzBindName);
     4072                Assert(hrc == S_OK);
     4073                if (hrc == S_OK)
     4074                {
     4075                    int cwBindName = (int)wcslen(pswzBindName) + 1;
     4076                    int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX);
     4077                    if(sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName)
     4078                    {
     4079                        strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX);
     4080                        pszTrunkName += cbFullBindNamePrefix-1;
     4081                        if(!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName,
     4082                                sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL))
     4083                        {
     4084                            Assert(0);
     4085                            DWORD err = GetLastError();
     4086                            hrc = HRESULT_FROM_WIN32(err);
     4087                            AssertMsgFailed(("%hrc=%Rhrc %#x\n", hrc, hrc));
     4088                            LogRel(("NetworkAttachmentType_HostOnly: WideCharToMultiByte failed, hr=%Rhrc (0x%x)\n", hrc, hrc));
     4089                        }
     4090                    }
     4091                    else
     4092                    {
     4093                        Assert(0);
     4094                        LogRel(("NetworkAttachmentType_HostOnly: insufficient szTrunkName buffer space\n"));
     4095                        /** @todo set appropriate error code */
     4096                        hrc = E_FAIL;
     4097                    }
     4098
     4099                    if(hrc != S_OK)
     4100                    {
     4101                        Assert(0);
     4102                        CoTaskMemFree(pswzBindName);
     4103                        VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
     4104                        H();
     4105                    }
     4106                }
     4107                else
     4108                {
     4109                    Assert(0);
     4110                    VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
     4111                    LogRel(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
     4112                    H();
     4113                }
     4114
     4115
     4116                CoTaskMemFree(pswzBindName);
     4117
     4118                pAdaptorComponent.setNull();
     4119                /* release the pNc finally */
     4120                VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
     4121
     4122                const char *pszTrunk = szTrunkName;
     4123
     4124
     4125                /* TODO: set the proper Trunk and Network values, currently the driver uses the first adapter instance */
     4126                rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);
     4127                RC_CHECK();
     4128                rc = CFGMR3InsertString(pCfg, "Trunk", pszTrunk);
     4129                RC_CHECK();
     4130                char szNetwork[80];
     4131                RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
     4132                rc = CFGMR3InsertString(pCfg, "Network", szNetwork);
     4133                RC_CHECK();
     4134                networkName = Bstr(szNetwork);
     4135                trunkName   = Bstr(pszTrunk);
     4136                trunkType   = TRUNKTYPE_NETADP;
     4137# endif /* defined VBOX_WITH_NETFLT*/
     4138#elif defined(RT_OS_DARWIN)
     4139                rc = CFGMR3InsertString(pCfg, "Trunk", "vboxnet0");
     4140                RC_CHECK();
     4141                rc = CFGMR3InsertString(pCfg, "Network", "HostInterfaceNetworking-vboxnet0");
     4142                RC_CHECK();
     4143                rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);
     4144                RC_CHECK();
     4145                networkName = Bstr("HostInterfaceNetworking-vboxnet0");
     4146                trunkName   = Bstr("vboxnet0");
     4147                trunkType   = TRUNKTYPE_NETADP;
     4148#else
     4149                rc = CFGMR3InsertString(pCfg, "Trunk", "vboxnet0");
     4150                RC_CHECK();
     4151                rc = CFGMR3InsertString(pCfg, "Network", "HostInterfaceNetworking-vboxnet0");
     4152                RC_CHECK();
     4153                rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);
     4154                RC_CHECK();
     4155                networkName = Bstr("HostInterfaceNetworking-vboxnet0");
     4156                trunkName   = Bstr("vboxnet0");
     4157                trunkType   = TRUNKTYPE_NETFLT;
     4158#endif
     4159#if !defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
     4160                Bstr HifName;
     4161                hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
     4162                if(FAILED(hrc))
     4163                {
     4164                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
     4165                    H();
     4166                }
     4167
     4168                LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface):  ", hrc));
     4169                Utf8Str HifNameUtf8(HifName);
     4170                const char *pszHifName = HifNameUtf8.raw();
     4171                ComPtr<IHostNetworkInterface> hostInterface;
     4172                rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
     4173                if (!SUCCEEDED(rc))
     4174                {
     4175                    LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)", rc));
     4176                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     4177                                      N_("Inexistent host networking interface, name '%ls'"),
     4178                                      HifName.raw());
     4179                }
     4180                Bstr tmpAddr, tmpMask;
     4181                hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPAddress"), tmpAddr.asOutParam());
     4182                if (SUCCEEDED(hrc) && !tmpAddr.isNull())
     4183                {
     4184                    hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPNetMask"), tmpMask.asOutParam());
     4185                    if (SUCCEEDED(hrc) && !tmpAddr.isEmpty())
     4186                        hrc = hostInterface->EnableStaticIpConfig(tmpAddr, tmpMask);
     4187                }
     4188                else
     4189                    hrc = hostInterface->EnableStaticIpConfig(Bstr(VBOXNET_IPV4ADDR_DEFAULT),
     4190                                                              Bstr(VBOXNET_IPV4MASK_DEFAULT));
     4191
     4192
     4193                hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPV6Address"), tmpAddr.asOutParam());
     4194                if (SUCCEEDED(hrc))
     4195                    hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPV6NetMask"), tmpMask.asOutParam());
     4196                if (SUCCEEDED(hrc) && !tmpAddr.isEmpty())
     4197                    hrc = hostInterface->EnableStaticIpConfigV6(tmpAddr, Utf8Str(tmpMask).toUInt32());
     4198#endif
     4199                break;
     4200            }
     4201
     4202            default:
     4203                AssertMsgFailed(("should not get here!\n"));
     4204                break;
     4205        }
     4206
     4207        /*
     4208         * Attempt to attach the driver.
     4209         */
     4210        switch (eAttachmentType)
     4211        {
     4212            case NetworkAttachmentType_Null:
     4213                break;
     4214
     4215            case NetworkAttachmentType_Bridged:
     4216            case NetworkAttachmentType_Internal:
     4217            case NetworkAttachmentType_HostOnly:
     4218            case NetworkAttachmentType_NAT:
     4219            {
     4220                if (SUCCEEDED(hrc) && SUCCEEDED(rc))
     4221                {
     4222                    rc = PDMR3DeviceAttach (pVM, pszDevice, uInstance, uLun, NULL);
     4223                    AssertRC (rc);
     4224
     4225                    if(!networkName.isNull())
     4226                    {
     4227                        /*
     4228                         * Until we implement service reference counters DHCP Server will be stopped
     4229                         * by DHCPServerRunner destructor.
     4230                         */
     4231                        ComPtr<IDHCPServer> dhcpServer;
     4232                        hrc = virtualBox->FindDHCPServerByNetworkName(networkName.mutableRaw(), dhcpServer.asOutParam());
     4233                        if(SUCCEEDED(hrc))
     4234                        {
     4235                            /* there is a DHCP server available for this network */
     4236                            BOOL bEnabled;
     4237                            hrc = dhcpServer->COMGETTER(Enabled)(&bEnabled);
     4238                            if(FAILED(hrc))
     4239                            {
     4240                                LogRel(("DHCP svr: COMGETTER(Enabled) failed, hrc (0x%x)", hrc));
     4241                                H();
     4242                            }
     4243
     4244                            if(bEnabled)
     4245                                hrc = dhcpServer->Start(networkName, trunkName, trunkType);
     4246                        }
     4247                        else
     4248                        {
     4249                            hrc = S_OK;
     4250                        }
     4251                    }
     4252                }
     4253
     4254                break;
     4255            }
     4256
     4257            default:
     4258                AssertMsgFailed(("should not get here!\n"));
     4259                break;
     4260        }
     4261
     4262        *meAttachmentType = eAttachmentType;
     4263    }
     4264    while (0);
     4265
     4266#undef STR_FREE
     4267#undef STR_CONV
     4268#undef H
     4269#undef RC_CHECK
     4270
     4271rcfailed:
     4272    /*
     4273     * Resume the VM if necessary.
     4274     */
     4275    if (fResume)
     4276    {
     4277        LogFlowFunc (("Resuming the VM...\n"));
     4278        /* disable the callback to prevent Console-level state change */
     4279        pThis->mVMStateChangeCallbackDisabled = true;
     4280        rc = VMR3Resume (pVM);
     4281        pThis->mVMStateChangeCallbackDisabled = false;
     4282        AssertRC (rc);
     4283        if (VBOX_FAILURE (rc))
     4284        {
     4285            /* too bad, we failed. try to sync the console state with the VMM state */
     4286            vmstateChangeCallback (pVM, VMSTATE_SUSPENDED, enmVMState, pThis);
     4287        }
     4288        /// @todo (r=dmik) if we failed with drive mount, then the VMR3Resume
     4289        //  error (if any) will be hidden from the caller. For proper reporting
     4290        //  of such multiple errors to the caller we need to enhance the
     4291        //  IVirtualBoxError interface. For now, give the first error the higher
     4292        //  priority.
     4293        if (VBOX_SUCCESS (rcRet))
     4294            rcRet = rc;
     4295    }
     4296
     4297    LogFlowFunc (("Returning %Rrc\n", rcRet));
     4298    return rcRet;
     4299}
     4300#endif /* VBOX_DYNAMIC_NET_ATTACH */
     4301
    32484302
    32494303/**
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r20501 r20521  
    13641364        {
    13651365            case NetworkAttachmentType_Null:
     1366#ifdef VBOX_DYNAMIC_NET_ATTACH
     1367                pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Null;
     1368#endif /* VBOX_DYNAMIC_NET_ATTACH */
    13661369                break;
    13671370
     
    14121415                    STR_FREE();
    14131416                }
     1417#ifdef VBOX_DYNAMIC_NET_ATTACH
     1418                pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_NAT;
     1419#endif /* VBOX_DYNAMIC_NET_ATTACH */
    14141420                break;
    14151421            }
     
    17451751# error "Port me"
    17461752#endif
     1753#ifdef VBOX_DYNAMIC_NET_ATTACH
     1754                    pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Bridged;
     1755#endif /* VBOX_DYNAMIC_NET_ATTACH */
    17471756                }
    17481757                else
     
    17931802                    STR_FREE();
    17941803                }
     1804#ifdef VBOX_DYNAMIC_NET_ATTACH
     1805                pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Internal;
     1806#endif /* VBOX_DYNAMIC_NET_ATTACH */
    17951807                break;
    17961808            }
     
    20042016                    hrc = hostInterface->EnableStaticIpConfigV6(tmpAddr, Utf8Str(tmpMask).toUInt32());
    20052017#endif
     2018#ifdef VBOX_DYNAMIC_NET_ATTACH
     2019                pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_HostOnly;
     2020#endif /* VBOX_DYNAMIC_NET_ATTACH */
    20062021                break;
    20072022            }
  • trunk/src/VBox/Main/Makefile.kmk

    r20501 r20521  
    563563VBoxC_DEFS += VBOX_WITH_VIDEOHWACCEL
    564564endif
     565
     566ifdef VBOX_DYNAMIC_NET_ATTACH
     567VBoxC_DEFS += VBOX_DYNAMIC_NET_ATTACH
     568endif
     569
    565570VBoxC_DEFS.darwin.x86 = VBOX_WITH_2X_4GB_ADDR_SPACE
    566571VBoxC_DEFS.win.x86 += _WIN32_WINNT=0x0500
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r19239 r20521  
    2727#include "VirtualBoxBase.h"
    2828#include "ProgressImpl.h"
     29
     30#ifdef VBOX_DYNAMIC_NET_ATTACH
     31# include "SchemaDefs.h"
     32#endif /* VBOX_DYNAMIC_NET_ATTACH */
    2933
    3034class Guest;
     
    439443                                          DriveState_T eState, DriveState_T *peState,
    440444                                          const char *pszPath, bool fPassthrough);
     445#ifdef VBOX_DYNAMIC_NET_ATTACH
     446    HRESULT doNetworkAdapterChange (const char *pszDevice, unsigned uInstance,
     447                                    unsigned uLun, NetworkAttachmentType_T eAttachmentType,
     448                                    NetworkAttachmentType_T *meAttachmentType,
     449                                    INetworkAdapter *aNetworkAdapter);
     450    static DECLCALLBACK(int) changeNetworkAttachment (Console *pThis, const char *pszDevice,
     451                                                      unsigned uInstance, unsigned uLun,
     452                                                      NetworkAttachmentType_T eAttachmentType,
     453                                                      NetworkAttachmentType_T *meAttachmentType,
     454                                                      INetworkAdapter *aNetworkAdapter);
     455#endif /* VBOX_DYNAMIC_NET_ATTACH */
    441456
    442457#ifdef VBOX_WITH_USB
     
    539554     * This does not have to match the state maintained in the Floppy. */
    540555    DriveState_T meFloppyState;
     556#ifdef VBOX_DYNAMIC_NET_ATTACH
     557    /** The current network attachment type in the VM.
     558     * This does not have to match the state maintained in the NetworkAdapter. */
     559    NetworkAttachmentType_T meAttachmentType[SchemaDefs::NetworkAdapterCount];
     560#endif /* VBOX_DYNAMIC_NET_ATTACH */
    541561
    542562    VMMDev * const mVMMDev;
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