VirtualBox

Changeset 30746 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 8, 2010 4:42:49 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
63518
Message:

Main: clean up spaghetti code in Console::configConstructor(): remove RC_CHECK() macro and delegate error handling to a few shared functions; move XML exceptions to separate header in IPRT to allow for reuse

Location:
trunk/src/VBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ApplianceImplExport.cpp

    r29984 r30746  
    16171617                           pcszManifestFileOnly, vrc);
    16181618    }
    1619     catch(xml::Error &x)
     1619    catch (iprt::Error &x)  // includes all XML exceptions
    16201620    {
    16211621        rc = setError(VBOX_E_FILE_ERROR,
    16221622                      x.what());
    16231623    }
    1624     catch(HRESULT aRC)
     1624    catch (HRESULT aRC)
    16251625    {
    16261626        rc = aRC;
  • trunk/src/VBox/Main/ApplianceImplImport.cpp

    r30739 r30746  
    684684        RTStrFree(pszDigest);
    685685    }
    686     catch(xml::Error &x)
     686    catch (iprt::Error &x)      // includes all XML exceptions
    687687    {
    688688        rc = setError(VBOX_E_FILE_ERROR,
    689689                      x.what());
    690690    }
    691     catch(HRESULT aRC)
     691    catch (HRESULT aRC)
    692692    {
    693693        rc = aRC;
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r30742 r30746  
    4949#include <iprt/string.h>
    5050#include <iprt/system.h>
     51#include <iprt/cpp/exception.h>
    5152#if 0 /* enable to play with lots of memory. */
    5253# include <iprt/env.h>
     
    309310}
    310311
     312class RT_DECL_CLASS ConfigError : public iprt::Error
     313{
     314public:
     315
     316    ConfigError(const char *pcszFunction,
     317                int vrc,
     318                const char *pcszName)
     319        : iprt::Error(Utf8StrFmt("%s failed: rc=%Rrc, pcszName=%s", pcszFunction, vrc, pcszName)),
     320          m_vrc(vrc)
     321    {
     322        AssertMsgFailed(("%s\n", what())); // in strict mode, hit a breakpoint here
     323    }
     324
     325    int m_vrc;
     326};
     327
     328
     329/**
     330 * Helper that calls CFGMR3InsertString and throws an iprt::Error if that
     331 * fails (C-string variant).
     332 * @param pParent
     333 * @param pcszNodeName
     334 * @param strValue
     335 */
     336void InsertConfigString(PCFGMNODE pNode,
     337                        const char *pcszName,
     338                        const char *pcszValue)
     339{
     340    int vrc = CFGMR3InsertString(pNode,
     341                                 pcszName,
     342                                 pcszValue);
     343    if (RT_FAILURE(vrc))
     344        throw ConfigError("CFGMR3InsertString", vrc, pcszName);
     345}
     346
     347/**
     348 * Helper that calls CFGMR3InsertString and throws an iprt::Error if that
     349 * fails (Utf8Str variant).
     350 * @param pParent
     351 * @param pcszNodeName
     352 * @param strValue
     353 */
     354void InsertConfigString(PCFGMNODE pNode,
     355                        const char *pcszName,
     356                        const Utf8Str &strValue)
     357{
     358    InsertConfigString(pNode, pcszName, strValue.c_str());
     359}
     360
     361/**
     362 * Helper that calls CFGMR3InsertString and throws an iprt::Error if that
     363 * fails (Bstr variant).
     364 * @param pParent
     365 * @param pcszNodeName
     366 * @param strValue
     367 */
     368void InsertConfigString(PCFGMNODE pNode,
     369                        const char *pcszName,
     370                        const Bstr &bstrValue)
     371{
     372    InsertConfigString(pNode, pcszName, Utf8Str(bstrValue).c_str());
     373}
     374
     375/**
     376 *
     377 * @param pNode
     378 * @param pcszName
     379 * @param pvBytes
     380 * @param cbBytes
     381 */
     382void InsertConfigBytes(PCFGMNODE pNode,
     383                       const char *pcszName,
     384                       const void *pvBytes,
     385                       size_t cbBytes)
     386{
     387    int vrc = CFGMR3InsertBytes(pNode,
     388                                pcszName,
     389                                pvBytes,
     390                                cbBytes);
     391    if (RT_FAILURE(vrc))
     392        throw ConfigError("CFGMR3InsertBytes", vrc, pcszName);
     393}
     394
     395/**
     396 *
     397 * @param pNode
     398 * @param pcszName
     399 * @param u64Integer
     400 */
     401void InsertConfigInteger(PCFGMNODE pNode,
     402                         const char *pcszName,
     403                         uint64_t u64Integer)
     404{
     405    int vrc = CFGMR3InsertInteger(pNode,
     406                                  pcszName,
     407                                  u64Integer);
     408    if (RT_FAILURE(vrc))
     409        throw ConfigError("CFGMR3InsertInteger", vrc, pcszName);
     410}
     411
     412/**
     413 *
     414 * @param pNode
     415 * @param pcszName
     416 * @param ppChild
     417 */
     418void InsertConfigNode(PCFGMNODE pNode,
     419                      const char *pcszName,
     420                      PCFGMNODE *ppChild)
     421{
     422    int vrc = CFGMR3InsertNode(pNode, pcszName, ppChild);
     423    if (RT_FAILURE(vrc))
     424        throw ConfigError("CFGMR3InsertNode", vrc, pcszName);
     425}
     426
     427/**
     428 *
     429 * @param pNode
     430 * @param pcszName
     431 */
     432void RemoveConfigValue(PCFGMNODE pNode,
     433                       const char *pcszName)
     434{
     435    int vrc = CFGMR3RemoveValue(pNode, pcszName);
     436    if (RT_FAILURE(vrc))
     437        throw ConfigError("CFGMR3RemoveValue", vrc, pcszName);
     438}
     439
    311440/**
    312441 *  Construct the VM configuration tree (CFGM).
     
    359488    Bstr            bstr;
    360489
    361 #define RC_CHECK()  AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc)
    362490#define H()         AssertMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE)
    363491
     
    379507    hrc = pMachine->COMGETTER(HardwareUUID)(bstr.asOutParam());                         H();
    380508    RTUUID HardwareUuid;
    381     rc = RTUuidFromUtf16(&HardwareUuid, bstr.raw());                                    RC_CHECK();
     509    rc = RTUuidFromUtf16(&HardwareUuid, bstr.raw());
     510    AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc);
    382511
    383512    ULONG cRamMBs;
     
    413542    Assert(pRoot);
    414543
    415     /*
    416      * Set the root (and VMM) level values.
    417      */
    418     hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                                 H();
    419     rc = CFGMR3InsertStringW(pRoot, "Name",                 bstr.raw());                RC_CHECK();
    420     rc = CFGMR3InsertBytes(pRoot,   "UUID", &HardwareUuid, sizeof(HardwareUuid));       RC_CHECK();
    421     rc = CFGMR3InsertInteger(pRoot, "RamSize",              cbRam);                     RC_CHECK();
    422     rc = CFGMR3InsertInteger(pRoot, "RamHoleSize",          cbRamHole);                 RC_CHECK();
    423     rc = CFGMR3InsertInteger(pRoot, "NumCPUs",              cCpus);                     RC_CHECK();
    424     rc = CFGMR3InsertInteger(pRoot, "TimerMillies",         10);                        RC_CHECK();
     544    // InsertConfigString throws
     545    try
     546    {
     547
     548        /*
     549         * Set the root (and VMM) level values.
     550         */
     551        hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                                 H();
     552        InsertConfigString(pRoot, "Name",                 bstr);
     553        InsertConfigBytes(pRoot,   "UUID", &HardwareUuid, sizeof(HardwareUuid));
     554        InsertConfigInteger(pRoot, "RamSize",              cbRam);
     555        InsertConfigInteger(pRoot, "RamHoleSize",          cbRamHole);
     556        InsertConfigInteger(pRoot, "NumCPUs",              cCpus);
     557        InsertConfigInteger(pRoot, "TimerMillies",         10);
    425558#ifdef VBOX_WITH_RAW_MODE
    426     rc = CFGMR3InsertInteger(pRoot, "RawR3Enabled",         1);     /* boolean */       RC_CHECK();
    427     rc = CFGMR3InsertInteger(pRoot, "RawR0Enabled",         1);     /* boolean */       RC_CHECK();
    428     /** @todo Config: RawR0, PATMEnabled and CSAMEnabled needs attention later. */
    429     rc = CFGMR3InsertInteger(pRoot, "PATMEnabled",          1);     /* boolean */       RC_CHECK();
    430     rc = CFGMR3InsertInteger(pRoot, "CSAMEnabled",          1);     /* boolean */       RC_CHECK();
     559        InsertConfigInteger(pRoot, "RawR3Enabled",         1);     /* boolean */
     560        InsertConfigInteger(pRoot, "RawR0Enabled",         1);     /* boolean */
     561        /** @todo Config: RawR0, PATMEnabled and CSAMEnabled needs attention later. */
     562        InsertConfigInteger(pRoot, "PATMEnabled",          1);     /* boolean */
     563        InsertConfigInteger(pRoot, "CSAMEnabled",          1);     /* boolean */
    431564#endif
    432     /* Not necessary, but to make sure these two settings end up in the release log. */
    433     BOOL fPageFusion = FALSE;
    434     hrc = pMachine->COMGETTER(PageFusionEnabled)(&fPageFusion);                         H();
    435     rc = CFGMR3InsertInteger(pRoot, "PageFusion",           fPageFusion); /* boolean */ RC_CHECK();
    436     ULONG ulBalloonSize = 0;
    437     hrc = pMachine->COMGETTER(MemoryBalloonSize)(&ulBalloonSize);                       H();
    438     rc = CFGMR3InsertInteger(pRoot, "MemBalloonSize",       ulBalloonSize);             RC_CHECK();
    439 
    440     /*
    441      * CPUM values.
    442      */
    443     PCFGMNODE pCPUM;
    444     rc = CFGMR3InsertNode(pRoot, "CPUM", &pCPUM);                                       RC_CHECK();
    445 
    446     /* cpuid leaf overrides. */
    447     static uint32_t const s_auCpuIdRanges[] =
    448     {
    449         UINT32_C(0x00000000), UINT32_C(0x0000000a),
    450         UINT32_C(0x80000000), UINT32_C(0x8000000a)
    451     };
    452     for (unsigned i = 0; i < RT_ELEMENTS(s_auCpuIdRanges); i += 2)
    453         for (uint32_t uLeaf = s_auCpuIdRanges[i]; uLeaf < s_auCpuIdRanges[i + 1]; uLeaf++)
     565        /* Not necessary, but to make sure these two settings end up in the release log. */
     566        BOOL fPageFusion = FALSE;
     567        hrc = pMachine->COMGETTER(PageFusionEnabled)(&fPageFusion);                         H();
     568        InsertConfigInteger(pRoot, "PageFusion",           fPageFusion); /* boolean */
     569        ULONG ulBalloonSize = 0;
     570        hrc = pMachine->COMGETTER(MemoryBalloonSize)(&ulBalloonSize);                       H();
     571        InsertConfigInteger(pRoot, "MemBalloonSize",       ulBalloonSize);
     572
     573        /*
     574         * CPUM values.
     575         */
     576        PCFGMNODE pCPUM;
     577        InsertConfigNode(pRoot, "CPUM", &pCPUM);
     578
     579        /* cpuid leaf overrides. */
     580        static uint32_t const s_auCpuIdRanges[] =
    454581        {
    455             ULONG ulEax, ulEbx, ulEcx, ulEdx;
    456             hrc = pMachine->GetCPUIDLeaf(uLeaf, &ulEax, &ulEbx, &ulEcx, &ulEdx);
    457             if (SUCCEEDED(hrc))
    458             {
    459                 PCFGMNODE pLeaf;
    460                 rc = CFGMR3InsertNodeF(pCPUM, &pLeaf, "HostCPUID/%RX32", uLeaf);        RC_CHECK();
    461 
    462                 rc = CFGMR3InsertInteger(pLeaf, "eax", ulEax);                          RC_CHECK();
    463                 rc = CFGMR3InsertInteger(pLeaf, "ebx", ulEbx);                          RC_CHECK();
    464                 rc = CFGMR3InsertInteger(pLeaf, "ecx", ulEcx);                          RC_CHECK();
    465                 rc = CFGMR3InsertInteger(pLeaf, "edx", ulEdx);                          RC_CHECK();
    466             }
    467             else if (hrc != E_INVALIDARG)                                               H();
     582            UINT32_C(0x00000000), UINT32_C(0x0000000a),
     583            UINT32_C(0x80000000), UINT32_C(0x8000000a)
     584        };
     585        for (unsigned i = 0; i < RT_ELEMENTS(s_auCpuIdRanges); i += 2)
     586            for (uint32_t uLeaf = s_auCpuIdRanges[i]; uLeaf < s_auCpuIdRanges[i + 1]; uLeaf++)
     587            {
     588                ULONG ulEax, ulEbx, ulEcx, ulEdx;
     589                hrc = pMachine->GetCPUIDLeaf(uLeaf, &ulEax, &ulEbx, &ulEcx, &ulEdx);
     590                if (SUCCEEDED(hrc))
     591                {
     592                    PCFGMNODE pLeaf;
     593                    InsertConfigNode(pCPUM, Utf8StrFmt("HostCPUID/%RX32", uLeaf).c_str(), &pLeaf);
     594
     595                    InsertConfigInteger(pLeaf, "eax", ulEax);
     596                    InsertConfigInteger(pLeaf, "ebx", ulEbx);
     597                    InsertConfigInteger(pLeaf, "ecx", ulEcx);
     598                    InsertConfigInteger(pLeaf, "edx", ulEdx);
     599                }
     600                else if (hrc != E_INVALIDARG)                                               H();
     601            }
     602
     603        /* We must limit CPUID count for Windows NT 4, as otherwise it stops
     604        with error 0x3e (MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED). */
     605        if (osTypeId == "WindowsNT4")
     606        {
     607            LogRel(("Limiting CPUID leaf count for NT4 guests\n"));
     608            InsertConfigInteger(pCPUM, "NT4LeafLimit", true);
    468609        }
    469610
    470     /* We must limit CPUID count for Windows NT 4, as otherwise it stops
    471        with error 0x3e (MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED). */
    472     if (osTypeId == "WindowsNT4")
    473     {
    474         LogRel(("Limiting CPUID leaf count for NT4 guests\n"));
    475         rc = CFGMR3InsertInteger(pCPUM, "NT4LeafLimit", true);                          RC_CHECK();
    476     }
    477 
    478     /* Expose extended MWAIT features to Mac OS X guests. */
    479     if (fOsXGuest)
    480     {
    481         LogRel(("Using MWAIT extensions\n"));
    482         rc = CFGMR3InsertInteger(pCPUM, "MWaitExtensions", true);                       RC_CHECK();
    483     }
    484 
    485     /*
    486      * Hardware virtualization extensions.
    487      */
    488     BOOL fHWVirtExEnabled;
    489     BOOL fHwVirtExtForced;
     611        /* Expose extended MWAIT features to Mac OS X guests. */
     612        if (fOsXGuest)
     613        {
     614            LogRel(("Using MWAIT extensions\n"));
     615            InsertConfigInteger(pCPUM, "MWaitExtensions", true);
     616        }
     617
     618        /*
     619         * Hardware virtualization extensions.
     620         */
     621        BOOL fHWVirtExEnabled;
     622        BOOL fHwVirtExtForced;
    490623#ifdef VBOX_WITH_RAW_MODE
    491     hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &fHWVirtExEnabled); H();
    492     if (cCpus > 1) /** @todo SMP: This isn't nice, but things won't work on mac otherwise. */
    493         fHWVirtExEnabled = TRUE;
     624        hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &fHWVirtExEnabled); H();
     625        if (cCpus > 1) /** @todo SMP: This isn't nice, but things won't work on mac otherwise. */
     626            fHWVirtExEnabled = TRUE;
    494627# ifdef RT_OS_DARWIN
    495     fHwVirtExtForced = fHWVirtExEnabled;
     628        fHwVirtExtForced = fHWVirtExEnabled;
    496629# else
    497     /* - With more than 4GB PGM will use different RAMRANGE sizes for raw
    498          mode and hv mode to optimize lookup times.
    499        - With more than one virtual CPU, raw-mode isn't a fallback option. */
    500     fHwVirtExtForced = fHWVirtExEnabled
    501                     && (   cbRam > (_4G - cbRamHole)
    502                         || cCpus > 1);
     630        /* - With more than 4GB PGM will use different RAMRANGE sizes for raw
     631             mode and hv mode to optimize lookup times.
     632           - With more than one virtual CPU, raw-mode isn't a fallback option. */
     633        fHwVirtExtForced = fHWVirtExEnabled
     634                        && (   cbRam > (_4G - cbRamHole)
     635                            || cCpus > 1);
    503636# endif
    504637#else  /* !VBOX_WITH_RAW_MODE */
    505     fHWVirtExEnabled = fHwVirtExtForced = TRUE;
     638        fHWVirtExEnabled = fHwVirtExtForced = TRUE;
    506639#endif /* !VBOX_WITH_RAW_MODE */
    507     rc = CFGMR3InsertInteger(pRoot, "HwVirtExtForced",      fHwVirtExtForced);          RC_CHECK();
    508 
    509     PCFGMNODE pHWVirtExt;
    510     rc = CFGMR3InsertNode(pRoot, "HWVirtExt", &pHWVirtExt);                             RC_CHECK();
    511     if (fHWVirtExEnabled)
    512     {
    513         rc = CFGMR3InsertInteger(pHWVirtExt, "Enabled",     1);                         RC_CHECK();
    514 
    515         /* Indicate whether 64-bit guests are supported or not. */
    516         /** @todo This is currently only forced off on 32-bit hosts only because it
    517          *        makes a lof of difference there (REM and Solaris performance).
    518          */
    519         BOOL fSupportsLongMode = false;
    520         hrc = host->GetProcessorFeature(ProcessorFeature_LongMode,
    521                                         &fSupportsLongMode);                            H();
    522         hrc = guestOSType->COMGETTER(Is64Bit)(&fIs64BitGuest);                          H();
    523 
    524         if (fSupportsLongMode && fIs64BitGuest)
     640        InsertConfigInteger(pRoot, "HwVirtExtForced",      fHwVirtExtForced);
     641
     642        PCFGMNODE pHWVirtExt;
     643        InsertConfigNode(pRoot, "HWVirtExt", &pHWVirtExt);
     644        if (fHWVirtExEnabled)
    525645        {
    526             rc = CFGMR3InsertInteger(pHWVirtExt, "64bitEnabled", 1);                    RC_CHECK();
     646            InsertConfigInteger(pHWVirtExt, "Enabled",     1);
     647
     648            /* Indicate whether 64-bit guests are supported or not. */
     649            /** @todo This is currently only forced off on 32-bit hosts only because it
     650             *        makes a lof of difference there (REM and Solaris performance).
     651             */
     652            BOOL fSupportsLongMode = false;
     653            hrc = host->GetProcessorFeature(ProcessorFeature_LongMode,
     654                                            &fSupportsLongMode);                            H();
     655            hrc = guestOSType->COMGETTER(Is64Bit)(&fIs64BitGuest);                          H();
     656
     657            if (fSupportsLongMode && fIs64BitGuest)
     658            {
     659                InsertConfigInteger(pHWVirtExt, "64bitEnabled", 1);
    527660#if ARCH_BITS == 32 /* The recompiler must use VBoxREM64 (32-bit host only). */
    528             PCFGMNODE pREM;
    529             rc = CFGMR3InsertNode(pRoot, "REM", &pREM);                                 RC_CHECK();
    530             rc = CFGMR3InsertInteger(pREM, "64bitEnabled", 1);                          RC_CHECK();
     661                PCFGMNODE pREM;
     662                InsertConfigNode(pRoot, "REM", &pREM);
     663                InsertConfigInteger(pREM, "64bitEnabled", 1);
    531664#endif
     665            }
     666#if ARCH_BITS == 32 /* 32-bit guests only. */
     667            else
     668            {
     669                InsertConfigInteger(pHWVirtExt, "64bitEnabled", 0);
     670            }
     671#endif
     672
     673            /** @todo Not exactly pretty to check strings; VBOXOSTYPE would be better, but that requires quite a bit of API change in Main. */
     674            if (    !fIs64BitGuest
     675                &&  fIOAPIC
     676                &&  (   osTypeId == "WindowsNT4"
     677                    || osTypeId == "Windows2000"
     678                    || osTypeId == "WindowsXP"
     679                    || osTypeId == "Windows2003"))
     680            {
     681                /* Only allow TPR patching for NT, Win2k, XP and Windows Server 2003. (32 bits mode)
     682                 * We may want to consider adding more guest OSes (Solaris) later on.
     683                 */
     684                InsertConfigInteger(pHWVirtExt, "TPRPatchingEnabled", 1);
     685            }
    532686        }
    533 #if ARCH_BITS == 32 /* 32-bit guests only. */
     687
     688        /* HWVirtEx exclusive mode */
     689        BOOL fHWVirtExExclusive = true;
     690        hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Exclusive, &fHWVirtExExclusive); H();
     691        InsertConfigInteger(pHWVirtExt, "Exclusive", fHWVirtExExclusive);
     692
     693        /* Nested paging (VT-x/AMD-V) */
     694        BOOL fEnableNestedPaging = false;
     695        hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &fEnableNestedPaging); H();
     696        InsertConfigInteger(pHWVirtExt, "EnableNestedPaging", fEnableNestedPaging);
     697
     698        /* Large pages; requires nested paging */
     699        BOOL fEnableLargePages = false;
     700        hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &fEnableLargePages); H();
     701        InsertConfigInteger(pHWVirtExt, "EnableLargePages", fEnableLargePages);
     702
     703        /* VPID (VT-x) */
     704        BOOL fEnableVPID = false;
     705        hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_VPID, &fEnableVPID);       H();
     706        InsertConfigInteger(pHWVirtExt, "EnableVPID", fEnableVPID);
     707
     708        /* Physical Address Extension (PAE) */
     709        BOOL fEnablePAE = false;
     710        hrc = pMachine->GetCPUProperty(CPUPropertyType_PAE, &fEnablePAE);                   H();
     711        InsertConfigInteger(pRoot, "EnablePAE", fEnablePAE);
     712
     713        /* Synthetic CPU */
     714        BOOL fSyntheticCpu = false;
     715        hrc = pMachine->GetCPUProperty(CPUPropertyType_Synthetic, &fSyntheticCpu);          H();
     716        InsertConfigInteger(pRoot, "SyntheticCpu", fSyntheticCpu);
     717
     718        BOOL fPXEDebug;
     719        hrc = biosSettings->COMGETTER(PXEDebugEnabled)(&fPXEDebug);                         H();
     720
     721        /*
     722         * PDM config.
     723         *  Load drivers in VBoxC.[so|dll]
     724         */
     725        PCFGMNODE pPDM;
     726        PCFGMNODE pDrivers;
     727        PCFGMNODE pMod;
     728        InsertConfigNode(pRoot,    "PDM", &pPDM);
     729        InsertConfigNode(pPDM,     "Drivers", &pDrivers);
     730        InsertConfigNode(pDrivers, "VBoxC", &pMod);
     731#ifdef VBOX_WITH_XPCOM
     732        // VBoxC is located in the components subdirectory
     733        char szPathVBoxC[RTPATH_MAX];
     734        rc = RTPathAppPrivateArch(szPathVBoxC, RTPATH_MAX - sizeof("/components/VBoxC"));   AssertRC(rc);
     735        strcat(szPathVBoxC, "/components/VBoxC");
     736        InsertConfigString(pMod,   "Path",  szPathVBoxC);
     737#else
     738        InsertConfigString(pMod,   "Path",  "VBoxC");
     739#endif
     740
     741        /*
     742         * I/O settings (cach, max bandwidth, ...).
     743         */
     744        PCFGMNODE pPDMAc;
     745        PCFGMNODE pPDMAcFile;
     746        InsertConfigNode(pPDM, "AsyncCompletion", &pPDMAc);
     747        InsertConfigNode(pPDMAc, "File", &pPDMAcFile);
     748
     749        /* Builtin I/O cache */
     750        BOOL fIoCache = true;
     751        hrc = pMachine->COMGETTER(IoCacheEnabled)(&fIoCache);                               H();
     752        InsertConfigInteger(pPDMAcFile, "CacheEnabled", fIoCache);
     753
     754        /* I/O cache size */
     755        ULONG ioCacheSize = 5;
     756        hrc = pMachine->COMGETTER(IoCacheSize)(&ioCacheSize);                               H();
     757        InsertConfigInteger(pPDMAcFile, "CacheSize", ioCacheSize * _1M);
     758
     759        /* Maximum I/O bandwidth */
     760        ULONG ioBandwidthMax = 0;
     761        hrc = pMachine->COMGETTER(IoBandwidthMax)(&ioBandwidthMax);                         H();
     762        if (ioBandwidthMax != 0)
     763        {
     764            InsertConfigInteger(pPDMAcFile, "VMTransferPerSecMax", ioBandwidthMax * _1M);
     765        }
     766
     767        /*
     768         * Devices
     769         */
     770        PCFGMNODE pDevices = NULL;      /* /Devices */
     771        PCFGMNODE pDev = NULL;          /* /Devices/Dev/ */
     772        PCFGMNODE pInst = NULL;         /* /Devices/Dev/0/ */
     773        PCFGMNODE pCfg = NULL;          /* /Devices/Dev/.../Config/ */
     774        PCFGMNODE pLunL0 = NULL;        /* /Devices/Dev/0/LUN#0/ */
     775        PCFGMNODE pLunL1 = NULL;        /* /Devices/Dev/0/LUN#0/AttachedDriver/ */
     776        PCFGMNODE pLunL2 = NULL;        /* /Devices/Dev/0/LUN#0/AttachedDriver/Config/ */
     777        PCFGMNODE pBiosCfg = NULL;      /* /Devices/pcbios/0/Config/ */
     778        PCFGMNODE pNetBootCfg = NULL;   /* /Devices/pcbios/0/Config/NetBoot/ */
     779
     780        InsertConfigNode(pRoot, "Devices", &pDevices);
     781
     782        /*
     783         * PC Arch.
     784         */
     785        InsertConfigNode(pDevices, "pcarch", &pDev);
     786        InsertConfigNode(pDev,     "0", &pInst);
     787        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     788        InsertConfigNode(pInst,    "Config", &pCfg);
     789
     790        /*
     791         * The time offset
     792         */
     793        LONG64 timeOffset;
     794        hrc = biosSettings->COMGETTER(TimeOffset)(&timeOffset);                             H();
     795        PCFGMNODE pTMNode;
     796        InsertConfigNode(pRoot, "TM", &pTMNode);
     797        InsertConfigInteger(pTMNode, "UTCOffset", timeOffset * 1000000);
     798
     799        /*
     800         * DMA
     801         */
     802        InsertConfigNode(pDevices, "8237A", &pDev);
     803        InsertConfigNode(pDev,     "0", &pInst);
     804        InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
     805
     806        /*
     807         * PCI buses.
     808         */
     809        InsertConfigNode(pDevices, "pci", &pDev); /* piix3 */
     810        InsertConfigNode(pDev,     "0", &pInst);
     811        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     812        InsertConfigNode(pInst,    "Config", &pCfg);
     813        InsertConfigInteger(pCfg, "IOAPIC", fIOAPIC);
     814
     815#if 0 /* enable this to test PCI bridging */
     816        InsertConfigNode(pDevices, "pcibridge", &pDev);
     817        InsertConfigNode(pDev,     "0", &pInst);
     818        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     819        InsertConfigNode(pInst,    "Config", &pCfg);
     820        InsertConfigInteger(pInst, "PCIDeviceNo",         14);
     821        InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     822        rc = CFGMR3InsertInteger(pInst, "PCIBusNo",             0);/* -> pci[0] */          RC_CHECK();
     823
     824        InsertConfigNode(pDev,     "1", &pInst);
     825        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     826        InsertConfigNode(pInst,    "Config", &pCfg);
     827        InsertConfigInteger(pInst, "PCIDeviceNo",          1);
     828        InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     829        rc = CFGMR3InsertInteger(pInst, "PCIBusNo",             1);/* ->pcibridge[0] */     RC_CHECK();
     830
     831        InsertConfigNode(pDev,     "2", &pInst);
     832        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     833        InsertConfigNode(pInst,    "Config", &pCfg);
     834        InsertConfigInteger(pInst, "PCIDeviceNo",          3);
     835        InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     836        rc = CFGMR3InsertInteger(pInst, "PCIBusNo",             1);/* ->pcibridge[0] */     RC_CHECK();
     837#endif
     838
     839        /*
     840         * Enable 3 following devices: HPET, SMC, LPC on MacOS X guests
     841         */
     842        /*
     843         * High Precision Event Timer (HPET)
     844         */
     845        BOOL fHpetEnabled;
     846#ifdef VBOX_WITH_HPET
     847        /* Other guests may wish to use HPET too, but MacOS X not functional without it */
     848        hrc = pMachine->COMGETTER(HpetEnabled)(&fHpetEnabled);                              H();
     849        /* so always enable HPET in extended profile */
     850        fHpetEnabled |= fOsXGuest;
     851#else
     852        fHpetEnabled = false;
     853#endif
     854        if (fHpetEnabled)
     855        {
     856            InsertConfigNode(pDevices, "hpet", &pDev);
     857            InsertConfigNode(pDev,     "0", &pInst);
     858            InsertConfigInteger(pInst, "Trusted",   1); /* boolean */
     859        }
     860
     861        /*
     862         * System Management Controller (SMC)
     863         */
     864        BOOL fSmcEnabled;
     865#ifdef VBOX_WITH_SMC
     866        fSmcEnabled = fOsXGuest;
     867#else
     868        fSmcEnabled = false;
     869#endif
     870        if (fSmcEnabled)
     871        {
     872            InsertConfigNode(pDevices, "smc", &pDev);
     873            InsertConfigNode(pDev,     "0", &pInst);
     874            InsertConfigInteger(pInst, "Trusted",   1); /* boolean */
     875            InsertConfigNode(pInst,    "Config", &pCfg);
     876
     877            bool fGetKeyFromRealSMC;
     878            Bstr bstrKey;
     879            rc = getSmcDeviceKey(pMachine, bstrKey.asOutParam(), &fGetKeyFromRealSMC);
     880            AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc);
     881
     882            InsertConfigString(pCfg,   "DeviceKey", bstrKey);
     883            InsertConfigInteger(pCfg, "GetKeyFromRealSMC", fGetKeyFromRealSMC);
     884        }
     885
     886        /*
     887         * Low Pin Count (LPC) bus
     888         */
     889        BOOL fLpcEnabled;
     890        /** @todo: implement appropriate getter */
     891#ifdef VBOX_WITH_LPC
     892        fLpcEnabled = fOsXGuest;
     893#else
     894        fLpcEnabled = false;
     895#endif
     896        if (fLpcEnabled)
     897        {
     898            InsertConfigNode(pDevices, "lpc", &pDev);
     899            InsertConfigNode(pDev,     "0", &pInst);
     900            InsertConfigInteger(pInst, "Trusted",   1); /* boolean */
     901        }
     902
     903        /*
     904         * PS/2 keyboard & mouse.
     905         */
     906        InsertConfigNode(pDevices, "pckbd", &pDev);
     907        InsertConfigNode(pDev,     "0", &pInst);
     908        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     909        InsertConfigNode(pInst,    "Config", &pCfg);
     910
     911        InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     912        InsertConfigString(pLunL0, "Driver",               "KeyboardQueue");
     913        InsertConfigNode(pLunL0,   "Config", &pCfg);
     914        InsertConfigInteger(pCfg, "QueueSize",            64);
     915
     916        InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
     917        InsertConfigString(pLunL1, "Driver",               "MainKeyboard");
     918        InsertConfigNode(pLunL1,   "Config", &pCfg);
     919        Keyboard *pKeyboard = pConsole->mKeyboard;
     920        InsertConfigInteger(pCfg, "Object",     (uintptr_t)pKeyboard);
     921
     922        InsertConfigNode(pInst,    "LUN#1", &pLunL0);
     923        InsertConfigString(pLunL0, "Driver",               "MouseQueue");
     924        InsertConfigNode(pLunL0,   "Config", &pCfg);
     925        InsertConfigInteger(pCfg, "QueueSize",            128);
     926
     927        InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
     928        InsertConfigString(pLunL1, "Driver",               "MainMouse");
     929        InsertConfigNode(pLunL1,   "Config", &pCfg);
     930        Mouse *pMouse = pConsole->mMouse;
     931        InsertConfigInteger(pCfg, "Object",     (uintptr_t)pMouse);
     932
     933        /*
     934         * i8254 Programmable Interval Timer And Dummy Speaker
     935         */
     936        InsertConfigNode(pDevices, "i8254", &pDev);
     937        InsertConfigNode(pDev,     "0", &pInst);
     938        InsertConfigNode(pInst,    "Config", &pCfg);
     939#ifdef DEBUG
     940        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     941#endif
     942
     943        /*
     944         * i8259 Programmable Interrupt Controller.
     945         */
     946        InsertConfigNode(pDevices, "i8259", &pDev);
     947        InsertConfigNode(pDev,     "0", &pInst);
     948        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     949        InsertConfigNode(pInst,    "Config", &pCfg);
     950
     951        /*
     952         * Advanced Programmable Interrupt Controller.
     953         * SMP: Each CPU has a LAPIC, but we have a single device representing all LAPICs states,
     954         *      thus only single insert
     955         */
     956        InsertConfigNode(pDevices, "apic", &pDev);
     957        InsertConfigNode(pDev, "0", &pInst);
     958        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     959        InsertConfigNode(pInst,    "Config", &pCfg);
     960        InsertConfigInteger(pCfg, "IOAPIC", fIOAPIC);
     961        InsertConfigInteger(pCfg, "NumCPUs", cCpus);
     962
     963        if (fIOAPIC)
     964        {
     965            /*
     966             * I/O Advanced Programmable Interrupt Controller.
     967             */
     968            InsertConfigNode(pDevices, "ioapic", &pDev);
     969            InsertConfigNode(pDev,     "0", &pInst);
     970            InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
     971            InsertConfigNode(pInst,    "Config", &pCfg);
     972        }
     973
     974        /*
     975         * RTC MC146818.
     976         */
     977        InsertConfigNode(pDevices, "mc146818", &pDev);
     978        InsertConfigNode(pDev,     "0", &pInst);
     979        InsertConfigNode(pInst,    "Config", &pCfg);
     980        BOOL fRTCUseUTC;
     981        hrc = pMachine->COMGETTER(RTCUseUTC)(&fRTCUseUTC);                                  H();
     982        InsertConfigInteger(pCfg, "UseUTC", fRTCUseUTC ? 1 : 0);
     983
     984        /*
     985         * VGA.
     986         */
     987        InsertConfigNode(pDevices, "vga", &pDev);
     988        InsertConfigNode(pDev,     "0", &pInst);
     989        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     990        InsertConfigInteger(pInst, "PCIDeviceNo",          2);
     991        Assert(!afPciDeviceNo[2]);
     992        afPciDeviceNo[2] = true;
     993        InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     994        InsertConfigNode(pInst,    "Config", &pCfg);
     995        ULONG cVRamMBs;
     996        hrc = pMachine->COMGETTER(VRAMSize)(&cVRamMBs);                                     H();
     997        InsertConfigInteger(pCfg, "VRamSize",             cVRamMBs * _1M);
     998        ULONG cMonitorCount;
     999        hrc = pMachine->COMGETTER(MonitorCount)(&cMonitorCount);                            H();
     1000        InsertConfigInteger(pCfg, "MonitorCount",         cMonitorCount);
     1001#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
     1002        InsertConfigInteger(pCfg, "R0Enabled",            fHWVirtExEnabled);
     1003#endif
     1004
     1005        /*
     1006         * BIOS logo
     1007         */
     1008        BOOL fFadeIn;
     1009        hrc = biosSettings->COMGETTER(LogoFadeIn)(&fFadeIn);                                H();
     1010        InsertConfigInteger(pCfg, "FadeIn",  fFadeIn ? 1 : 0);
     1011        BOOL fFadeOut;
     1012        hrc = biosSettings->COMGETTER(LogoFadeOut)(&fFadeOut);                              H();
     1013        InsertConfigInteger(pCfg, "FadeOut", fFadeOut ? 1: 0);
     1014        ULONG logoDisplayTime;
     1015        hrc = biosSettings->COMGETTER(LogoDisplayTime)(&logoDisplayTime);                   H();
     1016        InsertConfigInteger(pCfg, "LogoTime", logoDisplayTime);
     1017        Bstr logoImagePath;
     1018        hrc = biosSettings->COMGETTER(LogoImagePath)(logoImagePath.asOutParam());           H();
     1019        InsertConfigString(pCfg,   "LogoFile", Utf8Str(logoImagePath ? logoImagePath : "") );
     1020
     1021        /*
     1022         * Boot menu
     1023         */
     1024        BIOSBootMenuMode_T eBootMenuMode;
     1025        int iShowBootMenu;
     1026        biosSettings->COMGETTER(BootMenuMode)(&eBootMenuMode);
     1027        switch (eBootMenuMode)
     1028        {
     1029            case BIOSBootMenuMode_Disabled: iShowBootMenu = 0;  break;
     1030            case BIOSBootMenuMode_MenuOnly: iShowBootMenu = 1;  break;
     1031            default:                        iShowBootMenu = 2;  break;
     1032        }
     1033        InsertConfigInteger(pCfg, "ShowBootMenu", iShowBootMenu);
     1034
     1035        /* Custom VESA mode list */
     1036        unsigned cModes = 0;
     1037        for (unsigned iMode = 1; iMode <= 16; ++iMode)
     1038        {
     1039            char szExtraDataKey[sizeof("CustomVideoModeXX")];
     1040            RTStrPrintf(szExtraDataKey, sizeof(szExtraDataKey), "CustomVideoMode%u", iMode);
     1041            hrc = pMachine->GetExtraData(Bstr(szExtraDataKey), bstr.asOutParam());          H();
     1042            if (bstr.isEmpty())
     1043                break;
     1044            InsertConfigString(pCfg, szExtraDataKey, bstr);
     1045            ++cModes;
     1046        }
     1047        InsertConfigInteger(pCfg, "CustomVideoModes", cModes);
     1048
     1049        /* VESA height reduction */
     1050        ULONG ulHeightReduction;
     1051        IFramebuffer *pFramebuffer = pConsole->getDisplay()->getFramebuffer();
     1052        if (pFramebuffer)
     1053        {
     1054            hrc = pFramebuffer->COMGETTER(HeightReduction)(&ulHeightReduction);             H();
     1055        }
    5341056        else
    5351057        {
    536             rc = CFGMR3InsertInteger(pHWVirtExt, "64bitEnabled", 0);                    RC_CHECK();
     1058            /* If framebuffer is not available, there is no height reduction. */
     1059            ulHeightReduction = 0;
    5371060        }
     1061        InsertConfigInteger(pCfg, "HeightReduction", ulHeightReduction);
     1062
     1063        /* Attach the display. */
     1064        InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     1065        InsertConfigString(pLunL0, "Driver",               "MainDisplay");
     1066        InsertConfigNode(pLunL0,   "Config", &pCfg);
     1067        Display *pDisplay = pConsole->mDisplay;
     1068        InsertConfigInteger(pCfg, "Object", (uintptr_t)pDisplay);
     1069
     1070
     1071        /*
     1072         * Firmware.
     1073         */
     1074        FirmwareType_T eFwType =  FirmwareType_BIOS;
     1075        hrc = pMachine->COMGETTER(FirmwareType)(&eFwType);                                  H();
     1076
     1077#ifdef VBOX_WITH_EFI
     1078        BOOL fEfiEnabled = (eFwType >= FirmwareType_EFI) && (eFwType <= FirmwareType_EFIDUAL);
     1079#else
     1080        BOOL fEfiEnabled = false;
    5381081#endif
    539 
    540         /** @todo Not exactly pretty to check strings; VBOXOSTYPE would be better, but that requires quite a bit of API change in Main. */
    541         if (    !fIs64BitGuest
    542             &&  fIOAPIC
    543             &&  (   osTypeId == "WindowsNT4"
    544                  || osTypeId == "Windows2000"
    545                  || osTypeId == "WindowsXP"
    546                  || osTypeId == "Windows2003"))
     1082        if (!fEfiEnabled)
    5471083        {
    548             /* Only allow TPR patching for NT, Win2k, XP and Windows Server 2003. (32 bits mode)
    549              * We may want to consider adding more guest OSes (Solaris) later on.
     1084            /*
     1085             * PC Bios.
    5501086             */
    551             rc = CFGMR3InsertInteger(pHWVirtExt, "TPRPatchingEnabled", 1);              RC_CHECK();
     1087            InsertConfigNode(pDevices, "pcbios", &pDev);
     1088            InsertConfigNode(pDev,     "0", &pInst);
     1089            InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     1090            InsertConfigNode(pInst,    "Config", &pBiosCfg);
     1091            InsertConfigInteger(pBiosCfg, "RamSize",              cbRam);
     1092            InsertConfigInteger(pBiosCfg, "RamHoleSize",          cbRamHole);
     1093            InsertConfigInteger(pBiosCfg, "NumCPUs",              cCpus);
     1094            InsertConfigString(pBiosCfg,   "HardDiskDevice",       "piix3ide");
     1095            InsertConfigString(pBiosCfg,   "FloppyDevice",         "i82078");
     1096            InsertConfigInteger(pBiosCfg, "IOAPIC",               fIOAPIC);
     1097            InsertConfigInteger(pBiosCfg, "PXEDebug",             fPXEDebug);
     1098            InsertConfigBytes(pBiosCfg,    "UUID", &HardwareUuid,sizeof(HardwareUuid));
     1099            InsertConfigNode(pBiosCfg,   "NetBoot", &pNetBootCfg);
     1100
     1101            DeviceType_T bootDevice;
     1102            if (SchemaDefs::MaxBootPosition > 9)
     1103            {
     1104                AssertMsgFailed(("Too many boot devices %d\n",
     1105                                SchemaDefs::MaxBootPosition));
     1106                return VERR_INVALID_PARAMETER;
     1107            }
     1108
     1109            for (ULONG pos = 1; pos <= SchemaDefs::MaxBootPosition; ++pos)
     1110            {
     1111                hrc = pMachine->GetBootOrder(pos, &bootDevice);                             H();
     1112
     1113                char szParamName[] = "BootDeviceX";
     1114                szParamName[sizeof(szParamName) - 2] = ((char (pos - 1)) + '0');
     1115
     1116                const char *pszBootDevice;
     1117                switch (bootDevice)
     1118                {
     1119                    case DeviceType_Null:
     1120                        pszBootDevice = "NONE";
     1121                        break;
     1122                    case DeviceType_HardDisk:
     1123                        pszBootDevice = "IDE";
     1124                        break;
     1125                    case DeviceType_DVD:
     1126                        pszBootDevice = "DVD";
     1127                        break;
     1128                    case DeviceType_Floppy:
     1129                        pszBootDevice = "FLOPPY";
     1130                        break;
     1131                    case DeviceType_Network:
     1132                        pszBootDevice = "LAN";
     1133                        break;
     1134                    default:
     1135                        AssertMsgFailed(("Invalid bootDevice=%d\n", bootDevice));
     1136                        return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
     1137                                        N_("Invalid boot device '%d'"), bootDevice);
     1138                }
     1139                InsertConfigString(pBiosCfg, szParamName, pszBootDevice);
     1140            }
    5521141        }
    553     }
    554 
    555     /* HWVirtEx exclusive mode */
    556     BOOL fHWVirtExExclusive = true;
    557     hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Exclusive, &fHWVirtExExclusive); H();
    558     rc = CFGMR3InsertInteger(pHWVirtExt, "Exclusive", fHWVirtExExclusive);              RC_CHECK();
    559 
    560     /* Nested paging (VT-x/AMD-V) */
    561     BOOL fEnableNestedPaging = false;
    562     hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &fEnableNestedPaging); H();
    563     rc = CFGMR3InsertInteger(pHWVirtExt, "EnableNestedPaging", fEnableNestedPaging);    RC_CHECK();
    564 
    565     /* Large pages; requires nested paging */
    566     BOOL fEnableLargePages = false;
    567     hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &fEnableLargePages); H();
    568     rc = CFGMR3InsertInteger(pHWVirtExt, "EnableLargePages", fEnableLargePages);        RC_CHECK();
    569 
    570     /* VPID (VT-x) */
    571     BOOL fEnableVPID = false;
    572     hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_VPID, &fEnableVPID);       H();
    573     rc = CFGMR3InsertInteger(pHWVirtExt, "EnableVPID", fEnableVPID);                    RC_CHECK();
    574 
    575     /* Physical Address Extension (PAE) */
    576     BOOL fEnablePAE = false;
    577     hrc = pMachine->GetCPUProperty(CPUPropertyType_PAE, &fEnablePAE);                   H();
    578     rc = CFGMR3InsertInteger(pRoot, "EnablePAE", fEnablePAE);                           RC_CHECK();
    579 
    580     /* Synthetic CPU */
    581     BOOL fSyntheticCpu = false;
    582     hrc = pMachine->GetCPUProperty(CPUPropertyType_Synthetic, &fSyntheticCpu);          H();
    583     rc = CFGMR3InsertInteger(pRoot, "SyntheticCpu", fSyntheticCpu);                     RC_CHECK();
    584 
    585     BOOL fPXEDebug;
    586     hrc = biosSettings->COMGETTER(PXEDebugEnabled)(&fPXEDebug);                         H();
    587 
    588     /*
    589      * PDM config.
    590      *  Load drivers in VBoxC.[so|dll]
    591      */
    592     PCFGMNODE pPDM;
    593     PCFGMNODE pDrivers;
    594     PCFGMNODE pMod;
    595     rc = CFGMR3InsertNode(pRoot,    "PDM", &pPDM);                                      RC_CHECK();
    596     rc = CFGMR3InsertNode(pPDM,     "Drivers", &pDrivers);                              RC_CHECK();
    597     rc = CFGMR3InsertNode(pDrivers, "VBoxC", &pMod);                                    RC_CHECK();
    598 #ifdef VBOX_WITH_XPCOM
    599     // VBoxC is located in the components subdirectory
    600     char szPathVBoxC[RTPATH_MAX];
    601     rc = RTPathAppPrivateArch(szPathVBoxC, RTPATH_MAX - sizeof("/components/VBoxC"));   AssertRC(rc);
    602     strcat(szPathVBoxC, "/components/VBoxC");
    603     rc = CFGMR3InsertString(pMod,   "Path",  szPathVBoxC);                              RC_CHECK();
    604 #else
    605     rc = CFGMR3InsertString(pMod,   "Path",  "VBoxC");                                  RC_CHECK();
    606 #endif
    607 
    608     /*
    609      * I/O settings (cach, max bandwidth, ...).
    610      */
    611     PCFGMNODE pPDMAc;
    612     PCFGMNODE pPDMAcFile;
    613     rc = CFGMR3InsertNode(pPDM, "AsyncCompletion", &pPDMAc);                            RC_CHECK();
    614     rc = CFGMR3InsertNode(pPDMAc, "File", &pPDMAcFile);                                 RC_CHECK();
    615 
    616     /* Builtin I/O cache */
    617     BOOL fIoCache = true;
    618     hrc = pMachine->COMGETTER(IoCacheEnabled)(&fIoCache);                               H();
    619     rc = CFGMR3InsertInteger(pPDMAcFile, "CacheEnabled", fIoCache);                     RC_CHECK();
    620 
    621     /* I/O cache size */
    622     ULONG ioCacheSize = 5;
    623     hrc = pMachine->COMGETTER(IoCacheSize)(&ioCacheSize);                               H();
    624     rc = CFGMR3InsertInteger(pPDMAcFile, "CacheSize", ioCacheSize * _1M);               RC_CHECK();
    625 
    626     /* Maximum I/O bandwidth */
    627     ULONG ioBandwidthMax = 0;
    628     hrc = pMachine->COMGETTER(IoBandwidthMax)(&ioBandwidthMax);                         H();
    629     if (ioBandwidthMax != 0)
    630     {
    631         rc = CFGMR3InsertInteger(pPDMAcFile, "VMTransferPerSecMax", ioBandwidthMax * _1M); RC_CHECK();
    632     }
    633 
    634     /*
    635      * Devices
    636      */
    637     PCFGMNODE pDevices = NULL;      /* /Devices */
    638     PCFGMNODE pDev = NULL;          /* /Devices/Dev/ */
    639     PCFGMNODE pInst = NULL;         /* /Devices/Dev/0/ */
    640     PCFGMNODE pCfg = NULL;          /* /Devices/Dev/.../Config/ */
    641     PCFGMNODE pLunL0 = NULL;        /* /Devices/Dev/0/LUN#0/ */
    642     PCFGMNODE pLunL1 = NULL;        /* /Devices/Dev/0/LUN#0/AttachedDriver/ */
    643     PCFGMNODE pLunL2 = NULL;        /* /Devices/Dev/0/LUN#0/AttachedDriver/Config/ */
    644     PCFGMNODE pBiosCfg = NULL;      /* /Devices/pcbios/0/Config/ */
    645     PCFGMNODE pNetBootCfg = NULL;   /* /Devices/pcbios/0/Config/NetBoot/ */
    646 
    647     rc = CFGMR3InsertNode(pRoot, "Devices", &pDevices);                                 RC_CHECK();
    648 
    649     /*
    650      * PC Arch.
    651      */
    652     rc = CFGMR3InsertNode(pDevices, "pcarch", &pDev);                                   RC_CHECK();
    653     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    654     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    655     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    656 
    657     /*
    658      * The time offset
    659      */
    660     LONG64 timeOffset;
    661     hrc = biosSettings->COMGETTER(TimeOffset)(&timeOffset);                             H();
    662     PCFGMNODE pTMNode;
    663     rc = CFGMR3InsertNode(pRoot, "TM", &pTMNode);                                       RC_CHECK();
    664     rc = CFGMR3InsertInteger(pTMNode, "UTCOffset", timeOffset * 1000000);               RC_CHECK();
    665 
    666     /*
    667      * DMA
    668      */
    669     rc = CFGMR3InsertNode(pDevices, "8237A", &pDev);                                    RC_CHECK();
    670     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    671     rc = CFGMR3InsertInteger(pInst, "Trusted", 1);                  /* boolean */       RC_CHECK();
    672 
    673     /*
    674      * PCI buses.
    675      */
    676     rc = CFGMR3InsertNode(pDevices, "pci", &pDev); /* piix3 */                          RC_CHECK();
    677     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    678     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    679     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    680     rc = CFGMR3InsertInteger(pCfg,  "IOAPIC", fIOAPIC);                                 RC_CHECK();
    681 
    682 #if 0 /* enable this to test PCI bridging */
    683     rc = CFGMR3InsertNode(pDevices, "pcibridge", &pDev);                                RC_CHECK();
    684     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    685     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    686     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    687     rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",         14);                         RC_CHECK();
    688     rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);                         RC_CHECK();
    689     rc = CFGMR3InsertInteger(pInst, "PCIBusNo",             0);/* -> pci[0] */          RC_CHECK();
    690 
    691     rc = CFGMR3InsertNode(pDev,     "1", &pInst);                                       RC_CHECK();
    692     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    693     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    694     rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",          1);                         RC_CHECK();
    695     rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);                         RC_CHECK();
    696     rc = CFGMR3InsertInteger(pInst, "PCIBusNo",             1);/* ->pcibridge[0] */     RC_CHECK();
    697 
    698     rc = CFGMR3InsertNode(pDev,     "2", &pInst);                                       RC_CHECK();
    699     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    700     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    701     rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",          3);                         RC_CHECK();
    702     rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);                         RC_CHECK();
    703     rc = CFGMR3InsertInteger(pInst, "PCIBusNo",             1);/* ->pcibridge[0] */     RC_CHECK();
    704 #endif
    705 
    706     /*
    707      * Enable 3 following devices: HPET, SMC, LPC on MacOS X guests
    708      */
    709     /*
    710      * High Precision Event Timer (HPET)
    711      */
    712     BOOL fHpetEnabled;
    713 #ifdef VBOX_WITH_HPET
    714     /* Other guests may wish to use HPET too, but MacOS X not functional without it */
    715     hrc = pMachine->COMGETTER(HpetEnabled)(&fHpetEnabled);                              H();
    716     /* so always enable HPET in extended profile */
    717     fHpetEnabled |= fOsXGuest;
    718 #else
    719     fHpetEnabled = false;
    720 #endif
    721     if (fHpetEnabled)
    722     {
    723         rc = CFGMR3InsertNode(pDevices, "hpet", &pDev);                                 RC_CHECK();
    724         rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                   RC_CHECK();
    725         rc = CFGMR3InsertInteger(pInst, "Trusted",   1);     /* boolean */              RC_CHECK();
    726     }
    727 
    728     /*
    729      * System Management Controller (SMC)
    730      */
    731     BOOL fSmcEnabled;
    732 #ifdef VBOX_WITH_SMC
    733     fSmcEnabled = fOsXGuest;
    734 #else
    735     fSmcEnabled = false;
    736 #endif
    737     if (fSmcEnabled)
    738     {
    739         rc = CFGMR3InsertNode(pDevices, "smc", &pDev);                                  RC_CHECK();
    740         rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                   RC_CHECK();
    741         rc = CFGMR3InsertInteger(pInst, "Trusted",   1);     /* boolean */              RC_CHECK();
    742         rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                               RC_CHECK();
    743         bool fGetKeyFromRealSMC;
    744         Bstr bstrKey;
    745         rc = getSmcDeviceKey(pMachine, bstrKey.asOutParam(), &fGetKeyFromRealSMC);      RC_CHECK();
    746         rc = CFGMR3InsertString(pCfg,   "DeviceKey", Utf8Str(bstrKey).raw());           RC_CHECK();
    747         rc = CFGMR3InsertInteger(pCfg,  "GetKeyFromRealSMC", fGetKeyFromRealSMC);       RC_CHECK();
    748     }
    749 
    750     /*
    751      * Low Pin Count (LPC) bus
    752      */
    753     BOOL fLpcEnabled;
    754     /** @todo: implement appropriate getter */
    755 #ifdef VBOX_WITH_LPC
    756     fLpcEnabled = fOsXGuest;
    757 #else
    758     fLpcEnabled = false;
    759 #endif
    760     if (fLpcEnabled)
    761     {
    762         rc = CFGMR3InsertNode(pDevices, "lpc", &pDev);                                  RC_CHECK();
    763         rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                   RC_CHECK();
    764         rc = CFGMR3InsertInteger(pInst, "Trusted",   1);     /* boolean */              RC_CHECK();
    765     }
    766 
    767     /*
    768      * PS/2 keyboard & mouse.
    769      */
    770     rc = CFGMR3InsertNode(pDevices, "pckbd", &pDev);                                    RC_CHECK();
    771     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    772     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    773     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    774 
    775     rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                                  RC_CHECK();
    776     rc = CFGMR3InsertString(pLunL0, "Driver",               "KeyboardQueue");           RC_CHECK();
    777     rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                                   RC_CHECK();
    778     rc = CFGMR3InsertInteger(pCfg,  "QueueSize",            64);                        RC_CHECK();
    779 
    780     rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL1);                         RC_CHECK();
    781     rc = CFGMR3InsertString(pLunL1, "Driver",               "MainKeyboard");            RC_CHECK();
    782     rc = CFGMR3InsertNode(pLunL1,   "Config", &pCfg);                                   RC_CHECK();
    783     Keyboard *pKeyboard = pConsole->mKeyboard;
    784     rc = CFGMR3InsertInteger(pCfg,  "Object",     (uintptr_t)pKeyboard);                RC_CHECK();
    785 
    786     rc = CFGMR3InsertNode(pInst,    "LUN#1", &pLunL0);                                  RC_CHECK();
    787     rc = CFGMR3InsertString(pLunL0, "Driver",               "MouseQueue");              RC_CHECK();
    788     rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                                   RC_CHECK();
    789     rc = CFGMR3InsertInteger(pCfg,  "QueueSize",            128);                       RC_CHECK();
    790 
    791     rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL1);                         RC_CHECK();
    792     rc = CFGMR3InsertString(pLunL1, "Driver",               "MainMouse");               RC_CHECK();
    793     rc = CFGMR3InsertNode(pLunL1,   "Config", &pCfg);                                   RC_CHECK();
    794     Mouse *pMouse = pConsole->mMouse;
    795     rc = CFGMR3InsertInteger(pCfg,  "Object",     (uintptr_t)pMouse);                   RC_CHECK();
    796 
    797     /*
    798      * i8254 Programmable Interval Timer And Dummy Speaker
    799      */
    800     rc = CFGMR3InsertNode(pDevices, "i8254", &pDev);                                    RC_CHECK();
    801     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    802     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    803 #ifdef DEBUG
    804     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    805 #endif
    806 
    807     /*
    808      * i8259 Programmable Interrupt Controller.
    809      */
    810     rc = CFGMR3InsertNode(pDevices, "i8259", &pDev);                                    RC_CHECK();
    811     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    812     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    813     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    814 
    815     /*
    816      * Advanced Programmable Interrupt Controller.
    817      * SMP: Each CPU has a LAPIC, but we have a single device representing all LAPICs states,
    818      *      thus only single insert
    819      */
    820     rc = CFGMR3InsertNode(pDevices, "apic", &pDev);                                     RC_CHECK();
    821     rc = CFGMR3InsertNode(pDev, "0", &pInst);                                           RC_CHECK();
    822     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    823     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    824     rc = CFGMR3InsertInteger(pCfg,  "IOAPIC", fIOAPIC);                                 RC_CHECK();
    825     rc = CFGMR3InsertInteger(pCfg,  "NumCPUs", cCpus);                                  RC_CHECK();
    826 
    827     if (fIOAPIC)
    828     {
    829         /*
    830          * I/O Advanced Programmable Interrupt Controller.
    831          */
    832         rc = CFGMR3InsertNode(pDevices, "ioapic", &pDev);                               RC_CHECK();
    833         rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                   RC_CHECK();
    834         rc = CFGMR3InsertInteger(pInst, "Trusted",          1);     /* boolean */       RC_CHECK();
    835         rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                               RC_CHECK();
    836     }
    837 
    838     /*
    839      * RTC MC146818.
    840      */
    841     rc = CFGMR3InsertNode(pDevices, "mc146818", &pDev);                                 RC_CHECK();
    842     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    843     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    844     BOOL fRTCUseUTC;
    845     hrc = pMachine->COMGETTER(RTCUseUTC)(&fRTCUseUTC);                                  H();
    846     rc = CFGMR3InsertInteger(pCfg,  "UseUTC", fRTCUseUTC ? 1 : 0);                      RC_CHECK();
    847 
    848     /*
    849      * VGA.
    850      */
    851     rc = CFGMR3InsertNode(pDevices, "vga", &pDev);                                      RC_CHECK();
    852     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    853     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    854     rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",          2);                         RC_CHECK();
    855     Assert(!afPciDeviceNo[2]);
    856     afPciDeviceNo[2] = true;
    857     rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);                         RC_CHECK();
    858     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    859     ULONG cVRamMBs;
    860     hrc = pMachine->COMGETTER(VRAMSize)(&cVRamMBs);                                     H();
    861     rc = CFGMR3InsertInteger(pCfg,  "VRamSize",             cVRamMBs * _1M);            RC_CHECK();
    862     ULONG cMonitorCount;
    863     hrc = pMachine->COMGETTER(MonitorCount)(&cMonitorCount);                            H();
    864     rc = CFGMR3InsertInteger(pCfg,  "MonitorCount",         cMonitorCount);             RC_CHECK();
    865 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
    866     rc = CFGMR3InsertInteger(pCfg,  "R0Enabled",            fHWVirtExEnabled);          RC_CHECK();
    867 #endif
    868 
    869     /*
    870      * BIOS logo
    871      */
    872     BOOL fFadeIn;
    873     hrc = biosSettings->COMGETTER(LogoFadeIn)(&fFadeIn);                                H();
    874     rc = CFGMR3InsertInteger(pCfg,  "FadeIn",  fFadeIn ? 1 : 0);                        RC_CHECK();
    875     BOOL fFadeOut;
    876     hrc = biosSettings->COMGETTER(LogoFadeOut)(&fFadeOut);                              H();
    877     rc = CFGMR3InsertInteger(pCfg,  "FadeOut", fFadeOut ? 1: 0);                        RC_CHECK();
    878     ULONG logoDisplayTime;
    879     hrc = biosSettings->COMGETTER(LogoDisplayTime)(&logoDisplayTime);                   H();
    880     rc = CFGMR3InsertInteger(pCfg,  "LogoTime", logoDisplayTime);                       RC_CHECK();
    881     Bstr logoImagePath;
    882     hrc = biosSettings->COMGETTER(LogoImagePath)(logoImagePath.asOutParam());           H();
    883     rc = CFGMR3InsertString(pCfg,   "LogoFile", logoImagePath ? Utf8Str(logoImagePath).c_str() : ""); RC_CHECK();
    884 
    885     /*
    886      * Boot menu
    887      */
    888     BIOSBootMenuMode_T eBootMenuMode;
    889     int iShowBootMenu;
    890     biosSettings->COMGETTER(BootMenuMode)(&eBootMenuMode);
    891     switch (eBootMenuMode)
    892     {
    893         case BIOSBootMenuMode_Disabled: iShowBootMenu = 0;  break;
    894         case BIOSBootMenuMode_MenuOnly: iShowBootMenu = 1;  break;
    895         default:                        iShowBootMenu = 2;  break;
    896     }
    897     rc = CFGMR3InsertInteger(pCfg, "ShowBootMenu", iShowBootMenu);                      RC_CHECK();
    898 
    899     /* Custom VESA mode list */
    900     unsigned cModes = 0;
    901     for (unsigned iMode = 1; iMode <= 16; ++iMode)
    902     {
    903         char szExtraDataKey[sizeof("CustomVideoModeXX")];
    904         RTStrPrintf(szExtraDataKey, sizeof(szExtraDataKey), "CustomVideoMode%u", iMode);
    905         hrc = pMachine->GetExtraData(Bstr(szExtraDataKey), bstr.asOutParam());          H();
    906         if (bstr.isEmpty())
    907             break;
    908         rc = CFGMR3InsertStringW(pCfg, szExtraDataKey, bstr.raw());                     RC_CHECK();
    909         ++cModes;
    910     }
    911     rc = CFGMR3InsertInteger(pCfg,  "CustomVideoModes", cModes);                        RC_CHECK();
    912 
    913     /* VESA height reduction */
    914     ULONG ulHeightReduction;
    915     IFramebuffer *pFramebuffer = pConsole->getDisplay()->getFramebuffer();
    916     if (pFramebuffer)
    917     {
    918         hrc = pFramebuffer->COMGETTER(HeightReduction)(&ulHeightReduction);             H();
    919     }
    920     else
    921     {
    922         /* If framebuffer is not available, there is no height reduction. */
    923         ulHeightReduction = 0;
    924     }
    925     rc = CFGMR3InsertInteger(pCfg,  "HeightReduction", ulHeightReduction);              RC_CHECK();
    926 
    927     /* Attach the display. */
    928     rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                                  RC_CHECK();
    929     rc = CFGMR3InsertString(pLunL0, "Driver",               "MainDisplay");             RC_CHECK();
    930     rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                                   RC_CHECK();
    931     Display *pDisplay = pConsole->mDisplay;
    932     rc = CFGMR3InsertInteger(pCfg,  "Object", (uintptr_t)pDisplay);                     RC_CHECK();
    933 
    934 
    935     /*
    936      * Firmware.
    937      */
    938     FirmwareType_T eFwType =  FirmwareType_BIOS;
    939     hrc = pMachine->COMGETTER(FirmwareType)(&eFwType);                                  H();
    940 
    941 #ifdef VBOX_WITH_EFI
    942     BOOL fEfiEnabled = (eFwType >= FirmwareType_EFI) && (eFwType <= FirmwareType_EFIDUAL);
    943 #else
    944     BOOL fEfiEnabled = false;
    945 #endif
    946     if (!fEfiEnabled)
    947     {
    948         /*
    949          * PC Bios.
    950          */
    951         rc = CFGMR3InsertNode(pDevices, "pcbios", &pDev);                               RC_CHECK();
    952         rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                   RC_CHECK();
    953         rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */   RC_CHECK();
    954         rc = CFGMR3InsertNode(pInst,    "Config", &pBiosCfg);                           RC_CHECK();
    955         rc = CFGMR3InsertInteger(pBiosCfg,  "RamSize",              cbRam);             RC_CHECK();
    956         rc = CFGMR3InsertInteger(pBiosCfg,  "RamHoleSize",          cbRamHole);         RC_CHECK();
    957         rc = CFGMR3InsertInteger(pBiosCfg,  "NumCPUs",              cCpus);             RC_CHECK();
    958         rc = CFGMR3InsertString(pBiosCfg,   "HardDiskDevice",       "piix3ide");        RC_CHECK();
    959         rc = CFGMR3InsertString(pBiosCfg,   "FloppyDevice",         "i82078");          RC_CHECK();
    960         rc = CFGMR3InsertInteger(pBiosCfg,  "IOAPIC",               fIOAPIC);           RC_CHECK();
    961         rc = CFGMR3InsertInteger(pBiosCfg,  "PXEDebug",             fPXEDebug);         RC_CHECK();
    962         rc = CFGMR3InsertBytes(pBiosCfg,    "UUID", &HardwareUuid,sizeof(HardwareUuid));RC_CHECK();
    963         rc = CFGMR3InsertNode(pBiosCfg,   "NetBoot", &pNetBootCfg);                     RC_CHECK();
    964 
    965         DeviceType_T bootDevice;
    966         if (SchemaDefs::MaxBootPosition > 9)
     1142        else
    9671143        {
    968             AssertMsgFailed(("Too many boot devices %d\n",
    969                              SchemaDefs::MaxBootPosition));
    970             return VERR_INVALID_PARAMETER;
     1144            Utf8Str efiRomFile;
     1145
     1146            /* Autodetect firmware type, basing on guest type */
     1147            if (eFwType == FirmwareType_EFI)
     1148            {
     1149                eFwType =
     1150                        fIs64BitGuest ?
     1151                        (FirmwareType_T)FirmwareType_EFI64
     1152                        :
     1153                        (FirmwareType_T)FirmwareType_EFI32;
     1154            }
     1155            bool f64BitEntry = eFwType == FirmwareType_EFI64;
     1156
     1157            rc = findEfiRom(virtualBox, eFwType, efiRomFile);
     1158            AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc);
     1159
     1160            /* Get boot args */
     1161            Bstr bootArgs;
     1162            hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiBootArgs"), bootArgs.asOutParam()); H();
     1163
     1164            /* Get device props */
     1165            Bstr deviceProps;
     1166            hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiDeviceProps"), deviceProps.asOutParam()); H();
     1167            /* Get GOP mode settings */
     1168            uint32_t u32GopMode = UINT32_MAX;
     1169            hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiGopMode"), bstr.asOutParam()); H();
     1170            if (!bstr.isEmpty())
     1171                u32GopMode = Utf8Str(bstr).toUInt32();
     1172
     1173            /* UGA mode settings */
     1174            uint32_t u32UgaHorisontal = 0;
     1175            hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiUgaHorizontalResolution"), bstr.asOutParam()); H();
     1176            if (!bstr.isEmpty())
     1177                u32UgaHorisontal = Utf8Str(bstr).toUInt32();
     1178
     1179            uint32_t u32UgaVertical = 0;
     1180            hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiUgaVerticalResolution"), bstr.asOutParam()); H();
     1181            if (!bstr.isEmpty())
     1182                u32UgaVertical = Utf8Str(bstr).toUInt32();
     1183
     1184            /*
     1185             * EFI subtree.
     1186             */
     1187            InsertConfigNode(pDevices, "efi", &pDev);
     1188            InsertConfigNode(pDev,     "0", &pInst);
     1189            InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
     1190            InsertConfigNode(pInst,    "Config", &pCfg);
     1191            InsertConfigInteger(pCfg, "RamSize",          cbRam);
     1192            InsertConfigInteger(pCfg, "RamHoleSize",      cbRamHole);
     1193            InsertConfigInteger(pCfg, "NumCPUs",          cCpus);
     1194            InsertConfigString(pCfg,   "EfiRom",           efiRomFile.raw());
     1195            InsertConfigString(pCfg,   "BootArgs",         Utf8Str(bootArgs).raw());
     1196            InsertConfigString(pCfg,   "DeviceProps",      Utf8Str(deviceProps).raw());
     1197            InsertConfigInteger(pCfg, "IOAPIC",           fIOAPIC);
     1198            InsertConfigBytes(pCfg,    "UUID", &HardwareUuid,sizeof(HardwareUuid));
     1199            InsertConfigInteger(pCfg, "64BitEntry", f64BitEntry); /* boolean */
     1200            InsertConfigInteger(pCfg, "GopMode", u32GopMode);
     1201            InsertConfigInteger(pCfg, "UgaHorizontalResolution", u32UgaHorisontal);
     1202            InsertConfigInteger(pCfg, "UgaVerticalResolution", u32UgaVertical);
     1203
     1204            /* For OS X guests we'll force passing host's DMI info to the guest */
     1205            if (fOsXGuest)
     1206            {
     1207                InsertConfigInteger(pCfg, "DmiUseHostInfo", 1);
     1208                InsertConfigInteger(pCfg, "DmiExposeMemoryTable", 1);
     1209            }
    9711210        }
    9721211
    973         for (ULONG pos = 1; pos <= SchemaDefs::MaxBootPosition; ++pos)
     1212        /*
     1213         * Storage controllers.
     1214         */
     1215        com::SafeIfaceArray<IStorageController> ctrls;
     1216        PCFGMNODE aCtrlNodes[StorageControllerType_LsiLogicSas + 1] = {};
     1217        hrc = pMachine->COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(ctrls));       H();
     1218
     1219        for (size_t i = 0; i < ctrls.size(); ++i)
    9741220        {
    975             hrc = pMachine->GetBootOrder(pos, &bootDevice);                             H();
    976 
    977             char szParamName[] = "BootDeviceX";
    978             szParamName[sizeof(szParamName) - 2] = ((char (pos - 1)) + '0');
    979 
    980             const char *pszBootDevice;
    981             switch (bootDevice)
    982             {
    983                 case DeviceType_Null:
    984                     pszBootDevice = "NONE";
     1221            DeviceType_T *paLedDevType = NULL;
     1222
     1223            StorageControllerType_T enmCtrlType;
     1224            rc = ctrls[i]->COMGETTER(ControllerType)(&enmCtrlType);                         H();
     1225            AssertRelease((unsigned)enmCtrlType < RT_ELEMENTS(aCtrlNodes));
     1226
     1227            StorageBus_T enmBus;
     1228            rc = ctrls[i]->COMGETTER(Bus)(&enmBus);                                         H();
     1229
     1230            Bstr controllerName;
     1231            rc = ctrls[i]->COMGETTER(Name)(controllerName.asOutParam());                    H();
     1232
     1233            ULONG ulInstance = 999;
     1234            rc = ctrls[i]->COMGETTER(Instance)(&ulInstance);                                H();
     1235
     1236            BOOL fUseHostIOCache;
     1237            rc = ctrls[i]->COMGETTER(UseHostIOCache)(&fUseHostIOCache);                     H();
     1238
     1239            /* /Devices/<ctrldev>/ */
     1240            const char *pszCtrlDev = pConsole->convertControllerTypeToDev(enmCtrlType);
     1241            pDev = aCtrlNodes[enmCtrlType];
     1242            if (!pDev)
     1243            {
     1244                InsertConfigNode(pDevices, pszCtrlDev, &pDev);
     1245                aCtrlNodes[enmCtrlType] = pDev; /* IDE variants are handled in the switch */
     1246            }
     1247
     1248            /* /Devices/<ctrldev>/<instance>/ */
     1249            PCFGMNODE pCtlInst = NULL;
     1250            InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pCtlInst);
     1251
     1252            /* Device config: /Devices/<ctrldev>/<instance>/<values> & /ditto/Config/<values> */
     1253            InsertConfigInteger(pCtlInst, "Trusted",   1);
     1254            InsertConfigNode(pCtlInst,    "Config",    &pCfg);
     1255
     1256            switch (enmCtrlType)
     1257            {
     1258                case StorageControllerType_LsiLogic:
     1259                {
     1260                    InsertConfigInteger(pCtlInst, "PCIDeviceNo",          20);
     1261                    Assert(!afPciDeviceNo[20]);
     1262                    afPciDeviceNo[20] = true;
     1263                    InsertConfigInteger(pCtlInst, "PCIFunctionNo",        0);
     1264
     1265                    /* Attach the status driver */
     1266                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
     1267                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1268                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     1269                    InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedScsi]);
     1270                    InsertConfigInteger(pCfg, "First",    0);
     1271                    Assert(cLedScsi >= 16);
     1272                    InsertConfigInteger(pCfg, "Last",     15);
     1273                    paLedDevType = &pConsole->maStorageDevType[iLedScsi];
    9851274                    break;
    986                 case DeviceType_HardDisk:
    987                     pszBootDevice = "IDE";
     1275                }
     1276
     1277                case StorageControllerType_BusLogic:
     1278                {
     1279                    InsertConfigInteger(pCtlInst, "PCIDeviceNo",          21);
     1280                    Assert(!afPciDeviceNo[21]);
     1281                    afPciDeviceNo[21] = true;
     1282                    InsertConfigInteger(pCtlInst, "PCIFunctionNo",        0);
     1283
     1284                    /* Attach the status driver */
     1285                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
     1286                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1287                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     1288                    InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedScsi]);
     1289                    InsertConfigInteger(pCfg, "First",    0);
     1290                    Assert(cLedScsi >= 16);
     1291                    InsertConfigInteger(pCfg, "Last",     15);
     1292                    paLedDevType = &pConsole->maStorageDevType[iLedScsi];
    9881293                    break;
    989                 case DeviceType_DVD:
    990                     pszBootDevice = "DVD";
    991                     break;
    992                 case DeviceType_Floppy:
    993                     pszBootDevice = "FLOPPY";
    994                     break;
    995                 case DeviceType_Network:
    996                     pszBootDevice = "LAN";
    997                     break;
    998                 default:
    999                     AssertMsgFailed(("Invalid bootDevice=%d\n", bootDevice));
    1000                     return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
    1001                                       N_("Invalid boot device '%d'"), bootDevice);
    1002             }
    1003             rc = CFGMR3InsertString(pBiosCfg, szParamName, pszBootDevice);              RC_CHECK();
    1004         }
    1005     }
    1006     else
    1007     {
    1008         Utf8Str efiRomFile;
    1009 
    1010         /* Autodetect firmware type, basing on guest type */
    1011         if (eFwType == FirmwareType_EFI)
    1012         {
    1013             eFwType =
    1014                     fIs64BitGuest ?
    1015                     (FirmwareType_T)FirmwareType_EFI64
    1016                     :
    1017                     (FirmwareType_T)FirmwareType_EFI32;
    1018         }
    1019         bool f64BitEntry = eFwType == FirmwareType_EFI64;
    1020 
    1021         rc = findEfiRom(virtualBox, eFwType, efiRomFile);                                                                                                                          RC_CHECK();
    1022 
    1023         /* Get boot args */
    1024         Bstr bootArgs;
    1025         hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiBootArgs"), bootArgs.asOutParam()); H();
    1026 
    1027         /* Get device props */
    1028         Bstr deviceProps;
    1029         hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiDeviceProps"), deviceProps.asOutParam()); H();
    1030         /* Get GOP mode settings */
    1031         uint32_t u32GopMode = UINT32_MAX;
    1032         hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiGopMode"), bstr.asOutParam()); H();
    1033         if (!bstr.isEmpty())
    1034             u32GopMode = Utf8Str(bstr).toUInt32();
    1035 
    1036         /* UGA mode settings */
    1037         uint32_t u32UgaHorisontal = 0;
    1038         hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiUgaHorizontalResolution"), bstr.asOutParam()); H();
    1039         if (!bstr.isEmpty())
    1040             u32UgaHorisontal = Utf8Str(bstr).toUInt32();
    1041 
    1042         uint32_t u32UgaVertical = 0;
    1043         hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiUgaVerticalResolution"), bstr.asOutParam()); H();
    1044         if (!bstr.isEmpty())
    1045             u32UgaVertical = Utf8Str(bstr).toUInt32();
    1046 
    1047         /*
    1048          * EFI subtree.
    1049          */
    1050         rc = CFGMR3InsertNode(pDevices, "efi", &pDev);                                  RC_CHECK();
    1051         rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                   RC_CHECK();
    1052         rc = CFGMR3InsertInteger(pInst, "Trusted", 1);              /* boolean */       RC_CHECK();
    1053         rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                               RC_CHECK();
    1054         rc = CFGMR3InsertInteger(pCfg,  "RamSize",          cbRam);                     RC_CHECK();
    1055         rc = CFGMR3InsertInteger(pCfg,  "RamHoleSize",      cbRamHole);                 RC_CHECK();
    1056         rc = CFGMR3InsertInteger(pCfg,  "NumCPUs",          cCpus);                     RC_CHECK();
    1057         rc = CFGMR3InsertString(pCfg,   "EfiRom",           efiRomFile.raw());          RC_CHECK();
    1058         rc = CFGMR3InsertString(pCfg,   "BootArgs",         Utf8Str(bootArgs).raw());   RC_CHECK();
    1059         rc = CFGMR3InsertString(pCfg,   "DeviceProps",      Utf8Str(deviceProps).raw());RC_CHECK();
    1060         rc = CFGMR3InsertInteger(pCfg,  "IOAPIC",           fIOAPIC);                   RC_CHECK();
    1061         rc = CFGMR3InsertBytes(pCfg,    "UUID", &HardwareUuid,sizeof(HardwareUuid));    RC_CHECK();
    1062         rc = CFGMR3InsertInteger(pCfg,  "64BitEntry", f64BitEntry); /* boolean */       RC_CHECK();
    1063         rc = CFGMR3InsertInteger(pCfg,  "GopMode", u32GopMode);                         RC_CHECK();
    1064         rc = CFGMR3InsertInteger(pCfg,  "UgaHorizontalResolution", u32UgaHorisontal);   RC_CHECK();
    1065         rc = CFGMR3InsertInteger(pCfg,  "UgaVerticalResolution", u32UgaVertical);       RC_CHECK();
    1066 
    1067         /* For OS X guests we'll force passing host's DMI info to the guest */
    1068         if (fOsXGuest)
    1069         {
    1070             rc = CFGMR3InsertInteger(pCfg,  "DmiUseHostInfo", 1);                       RC_CHECK();
    1071             rc = CFGMR3InsertInteger(pCfg,  "DmiExposeMemoryTable", 1);                 RC_CHECK();
    1072         }
    1073     }
    1074 
    1075     /*
    1076      * Storage controllers.
    1077      */
    1078     com::SafeIfaceArray<IStorageController> ctrls;
    1079     PCFGMNODE aCtrlNodes[StorageControllerType_LsiLogicSas + 1] = {};
    1080     hrc = pMachine->COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(ctrls));       H();
    1081 
    1082     for (size_t i = 0; i < ctrls.size(); ++i)
    1083     {
    1084         DeviceType_T *paLedDevType = NULL;
    1085 
    1086         StorageControllerType_T enmCtrlType;
    1087         rc = ctrls[i]->COMGETTER(ControllerType)(&enmCtrlType);                         H();
    1088         AssertRelease((unsigned)enmCtrlType < RT_ELEMENTS(aCtrlNodes));
    1089 
    1090         StorageBus_T enmBus;
    1091         rc = ctrls[i]->COMGETTER(Bus)(&enmBus);                                         H();
    1092 
    1093         Bstr controllerName;
    1094         rc = ctrls[i]->COMGETTER(Name)(controllerName.asOutParam());                    H();
    1095 
    1096         ULONG ulInstance = 999;
    1097         rc = ctrls[i]->COMGETTER(Instance)(&ulInstance);                                H();
    1098 
    1099         BOOL fUseHostIOCache;
    1100         rc = ctrls[i]->COMGETTER(UseHostIOCache)(&fUseHostIOCache);                     H();
    1101 
    1102         /* /Devices/<ctrldev>/ */
    1103         const char *pszCtrlDev = pConsole->convertControllerTypeToDev(enmCtrlType);
    1104         pDev = aCtrlNodes[enmCtrlType];
    1105         if (!pDev)
    1106         {
    1107             rc = CFGMR3InsertNode(pDevices, pszCtrlDev, &pDev);                         RC_CHECK();
    1108             aCtrlNodes[enmCtrlType] = pDev; /* IDE variants are handled in the switch */
    1109         }
    1110 
    1111         /* /Devices/<ctrldev>/<instance>/ */
    1112         PCFGMNODE pCtlInst = NULL;
    1113         rc = CFGMR3InsertNodeF(pDev, &pCtlInst, "%u", ulInstance);                      RC_CHECK();
    1114 
    1115         /* Device config: /Devices/<ctrldev>/<instance>/<values> & /ditto/Config/<values> */
    1116         rc = CFGMR3InsertInteger(pCtlInst, "Trusted",   1);                             RC_CHECK();
    1117         rc = CFGMR3InsertNode(pCtlInst,    "Config",    &pCfg);                         RC_CHECK();
    1118 
    1119         switch (enmCtrlType)
    1120         {
    1121             case StorageControllerType_LsiLogic:
    1122             {
    1123                 rc = CFGMR3InsertInteger(pCtlInst, "PCIDeviceNo",          20);         RC_CHECK();
    1124                 Assert(!afPciDeviceNo[20]);
    1125                 afPciDeviceNo[20] = true;
    1126                 rc = CFGMR3InsertInteger(pCtlInst, "PCIFunctionNo",        0);          RC_CHECK();
    1127 
    1128                 /* Attach the status driver */
    1129                 rc = CFGMR3InsertNode(pCtlInst, "LUN#999", &pLunL0);                    RC_CHECK();
    1130                 rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");  RC_CHECK();
    1131                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1132                 rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedScsi]); RC_CHECK();
    1133                 rc = CFGMR3InsertInteger(pCfg,  "First",    0);                         RC_CHECK();
    1134                 Assert(cLedScsi >= 16);
    1135                 rc = CFGMR3InsertInteger(pCfg,  "Last",     15);                        RC_CHECK();
    1136                 paLedDevType = &pConsole->maStorageDevType[iLedScsi];
    1137                 break;
    1138             }
    1139 
    1140             case StorageControllerType_BusLogic:
    1141             {
    1142                 rc = CFGMR3InsertInteger(pCtlInst, "PCIDeviceNo",          21);         RC_CHECK();
    1143                 Assert(!afPciDeviceNo[21]);
    1144                 afPciDeviceNo[21] = true;
    1145                 rc = CFGMR3InsertInteger(pCtlInst, "PCIFunctionNo",        0);          RC_CHECK();
    1146 
    1147                 /* Attach the status driver */
    1148                 rc = CFGMR3InsertNode(pCtlInst, "LUN#999", &pLunL0);                    RC_CHECK();
    1149                 rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");  RC_CHECK();
    1150                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1151                 rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedScsi]); RC_CHECK();
    1152                 rc = CFGMR3InsertInteger(pCfg,  "First",    0);                         RC_CHECK();
    1153                 Assert(cLedScsi >= 16);
    1154                 rc = CFGMR3InsertInteger(pCfg,  "Last",     15);                        RC_CHECK();
    1155                 paLedDevType = &pConsole->maStorageDevType[iLedScsi];
    1156                 break;
    1157             }
    1158 
    1159             case StorageControllerType_IntelAhci:
    1160             {
    1161                 rc = CFGMR3InsertInteger(pCtlInst, "PCIDeviceNo",          13);         RC_CHECK();
    1162                 Assert(!afPciDeviceNo[13]);
    1163                 afPciDeviceNo[13] = true;
    1164                 rc = CFGMR3InsertInteger(pCtlInst, "PCIFunctionNo",        0);          RC_CHECK();
    1165 
    1166                 ULONG cPorts = 0;
    1167                 hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts);                          H();
    1168                 rc = CFGMR3InsertInteger(pCfg, "PortCount", cPorts);                    RC_CHECK();
    1169 
    1170                 /* Needed configuration values for the bios. */
    1171                 if (pBiosCfg)
    1172                 {
    1173                     rc = CFGMR3InsertString(pBiosCfg, "SataHardDiskDevice", "ahci");    RC_CHECK();
    1174                 }
    1175 
    1176                 for (uint32_t j = 0; j < 4; ++j)
    1177                 {
    1178                     static const char * const s_apszConfig[4] =
    1179                     { "PrimaryMaster", "PrimarySlave", "SecondaryMaster", "SecondarySlave" };
    1180                     static const char * const s_apszBiosConfig[4] =
    1181                     { "SataPrimaryMasterLUN", "SataPrimarySlaveLUN", "SataSecondaryMasterLUN", "SataSecondarySlaveLUN" };
    1182 
    1183                     LONG lPortNumber = -1;
    1184                     hrc = ctrls[i]->GetIDEEmulationPort(j, &lPortNumber);               H();
    1185                     rc = CFGMR3InsertInteger(pCfg, s_apszConfig[j], lPortNumber);       RC_CHECK();
     1294                }
     1295
     1296                case StorageControllerType_IntelAhci:
     1297                {
     1298                    InsertConfigInteger(pCtlInst, "PCIDeviceNo",          13);
     1299                    Assert(!afPciDeviceNo[13]);
     1300                    afPciDeviceNo[13] = true;
     1301                    InsertConfigInteger(pCtlInst, "PCIFunctionNo",        0);
     1302
     1303                    ULONG cPorts = 0;
     1304                    hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts);                          H();
     1305                    InsertConfigInteger(pCfg, "PortCount", cPorts);
     1306
     1307                    /* Needed configuration values for the bios. */
    11861308                    if (pBiosCfg)
    11871309                    {
    1188                         rc = CFGMR3InsertInteger(pBiosCfg, s_apszBiosConfig[j], lPortNumber); RC_CHECK();
     1310                        InsertConfigString(pBiosCfg, "SataHardDiskDevice", "ahci");
    11891311                    }
    1190                 }
    1191 
    1192                 /* Attach the status driver */
    1193                 rc = CFGMR3InsertNode(pCtlInst, "LUN#999", &pLunL0);                    RC_CHECK();
    1194                 rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");  RC_CHECK();
    1195                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1196                 AssertRelease(cPorts <= cLedSata);
    1197                 rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedSata]); RC_CHECK();
    1198                 rc = CFGMR3InsertInteger(pCfg,  "First",    0);                         RC_CHECK();
    1199                 rc = CFGMR3InsertInteger(pCfg,  "Last",     cPorts - 1);                RC_CHECK();
    1200                 paLedDevType = &pConsole->maStorageDevType[iLedSata];
    1201                 break;
    1202             }
    1203 
    1204             case StorageControllerType_PIIX3:
    1205             case StorageControllerType_PIIX4:
    1206             case StorageControllerType_ICH6:
    1207             {
    1208                 /*
    1209                  * IDE (update this when the main interface changes)
    1210                  */
    1211                 rc = CFGMR3InsertInteger(pCtlInst, "PCIDeviceNo",          1);          RC_CHECK();
    1212                 Assert(!afPciDeviceNo[1]);
    1213                 afPciDeviceNo[1] = true;
    1214                 rc = CFGMR3InsertInteger(pCtlInst, "PCIFunctionNo",        1);          RC_CHECK();
    1215                 rc = CFGMR3InsertString(pCfg,  "Type", controllerString(enmCtrlType));  RC_CHECK();
    1216 
    1217                 /* Attach the status driver */
    1218                 rc = CFGMR3InsertNode(pCtlInst,    "LUN#999", &pLunL0);                 RC_CHECK();
    1219                 rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");  RC_CHECK();
    1220                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1221                 rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedIde]); RC_CHECK();
    1222                 rc = CFGMR3InsertInteger(pCfg,  "First",    0);                         RC_CHECK();
    1223                 Assert(cLedIde >= 4);
    1224                 rc = CFGMR3InsertInteger(pCfg,  "Last",     3);                         RC_CHECK();
    1225                 paLedDevType = &pConsole->maStorageDevType[iLedIde];
    1226 
    1227                 /* IDE flavors */
    1228                 aCtrlNodes[StorageControllerType_PIIX3] = pDev;
    1229                 aCtrlNodes[StorageControllerType_PIIX4] = pDev;
    1230                 aCtrlNodes[StorageControllerType_ICH6]  = pDev;
    1231                 break;
    1232             }
    1233 
    1234             case StorageControllerType_I82078:
    1235             {
    1236                 /*
    1237                  * i82078 Floppy drive controller
    1238                  */
    1239                 fFdcEnabled = true;
    1240                 rc = CFGMR3InsertInteger(pCfg,  "IRQ",       6);                        RC_CHECK();
    1241                 rc = CFGMR3InsertInteger(pCfg,  "DMA",       2);                        RC_CHECK();
    1242                 rc = CFGMR3InsertInteger(pCfg,  "MemMapped", 0 );                       RC_CHECK();
    1243                 rc = CFGMR3InsertInteger(pCfg,  "IOBase",    0x3f0);                    RC_CHECK();
    1244 
    1245                 /* Attach the status driver */
    1246                 rc = CFGMR3InsertNode(pCtlInst, "LUN#999", &pLunL0);                    RC_CHECK();
    1247                 rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");  RC_CHECK();
    1248                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1249                 rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedFloppy]); RC_CHECK();
    1250                 rc = CFGMR3InsertInteger(pCfg,  "First",    0);                         RC_CHECK();
    1251                 Assert(cLedFloppy >= 1);
    1252                 rc = CFGMR3InsertInteger(pCfg,  "Last",     0);                         RC_CHECK();
    1253                 paLedDevType = &pConsole->maStorageDevType[iLedFloppy];
    1254                 break;
    1255             }
    1256 
    1257             case StorageControllerType_LsiLogicSas:
    1258             {
    1259                 rc = CFGMR3InsertInteger(pCtlInst, "PCIDeviceNo",          22);         RC_CHECK();
    1260                 Assert(!afPciDeviceNo[22]);
    1261                 afPciDeviceNo[22] = true;
    1262                 rc = CFGMR3InsertInteger(pCtlInst, "PCIFunctionNo",        0);          RC_CHECK();
    1263 
    1264                 rc = CFGMR3InsertString(pCfg,  "ControllerType", "SAS1068");            RC_CHECK();
    1265 
    1266                 /* Attach the status driver */
    1267                 rc = CFGMR3InsertNode(pCtlInst, "LUN#999", &pLunL0);                    RC_CHECK();
    1268                 rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");  RC_CHECK();
    1269                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1270                 rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedSas]); RC_CHECK();
    1271                 rc = CFGMR3InsertInteger(pCfg,  "First",    0);                         RC_CHECK();
    1272                 Assert(cLedSas >= 8);
    1273                 rc = CFGMR3InsertInteger(pCfg,  "Last",     7);                         RC_CHECK();
    1274                 paLedDevType = &pConsole->maStorageDevType[iLedSas];
    1275                 break;
    1276             }
    1277 
    1278             default:
    1279                 AssertMsgFailedReturn(("invalid storage controller type: %d\n", enmCtrlType), VERR_GENERAL_FAILURE);
    1280         }
    1281 
    1282         /* Attach the media to the storage controllers. */
    1283         com::SafeIfaceArray<IMediumAttachment> atts;
    1284         hrc = pMachine->GetMediumAttachmentsOfController(controllerName,
    1285                                                          ComSafeArrayAsOutParam(atts)); H();
    1286 
    1287         for (size_t j = 0; j < atts.size(); ++j)
    1288         {
    1289             rc = pConsole->configMediumAttachment(pCtlInst,
    1290                                                   pszCtrlDev,
    1291                                                   ulInstance,
    1292                                                   enmBus,
    1293                                                   fUseHostIOCache,
    1294                                                   false /* fSetupMerge */,
    1295                                                   0 /* uMergeSource */,
    1296                                                   0 /* uMergeTarget */,
    1297                                                   atts[j],
    1298                                                   pConsole->mMachineState,
    1299                                                   NULL /* phrc */,
    1300                                                   false /* fAttachDetach */,
    1301                                                   false /* fForceUnmount */,
    1302                                                   pVM,
    1303                                                   paLedDevType);                        RC_CHECK();
     1312
     1313                    for (uint32_t j = 0; j < 4; ++j)
     1314                    {
     1315                        static const char * const s_apszConfig[4] =
     1316                        { "PrimaryMaster", "PrimarySlave", "SecondaryMaster", "SecondarySlave" };
     1317                        static const char * const s_apszBiosConfig[4] =
     1318                        { "SataPrimaryMasterLUN", "SataPrimarySlaveLUN", "SataSecondaryMasterLUN", "SataSecondarySlaveLUN" };
     1319
     1320                        LONG lPortNumber = -1;
     1321                        hrc = ctrls[i]->GetIDEEmulationPort(j, &lPortNumber);               H();
     1322                        InsertConfigInteger(pCfg, s_apszConfig[j], lPortNumber);
     1323                        if (pBiosCfg)
     1324                            InsertConfigInteger(pBiosCfg, s_apszBiosConfig[j], lPortNumber);
     1325                    }
     1326
     1327                    /* Attach the status driver */
     1328                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
     1329                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1330                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     1331                    AssertRelease(cPorts <= cLedSata);
     1332                    InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedSata]);
     1333                    InsertConfigInteger(pCfg, "First",    0);
     1334                    InsertConfigInteger(pCfg, "Last",     cPorts - 1);
     1335                    paLedDevType = &pConsole->maStorageDevType[iLedSata];
     1336                    break;
     1337                }
     1338
     1339                case StorageControllerType_PIIX3:
     1340                case StorageControllerType_PIIX4:
     1341                case StorageControllerType_ICH6:
     1342                {
     1343                    /*
     1344                     * IDE (update this when the main interface changes)
     1345                     */
     1346                    InsertConfigInteger(pCtlInst, "PCIDeviceNo",          1);
     1347                    Assert(!afPciDeviceNo[1]);
     1348                    afPciDeviceNo[1] = true;
     1349                    InsertConfigInteger(pCtlInst, "PCIFunctionNo",        1);
     1350                    InsertConfigString(pCfg,  "Type", controllerString(enmCtrlType));
     1351
     1352                    /* Attach the status driver */
     1353                    InsertConfigNode(pCtlInst,    "LUN#999", &pLunL0);
     1354                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1355                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     1356                    InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedIde]);
     1357                    InsertConfigInteger(pCfg, "First",    0);
     1358                    Assert(cLedIde >= 4);
     1359                    InsertConfigInteger(pCfg, "Last",     3);
     1360                    paLedDevType = &pConsole->maStorageDevType[iLedIde];
     1361
     1362                    /* IDE flavors */
     1363                    aCtrlNodes[StorageControllerType_PIIX3] = pDev;
     1364                    aCtrlNodes[StorageControllerType_PIIX4] = pDev;
     1365                    aCtrlNodes[StorageControllerType_ICH6]  = pDev;
     1366                    break;
     1367                }
     1368
     1369                case StorageControllerType_I82078:
     1370                {
     1371                    /*
     1372                     * i82078 Floppy drive controller
     1373                     */
     1374                    fFdcEnabled = true;
     1375                    InsertConfigInteger(pCfg, "IRQ",       6);
     1376                    InsertConfigInteger(pCfg, "DMA",       2);
     1377                    InsertConfigInteger(pCfg, "MemMapped", 0 );
     1378                    InsertConfigInteger(pCfg, "IOBase",    0x3f0);
     1379
     1380                    /* Attach the status driver */
     1381                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
     1382                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1383                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     1384                    InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedFloppy]);
     1385                    InsertConfigInteger(pCfg, "First",    0);
     1386                    Assert(cLedFloppy >= 1);
     1387                    InsertConfigInteger(pCfg, "Last",     0);
     1388                    paLedDevType = &pConsole->maStorageDevType[iLedFloppy];
     1389                    break;
     1390                }
     1391
     1392                case StorageControllerType_LsiLogicSas:
     1393                {
     1394                    InsertConfigInteger(pCtlInst, "PCIDeviceNo",          22);
     1395                    Assert(!afPciDeviceNo[22]);
     1396                    afPciDeviceNo[22] = true;
     1397                    InsertConfigInteger(pCtlInst, "PCIFunctionNo",        0);
     1398
     1399                    InsertConfigString(pCfg,  "ControllerType", "SAS1068");
     1400
     1401                    /* Attach the status driver */
     1402                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
     1403                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1404                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     1405                    InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapStorageLeds[iLedSas]);
     1406                    InsertConfigInteger(pCfg, "First",    0);
     1407                    Assert(cLedSas >= 8);
     1408                    InsertConfigInteger(pCfg, "Last",     7);
     1409                    paLedDevType = &pConsole->maStorageDevType[iLedSas];
     1410                    break;
     1411                }
     1412
     1413                default:
     1414                    AssertMsgFailedReturn(("invalid storage controller type: %d\n", enmCtrlType), VERR_GENERAL_FAILURE);
     1415            }
     1416
     1417            /* Attach the media to the storage controllers. */
     1418            com::SafeIfaceArray<IMediumAttachment> atts;
     1419            hrc = pMachine->GetMediumAttachmentsOfController(controllerName,
     1420                                                            ComSafeArrayAsOutParam(atts)); H();
     1421
     1422            for (size_t j = 0; j < atts.size(); ++j)
     1423            {
     1424                rc = pConsole->configMediumAttachment(pCtlInst,
     1425                                                    pszCtrlDev,
     1426                                                    ulInstance,
     1427                                                    enmBus,
     1428                                                    fUseHostIOCache,
     1429                                                    false /* fSetupMerge */,
     1430                                                    0 /* uMergeSource */,
     1431                                                    0 /* uMergeTarget */,
     1432                                                    atts[j],
     1433                                                    pConsole->mMachineState,
     1434                                                    NULL /* phrc */,
     1435                                                    false /* fAttachDetach */,
     1436                                                    false /* fForceUnmount */,
     1437                                                    pVM,
     1438                                                    paLedDevType);
     1439                if (RT_FAILURE(rc))
     1440                    return rc;
     1441            }
     1442            H();
    13041443        }
    13051444        H();
    1306     }
    1307     H();
    1308 
    1309     /*
    1310      * Network adapters
    1311      */
     1445
     1446        /*
     1447         * Network adapters
     1448         */
    13121449#ifdef VMWARE_NET_IN_SLOT_11
    1313     bool fSwapSlots3and11 = false;
     1450        bool fSwapSlots3and11 = false;
    13141451#endif
    1315     PCFGMNODE pDevPCNet = NULL;          /* PCNet-type devices */
    1316     rc = CFGMR3InsertNode(pDevices, "pcnet", &pDevPCNet);                               RC_CHECK();
     1452        PCFGMNODE pDevPCNet = NULL;          /* PCNet-type devices */
     1453        InsertConfigNode(pDevices, "pcnet", &pDevPCNet);
    13171454#ifdef VBOX_WITH_E1000
    1318     PCFGMNODE pDevE1000 = NULL;          /* E1000-type devices */
    1319     rc = CFGMR3InsertNode(pDevices, "e1000", &pDevE1000);                               RC_CHECK();
     1455        PCFGMNODE pDevE1000 = NULL;          /* E1000-type devices */
     1456        InsertConfigNode(pDevices, "e1000", &pDevE1000);
    13201457#endif
    13211458#ifdef VBOX_WITH_VIRTIO
    1322     PCFGMNODE pDevVirtioNet = NULL;          /* Virtio network devices */
    1323     rc = CFGMR3InsertNode(pDevices, "virtio-net", &pDevVirtioNet);                      RC_CHECK();
     1459        PCFGMNODE pDevVirtioNet = NULL;          /* Virtio network devices */
     1460        InsertConfigNode(pDevices, "virtio-net", &pDevVirtioNet);
    13241461#endif /* VBOX_WITH_VIRTIO */
    1325     std::list<BootNic> llBootNics;
    1326     for (ULONG ulInstance = 0; ulInstance < SchemaDefs::NetworkAdapterCount; ++ulInstance)
    1327     {
    1328         ComPtr<INetworkAdapter> networkAdapter;
    1329         hrc = pMachine->GetNetworkAdapter(ulInstance, networkAdapter.asOutParam());     H();
    1330         BOOL fEnabled = FALSE;
    1331         hrc = networkAdapter->COMGETTER(Enabled)(&fEnabled);                            H();
    1332         if (!fEnabled)
    1333             continue;
    1334 
    1335         /*
    1336          * The virtual hardware type. Create appropriate device first.
    1337          */
    1338         const char *pszAdapterName = "pcnet";
    1339         NetworkAdapterType_T adapterType;
    1340         hrc = networkAdapter->COMGETTER(AdapterType)(&adapterType);                     H();
    1341         switch (adapterType)
     1462        std::list<BootNic> llBootNics;
     1463        for (ULONG ulInstance = 0; ulInstance < SchemaDefs::NetworkAdapterCount; ++ulInstance)
    13421464        {
    1343             case NetworkAdapterType_Am79C970A:
    1344             case NetworkAdapterType_Am79C973:
    1345                 pDev = pDevPCNet;
    1346                 break;
     1465            ComPtr<INetworkAdapter> networkAdapter;
     1466            hrc = pMachine->GetNetworkAdapter(ulInstance, networkAdapter.asOutParam());     H();
     1467            BOOL fEnabled = FALSE;
     1468            hrc = networkAdapter->COMGETTER(Enabled)(&fEnabled);                            H();
     1469            if (!fEnabled)
     1470                continue;
     1471
     1472            /*
     1473             * The virtual hardware type. Create appropriate device first.
     1474             */
     1475            const char *pszAdapterName = "pcnet";
     1476            NetworkAdapterType_T adapterType;
     1477            hrc = networkAdapter->COMGETTER(AdapterType)(&adapterType);                     H();
     1478            switch (adapterType)
     1479            {
     1480                case NetworkAdapterType_Am79C970A:
     1481                case NetworkAdapterType_Am79C973:
     1482                    pDev = pDevPCNet;
     1483                    break;
    13471484#ifdef VBOX_WITH_E1000
    1348             case NetworkAdapterType_I82540EM:
    1349             case NetworkAdapterType_I82543GC:
    1350             case NetworkAdapterType_I82545EM:
    1351                 pDev = pDevE1000;
    1352                 pszAdapterName = "e1000";
    1353                 break;
     1485                case NetworkAdapterType_I82540EM:
     1486                case NetworkAdapterType_I82543GC:
     1487                case NetworkAdapterType_I82545EM:
     1488                    pDev = pDevE1000;
     1489                    pszAdapterName = "e1000";
     1490                    break;
    13541491#endif
    13551492#ifdef VBOX_WITH_VIRTIO
    1356             case NetworkAdapterType_Virtio:
    1357                 pDev = pDevVirtioNet;
    1358                 pszAdapterName = "virtio-net";
    1359                 break;
     1493                case NetworkAdapterType_Virtio:
     1494                    pDev = pDevVirtioNet;
     1495                    pszAdapterName = "virtio-net";
     1496                    break;
    13601497#endif /* VBOX_WITH_VIRTIO */
    1361             default:
    1362                 AssertMsgFailed(("Invalid network adapter type '%d' for slot '%d'",
    1363                                  adapterType, ulInstance));
    1364                 return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
    1365                                   N_("Invalid network adapter type '%d' for slot '%d'"),
    1366                                   adapterType, ulInstance);
     1498                default:
     1499                    AssertMsgFailed(("Invalid network adapter type '%d' for slot '%d'",
     1500                                    adapterType, ulInstance));
     1501                    return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
     1502                                      N_("Invalid network adapter type '%d' for slot '%d'"),
     1503                                      adapterType, ulInstance);
     1504            }
     1505
     1506            InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
     1507            InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     1508            /* the first network card gets the PCI ID 3, the next 3 gets 8..10,
     1509             * next 4 get 16..19. */
     1510            unsigned iPciDeviceNo = 3;
     1511            if (ulInstance)
     1512            {
     1513                if (ulInstance < 4)
     1514                    iPciDeviceNo = ulInstance - 1 + 8;
     1515                else
     1516                    iPciDeviceNo = ulInstance - 4 + 16;
     1517            }
     1518#ifdef VMWARE_NET_IN_SLOT_11
     1519            /*
     1520             * Dirty hack for PCI slot compatibility with VMWare,
     1521             * it assigns slot 11 to the first network controller.
     1522             */
     1523            if (iPciDeviceNo == 3 && adapterType == NetworkAdapterType_I82545EM)
     1524            {
     1525                iPciDeviceNo = 0x11;
     1526                fSwapSlots3and11 = true;
     1527            }
     1528            else if (iPciDeviceNo == 0x11 && fSwapSlots3and11)
     1529                iPciDeviceNo = 3;
     1530#endif
     1531            InsertConfigInteger(pInst, "PCIDeviceNo", iPciDeviceNo);
     1532            Assert(!afPciDeviceNo[iPciDeviceNo]);
     1533            afPciDeviceNo[iPciDeviceNo] = true;
     1534            InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     1535            InsertConfigNode(pInst, "Config", &pCfg);
     1536#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE   not safe here yet. */
     1537            if (pDev == pDevPCNet)
     1538            {
     1539                InsertConfigInteger(pCfg, "R0Enabled",    false);
     1540            }
     1541#endif
     1542            /*
     1543             * Collect information needed for network booting and add it to the list.
     1544             */
     1545            BootNic     nic;
     1546
     1547            nic.mInstance = ulInstance;
     1548            nic.mPciDev   = iPciDeviceNo;
     1549            nic.mPciFn    = 0;
     1550
     1551            hrc = networkAdapter->COMGETTER(BootPriority)(&nic.mBootPrio);                  H();
     1552
     1553            llBootNics.push_back(nic);
     1554
     1555            /*
     1556             * The virtual hardware type. PCNet supports two types.
     1557             */
     1558            switch (adapterType)
     1559            {
     1560                case NetworkAdapterType_Am79C970A:
     1561                    InsertConfigInteger(pCfg, "Am79C973", 0);
     1562                    break;
     1563                case NetworkAdapterType_Am79C973:
     1564                    InsertConfigInteger(pCfg, "Am79C973", 1);
     1565                    break;
     1566                case NetworkAdapterType_I82540EM:
     1567                    InsertConfigInteger(pCfg, "AdapterType", 0);
     1568                    break;
     1569                case NetworkAdapterType_I82543GC:
     1570                    InsertConfigInteger(pCfg, "AdapterType", 1);
     1571                    break;
     1572                case NetworkAdapterType_I82545EM:
     1573                    InsertConfigInteger(pCfg, "AdapterType", 2);
     1574                    break;
     1575            }
     1576
     1577            /*
     1578             * Get the MAC address and convert it to binary representation
     1579             */
     1580            Bstr macAddr;
     1581            hrc = networkAdapter->COMGETTER(MACAddress)(macAddr.asOutParam());              H();
     1582            Assert(macAddr);
     1583            Utf8Str macAddrUtf8 = macAddr;
     1584            char *macStr = (char*)macAddrUtf8.raw();
     1585            Assert(strlen(macStr) == 12);
     1586            RTMAC Mac;
     1587            memset(&Mac, 0, sizeof(Mac));
     1588            char *pMac = (char*)&Mac;
     1589            for (uint32_t i = 0; i < 6; ++i)
     1590            {
     1591                char c1 = *macStr++ - '0';
     1592                if (c1 > 9)
     1593                    c1 -= 7;
     1594                char c2 = *macStr++ - '0';
     1595                if (c2 > 9)
     1596                    c2 -= 7;
     1597                *pMac++ = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
     1598            }
     1599            InsertConfigBytes(pCfg, "MAC", &Mac, sizeof(Mac));
     1600
     1601            /*
     1602             * Check if the cable is supposed to be unplugged
     1603             */
     1604            BOOL fCableConnected;
     1605            hrc = networkAdapter->COMGETTER(CableConnected)(&fCableConnected);              H();
     1606            InsertConfigInteger(pCfg, "CableConnected", fCableConnected ? 1 : 0);
     1607
     1608            /*
     1609             * Line speed to report from custom drivers
     1610             */
     1611            ULONG ulLineSpeed;
     1612            hrc = networkAdapter->COMGETTER(LineSpeed)(&ulLineSpeed);                       H();
     1613            InsertConfigInteger(pCfg, "LineSpeed", ulLineSpeed);
     1614
     1615            /*
     1616             * Attach the status driver.
     1617             */
     1618            InsertConfigNode(pInst,    "LUN#999", &pLunL0);
     1619            InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1620            InsertConfigNode(pLunL0,   "Config", &pCfg);
     1621            InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapNetworkLeds[ulInstance]);
     1622
     1623            /*
     1624             * Configure the network card now
     1625             */
     1626            rc = pConsole->configNetwork(pszAdapterName,
     1627                                         ulInstance,
     1628                                         0,
     1629                                         networkAdapter,
     1630                                         pCfg,
     1631                                         pLunL0,
     1632                                         pInst,
     1633                                         false /*fAttachDetach*/);
     1634            if (RT_FAILURE(rc))
     1635                return rc;
    13671636        }
    13681637
    1369         rc = CFGMR3InsertNodeF(pDev, &pInst, "%u", ulInstance);                         RC_CHECK();
    1370         rc = CFGMR3InsertInteger(pInst, "Trusted",              1); /* boolean */       RC_CHECK();
    1371         /* the first network card gets the PCI ID 3, the next 3 gets 8..10,
    1372          * next 4 get 16..19. */
    1373         unsigned iPciDeviceNo = 3;
    1374         if (ulInstance)
     1638        /*
     1639         * Build network boot information and transfer it to the BIOS.
     1640         */
     1641        if (pNetBootCfg && !llBootNics.empty())  /* NetBoot node doesn't exist for EFI! */
    13751642        {
    1376             if (ulInstance < 4)
    1377                 iPciDeviceNo = ulInstance - 1 + 8;
    1378             else
    1379                 iPciDeviceNo = ulInstance - 4 + 16;
     1643            llBootNics.sort();  /* Sort the list by boot priority. */
     1644
     1645            char        achBootIdx[] = "0";
     1646            unsigned    uBootIdx = 0;
     1647
     1648            for (std::list<BootNic>::iterator it = llBootNics.begin(); it != llBootNics.end(); ++it)
     1649            {
     1650                /* A NIC with priority 0 is only used if it's first in the list. */
     1651                if (it->mBootPrio == 0 && uBootIdx != 0)
     1652                    break;
     1653
     1654                PCFGMNODE pNetBtDevCfg;
     1655                achBootIdx[0] = '0' + uBootIdx++;   /* Boot device order. */
     1656                InsertConfigNode(pNetBootCfg, achBootIdx, &pNetBtDevCfg);
     1657                InsertConfigInteger(pNetBtDevCfg, "NIC", it->mInstance);
     1658                InsertConfigInteger(pNetBtDevCfg, "PCIDeviceNo", it->mPciDev);
     1659                InsertConfigInteger(pNetBtDevCfg, "PCIFunctionNo", it->mPciFn);
     1660            }
    13801661        }
    1381 #ifdef VMWARE_NET_IN_SLOT_11
    1382         /*
    1383          * Dirty hack for PCI slot compatibility with VMWare,
    1384          * it assigns slot 11 to the first network controller.
    1385          */
    1386         if (iPciDeviceNo == 3 && adapterType == NetworkAdapterType_I82545EM)
     1662
     1663        /*
     1664         * Serial (UART) Ports
     1665         */
     1666        InsertConfigNode(pDevices, "serial", &pDev);
     1667        for (ULONG ulInstance = 0; ulInstance < SchemaDefs::SerialPortCount; ++ulInstance)
    13871668        {
    1388             iPciDeviceNo = 0x11;
    1389             fSwapSlots3and11 = true;
     1669            ComPtr<ISerialPort> serialPort;
     1670            hrc = pMachine->GetSerialPort(ulInstance, serialPort.asOutParam());             H();
     1671            BOOL fEnabled = FALSE;
     1672            if (serialPort)
     1673                hrc = serialPort->COMGETTER(Enabled)(&fEnabled);                            H();
     1674            if (!fEnabled)
     1675                continue;
     1676
     1677            InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
     1678            InsertConfigNode(pInst, "Config", &pCfg);
     1679
     1680            ULONG ulIRQ;
     1681            hrc = serialPort->COMGETTER(IRQ)(&ulIRQ);                                       H();
     1682            InsertConfigInteger(pCfg, "IRQ", ulIRQ);
     1683            ULONG ulIOBase;
     1684            hrc = serialPort->COMGETTER(IOBase)(&ulIOBase);                                 H();
     1685            InsertConfigInteger(pCfg, "IOBase", ulIOBase);
     1686            BOOL  fServer;
     1687            hrc = serialPort->COMGETTER(Server)(&fServer);                                  H();
     1688            hrc = serialPort->COMGETTER(Path)(bstr.asOutParam());                           H();
     1689            PortMode_T eHostMode;
     1690            hrc = serialPort->COMGETTER(HostMode)(&eHostMode);                              H();
     1691            if (eHostMode != PortMode_Disconnected)
     1692            {
     1693                InsertConfigNode(pInst,     "LUN#0", &pLunL0);
     1694                if (eHostMode == PortMode_HostPipe)
     1695                {
     1696                    InsertConfigString(pLunL0,  "Driver", "Char");
     1697                    InsertConfigNode(pLunL0,    "AttachedDriver", &pLunL1);
     1698                    InsertConfigString(pLunL1,  "Driver", "NamedPipe");
     1699                    InsertConfigNode(pLunL1,    "Config", &pLunL2);
     1700                    InsertConfigString(pLunL2, "Location", bstr);
     1701                    InsertConfigInteger(pLunL2, "IsServer", fServer);
     1702                }
     1703                else if (eHostMode == PortMode_HostDevice)
     1704                {
     1705                    InsertConfigString(pLunL0,  "Driver", "Host Serial");
     1706                    InsertConfigNode(pLunL0,    "Config", &pLunL1);
     1707                    InsertConfigString(pLunL1, "DevicePath", bstr);
     1708                }
     1709                else if (eHostMode == PortMode_RawFile)
     1710                {
     1711                    InsertConfigString(pLunL0,  "Driver", "Char");
     1712                    InsertConfigNode(pLunL0,    "AttachedDriver", &pLunL1);
     1713                    InsertConfigString(pLunL1,  "Driver", "RawFile");
     1714                    InsertConfigNode(pLunL1,    "Config", &pLunL2);
     1715                    InsertConfigString(pLunL2, "Location", bstr);
     1716                }
     1717            }
    13901718        }
    1391         else if (iPciDeviceNo == 0x11 && fSwapSlots3and11)
    1392             iPciDeviceNo = 3;
    1393 #endif
    1394         rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", iPciDeviceNo);                   RC_CHECK();
    1395         Assert(!afPciDeviceNo[iPciDeviceNo]);
    1396         afPciDeviceNo[iPciDeviceNo] = true;
    1397         rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);                     RC_CHECK();
    1398         rc = CFGMR3InsertNode(pInst, "Config", &pCfg);                                  RC_CHECK();
    1399 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE /* not safe here yet. */
    1400         if (pDev == pDevPCNet)
     1719
     1720        /*
     1721         * Parallel (LPT) Ports
     1722         */
     1723        InsertConfigNode(pDevices, "parallel", &pDev);
     1724        for (ULONG ulInstance = 0; ulInstance < SchemaDefs::ParallelPortCount; ++ulInstance)
    14011725        {
    1402             rc = CFGMR3InsertInteger(pCfg,  "R0Enabled",    false);                     RC_CHECK();
     1726            ComPtr<IParallelPort> parallelPort;
     1727            hrc = pMachine->GetParallelPort(ulInstance, parallelPort.asOutParam());         H();
     1728            BOOL fEnabled = FALSE;
     1729            if (parallelPort)
     1730            {
     1731                hrc = parallelPort->COMGETTER(Enabled)(&fEnabled);                          H();
     1732            }
     1733            if (!fEnabled)
     1734                continue;
     1735
     1736            InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
     1737            InsertConfigNode(pInst, "Config", &pCfg);
     1738
     1739            ULONG ulIRQ;
     1740            hrc = parallelPort->COMGETTER(IRQ)(&ulIRQ);                                     H();
     1741            InsertConfigInteger(pCfg, "IRQ", ulIRQ);
     1742            ULONG ulIOBase;
     1743            hrc = parallelPort->COMGETTER(IOBase)(&ulIOBase);                               H();
     1744            InsertConfigInteger(pCfg, "IOBase", ulIOBase);
     1745            InsertConfigNode(pInst,     "LUN#0", &pLunL0);
     1746            InsertConfigString(pLunL0,  "Driver", "HostParallel");
     1747            InsertConfigNode(pLunL0,    "AttachedDriver", &pLunL1);
     1748            hrc = parallelPort->COMGETTER(Path)(bstr.asOutParam());                         H();
     1749            InsertConfigString(pLunL1,  "DevicePath", bstr);
    14031750        }
    1404 #endif
    1405         /*
    1406          * Collect information needed for network booting and add it to the list.
    1407          */
    1408         BootNic     nic;
    1409 
    1410         nic.mInstance = ulInstance;
    1411         nic.mPciDev   = iPciDeviceNo;
    1412         nic.mPciFn    = 0;
    1413 
    1414         hrc = networkAdapter->COMGETTER(BootPriority)(&nic.mBootPrio);                  H();
    1415 
    1416         llBootNics.push_back(nic);
    1417 
    1418         /*
    1419          * The virtual hardware type. PCNet supports two types.
    1420          */
    1421         switch (adapterType)
     1751
     1752        /*
     1753         * VMM Device
     1754         */
     1755        InsertConfigNode(pDevices, "VMMDev", &pDev);
     1756        InsertConfigNode(pDev,     "0", &pInst);
     1757        InsertConfigNode(pInst,    "Config", &pCfg);
     1758        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     1759        InsertConfigInteger(pInst, "PCIDeviceNo",          4);
     1760        Assert(!afPciDeviceNo[4]);
     1761        afPciDeviceNo[4] = true;
     1762        InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     1763        Bstr hwVersion;
     1764        hrc = pMachine->COMGETTER(HardwareVersion)(hwVersion.asOutParam());                 H();
     1765        InsertConfigInteger(pCfg, "RamSize",              cbRam);
     1766        if (hwVersion.compare(Bstr("1")) == 0) /* <= 2.0.x */
     1767            InsertConfigInteger(pCfg, "HeapEnabled", 0);
     1768
     1769        /* the VMM device's Main driver */
     1770        InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     1771        InsertConfigString(pLunL0, "Driver",               "HGCM");
     1772        InsertConfigNode(pLunL0,   "Config", &pCfg);
     1773        VMMDev *pVMMDev = pConsole->mVMMDev;
     1774        InsertConfigInteger(pCfg, "Object", (uintptr_t)pVMMDev);
     1775
     1776        /*
     1777         * Attach the status driver.
     1778         */
     1779        InsertConfigNode(pInst,    "LUN#999", &pLunL0);
     1780        InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1781        InsertConfigNode(pLunL0,   "Config", &pCfg);
     1782        InsertConfigInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapSharedFolderLed);
     1783        InsertConfigInteger(pCfg, "First",    0);
     1784        InsertConfigInteger(pCfg, "Last",     0);
     1785
     1786        /*
     1787         * Audio Sniffer Device
     1788         */
     1789        InsertConfigNode(pDevices, "AudioSniffer", &pDev);
     1790        InsertConfigNode(pDev,     "0", &pInst);
     1791        InsertConfigNode(pInst,    "Config", &pCfg);
     1792
     1793        /* the Audio Sniffer device's Main driver */
     1794        InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     1795        InsertConfigString(pLunL0, "Driver",               "MainAudioSniffer");
     1796        InsertConfigNode(pLunL0,   "Config", &pCfg);
     1797        AudioSniffer *pAudioSniffer = pConsole->mAudioSniffer;
     1798        InsertConfigInteger(pCfg, "Object", (uintptr_t)pAudioSniffer);
     1799
     1800        /*
     1801         * AC'97 ICH / SoundBlaster16 audio
     1802         */
     1803        BOOL enabled;
     1804        ComPtr<IAudioAdapter> audioAdapter;
     1805        hrc = pMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());                 H();
     1806        if (audioAdapter)
     1807            hrc = audioAdapter->COMGETTER(Enabled)(&enabled);                               H();
     1808
     1809        if (enabled)
    14221810        {
    1423             case NetworkAdapterType_Am79C970A:
    1424                 rc = CFGMR3InsertInteger(pCfg, "Am79C973", 0);                          RC_CHECK();
    1425                 break;
    1426             case NetworkAdapterType_Am79C973:
    1427                 rc = CFGMR3InsertInteger(pCfg, "Am79C973", 1);                          RC_CHECK();
    1428                 break;
    1429             case NetworkAdapterType_I82540EM:
    1430                 rc = CFGMR3InsertInteger(pCfg, "AdapterType", 0);                       RC_CHECK();
    1431                 break;
    1432             case NetworkAdapterType_I82543GC:
    1433                 rc = CFGMR3InsertInteger(pCfg, "AdapterType", 1);                       RC_CHECK();
    1434                 break;
    1435             case NetworkAdapterType_I82545EM:
    1436                 rc = CFGMR3InsertInteger(pCfg, "AdapterType", 2);                       RC_CHECK();
    1437                 break;
    1438         }
    1439 
    1440         /*
    1441          * Get the MAC address and convert it to binary representation
    1442          */
    1443         Bstr macAddr;
    1444         hrc = networkAdapter->COMGETTER(MACAddress)(macAddr.asOutParam());              H();
    1445         Assert(macAddr);
    1446         Utf8Str macAddrUtf8 = macAddr;
    1447         char *macStr = (char*)macAddrUtf8.raw();
    1448         Assert(strlen(macStr) == 12);
    1449         RTMAC Mac;
    1450         memset(&Mac, 0, sizeof(Mac));
    1451         char *pMac = (char*)&Mac;
    1452         for (uint32_t i = 0; i < 6; ++i)
    1453         {
    1454             char c1 = *macStr++ - '0';
    1455             if (c1 > 9)
    1456                 c1 -= 7;
    1457             char c2 = *macStr++ - '0';
    1458             if (c2 > 9)
    1459                 c2 -= 7;
    1460             *pMac++ = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
    1461         }
    1462         rc = CFGMR3InsertBytes(pCfg, "MAC", &Mac, sizeof(Mac));                         RC_CHECK();
    1463 
    1464         /*
    1465          * Check if the cable is supposed to be unplugged
    1466          */
    1467         BOOL fCableConnected;
    1468         hrc = networkAdapter->COMGETTER(CableConnected)(&fCableConnected);              H();
    1469         rc = CFGMR3InsertInteger(pCfg, "CableConnected", fCableConnected ? 1 : 0);      RC_CHECK();
    1470 
    1471         /*
    1472          * Line speed to report from custom drivers
    1473          */
    1474         ULONG ulLineSpeed;
    1475         hrc = networkAdapter->COMGETTER(LineSpeed)(&ulLineSpeed);                       H();
    1476         rc = CFGMR3InsertInteger(pCfg, "LineSpeed", ulLineSpeed);                       RC_CHECK();
    1477 
    1478         /*
    1479          * Attach the status driver.
    1480          */
    1481         rc = CFGMR3InsertNode(pInst,    "LUN#999", &pLunL0);                            RC_CHECK();
    1482         rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");          RC_CHECK();
    1483         rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                               RC_CHECK();
    1484         rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapNetworkLeds[ulInstance]); RC_CHECK();
    1485 
    1486         /*
    1487          * Configure the network card now
    1488          */
    1489         rc = pConsole->configNetwork(pszAdapterName, ulInstance, 0,
    1490                                      networkAdapter, pCfg, pLunL0, pInst,
    1491                                      false /*fAttachDetach*/);                          RC_CHECK();
    1492     }
    1493 
    1494     /*
    1495      * Build network boot information and transfer it to the BIOS.
    1496      */
    1497     if (pNetBootCfg && !llBootNics.empty())  /* NetBoot node doesn't exist for EFI! */
    1498     {
    1499         llBootNics.sort();  /* Sort the list by boot priority. */
    1500 
    1501         char        achBootIdx[] = "0";
    1502         unsigned    uBootIdx = 0;
    1503 
    1504         for (std::list<BootNic>::iterator it = llBootNics.begin(); it != llBootNics.end(); ++it)
    1505         {
    1506             /* A NIC with priority 0 is only used if it's first in the list. */
    1507             if (it->mBootPrio == 0 && uBootIdx != 0)
    1508                 break;
    1509 
    1510             PCFGMNODE pNetBtDevCfg;
    1511             achBootIdx[0] = '0' + uBootIdx++;   /* Boot device order. */
    1512             rc = CFGMR3InsertNode(pNetBootCfg, achBootIdx, &pNetBtDevCfg);              RC_CHECK();
    1513             rc = CFGMR3InsertInteger(pNetBtDevCfg, "NIC", it->mInstance);               RC_CHECK();
    1514             rc = CFGMR3InsertInteger(pNetBtDevCfg, "PCIDeviceNo", it->mPciDev);         RC_CHECK();
    1515             rc = CFGMR3InsertInteger(pNetBtDevCfg, "PCIFunctionNo", it->mPciFn);        RC_CHECK();
    1516         }
    1517     }
    1518 
    1519     /*
    1520      * Serial (UART) Ports
    1521      */
    1522     rc = CFGMR3InsertNode(pDevices, "serial", &pDev);                                   RC_CHECK();
    1523     for (ULONG ulInstance = 0; ulInstance < SchemaDefs::SerialPortCount; ++ulInstance)
    1524     {
    1525         ComPtr<ISerialPort> serialPort;
    1526         hrc = pMachine->GetSerialPort(ulInstance, serialPort.asOutParam());             H();
    1527         BOOL fEnabled = FALSE;
    1528         if (serialPort)
    1529             hrc = serialPort->COMGETTER(Enabled)(&fEnabled);                            H();
    1530         if (!fEnabled)
    1531             continue;
    1532 
    1533         rc = CFGMR3InsertNodeF(pDev, &pInst, "%u", ulInstance);                         RC_CHECK();
    1534         rc = CFGMR3InsertNode(pInst, "Config", &pCfg);                                  RC_CHECK();
    1535 
    1536         ULONG ulIRQ;
    1537         hrc = serialPort->COMGETTER(IRQ)(&ulIRQ);                                       H();
    1538         rc = CFGMR3InsertInteger(pCfg,   "IRQ", ulIRQ);                                 RC_CHECK();
    1539         ULONG ulIOBase;
    1540         hrc = serialPort->COMGETTER(IOBase)(&ulIOBase);                                 H();
    1541         rc = CFGMR3InsertInteger(pCfg,   "IOBase", ulIOBase);                           RC_CHECK();
    1542         BOOL  fServer;
    1543         hrc = serialPort->COMGETTER(Server)(&fServer);                                  H();
    1544         hrc = serialPort->COMGETTER(Path)(bstr.asOutParam());                           H();
    1545         PortMode_T eHostMode;
    1546         hrc = serialPort->COMGETTER(HostMode)(&eHostMode);                              H();
    1547         if (eHostMode != PortMode_Disconnected)
    1548         {
    1549             rc = CFGMR3InsertNode(pInst,     "LUN#0", &pLunL0);                         RC_CHECK();
    1550             if (eHostMode == PortMode_HostPipe)
    1551             {
    1552                 rc = CFGMR3InsertString(pLunL0,  "Driver", "Char");                     RC_CHECK();
    1553                 rc = CFGMR3InsertNode(pLunL0,    "AttachedDriver", &pLunL1);            RC_CHECK();
    1554                 rc = CFGMR3InsertString(pLunL1,  "Driver", "NamedPipe");                RC_CHECK();
    1555                 rc = CFGMR3InsertNode(pLunL1,    "Config", &pLunL2);                    RC_CHECK();
    1556                 rc = CFGMR3InsertStringW(pLunL2, "Location", bstr.raw());               RC_CHECK();
    1557                 rc = CFGMR3InsertInteger(pLunL2, "IsServer", fServer);                  RC_CHECK();
    1558             }
    1559             else if (eHostMode == PortMode_HostDevice)
    1560             {
    1561                 rc = CFGMR3InsertString(pLunL0,  "Driver", "Host Serial");              RC_CHECK();
    1562                 rc = CFGMR3InsertNode(pLunL0,    "Config", &pLunL1);                    RC_CHECK();
    1563                 rc = CFGMR3InsertStringW(pLunL1, "DevicePath", bstr.raw());             RC_CHECK();
    1564             }
    1565             else if (eHostMode == PortMode_RawFile)
    1566             {
    1567                 rc = CFGMR3InsertString(pLunL0,  "Driver", "Char");                     RC_CHECK();
    1568                 rc = CFGMR3InsertNode(pLunL0,    "AttachedDriver", &pLunL1);            RC_CHECK();
    1569                 rc = CFGMR3InsertString(pLunL1,  "Driver", "RawFile");                  RC_CHECK();
    1570                 rc = CFGMR3InsertNode(pLunL1,    "Config", &pLunL2);                    RC_CHECK();
    1571                 rc = CFGMR3InsertStringW(pLunL2, "Location", bstr.raw());               RC_CHECK();
    1572             }
    1573         }
    1574     }
    1575 
    1576     /*
    1577      * Parallel (LPT) Ports
    1578      */
    1579     rc = CFGMR3InsertNode(pDevices, "parallel", &pDev);                                 RC_CHECK();
    1580     for (ULONG ulInstance = 0; ulInstance < SchemaDefs::ParallelPortCount; ++ulInstance)
    1581     {
    1582         ComPtr<IParallelPort> parallelPort;
    1583         hrc = pMachine->GetParallelPort(ulInstance, parallelPort.asOutParam());         H();
    1584         BOOL fEnabled = FALSE;
    1585         if (parallelPort)
    1586         {
    1587             hrc = parallelPort->COMGETTER(Enabled)(&fEnabled);                          H();
    1588         }
    1589         if (!fEnabled)
    1590             continue;
    1591 
    1592         rc = CFGMR3InsertNodeF(pDev, &pInst, "%u", ulInstance);                         RC_CHECK();
    1593         rc = CFGMR3InsertNode(pInst, "Config", &pCfg);                                  RC_CHECK();
    1594 
    1595         ULONG ulIRQ;
    1596         hrc = parallelPort->COMGETTER(IRQ)(&ulIRQ);                                     H();
    1597         rc = CFGMR3InsertInteger(pCfg,   "IRQ", ulIRQ);                                 RC_CHECK();
    1598         ULONG ulIOBase;
    1599         hrc = parallelPort->COMGETTER(IOBase)(&ulIOBase);                               H();
    1600         rc = CFGMR3InsertInteger(pCfg,   "IOBase", ulIOBase);                           RC_CHECK();
    1601         rc = CFGMR3InsertNode(pInst,     "LUN#0", &pLunL0);                             RC_CHECK();
    1602         rc = CFGMR3InsertString(pLunL0,  "Driver", "HostParallel");                     RC_CHECK();
    1603         rc = CFGMR3InsertNode(pLunL0,    "AttachedDriver", &pLunL1);                    RC_CHECK();
    1604         hrc = parallelPort->COMGETTER(Path)(bstr.asOutParam());                         H();
    1605         rc = CFGMR3InsertStringW(pLunL1,  "DevicePath", bstr.raw());                    RC_CHECK();
    1606     }
    1607 
    1608     /*
    1609      * VMM Device
    1610      */
    1611     rc = CFGMR3InsertNode(pDevices, "VMMDev", &pDev);                                   RC_CHECK();
    1612     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    1613     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    1614     rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */       RC_CHECK();
    1615     rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",          4);                         RC_CHECK();
    1616     Assert(!afPciDeviceNo[4]);
    1617     afPciDeviceNo[4] = true;
    1618     rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);                         RC_CHECK();
    1619     Bstr hwVersion;
    1620     hrc = pMachine->COMGETTER(HardwareVersion)(hwVersion.asOutParam());                 H();
    1621     rc = CFGMR3InsertInteger(pCfg,  "RamSize",              cbRam);                     RC_CHECK();
    1622     if (hwVersion.compare(Bstr("1")) == 0) /* <= 2.0.x */
    1623     {
    1624         CFGMR3InsertInteger(pCfg, "HeapEnabled", 0);                                    RC_CHECK();
    1625     }
    1626 
    1627     /* the VMM device's Main driver */
    1628     rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                                  RC_CHECK();
    1629     rc = CFGMR3InsertString(pLunL0, "Driver",               "HGCM");                    RC_CHECK();
    1630     rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                                   RC_CHECK();
    1631     VMMDev *pVMMDev = pConsole->mVMMDev;
    1632     rc = CFGMR3InsertInteger(pCfg,  "Object", (uintptr_t)pVMMDev);                      RC_CHECK();
    1633 
    1634     /*
    1635      * Attach the status driver.
    1636      */
    1637     rc = CFGMR3InsertNode(pInst,    "LUN#999", &pLunL0);                                RC_CHECK();
    1638     rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");              RC_CHECK();
    1639     rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                                   RC_CHECK();
    1640     rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapSharedFolderLed); RC_CHECK();
    1641     rc = CFGMR3InsertInteger(pCfg,  "First",    0);                                     RC_CHECK();
    1642     rc = CFGMR3InsertInteger(pCfg,  "Last",     0);                                     RC_CHECK();
    1643 
    1644     /*
    1645      * Audio Sniffer Device
    1646      */
    1647     rc = CFGMR3InsertNode(pDevices, "AudioSniffer", &pDev);                             RC_CHECK();
    1648     rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                       RC_CHECK();
    1649     rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                                   RC_CHECK();
    1650 
    1651     /* the Audio Sniffer device's Main driver */
    1652     rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                                  RC_CHECK();
    1653     rc = CFGMR3InsertString(pLunL0, "Driver",               "MainAudioSniffer");        RC_CHECK();
    1654     rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                                   RC_CHECK();
    1655     AudioSniffer *pAudioSniffer = pConsole->mAudioSniffer;
    1656     rc = CFGMR3InsertInteger(pCfg,  "Object", (uintptr_t)pAudioSniffer);                RC_CHECK();
    1657 
    1658     /*
    1659      * AC'97 ICH / SoundBlaster16 audio
    1660      */
    1661     BOOL enabled;
    1662     ComPtr<IAudioAdapter> audioAdapter;
    1663     hrc = pMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());                 H();
    1664     if (audioAdapter)
    1665         hrc = audioAdapter->COMGETTER(Enabled)(&enabled);                               H();
    1666 
    1667     if (enabled)
    1668     {
    1669         AudioControllerType_T audioController;
    1670         hrc = audioAdapter->COMGETTER(AudioController)(&audioController);               H();
    1671         switch (audioController)
    1672         {
    1673             case AudioControllerType_AC97:
    1674             {
    1675                 /* default: ICH AC97 */
    1676                 rc = CFGMR3InsertNode(pDevices, "ichac97", &pDev);                      RC_CHECK();
    1677                 rc = CFGMR3InsertNode(pDev,     "0", &pInst);
    1678                 rc = CFGMR3InsertInteger(pInst, "Trusted",          1); /* bool */      RC_CHECK();
    1679                 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",      5);                 RC_CHECK();
    1680                 Assert(!afPciDeviceNo[5]);
    1681                 afPciDeviceNo[5] = true;
    1682                 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",    0);                 RC_CHECK();
    1683                 rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                       RC_CHECK();
    1684                 break;
    1685             }
    1686             case AudioControllerType_SB16:
    1687             {
    1688                 /* legacy SoundBlaster16 */
    1689                 rc = CFGMR3InsertNode(pDevices, "sb16", &pDev);                         RC_CHECK();
    1690                 rc = CFGMR3InsertNode(pDev,     "0", &pInst);                           RC_CHECK();
    1691                 rc = CFGMR3InsertInteger(pInst, "Trusted",          1); /* bool */      RC_CHECK();
    1692                 rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                       RC_CHECK();
    1693                 rc = CFGMR3InsertInteger(pCfg,  "IRQ", 5);                              RC_CHECK();
    1694                 rc = CFGMR3InsertInteger(pCfg,  "DMA", 1);                              RC_CHECK();
    1695                 rc = CFGMR3InsertInteger(pCfg,  "DMA16", 5);                            RC_CHECK();
    1696                 rc = CFGMR3InsertInteger(pCfg,  "Port", 0x220);                         RC_CHECK();
    1697                 rc = CFGMR3InsertInteger(pCfg,  "Version", 0x0405);                     RC_CHECK();
    1698                 break;
    1699             }
    1700         }
    1701 
    1702         /* the Audio driver */
    1703         rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                              RC_CHECK();
    1704         rc = CFGMR3InsertString(pLunL0, "Driver",               "AUDIO");               RC_CHECK();
    1705         rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                               RC_CHECK();
    1706 
    1707         AudioDriverType_T audioDriver;
    1708         hrc = audioAdapter->COMGETTER(AudioDriver)(&audioDriver);                       H();
    1709         switch (audioDriver)
    1710         {
    1711             case AudioDriverType_Null:
    1712             {
    1713                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "null");                   RC_CHECK();
    1714                 break;
    1715             }
     1811            AudioControllerType_T audioController;
     1812            hrc = audioAdapter->COMGETTER(AudioController)(&audioController);               H();
     1813            switch (audioController)
     1814            {
     1815                case AudioControllerType_AC97:
     1816                {
     1817                    /* default: ICH AC97 */
     1818                    InsertConfigNode(pDevices, "ichac97", &pDev);
     1819                    rc = CFGMR3InsertNode(pDev,     "0", &pInst);
     1820                    InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
     1821                    InsertConfigInteger(pInst, "PCIDeviceNo",      5);
     1822                    Assert(!afPciDeviceNo[5]);
     1823                    afPciDeviceNo[5] = true;
     1824                    InsertConfigInteger(pInst, "PCIFunctionNo",    0);
     1825                    InsertConfigNode(pInst,    "Config", &pCfg);
     1826                    break;
     1827                }
     1828                case AudioControllerType_SB16:
     1829                {
     1830                    /* legacy SoundBlaster16 */
     1831                    InsertConfigNode(pDevices, "sb16", &pDev);
     1832                    InsertConfigNode(pDev,     "0", &pInst);
     1833                    InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
     1834                    InsertConfigNode(pInst,    "Config", &pCfg);
     1835                    InsertConfigInteger(pCfg, "IRQ", 5);
     1836                    InsertConfigInteger(pCfg, "DMA", 1);
     1837                    InsertConfigInteger(pCfg, "DMA16", 5);
     1838                    InsertConfigInteger(pCfg, "Port", 0x220);
     1839                    InsertConfigInteger(pCfg, "Version", 0x0405);
     1840                    break;
     1841                }
     1842            }
     1843
     1844            /* the Audio driver */
     1845            InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     1846            InsertConfigString(pLunL0, "Driver",               "AUDIO");
     1847            InsertConfigNode(pLunL0,   "Config", &pCfg);
     1848
     1849            AudioDriverType_T audioDriver;
     1850            hrc = audioAdapter->COMGETTER(AudioDriver)(&audioDriver);                       H();
     1851            switch (audioDriver)
     1852            {
     1853                case AudioDriverType_Null:
     1854                {
     1855                    InsertConfigString(pCfg, "AudioDriver", "null");
     1856                    break;
     1857                }
    17161858#ifdef RT_OS_WINDOWS
    17171859#ifdef VBOX_WITH_WINMM
    1718             case AudioDriverType_WinMM:
    1719             {
    1720                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "winmm");                  RC_CHECK();
    1721                 break;
    1722             }
     1860                case AudioDriverType_WinMM:
     1861                {
     1862                    InsertConfigString(pCfg, "AudioDriver", "winmm");
     1863                    break;
     1864                }
    17231865#endif
    1724             case AudioDriverType_DirectSound:
    1725             {
    1726                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "dsound");                 RC_CHECK();
    1727                 break;
    1728             }
     1866                case AudioDriverType_DirectSound:
     1867                {
     1868                    InsertConfigString(pCfg, "AudioDriver", "dsound");
     1869                    break;
     1870                }
    17291871#endif /* RT_OS_WINDOWS */
    17301872#ifdef RT_OS_SOLARIS
    1731             case AudioDriverType_SolAudio:
    1732             {
    1733                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "solaudio");               RC_CHECK();
    1734                 break;
    1735             }
     1873                case AudioDriverType_SolAudio:
     1874                {
     1875                    InsertConfigString(pCfg, "AudioDriver", "solaudio");
     1876                    break;
     1877                }
    17361878#endif
    17371879#ifdef RT_OS_LINUX
    17381880# ifdef VBOX_WITH_ALSA
    1739             case AudioDriverType_ALSA:
    1740             {
    1741                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "alsa");                   RC_CHECK();
    1742                 break;
    1743             }
     1881                case AudioDriverType_ALSA:
     1882                {
     1883                    InsertConfigString(pCfg, "AudioDriver", "alsa");
     1884                    break;
     1885                }
    17441886# endif
    17451887# ifdef VBOX_WITH_PULSE
    1746             case AudioDriverType_Pulse:
    1747             {
    1748                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "pulse");                  RC_CHECK();
    1749                 break;
    1750             }
     1888                case AudioDriverType_Pulse:
     1889                {
     1890                    InsertConfigString(pCfg, "AudioDriver", "pulse");
     1891                    break;
     1892                }
    17511893# endif
    17521894#endif /* RT_OS_LINUX */
    17531895#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(VBOX_WITH_SOLARIS_OSS)
    1754             case AudioDriverType_OSS:
    1755             {
    1756                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "oss");                    RC_CHECK();
    1757                 break;
    1758             }
     1896                case AudioDriverType_OSS:
     1897                {
     1898                    InsertConfigString(pCfg, "AudioDriver", "oss");
     1899                    break;
     1900                }
    17591901#endif
    17601902#ifdef RT_OS_FREEBSD
    17611903# ifdef VBOX_WITH_PULSE
    1762             case AudioDriverType_Pulse:
    1763             {
    1764                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "pulse");                  RC_CHECK();
    1765                 break;
    1766             }
     1904                case AudioDriverType_Pulse:
     1905                {
     1906                    InsertConfigString(pCfg, "AudioDriver", "pulse");
     1907                    break;
     1908                }
    17671909# endif
    17681910#endif
    17691911#ifdef RT_OS_DARWIN
    1770             case AudioDriverType_CoreAudio:
    1771             {
    1772                 rc = CFGMR3InsertString(pCfg, "AudioDriver", "coreaudio");              RC_CHECK();
    1773                 break;
    1774             }
     1912                case AudioDriverType_CoreAudio:
     1913                {
     1914                    InsertConfigString(pCfg, "AudioDriver", "coreaudio");
     1915                    break;
     1916                }
    17751917#endif
     1918            }
     1919            hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                             H();
     1920            InsertConfigString(pCfg, "StreamName", bstr);
    17761921        }
    1777         hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                             H();
    1778         rc = CFGMR3InsertStringW(pCfg, "StreamName", bstr.raw());                       RC_CHECK();
    1779     }
    1780 
    1781     /*
    1782      * The USB Controller.
    1783      */
    1784     ComPtr<IUSBController> USBCtlPtr;
    1785     hrc = pMachine->COMGETTER(USBController)(USBCtlPtr.asOutParam());
    1786     if (USBCtlPtr)
    1787     {
    1788         BOOL fOhciEnabled;
    1789         hrc = USBCtlPtr->COMGETTER(Enabled)(&fOhciEnabled);                             H();
    1790         if (fOhciEnabled)
     1922
     1923        /*
     1924         * The USB Controller.
     1925         */
     1926        ComPtr<IUSBController> USBCtlPtr;
     1927        hrc = pMachine->COMGETTER(USBController)(USBCtlPtr.asOutParam());
     1928        if (USBCtlPtr)
    17911929        {
    1792             rc = CFGMR3InsertNode(pDevices, "usb-ohci", &pDev);                         RC_CHECK();
    1793             rc = CFGMR3InsertNode(pDev,     "0", &pInst);                               RC_CHECK();
    1794             rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                           RC_CHECK();
    1795             rc = CFGMR3InsertInteger(pInst, "Trusted",              1); /* boolean */   RC_CHECK();
    1796             rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",          6);                 RC_CHECK();
    1797             Assert(!afPciDeviceNo[6]);
    1798             afPciDeviceNo[6] = true;
    1799             rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);                 RC_CHECK();
    1800 
    1801             rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                          RC_CHECK();
    1802             rc = CFGMR3InsertString(pLunL0, "Driver",               "VUSBRootHub");     RC_CHECK();
    1803             rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                           RC_CHECK();
     1930            BOOL fOhciEnabled;
     1931            hrc = USBCtlPtr->COMGETTER(Enabled)(&fOhciEnabled);                             H();
     1932            if (fOhciEnabled)
     1933            {
     1934                InsertConfigNode(pDevices, "usb-ohci", &pDev);
     1935                InsertConfigNode(pDev,     "0", &pInst);
     1936                InsertConfigNode(pInst,    "Config", &pCfg);
     1937                InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     1938                InsertConfigInteger(pInst, "PCIDeviceNo",          6);
     1939                Assert(!afPciDeviceNo[6]);
     1940                afPciDeviceNo[6] = true;
     1941                InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     1942
     1943                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     1944                InsertConfigString(pLunL0, "Driver",               "VUSBRootHub");
     1945                InsertConfigNode(pLunL0,   "Config", &pCfg);
     1946
     1947                /*
     1948                * Attach the status driver.
     1949                */
     1950                InsertConfigNode(pInst,    "LUN#999", &pLunL0);
     1951                InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1952                InsertConfigNode(pLunL0,   "Config", &pCfg);
     1953                InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapUSBLed[0]);
     1954                InsertConfigInteger(pCfg, "First",    0);
     1955                InsertConfigInteger(pCfg, "Last",     0);
     1956
     1957#ifdef VBOX_WITH_EHCI
     1958                BOOL fEhciEnabled;
     1959                hrc = USBCtlPtr->COMGETTER(EnabledEhci)(&fEhciEnabled);                     H();
     1960                if (fEhciEnabled)
     1961                {
     1962                    InsertConfigNode(pDevices, "usb-ehci", &pDev);
     1963                    InsertConfigNode(pDev,     "0", &pInst);
     1964                    InsertConfigNode(pInst,    "Config", &pCfg);
     1965                    InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
     1966                    InsertConfigInteger(pInst, "PCIDeviceNo",          11);
     1967                    Assert(!afPciDeviceNo[11]);
     1968                    afPciDeviceNo[11] = true;
     1969                    InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     1970
     1971                    InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     1972                    InsertConfigString(pLunL0, "Driver",               "VUSBRootHub");
     1973                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     1974
     1975                    /*
     1976                     * Attach the status driver.
     1977                     */
     1978                    InsertConfigNode(pInst,    "LUN#999", &pLunL0);
     1979                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
     1980                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     1981                    InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapUSBLed[1]);
     1982                    InsertConfigInteger(pCfg, "First",    0);
     1983                    InsertConfigInteger(pCfg, "Last",     0);
     1984                }
     1985#endif
     1986
     1987                /*
     1988                 * Virtual USB Devices.
     1989                 */
     1990                PCFGMNODE pUsbDevices = NULL;
     1991                InsertConfigNode(pRoot, "USB", &pUsbDevices);
     1992
     1993#ifdef VBOX_WITH_USB
     1994                {
     1995                    /*
     1996                    * Global USB options, currently unused as we'll apply the 2.0 -> 1.1 morphing
     1997                    * on a per device level now.
     1998                    */
     1999                    InsertConfigNode(pUsbDevices, "USBProxy", &pCfg);
     2000                    InsertConfigNode(pCfg, "GlobalConfig", &pCfg);
     2001                    // This globally enables the 2.0 -> 1.1 device morphing of proxied devies to keep windows quiet.
     2002                    //InsertConfigInteger(pCfg, "Force11Device", true);
     2003                    // The following breaks stuff, but it makes MSDs work in vista. (I include it here so
     2004                    // that it's documented somewhere.) Users needing it can use:
     2005                    //      VBoxManage setextradata "myvm" "VBoxInternal/USB/USBProxy/GlobalConfig/Force11PacketSize" 1
     2006                    //InsertConfigInteger(pCfg, "Force11PacketSize", true);
     2007                }
     2008#endif
     2009
     2010# if 0  /* Virtual MSD*/
     2011
     2012                InsertConfigNode(pUsbDevices, "Msd", &pDev);
     2013                InsertConfigNode(pDev,     "0", &pInst);
     2014                InsertConfigNode(pInst,    "Config", &pCfg);
     2015                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     2016
     2017                InsertConfigString(pLunL0, "Driver", "SCSI");
     2018                InsertConfigNode(pLunL0,   "Config", &pCfg);
     2019
     2020                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
     2021                InsertConfigString(pLunL1, "Driver", "Block");
     2022                InsertConfigNode(pLunL1,   "Config", &pCfg);
     2023                InsertConfigString(pCfg,   "Type", "HardDisk");
     2024                InsertConfigInteger(pCfg, "Mountable", 0);
     2025
     2026                InsertConfigNode(pLunL1,   "AttachedDriver", &pLunL2);
     2027                InsertConfigString(pLunL2, "Driver", "VD");
     2028                InsertConfigNode(pLunL2,   "Config", &pCfg);
     2029                InsertConfigString(pCfg,   "Path", "/Volumes/DataHFS/bird/VDIs/linux.vdi");
     2030                InsertConfigString(pCfg,   "Format", "VDI");
     2031# endif
     2032
     2033                /* Virtual USB Mouse/Tablet */
     2034                PointingHidType_T aPointingHid;
     2035                hrc = pMachine->COMGETTER(PointingHidType)(&aPointingHid);                  H();
     2036                if (aPointingHid == PointingHidType_USBMouse || aPointingHid == PointingHidType_USBTablet)
     2037                {
     2038                    InsertConfigNode(pUsbDevices, "HidMouse", &pDev);
     2039                    InsertConfigNode(pDev,     "0", &pInst);
     2040                    InsertConfigNode(pInst,    "Config", &pCfg);
     2041
     2042                    if (aPointingHid == PointingHidType_USBTablet)
     2043                    {
     2044                        InsertConfigInteger(pCfg, "Absolute", 1);
     2045                    }
     2046                    else
     2047                    {
     2048                        InsertConfigInteger(pCfg, "Absolute", 0);
     2049                    }
     2050                    InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     2051                    InsertConfigString(pLunL0, "Driver",        "MouseQueue");
     2052                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     2053                    InsertConfigInteger(pCfg, "QueueSize",            128);
     2054
     2055                    InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
     2056                    InsertConfigString(pLunL1, "Driver",        "MainMouse");
     2057                    InsertConfigNode(pLunL1,   "Config", &pCfg);
     2058                    pMouse = pConsole->mMouse;
     2059                    InsertConfigInteger(pCfg, "Object",     (uintptr_t)pMouse);
     2060                }
     2061
     2062                /* Virtual USB Keyboard */
     2063                KeyboardHidType_T aKbdHid;
     2064                hrc = pMachine->COMGETTER(KeyboardHidType)(&aKbdHid);                       H();
     2065                if (aKbdHid == KeyboardHidType_USBKeyboard)
     2066                {
     2067                    InsertConfigNode(pUsbDevices, "HidKeyboard", &pDev);
     2068                    InsertConfigNode(pDev,     "0", &pInst);
     2069                    InsertConfigNode(pInst,    "Config", &pCfg);
     2070
     2071                    InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     2072                    InsertConfigString(pLunL0, "Driver",               "KeyboardQueue");
     2073                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     2074                    InsertConfigInteger(pCfg, "QueueSize",            64);
     2075
     2076                    InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
     2077                    InsertConfigString(pLunL1, "Driver",               "MainKeyboard");
     2078                    InsertConfigNode(pLunL1,   "Config", &pCfg);
     2079                    pKeyboard = pConsole->mKeyboard;
     2080                    InsertConfigInteger(pCfg, "Object",     (uintptr_t)pKeyboard);
     2081                }
     2082            }
     2083        }
     2084
     2085        /*
     2086         * Clipboard
     2087         */
     2088        {
     2089            ClipboardMode_T mode = ClipboardMode_Disabled;
     2090            hrc = pMachine->COMGETTER(ClipboardMode)(&mode);                                H();
     2091
     2092            if (mode != ClipboardMode_Disabled)
     2093            {
     2094                /* Load the service */
     2095                rc = pConsole->mVMMDev->hgcmLoadService("VBoxSharedClipboard", "VBoxSharedClipboard");
     2096
     2097                if (RT_FAILURE(rc))
     2098                {
     2099                    LogRel(("VBoxSharedClipboard is not available. rc = %Rrc\n", rc));
     2100                    /* That is not a fatal failure. */
     2101                    rc = VINF_SUCCESS;
     2102                }
     2103                else
     2104                {
     2105                    /* Setup the service. */
     2106                    VBOXHGCMSVCPARM parm;
     2107
     2108                    parm.type = VBOX_HGCM_SVC_PARM_32BIT;
     2109
     2110                    switch (mode)
     2111                    {
     2112                        default:
     2113                        case ClipboardMode_Disabled:
     2114                        {
     2115                            LogRel(("VBoxSharedClipboard mode: Off\n"));
     2116                            parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_OFF;
     2117                            break;
     2118                        }
     2119                        case ClipboardMode_GuestToHost:
     2120                        {
     2121                            LogRel(("VBoxSharedClipboard mode: Guest to Host\n"));
     2122                            parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_GUEST_TO_HOST;
     2123                            break;
     2124                        }
     2125                        case ClipboardMode_HostToGuest:
     2126                        {
     2127                            LogRel(("VBoxSharedClipboard mode: Host to Guest\n"));
     2128                            parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST;
     2129                            break;
     2130                        }
     2131                        case ClipboardMode_Bidirectional:
     2132                        {
     2133                            LogRel(("VBoxSharedClipboard mode: Bidirectional\n"));
     2134                            parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL;
     2135                            break;
     2136                        }
     2137                    }
     2138
     2139                    pConsole->mVMMDev->hgcmHostCall("VBoxSharedClipboard", VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE, 1, &parm);
     2140
     2141                    Log(("Set VBoxSharedClipboard mode\n"));
     2142                }
     2143            }
     2144        }
     2145
     2146#ifdef VBOX_WITH_CROGL
     2147        /*
     2148         * crOpenGL
     2149         */
     2150        {
     2151            BOOL fEnabled = false;
     2152            hrc = pMachine->COMGETTER(Accelerate3DEnabled)(&fEnabled); H();
     2153
     2154            if (fEnabled)
     2155            {
     2156                /* Load the service */
     2157                rc = pConsole->mVMMDev->hgcmLoadService("VBoxSharedCrOpenGL", "VBoxSharedCrOpenGL");
     2158                if (RT_FAILURE(rc))
     2159                {
     2160                    LogRel(("Failed to load Shared OpenGL service %Rrc\n", rc));
     2161                    /* That is not a fatal failure. */
     2162                    rc = VINF_SUCCESS;
     2163                }
     2164                else
     2165                {
     2166                    LogRel(("Shared crOpenGL service loaded.\n"));
     2167
     2168                    /* Setup the service. */
     2169                    VBOXHGCMSVCPARM parm;
     2170                    parm.type = VBOX_HGCM_SVC_PARM_PTR;
     2171
     2172                    parm.u.pointer.addr = (IConsole*) (Console*) pConsole;
     2173                    parm.u.pointer.size = sizeof(IConsole *);
     2174
     2175                    rc = pConsole->mVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_SET_CONSOLE,
     2176                                                        SHCRGL_CPARMS_SET_CONSOLE, &parm);
     2177                    if (!RT_SUCCESS(rc))
     2178                        AssertMsgFailed(("SHCRGL_HOST_FN_SET_CONSOLE failed with %Rrc\n", rc));
     2179
     2180                    parm.u.pointer.addr = pVM;
     2181                    parm.u.pointer.size = sizeof(pVM);
     2182                    rc = pConsole->mVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_SET_VM,
     2183                                                        SHCRGL_CPARMS_SET_VM, &parm);
     2184                    if (!RT_SUCCESS(rc))
     2185                        AssertMsgFailed(("SHCRGL_HOST_FN_SET_VM failed with %Rrc\n", rc));
     2186                }
     2187
     2188            }
     2189        }
     2190#endif
     2191
     2192#ifdef VBOX_WITH_GUEST_PROPS
     2193        /*
     2194         * Guest property service
     2195         */
     2196
     2197        rc = configGuestProperties(pConsole);
     2198#endif /* VBOX_WITH_GUEST_PROPS defined */
     2199
     2200#ifdef VBOX_WITH_GUEST_CONTROL
     2201        /*
     2202         * Guest control service
     2203         */
     2204
     2205        rc = configGuestControl(pConsole);
     2206#endif /* VBOX_WITH_GUEST_CONTROL defined */
     2207
     2208        /*
     2209         * ACPI
     2210         */
     2211        BOOL fACPI;
     2212        hrc = biosSettings->COMGETTER(ACPIEnabled)(&fACPI);                                 H();
     2213        if (fACPI)
     2214        {
     2215            BOOL fCpuHotPlug = false;
     2216            BOOL fShowCpu = fOsXGuest;
     2217            /* Always show the CPU leafs when we have multiple VCPUs or when the IO-APIC is enabled.
     2218             * The Windows SMP kernel needs a CPU leaf or else its idle loop will burn cpu cycles; the
     2219             * intelppm driver refuses to register an idle state handler.
     2220             */
     2221            if ((cCpus > 1) || fIOAPIC)
     2222                fShowCpu = true;
     2223
     2224            hrc = pMachine->COMGETTER(CPUHotPlugEnabled)(&fCpuHotPlug);                     H();
     2225
     2226            InsertConfigNode(pDevices, "acpi", &pDev);
     2227            InsertConfigNode(pDev,     "0", &pInst);
     2228            InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
     2229            InsertConfigNode(pInst,    "Config", &pCfg);
     2230            InsertConfigInteger(pCfg, "RamSize",          cbRam);
     2231            InsertConfigInteger(pCfg, "RamHoleSize",      cbRamHole);
     2232            InsertConfigInteger(pCfg, "NumCPUs",          cCpus);
     2233
     2234            InsertConfigInteger(pCfg, "IOAPIC", fIOAPIC);
     2235            InsertConfigInteger(pCfg, "FdcEnabled", fFdcEnabled);
     2236            InsertConfigInteger(pCfg, "HpetEnabled", fHpetEnabled);
     2237            InsertConfigInteger(pCfg, "SmcEnabled", fSmcEnabled);
     2238            InsertConfigInteger(pCfg, "ShowRtc",    fOsXGuest);
     2239            if (fOsXGuest && !llBootNics.empty())
     2240            {
     2241                BootNic aNic = llBootNics.front();
     2242                uint32_t u32NicPciAddr = (aNic.mPciDev << 16) | aNic.mPciFn;
     2243                InsertConfigInteger(pCfg, "NicPciAddress",    u32NicPciAddr);
     2244            }
     2245            InsertConfigInteger(pCfg, "ShowCpu", fShowCpu);
     2246            InsertConfigInteger(pCfg, "CpuHotPlug", fCpuHotPlug);
     2247            InsertConfigInteger(pInst, "PCIDeviceNo",          7);
     2248            Assert(!afPciDeviceNo[7]);
     2249            afPciDeviceNo[7] = true;
     2250            InsertConfigInteger(pInst, "PCIFunctionNo",        0);
     2251
     2252            InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     2253            InsertConfigString(pLunL0, "Driver",               "ACPIHost");
     2254            InsertConfigNode(pLunL0,   "Config", &pCfg);
     2255
     2256            /* Attach the dummy CPU drivers */
     2257            for (ULONG iCpuCurr = 1; iCpuCurr < cCpus; iCpuCurr++)
     2258            {
     2259                BOOL fCpuAttached = true;
     2260
     2261                if (fCpuHotPlug)
     2262                {
     2263                    hrc = pMachine->GetCPUStatus(iCpuCurr, &fCpuAttached);                  H();
     2264                }
     2265
     2266                if (fCpuAttached)
     2267                {
     2268                    InsertConfigNode(pInst, Utf8StrFmt("LUN#%u", iCpuCurr).c_str(), &pLunL0);
     2269                    InsertConfigString(pLunL0, "Driver",           "ACPICpu");
     2270                    InsertConfigNode(pLunL0,   "Config", &pCfg);
     2271                }
     2272            }
     2273        }
     2274
     2275        /*
     2276         * CFGM overlay handling.
     2277         *
     2278         * Here we check the extra data entries for CFGM values
     2279         * and create the nodes and insert the values on the fly. Existing
     2280         * values will be removed and reinserted. CFGM is typed, so by default
     2281         * we will guess whether it's a string or an integer (byte arrays are
     2282         * not currently supported). It's possible to override this autodetection
     2283         * by adding "string:", "integer:" or "bytes:" (future).
     2284         *
     2285         * We first perform a run on global extra data, then on the machine
     2286         * extra data to support global settings with local overrides.
     2287         */
     2288        /** @todo add support for removing nodes and byte blobs. */
     2289        SafeArray<BSTR> aGlobalExtraDataKeys;
     2290        SafeArray<BSTR> aMachineExtraDataKeys;
     2291        /*
     2292         * Get the next key
     2293         */
     2294        if (FAILED(hrc = virtualBox->GetExtraDataKeys(ComSafeArrayAsOutParam(aGlobalExtraDataKeys))))
     2295            AssertMsgFailed(("VirtualBox::GetExtraDataKeys failed with %Rrc\n", hrc));
     2296
     2297        // remember the no. of global values so we can call the correct method below
     2298        size_t cGlobalValues = aGlobalExtraDataKeys.size();
     2299
     2300        if (FAILED(hrc = pMachine->GetExtraDataKeys(ComSafeArrayAsOutParam(aMachineExtraDataKeys))))
     2301            AssertMsgFailed(("IMachine::GetExtraDataKeys failed with %Rrc\n", hrc));
     2302
     2303        // build a combined list from global keys...
     2304        std::list<Utf8Str> llExtraDataKeys;
     2305
     2306        for (size_t i = 0; i < aGlobalExtraDataKeys.size(); ++i)
     2307            llExtraDataKeys.push_back(Utf8Str(aGlobalExtraDataKeys[i]));
     2308        // ... and machine keys
     2309        for (size_t i = 0; i < aMachineExtraDataKeys.size(); ++i)
     2310            llExtraDataKeys.push_back(Utf8Str(aMachineExtraDataKeys[i]));
     2311
     2312        size_t i2 = 0;
     2313        for (std::list<Utf8Str>::const_iterator it = llExtraDataKeys.begin();
     2314            it != llExtraDataKeys.end();
     2315            ++it, ++i2)
     2316        {
     2317            const Utf8Str &strKey = *it;
    18042318
    18052319            /*
    1806              * Attach the status driver.
     2320             * We only care about keys starting with "VBoxInternal/" (skip "G:" or "M:")
    18072321             */
    1808             rc = CFGMR3InsertNode(pInst,    "LUN#999", &pLunL0);                        RC_CHECK();
    1809             rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");      RC_CHECK();
    1810             rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                           RC_CHECK();
    1811             rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapUSBLed[0]);RC_CHECK();
    1812             rc = CFGMR3InsertInteger(pCfg,  "First",    0);                             RC_CHECK();
    1813             rc = CFGMR3InsertInteger(pCfg,  "Last",     0);                             RC_CHECK();
    1814 
    1815 #ifdef VBOX_WITH_EHCI
    1816             BOOL fEhciEnabled;
    1817             hrc = USBCtlPtr->COMGETTER(EnabledEhci)(&fEhciEnabled);                     H();
    1818             if (fEhciEnabled)
    1819             {
    1820                 rc = CFGMR3InsertNode(pDevices, "usb-ehci", &pDev);                     RC_CHECK();
    1821                 rc = CFGMR3InsertNode(pDev,     "0", &pInst);                           RC_CHECK();
    1822                 rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                       RC_CHECK();
    1823                 rc = CFGMR3InsertInteger(pInst, "Trusted",              1); /* bool */  RC_CHECK();
    1824                 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",          11);            RC_CHECK();
    1825                 Assert(!afPciDeviceNo[11]);
    1826                 afPciDeviceNo[11] = true;
    1827                 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);             RC_CHECK();
    1828 
    1829                 rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                      RC_CHECK();
    1830                 rc = CFGMR3InsertString(pLunL0, "Driver",               "VUSBRootHub"); RC_CHECK();
    1831                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1832 
    1833                 /*
    1834                  * Attach the status driver.
    1835                  */
    1836                 rc = CFGMR3InsertNode(pInst,    "LUN#999", &pLunL0);                    RC_CHECK();
    1837                 rc = CFGMR3InsertString(pLunL0, "Driver",               "MainStatus");  RC_CHECK();
    1838                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1839                 rc = CFGMR3InsertInteger(pCfg,  "papLeds", (uintptr_t)&pConsole->mapUSBLed[1]);RC_CHECK();
    1840                 rc = CFGMR3InsertInteger(pCfg,  "First",    0);                         RC_CHECK();
    1841                 rc = CFGMR3InsertInteger(pCfg,  "Last",     0);                         RC_CHECK();
    1842             }
    1843 #endif
     2322            if (!strKey.startsWith("VBoxInternal/"))
     2323                continue;
     2324
     2325            const char *pszExtraDataKey = strKey.raw() + sizeof("VBoxInternal/") - 1;
     2326
     2327            // get the value
     2328            Bstr strExtraDataValue;
     2329            if (i2 < cGlobalValues)
     2330                // this is still one of the global values:
     2331                hrc = virtualBox->GetExtraData(Bstr(strKey), strExtraDataValue.asOutParam());
     2332            else
     2333                hrc = pMachine->GetExtraData(Bstr(strKey), strExtraDataValue.asOutParam());
     2334            if (FAILED(hrc))
     2335                LogRel(("Warning: Cannot get extra data key %s, rc = %Rrc\n", strKey.raw(), hrc));
    18442336
    18452337            /*
    1846              * Virtual USB Devices.
     2338             * The key will be in the format "Node1/Node2/Value" or simply "Value".
     2339             * Split the two and get the node, delete the value and create the node
     2340             * if necessary.
    18472341             */
    1848             PCFGMNODE pUsbDevices = NULL;
    1849             rc = CFGMR3InsertNode(pRoot, "USB", &pUsbDevices);                          RC_CHECK();
    1850 
    1851 #ifdef VBOX_WITH_USB
    1852             {
    1853                 /*
    1854                  * Global USB options, currently unused as we'll apply the 2.0 -> 1.1 morphing
    1855                  * on a per device level now.
    1856                  */
    1857                 rc = CFGMR3InsertNode(pUsbDevices, "USBProxy", &pCfg);                  RC_CHECK();
    1858                 rc = CFGMR3InsertNode(pCfg, "GlobalConfig", &pCfg);                     RC_CHECK();
    1859                 // This globally enables the 2.0 -> 1.1 device morphing of proxied devies to keep windows quiet.
    1860                 //rc = CFGMR3InsertInteger(pCfg, "Force11Device", true);                RC_CHECK();
    1861                 // The following breaks stuff, but it makes MSDs work in vista. (I include it here so
    1862                 // that it's documented somewhere.) Users needing it can use:
    1863                 //      VBoxManage setextradata "myvm" "VBoxInternal/USB/USBProxy/GlobalConfig/Force11PacketSize" 1
    1864                 //rc = CFGMR3InsertInteger(pCfg, "Force11PacketSize", true);            RC_CHECK();
    1865             }
    1866 #endif
    1867 
    1868 # if 0  /* Virtual MSD*/
    1869 
    1870             rc = CFGMR3InsertNode(pUsbDevices, "Msd", &pDev);                           RC_CHECK();
    1871             rc = CFGMR3InsertNode(pDev,     "0", &pInst);                               RC_CHECK();
    1872             rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                           RC_CHECK();
    1873             rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                          RC_CHECK();
    1874 
    1875             rc = CFGMR3InsertString(pLunL0, "Driver", "SCSI");                          RC_CHECK();
    1876             rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                           RC_CHECK();
    1877 
    1878             rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL1);                 RC_CHECK();
    1879             rc = CFGMR3InsertString(pLunL1, "Driver", "Block");                         RC_CHECK();
    1880             rc = CFGMR3InsertNode(pLunL1,   "Config", &pCfg);                           RC_CHECK();
    1881             rc = CFGMR3InsertString(pCfg,   "Type", "HardDisk");                        RC_CHECK();
    1882             rc = CFGMR3InsertInteger(pCfg,  "Mountable", 0);                            RC_CHECK();
    1883 
    1884             rc = CFGMR3InsertNode(pLunL1,   "AttachedDriver", &pLunL2);                 RC_CHECK();
    1885             rc = CFGMR3InsertString(pLunL2, "Driver", "VD");                            RC_CHECK();
    1886             rc = CFGMR3InsertNode(pLunL2,   "Config", &pCfg);                           RC_CHECK();
    1887             rc = CFGMR3InsertString(pCfg,   "Path", "/Volumes/DataHFS/bird/VDIs/linux.vdi"); RC_CHECK();
    1888             rc = CFGMR3InsertString(pCfg,   "Format", "VDI");                           RC_CHECK();
    1889 # endif
    1890 
    1891             /* Virtual USB Mouse/Tablet */
    1892             PointingHidType_T aPointingHid;
    1893             hrc = pMachine->COMGETTER(PointingHidType)(&aPointingHid);                  H();
    1894             if (aPointingHid == PointingHidType_USBMouse || aPointingHid == PointingHidType_USBTablet)
    1895             {
    1896                 rc = CFGMR3InsertNode(pUsbDevices, "HidMouse", &pDev);                  RC_CHECK();
    1897                 rc = CFGMR3InsertNode(pDev,     "0", &pInst);                           RC_CHECK();
    1898                 rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                       RC_CHECK();
    1899 
    1900                 if (aPointingHid == PointingHidType_USBTablet)
    1901                 {
    1902                     rc = CFGMR3InsertInteger(pCfg, "Absolute", 1);                      RC_CHECK();
    1903                 }
     2342            PCFGMNODE pNode;
     2343            const char *pszCFGMValueName = strrchr(pszExtraDataKey, '/');
     2344            if (pszCFGMValueName)
     2345            {
     2346                /* terminate the node and advance to the value (Utf8Str might not
     2347                offically like this but wtf) */
     2348                *(char*)pszCFGMValueName = '\0';
     2349                ++pszCFGMValueName;
     2350
     2351                /* does the node already exist? */
     2352                pNode = CFGMR3GetChild(pRoot, pszExtraDataKey);
     2353                if (pNode)
     2354                    CFGMR3RemoveValue(pNode, pszCFGMValueName);
    19042355                else
    19052356                {
    1906                     rc = CFGMR3InsertInteger(pCfg, "Absolute", 0);                      RC_CHECK();
    1907                 }
    1908                 rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                      RC_CHECK();
    1909                 rc = CFGMR3InsertString(pLunL0, "Driver",        "MouseQueue");         RC_CHECK();
    1910                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1911                 rc = CFGMR3InsertInteger(pCfg,  "QueueSize",            128);           RC_CHECK();
    1912 
    1913                 rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL1);             RC_CHECK();
    1914                 rc = CFGMR3InsertString(pLunL1, "Driver",        "MainMouse");          RC_CHECK();
    1915                 rc = CFGMR3InsertNode(pLunL1,   "Config", &pCfg);                       RC_CHECK();
    1916                 pMouse = pConsole->mMouse;
    1917                 rc = CFGMR3InsertInteger(pCfg,  "Object",     (uintptr_t)pMouse);       RC_CHECK();
    1918             }
    1919 
    1920             /* Virtual USB Keyboard */
    1921             KeyboardHidType_T aKbdHid;
    1922             hrc = pMachine->COMGETTER(KeyboardHidType)(&aKbdHid);                       H();
    1923             if (aKbdHid == KeyboardHidType_USBKeyboard)
    1924             {
    1925                 rc = CFGMR3InsertNode(pUsbDevices, "HidKeyboard", &pDev);               RC_CHECK();
    1926                 rc = CFGMR3InsertNode(pDev,     "0", &pInst);                           RC_CHECK();
    1927                 rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                       RC_CHECK();
    1928 
    1929                 rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                      RC_CHECK();
    1930                 rc = CFGMR3InsertString(pLunL0, "Driver",               "KeyboardQueue"); RC_CHECK();
    1931                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    1932                 rc = CFGMR3InsertInteger(pCfg,  "QueueSize",            64);            RC_CHECK();
    1933 
    1934                 rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL1);             RC_CHECK();
    1935                 rc = CFGMR3InsertString(pLunL1, "Driver",               "MainKeyboard"); RC_CHECK();
    1936                 rc = CFGMR3InsertNode(pLunL1,   "Config", &pCfg);                       RC_CHECK();
    1937                 pKeyboard = pConsole->mKeyboard;
    1938                 rc = CFGMR3InsertInteger(pCfg,  "Object",     (uintptr_t)pKeyboard);    RC_CHECK();
     2357                    /* create the node */
     2358                    rc = CFGMR3InsertNode(pRoot, pszExtraDataKey, &pNode);
     2359                    if (RT_FAILURE(rc))
     2360                    {
     2361                        AssertLogRelMsgRC(rc, ("failed to insert node '%s'\n", pszExtraDataKey));
     2362                        continue;
     2363                    }
     2364                    Assert(pNode);
     2365                }
     2366            }
     2367            else
     2368            {
     2369                /* root value (no node path). */
     2370                pNode = pRoot;
     2371                pszCFGMValueName = pszExtraDataKey;
     2372                pszExtraDataKey--;
     2373                CFGMR3RemoveValue(pNode, pszCFGMValueName);
     2374            }
     2375
     2376            /*
     2377             * Now let's have a look at the value.
     2378             * Empty strings means that we should remove the value, which we've
     2379             * already done above.
     2380             */
     2381            Utf8Str strCFGMValueUtf8(strExtraDataValue);
     2382            const char *pszCFGMValue = strCFGMValueUtf8.raw();
     2383            if (    pszCFGMValue
     2384                && *pszCFGMValue)
     2385            {
     2386                uint64_t u64Value;
     2387
     2388                /* check for type prefix first. */
     2389                if (!strncmp(pszCFGMValue, "string:", sizeof("string:") - 1))
     2390                    InsertConfigString(pNode, pszCFGMValueName, pszCFGMValue + sizeof("string:") - 1);
     2391                else if (!strncmp(pszCFGMValue, "integer:", sizeof("integer:") - 1))
     2392                {
     2393                    rc = RTStrToUInt64Full(pszCFGMValue + sizeof("integer:") - 1, 0, &u64Value);
     2394                    if (RT_SUCCESS(rc))
     2395                        rc = CFGMR3InsertInteger(pNode, pszCFGMValueName, u64Value);
     2396                }
     2397                else if (!strncmp(pszCFGMValue, "bytes:", sizeof("bytes:") - 1))
     2398                    rc = VERR_NOT_IMPLEMENTED;
     2399                /* auto detect type. */
     2400                else if (RT_SUCCESS(RTStrToUInt64Full(pszCFGMValue, 0, &u64Value)))
     2401                    rc = CFGMR3InsertInteger(pNode, pszCFGMValueName, u64Value);
     2402                else
     2403                    InsertConfigString(pNode, pszCFGMValueName, pszCFGMValue);
     2404                AssertLogRelMsgRC(rc, ("failed to insert CFGM value '%s' to key '%s'\n", pszCFGMValue, pszExtraDataKey));
    19392405            }
    19402406        }
    19412407    }
    1942 
    1943     /*
    1944      * Clipboard
    1945      */
     2408    catch (ConfigError &x)
    19462409    {
    1947         ClipboardMode_T mode = ClipboardMode_Disabled;
    1948         hrc = pMachine->COMGETTER(ClipboardMode)(&mode);                                H();
    1949 
    1950         if (mode != ClipboardMode_Disabled)
    1951         {
    1952             /* Load the service */
    1953             rc = pConsole->mVMMDev->hgcmLoadService("VBoxSharedClipboard", "VBoxSharedClipboard");
    1954 
    1955             if (RT_FAILURE(rc))
    1956             {
    1957                 LogRel(("VBoxSharedClipboard is not available. rc = %Rrc\n", rc));
    1958                 /* That is not a fatal failure. */
    1959                 rc = VINF_SUCCESS;
    1960             }
    1961             else
    1962             {
    1963                 /* Setup the service. */
    1964                 VBOXHGCMSVCPARM parm;
    1965 
    1966                 parm.type = VBOX_HGCM_SVC_PARM_32BIT;
    1967 
    1968                 switch (mode)
    1969                 {
    1970                     default:
    1971                     case ClipboardMode_Disabled:
    1972                     {
    1973                         LogRel(("VBoxSharedClipboard mode: Off\n"));
    1974                         parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_OFF;
    1975                         break;
    1976                     }
    1977                     case ClipboardMode_GuestToHost:
    1978                     {
    1979                         LogRel(("VBoxSharedClipboard mode: Guest to Host\n"));
    1980                         parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_GUEST_TO_HOST;
    1981                         break;
    1982                     }
    1983                     case ClipboardMode_HostToGuest:
    1984                     {
    1985                         LogRel(("VBoxSharedClipboard mode: Host to Guest\n"));
    1986                         parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST;
    1987                         break;
    1988                     }
    1989                     case ClipboardMode_Bidirectional:
    1990                     {
    1991                         LogRel(("VBoxSharedClipboard mode: Bidirectional\n"));
    1992                         parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL;
    1993                         break;
    1994                     }
    1995                 }
    1996 
    1997                 pConsole->mVMMDev->hgcmHostCall("VBoxSharedClipboard", VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE, 1, &parm);
    1998 
    1999                 Log(("Set VBoxSharedClipboard mode\n"));
    2000             }
    2001         }
     2410        // InsertConfig threw something:
     2411        return x.m_vrc;
    20022412    }
    20032413
    2004 #ifdef VBOX_WITH_CROGL
    2005     /*
    2006      * crOpenGL
    2007      */
    2008     {
    2009         BOOL fEnabled = false;
    2010         hrc = pMachine->COMGETTER(Accelerate3DEnabled)(&fEnabled); H();
    2011 
    2012         if (fEnabled)
    2013         {
    2014             /* Load the service */
    2015             rc = pConsole->mVMMDev->hgcmLoadService("VBoxSharedCrOpenGL", "VBoxSharedCrOpenGL");
    2016             if (RT_FAILURE(rc))
    2017             {
    2018                 LogRel(("Failed to load Shared OpenGL service %Rrc\n", rc));
    2019                 /* That is not a fatal failure. */
    2020                 rc = VINF_SUCCESS;
    2021             }
    2022             else
    2023             {
    2024                 LogRel(("Shared crOpenGL service loaded.\n"));
    2025 
    2026                 /* Setup the service. */
    2027                 VBOXHGCMSVCPARM parm;
    2028                 parm.type = VBOX_HGCM_SVC_PARM_PTR;
    2029 
    2030                 parm.u.pointer.addr = (IConsole*) (Console*) pConsole;
    2031                 parm.u.pointer.size = sizeof(IConsole *);
    2032 
    2033                 rc = pConsole->mVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_SET_CONSOLE,
    2034                                                      SHCRGL_CPARMS_SET_CONSOLE, &parm);
    2035                 if (!RT_SUCCESS(rc))
    2036                     AssertMsgFailed(("SHCRGL_HOST_FN_SET_CONSOLE failed with %Rrc\n", rc));
    2037 
    2038                 parm.u.pointer.addr = pVM;
    2039                 parm.u.pointer.size = sizeof(pVM);
    2040                 rc = pConsole->mVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_SET_VM,
    2041                                                      SHCRGL_CPARMS_SET_VM, &parm);
    2042                 if (!RT_SUCCESS(rc))
    2043                     AssertMsgFailed(("SHCRGL_HOST_FN_SET_VM failed with %Rrc\n", rc));
    2044             }
    2045 
    2046         }
    2047     }
    2048 #endif
    2049 
    2050 #ifdef VBOX_WITH_GUEST_PROPS
    2051     /*
    2052      * Guest property service
    2053      */
    2054 
    2055     rc = configGuestProperties(pConsole);
    2056 #endif /* VBOX_WITH_GUEST_PROPS defined */
    2057 
    2058 #ifdef VBOX_WITH_GUEST_CONTROL
    2059     /*
    2060      * Guest control service
    2061      */
    2062 
    2063     rc = configGuestControl(pConsole);
    2064 #endif /* VBOX_WITH_GUEST_CONTROL defined */
    2065 
    2066     /*
    2067      * ACPI
    2068      */
    2069     BOOL fACPI;
    2070     hrc = biosSettings->COMGETTER(ACPIEnabled)(&fACPI);                                 H();
    2071     if (fACPI)
    2072     {
    2073         BOOL fCpuHotPlug = false;
    2074         BOOL fShowCpu = fOsXGuest;
    2075         /* Always show the CPU leafs when we have multiple VCPUs or when the IO-APIC is enabled.
    2076          * The Windows SMP kernel needs a CPU leaf or else its idle loop will burn cpu cycles; the
    2077          * intelppm driver refuses to register an idle state handler.
    2078          */
    2079         if ((cCpus > 1) || fIOAPIC)
    2080             fShowCpu = true;
    2081 
    2082         hrc = pMachine->COMGETTER(CPUHotPlugEnabled)(&fCpuHotPlug);                     H();
    2083 
    2084         rc = CFGMR3InsertNode(pDevices, "acpi", &pDev);                                 RC_CHECK();
    2085         rc = CFGMR3InsertNode(pDev,     "0", &pInst);                                   RC_CHECK();
    2086         rc = CFGMR3InsertInteger(pInst, "Trusted", 1);              /* boolean */       RC_CHECK();
    2087         rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                               RC_CHECK();
    2088         rc = CFGMR3InsertInteger(pCfg,  "RamSize",          cbRam);                     RC_CHECK();
    2089         rc = CFGMR3InsertInteger(pCfg,  "RamHoleSize",      cbRamHole);                 RC_CHECK();
    2090         rc = CFGMR3InsertInteger(pCfg,  "NumCPUs",          cCpus);                     RC_CHECK();
    2091 
    2092         rc = CFGMR3InsertInteger(pCfg,  "IOAPIC", fIOAPIC);                             RC_CHECK();
    2093         rc = CFGMR3InsertInteger(pCfg,  "FdcEnabled", fFdcEnabled);                     RC_CHECK();
    2094         rc = CFGMR3InsertInteger(pCfg,  "HpetEnabled", fHpetEnabled);                   RC_CHECK();
    2095         rc = CFGMR3InsertInteger(pCfg,  "SmcEnabled", fSmcEnabled);                     RC_CHECK();
    2096         rc = CFGMR3InsertInteger(pCfg,  "ShowRtc",    fOsXGuest);                       RC_CHECK();
    2097         if (fOsXGuest && !llBootNics.empty())
    2098         {
    2099             BootNic aNic = llBootNics.front();
    2100             uint32_t u32NicPciAddr = (aNic.mPciDev << 16) | aNic.mPciFn;
    2101             rc = CFGMR3InsertInteger(pCfg,  "NicPciAddress",    u32NicPciAddr);         RC_CHECK();
    2102         }
    2103         rc = CFGMR3InsertInteger(pCfg,  "ShowCpu", fShowCpu);                           RC_CHECK();
    2104         rc = CFGMR3InsertInteger(pCfg,  "CpuHotPlug", fCpuHotPlug);                     RC_CHECK();
    2105         rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo",          7);                     RC_CHECK();
    2106         Assert(!afPciDeviceNo[7]);
    2107         afPciDeviceNo[7] = true;
    2108         rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo",        0);                     RC_CHECK();
    2109 
    2110         rc = CFGMR3InsertNode(pInst,    "LUN#0", &pLunL0);                              RC_CHECK();
    2111         rc = CFGMR3InsertString(pLunL0, "Driver",               "ACPIHost");            RC_CHECK();
    2112         rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                               RC_CHECK();
    2113 
    2114         /* Attach the dummy CPU drivers */
    2115         for (ULONG iCpuCurr = 1; iCpuCurr < cCpus; iCpuCurr++)
    2116         {
    2117             BOOL fCpuAttached = true;
    2118 
    2119             if (fCpuHotPlug)
    2120             {
    2121                 hrc = pMachine->GetCPUStatus(iCpuCurr, &fCpuAttached);                  H();
    2122             }
    2123 
    2124             if (fCpuAttached)
    2125             {
    2126                 rc = CFGMR3InsertNodeF(pInst, &pLunL0, "LUN#%u", iCpuCurr);             RC_CHECK();
    2127                 rc = CFGMR3InsertString(pLunL0, "Driver",           "ACPICpu");         RC_CHECK();
    2128                 rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                       RC_CHECK();
    2129             }
    2130         }
    2131     }
    2132 
    2133 
    2134     /*
    2135      * CFGM overlay handling.
    2136      *
    2137      * Here we check the extra data entries for CFGM values
    2138      * and create the nodes and insert the values on the fly. Existing
    2139      * values will be removed and reinserted. CFGM is typed, so by default
    2140      * we will guess whether it's a string or an integer (byte arrays are
    2141      * not currently supported). It's possible to override this autodetection
    2142      * by adding "string:", "integer:" or "bytes:" (future).
    2143      *
    2144      * We first perform a run on global extra data, then on the machine
    2145      * extra data to support global settings with local overrides.
    2146      *
    2147      */
    2148     /** @todo add support for removing nodes and byte blobs. */
    2149     SafeArray<BSTR> aGlobalExtraDataKeys;
    2150     SafeArray<BSTR> aMachineExtraDataKeys;
    2151     /*
    2152      * Get the next key
    2153      */
    2154     if (FAILED(hrc = virtualBox->GetExtraDataKeys(ComSafeArrayAsOutParam(aGlobalExtraDataKeys))))
    2155         AssertMsgFailed(("VirtualBox::GetExtraDataKeys failed with %Rrc\n", hrc));
    2156 
    2157     // remember the no. of global values so we can call the correct method below
    2158     size_t cGlobalValues = aGlobalExtraDataKeys.size();
    2159 
    2160     if (FAILED(hrc = pMachine->GetExtraDataKeys(ComSafeArrayAsOutParam(aMachineExtraDataKeys))))
    2161         AssertMsgFailed(("IMachine::GetExtraDataKeys failed with %Rrc\n", hrc));
    2162 
    2163     // build a combined list from global keys...
    2164     std::list<Utf8Str> llExtraDataKeys;
    2165 
    2166     for (size_t i = 0; i < aGlobalExtraDataKeys.size(); ++i)
    2167         llExtraDataKeys.push_back(Utf8Str(aGlobalExtraDataKeys[i]));
    2168     // ... and machine keys
    2169     for (size_t i = 0; i < aMachineExtraDataKeys.size(); ++i)
    2170         llExtraDataKeys.push_back(Utf8Str(aMachineExtraDataKeys[i]));
    2171 
    2172     size_t i2 = 0;
    2173     for (std::list<Utf8Str>::const_iterator it = llExtraDataKeys.begin();
    2174          it != llExtraDataKeys.end();
    2175          ++it, ++i2)
    2176     {
    2177         const Utf8Str &strKey = *it;
    2178 
    2179         /*
    2180          * We only care about keys starting with "VBoxInternal/" (skip "G:" or "M:")
    2181          */
    2182         if (!strKey.startsWith("VBoxInternal/"))
    2183             continue;
    2184 
    2185         const char *pszExtraDataKey = strKey.raw() + sizeof("VBoxInternal/") - 1;
    2186 
    2187         // get the value
    2188         Bstr strExtraDataValue;
    2189         if (i2 < cGlobalValues)
    2190             // this is still one of the global values:
    2191             hrc = virtualBox->GetExtraData(Bstr(strKey), strExtraDataValue.asOutParam());
    2192         else
    2193             hrc = pMachine->GetExtraData(Bstr(strKey), strExtraDataValue.asOutParam());
    2194         if (FAILED(hrc))
    2195             LogRel(("Warning: Cannot get extra data key %s, rc = %Rrc\n", strKey.raw(), hrc));
    2196 
    2197         /*
    2198          * The key will be in the format "Node1/Node2/Value" or simply "Value".
    2199          * Split the two and get the node, delete the value and create the node
    2200          * if necessary.
    2201          */
    2202         PCFGMNODE pNode;
    2203         const char *pszCFGMValueName = strrchr(pszExtraDataKey, '/');
    2204         if (pszCFGMValueName)
    2205         {
    2206             /* terminate the node and advance to the value (Utf8Str might not
    2207                offically like this but wtf) */
    2208             *(char*)pszCFGMValueName = '\0';
    2209             ++pszCFGMValueName;
    2210 
    2211             /* does the node already exist? */
    2212             pNode = CFGMR3GetChild(pRoot, pszExtraDataKey);
    2213             if (pNode)
    2214                 CFGMR3RemoveValue(pNode, pszCFGMValueName);
    2215             else
    2216             {
    2217                 /* create the node */
    2218                 rc = CFGMR3InsertNode(pRoot, pszExtraDataKey, &pNode);
    2219                 if (RT_FAILURE(rc))
    2220                 {
    2221                     AssertLogRelMsgRC(rc, ("failed to insert node '%s'\n", pszExtraDataKey));
    2222                     continue;
    2223                 }
    2224                 Assert(pNode);
    2225             }
    2226         }
    2227         else
    2228         {
    2229             /* root value (no node path). */
    2230             pNode = pRoot;
    2231             pszCFGMValueName = pszExtraDataKey;
    2232             pszExtraDataKey--;
    2233             CFGMR3RemoveValue(pNode, pszCFGMValueName);
    2234         }
    2235 
    2236         /*
    2237          * Now let's have a look at the value.
    2238          * Empty strings means that we should remove the value, which we've
    2239          * already done above.
    2240          */
    2241         Utf8Str strCFGMValueUtf8(strExtraDataValue);
    2242         const char *pszCFGMValue = strCFGMValueUtf8.raw();
    2243         if (    pszCFGMValue
    2244             && *pszCFGMValue)
    2245         {
    2246             uint64_t u64Value;
    2247 
    2248             /* check for type prefix first. */
    2249             if (!strncmp(pszCFGMValue, "string:", sizeof("string:") - 1))
    2250                 rc = CFGMR3InsertString(pNode, pszCFGMValueName, pszCFGMValue + sizeof("string:") - 1);
    2251             else if (!strncmp(pszCFGMValue, "integer:", sizeof("integer:") - 1))
    2252             {
    2253                 rc = RTStrToUInt64Full(pszCFGMValue + sizeof("integer:") - 1, 0, &u64Value);
    2254                 if (RT_SUCCESS(rc))
    2255                     rc = CFGMR3InsertInteger(pNode, pszCFGMValueName, u64Value);
    2256             }
    2257             else if (!strncmp(pszCFGMValue, "bytes:", sizeof("bytes:") - 1))
    2258                 rc = VERR_NOT_IMPLEMENTED;
    2259             /* auto detect type. */
    2260             else if (RT_SUCCESS(RTStrToUInt64Full(pszCFGMValue, 0, &u64Value)))
    2261                 rc = CFGMR3InsertInteger(pNode, pszCFGMValueName, u64Value);
    2262             else
    2263                 rc = CFGMR3InsertString(pNode, pszCFGMValueName, pszCFGMValue);
    2264             AssertLogRelMsgRC(rc, ("failed to insert CFGM value '%s' to key '%s'\n", pszCFGMValue, pszExtraDataKey));
    2265         }
    2266     }
    2267 
    22682414#undef H
    2269 #undef RC_CHECK
    22702415
    22712416    /* Register VM state change handler */
     
    22902435 * Ellipsis to va_list wrapper for calling setVMRuntimeErrorCallback.
    22912436 */
    2292 /*static*/ void Console::setVMRuntimeErrorCallbackF(PVM pVM, void *pvConsole, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
     2437/*static*/
     2438void Console::setVMRuntimeErrorCallbackF(PVM pVM, void *pvConsole, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
    22932439{
    22942440    va_list va;
     
    23342480                                    DeviceType_T *paLedDevType)
    23352481{
    2336     int rc = VINF_SUCCESS;
    2337     HRESULT hrc;
    2338     Bstr    bstr;
    2339 
    2340 #define RC_CHECK()  AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc)
     2482    // InsertConfig* throws
     2483    try
     2484    {
     2485        int rc = VINF_SUCCESS;
     2486        HRESULT hrc;
     2487        Bstr    bstr;
     2488
     2489// #define RC_CHECK()  AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc)
    23412490#define H()         AssertMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE)
    23422491
    2343     LONG lDev;
    2344     hrc = pMediumAtt->COMGETTER(Device)(&lDev);                                         H();
    2345     LONG lPort;
    2346     hrc = pMediumAtt->COMGETTER(Port)(&lPort);                                          H();
    2347     DeviceType_T lType;
    2348     hrc = pMediumAtt->COMGETTER(Type)(&lType);                                          H();
    2349 
    2350     unsigned uLUN;
    2351     PCFGMNODE pLunL0 = NULL;
    2352     PCFGMNODE pCfg = NULL;
    2353     hrc = Console::convertBusPortDeviceToLun(enmBus, lPort, lDev, uLUN);                H();
    2354 
    2355     /* First check if the LUN already exists. */
    2356     pLunL0 = CFGMR3GetChildF(pCtlInst, "LUN#%u", uLUN);
    2357     if (pLunL0)
    2358     {
    2359         if (fAttachDetach)
     2492        LONG lDev;
     2493        hrc = pMediumAtt->COMGETTER(Device)(&lDev);                                         H();
     2494        LONG lPort;
     2495        hrc = pMediumAtt->COMGETTER(Port)(&lPort);                                          H();
     2496        DeviceType_T lType;
     2497        hrc = pMediumAtt->COMGETTER(Type)(&lType);                                          H();
     2498
     2499        unsigned uLUN;
     2500        PCFGMNODE pLunL0 = NULL;
     2501        PCFGMNODE pCfg = NULL;
     2502        hrc = Console::convertBusPortDeviceToLun(enmBus, lPort, lDev, uLUN);                H();
     2503
     2504        /* First check if the LUN already exists. */
     2505        pLunL0 = CFGMR3GetChildF(pCtlInst, "LUN#%u", uLUN);
     2506        if (pLunL0)
    23602507        {
    2361             if (lType != DeviceType_HardDisk)
    2362             {
    2363                 /* Unmount existing media only for floppy and DVD drives. */
    2364                 PPDMIBASE pBase;
    2365                 rc = PDMR3QueryLun(pVM, pcszDevice, uInstance, uLUN, &pBase);
    2366                 if (RT_FAILURE(rc))
    2367                 {
    2368                     if (rc == VERR_PDM_LUN_NOT_FOUND || rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
    2369                         rc = VINF_SUCCESS;
    2370                     AssertRC(rc);
    2371                 }
    2372                 else
    2373                 {
    2374                     PPDMIMOUNT pIMount = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMOUNT);
    2375                     AssertReturn(pIMount, VERR_INVALID_POINTER);
    2376 
    2377                     /* Unmount the media. */
    2378                     rc = pIMount->pfnUnmount(pIMount, fForceUnmount);
    2379                     if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
    2380                         rc = VINF_SUCCESS;
    2381                 }
    2382             }
    2383 
    2384             rc = PDMR3DeviceDetach(pVM, pcszDevice, 0, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
    2385             if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
    2386                 rc = VINF_SUCCESS;
    2387             RC_CHECK();
    2388 
    2389             CFGMR3RemoveNode(pLunL0);
     2508            if (fAttachDetach)
     2509            {
     2510                if (lType != DeviceType_HardDisk)
     2511                {
     2512                    /* Unmount existing media only for floppy and DVD drives. */
     2513                    PPDMIBASE pBase;
     2514                    rc = PDMR3QueryLun(pVM, pcszDevice, uInstance, uLUN, &pBase);
     2515                    if (RT_FAILURE(rc))
     2516                    {
     2517                        if (rc == VERR_PDM_LUN_NOT_FOUND || rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
     2518                            rc = VINF_SUCCESS;
     2519                        AssertRC(rc);
     2520                    }
     2521                    else
     2522                    {
     2523                        PPDMIMOUNT pIMount = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMOUNT);
     2524                        AssertReturn(pIMount, VERR_INVALID_POINTER);
     2525
     2526                        /* Unmount the media. */
     2527                        rc = pIMount->pfnUnmount(pIMount, fForceUnmount);
     2528                        if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
     2529                            rc = VINF_SUCCESS;
     2530                    }
     2531                }
     2532
     2533                rc = PDMR3DeviceDetach(pVM, pcszDevice, 0, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
     2534                if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
     2535                    rc = VINF_SUCCESS;
     2536                AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc);
     2537
     2538                CFGMR3RemoveNode(pLunL0);
     2539            }
     2540            else
     2541                AssertFailedReturn(VERR_INTERNAL_ERROR);
    23902542        }
    2391         else
    2392             AssertFailedReturn(VERR_INTERNAL_ERROR);
    2393     }
    2394 
    2395     rc = CFGMR3InsertNodeF(pCtlInst, &pLunL0, "LUN#%u", uLUN);                          RC_CHECK();
    2396 
    2397     /* SCSI has a another driver between device and block. */
    2398     if (enmBus == StorageBus_SCSI || enmBus == StorageBus_SAS)
    2399     {
    2400         rc = CFGMR3InsertString(pLunL0, "Driver", "SCSI");                              RC_CHECK();
    2401         rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                                 RC_CHECK();
    2402 
    2403         rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);                       RC_CHECK();
    2404     }
    2405 
    2406     ComPtr<IMedium> pMedium;
    2407     hrc = pMediumAtt->COMGETTER(Medium)(pMedium.asOutParam());                          H();
    2408 
    2409     if (lType == DeviceType_HardDisk)
    2410     {
    2411         /*
    2412          * Some sanity checks.
    2413          */
    2414         ComPtr<IMediumFormat> pMediumFormat;
    2415         hrc = pMedium->COMGETTER(MediumFormat)(pMediumFormat.asOutParam());             H();
    2416         ULONG uCaps;
    2417         hrc = pMediumFormat->COMGETTER(Capabilities)(&uCaps);                           H();
    2418         if (uCaps & MediumFormatCapabilities_File)
     2543
     2544        InsertConfigNode(pCtlInst, Utf8StrFmt("LUN#%u", uLUN).c_str(), &pLunL0);
     2545
     2546        /* SCSI has a another driver between device and block. */
     2547        if (enmBus == StorageBus_SCSI || enmBus == StorageBus_SAS)
    24192548        {
    2420             Bstr strFile;
    2421             hrc = pMedium->COMGETTER(Location)(strFile.asOutParam());                   H();
    2422             Utf8Str utfFile = Utf8Str(strFile);
    2423             Bstr strSnap;
    2424             ComPtr<IMachine> pMachine = machine();
    2425             hrc = pMachine->COMGETTER(SnapshotFolder)(strSnap.asOutParam());            H();
    2426             Utf8Str utfSnap = Utf8Str(strSnap);
    2427             RTFSTYPE enmFsTypeFile = RTFSTYPE_UNKNOWN;
    2428             RTFSTYPE enmFsTypeSnap = RTFSTYPE_UNKNOWN;
    2429             int rc2 = RTFsQueryType(utfFile.c_str(), &enmFsTypeFile);
    2430             AssertMsgRCReturn(rc2, ("Querying the file type of '%s' failed!\n", utfFile.c_str()), rc2);
    2431             /* Ignore the error code. On error, the file system type is still 'unknown' so
    2432              * none of the following pathes is taken. This can happen for new VMs which
    2433              * still don't have a snapshot folder. */
    2434             (void)RTFsQueryType(utfSnap.c_str(), &enmFsTypeSnap);
    2435             LogRel(("File system of '%s' is %s\n", utfFile.c_str(), RTFsTypeName(enmFsTypeFile)));
    2436             ULONG64 u64Size;
    2437             hrc = pMedium->COMGETTER(LogicalSize)(&u64Size);                            H();
    2438             u64Size *= _1M;
     2549            InsertConfigString(pLunL0, "Driver", "SCSI");
     2550            InsertConfigNode(pLunL0, "Config", &pCfg);
     2551
     2552            InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
     2553        }
     2554
     2555        ComPtr<IMedium> pMedium;
     2556        hrc = pMediumAtt->COMGETTER(Medium)(pMedium.asOutParam());                          H();
     2557
     2558        if (lType == DeviceType_HardDisk)
     2559        {
     2560            /*
     2561             * Some sanity checks.
     2562             */
     2563            ComPtr<IMediumFormat> pMediumFormat;
     2564            hrc = pMedium->COMGETTER(MediumFormat)(pMediumFormat.asOutParam());             H();
     2565            ULONG uCaps;
     2566            hrc = pMediumFormat->COMGETTER(Capabilities)(&uCaps);                           H();
     2567            if (uCaps & MediumFormatCapabilities_File)
     2568            {
     2569                Bstr strFile;
     2570                hrc = pMedium->COMGETTER(Location)(strFile.asOutParam());                   H();
     2571                Utf8Str utfFile = Utf8Str(strFile);
     2572                Bstr strSnap;
     2573                ComPtr<IMachine> pMachine = machine();
     2574                hrc = pMachine->COMGETTER(SnapshotFolder)(strSnap.asOutParam());            H();
     2575                Utf8Str utfSnap = Utf8Str(strSnap);
     2576                RTFSTYPE enmFsTypeFile = RTFSTYPE_UNKNOWN;
     2577                RTFSTYPE enmFsTypeSnap = RTFSTYPE_UNKNOWN;
     2578                int rc2 = RTFsQueryType(utfFile.c_str(), &enmFsTypeFile);
     2579                AssertMsgRCReturn(rc2, ("Querying the file type of '%s' failed!\n", utfFile.c_str()), rc2);
     2580                /* Ignore the error code. On error, the file system type is still 'unknown' so
     2581                 * none of the following pathes is taken. This can happen for new VMs which
     2582                 * still don't have a snapshot folder. */
     2583                (void)RTFsQueryType(utfSnap.c_str(), &enmFsTypeSnap);
     2584                LogRel(("File system of '%s' is %s\n", utfFile.c_str(), RTFsTypeName(enmFsTypeFile)));
     2585                ULONG64 u64Size;
     2586                hrc = pMedium->COMGETTER(LogicalSize)(&u64Size);                            H();
     2587                u64Size *= _1M;
    24392588#ifdef RT_OS_WINDOWS
    2440             if (   enmFsTypeFile == RTFSTYPE_FAT
    2441                 && u64Size >= _4G)
    2442             {
    2443                 const char *pszUnit;
    2444                 uint64_t u64Print = formatDiskSize(u64Size, &pszUnit);
    2445                 setVMRuntimeErrorCallbackF(pVM, this, 0,
    2446                         "FatPartitionDetected",
    2447                         N_("The medium '%ls' has a logical size of %RU64%s "
    2448                            "but the file system the medium is located on seems "
    2449                            "to be FAT(32) which cannot handle files bigger than 4GB.\n"
    2450                            "We strongly recommend to put all your virtual disk images and "
    2451                            "the snapshot folder onto an NTFS partition"),
    2452                         strFile.raw(), u64Print, pszUnit);
    2453             }
     2589                if (   enmFsTypeFile == RTFSTYPE_FAT
     2590                    && u64Size >= _4G)
     2591                {
     2592                    const char *pszUnit;
     2593                    uint64_t u64Print = formatDiskSize(u64Size, &pszUnit);
     2594                    setVMRuntimeErrorCallbackF(pVM, this, 0,
     2595                            "FatPartitionDetected",
     2596                            N_("The medium '%ls' has a logical size of %RU64%s "
     2597                            "but the file system the medium is located on seems "
     2598                            "to be FAT(32) which cannot handle files bigger than 4GB.\n"
     2599                            "We strongly recommend to put all your virtual disk images and "
     2600                            "the snapshot folder onto an NTFS partition"),
     2601                            strFile.raw(), u64Print, pszUnit);
     2602                }
    24542603#else /* !RT_OS_WINDOWS */
    2455             if (   enmFsTypeFile == RTFSTYPE_FAT
    2456                 || enmFsTypeFile == RTFSTYPE_EXT
    2457                 || enmFsTypeFile == RTFSTYPE_EXT2
    2458                 || enmFsTypeFile == RTFSTYPE_EXT3
    2459                 || enmFsTypeFile == RTFSTYPE_EXT4)
    2460             {
    2461                 RTFILE file;
    2462                 rc = RTFileOpen(&file, utfFile.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    2463                 if (RT_SUCCESS(rc))
    2464                 {
    2465                     RTFOFF maxSize;
    2466                     /* Careful: This function will work only on selected local file systems! */
    2467                     rc = RTFileGetMaxSizeEx(file, &maxSize);
    2468                     RTFileClose(file);
    2469                     if (   RT_SUCCESS(rc)
    2470                         && maxSize > 0
    2471                         && u64Size > (ULONG64)maxSize)
     2604                if (   enmFsTypeFile == RTFSTYPE_FAT
     2605                    || enmFsTypeFile == RTFSTYPE_EXT
     2606                    || enmFsTypeFile == RTFSTYPE_EXT2
     2607                    || enmFsTypeFile == RTFSTYPE_EXT3
     2608                    || enmFsTypeFile == RTFSTYPE_EXT4)
     2609                {
     2610                    RTFILE file;
     2611                    rc = RTFileOpen(&file, utfFile.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
     2612                    if (RT_SUCCESS(rc))
    24722613                    {
    2473                         const char *pszUnitSiz;
    2474                         const char *pszUnitMax;
    2475                         uint64_t u64PrintSiz = formatDiskSize(u64Size, &pszUnitSiz);
    2476                         uint64_t u64PrintMax = formatDiskSize(maxSize, &pszUnitMax);
    2477                         setVMRuntimeErrorCallbackF(pVM, this, 0,
    2478                                 "FatPartitionDetected", /* <= not exact but ... */
    2479                                 N_("The medium '%ls' has a logical size of %RU64%s "
    2480                                    "but the file system the medium is located on can "
    2481                                    "only handle files up to %RU64%s in theory.\n"
    2482                                    "We strongly recommend to put all your virtual disk "
    2483                                    "images and the snapshot folder onto a proper "
    2484                                    "file system (e.g. ext3) with a sufficient size"),
    2485                                 strFile.raw(), u64PrintSiz, pszUnitSiz, u64PrintMax, pszUnitMax);
     2614                        RTFOFF maxSize;
     2615                        /* Careful: This function will work only on selected local file systems! */
     2616                        rc = RTFileGetMaxSizeEx(file, &maxSize);
     2617                        RTFileClose(file);
     2618                        if (   RT_SUCCESS(rc)
     2619                            && maxSize > 0
     2620                            && u64Size > (ULONG64)maxSize)
     2621                        {
     2622                            const char *pszUnitSiz;
     2623                            const char *pszUnitMax;
     2624                            uint64_t u64PrintSiz = formatDiskSize(u64Size, &pszUnitSiz);
     2625                            uint64_t u64PrintMax = formatDiskSize(maxSize, &pszUnitMax);
     2626                            setVMRuntimeErrorCallbackF(pVM, this, 0,
     2627                                    "FatPartitionDetected", /* <= not exact but ... */
     2628                                    N_("The medium '%ls' has a logical size of %RU64%s "
     2629                                    "but the file system the medium is located on can "
     2630                                    "only handle files up to %RU64%s in theory.\n"
     2631                                    "We strongly recommend to put all your virtual disk "
     2632                                    "images and the snapshot folder onto a proper "
     2633                                    "file system (e.g. ext3) with a sufficient size"),
     2634                                    strFile.raw(), u64PrintSiz, pszUnitSiz, u64PrintMax, pszUnitMax);
     2635                        }
    24862636                    }
    24872637                }
    2488             }
    24892638#endif /* !RT_OS_WINDOWS */
    24902639
    2491             /*
    2492              * Snapshot folder:
    2493              * Here we test only for a FAT partition as we had to create a dummy file otherwise
    2494              */
    2495             if (   enmFsTypeSnap == RTFSTYPE_FAT
    2496                 && u64Size >= _4G
    2497                 && !mfSnapshotFolderSizeWarningShown)
    2498             {
    2499                 const char *pszUnit;
    2500                 uint64_t u64Print = formatDiskSize(u64Size, &pszUnit);
    2501                 setVMRuntimeErrorCallbackF(pVM, this, 0,
    2502                         "FatPartitionDetected",
     2640                /*
     2641                 * Snapshot folder:
     2642                 * Here we test only for a FAT partition as we had to create a dummy file otherwise
     2643                 */
     2644                if (   enmFsTypeSnap == RTFSTYPE_FAT
     2645                    && u64Size >= _4G
     2646                    && !mfSnapshotFolderSizeWarningShown)
     2647                {
     2648                    const char *pszUnit;
     2649                    uint64_t u64Print = formatDiskSize(u64Size, &pszUnit);
     2650                    setVMRuntimeErrorCallbackF(pVM, this, 0,
     2651                            "FatPartitionDetected",
    25032652#ifdef RT_OS_WINDOWS
    2504                         N_("The snapshot folder of this VM '%ls' seems to be located on "
    2505                            "a FAT(32) file system. The logical size of the medium '%ls' "
    2506                            "(%RU64%s) is bigger than the maximum file size this file "
    2507                            "system can handle (4GB).\n"
    2508                            "We strongly recommend to put all your virtual disk images and "
    2509                            "the snapshot folder onto an NTFS partition"),
    2510 #else
    2511                         N_("The snapshot folder of this VM '%ls' seems to be located on "
     2653                            N_("The snapshot folder of this VM '%ls' seems to be located on "
    25122654                            "a FAT(32) file system. The logical size of the medium '%ls' "
    25132655                            "(%RU64%s) is bigger than the maximum file size this file "
    25142656                            "system can handle (4GB).\n"
    25152657                            "We strongly recommend to put all your virtual disk images and "
    2516                             "the snapshot folder onto a proper file system (e.g. ext3)"),
     2658                            "the snapshot folder onto an NTFS partition"),
     2659#else
     2660                            N_("The snapshot folder of this VM '%ls' seems to be located on "
     2661                                "a FAT(32) file system. The logical size of the medium '%ls' "
     2662                                "(%RU64%s) is bigger than the maximum file size this file "
     2663                                "system can handle (4GB).\n"
     2664                                "We strongly recommend to put all your virtual disk images and "
     2665                                "the snapshot folder onto a proper file system (e.g. ext3)"),
    25172666#endif
    2518                         strSnap.raw(), strFile.raw(), u64Print, pszUnit);
    2519                 /* Show this particular warning only once */
    2520                 mfSnapshotFolderSizeWarningShown = true;
    2521             }
     2667                            strSnap.raw(), strFile.raw(), u64Print, pszUnit);
     2668                    /* Show this particular warning only once */
     2669                    mfSnapshotFolderSizeWarningShown = true;
     2670                }
    25222671
    25232672#ifdef RT_OS_LINUX
    2524             /*
    2525              * Ext4 bug: Check if the host I/O cache is disabled and the disk image is located
    2526              *           on an ext4 partition. Later we have to check the Linux kernel version!
    2527              * This bug apparently applies to the XFS file system as well.
    2528              */
    2529             if (   (uCaps & MediumFormatCapabilities_Asynchronous)
    2530                 && !fUseHostIOCache
    2531                 && (   enmFsTypeFile == RTFSTYPE_EXT4
    2532                     || enmFsTypeFile == RTFSTYPE_XFS))
    2533             {
    2534                 setVMRuntimeErrorCallbackF(pVM, this, 0,
    2535                         "Ext4PartitionDetected",
    2536                         N_("The host I/O cache for at least one controller is disabled "
    2537                            "and the medium '%ls' for this VM "
    2538                            "is located on an %s partition. There is a known Linux "
    2539                            "kernel bug which can lead to the corruption of the virtual "
    2540                            "disk image under these conditions.\n"
    2541                            "Either enable the host I/O cache permanently in the VM "
    2542                            "settings or put the disk image and the snapshot folder "
    2543                            "onto a different file system.\n"
    2544                            "The host I/O cache will now be enabled for this medium"),
    2545                         strFile.raw(), enmFsTypeFile == RTFSTYPE_EXT4 ? "ext4" : "xfs");
    2546                 fUseHostIOCache = true;
    2547             }
    2548             else if (   (uCaps & MediumFormatCapabilities_Asynchronous)
    2549                      && !fUseHostIOCache
    2550                      && (   enmFsTypeSnap == RTFSTYPE_EXT4
    2551                          || enmFsTypeSnap == RTFSTYPE_XFS)
    2552                      && !mfSnapshotFolderExt4WarningShown)
    2553             {
    2554                 setVMRuntimeErrorCallbackF(pVM, this, 0,
    2555                         "Ext4PartitionDetected",
    2556                         N_("The host I/O cache for at least one controller is disabled "
    2557                            "and the snapshot folder for this VM "
    2558                            "is located on an %s partition. There is a known Linux "
    2559                            "kernel bug which can lead to the corruption of the virtual "
    2560                            "disk image under these conditions.\n"
    2561                            "Either enable the host I/O cache permanently in the VM "
    2562                            "settings or put the disk image and the snapshot folder "
    2563                            "onto a different file system.\n"
    2564                            "The host I/O cache will now be enabled for this medium"),
    2565                         enmFsTypeSnap == RTFSTYPE_EXT4 ? "ext4" : "xfs");
    2566                 fUseHostIOCache = true;
    2567                 mfSnapshotFolderExt4WarningShown = true;
    2568             }
     2673                /*
     2674                 * Ext4 bug: Check if the host I/O cache is disabled and the disk image is located
     2675                 *           on an ext4 partition. Later we have to check the Linux kernel version!
     2676                 * This bug apparently applies to the XFS file system as well.
     2677                 */
     2678                if (   (uCaps & MediumFormatCapabilities_Asynchronous)
     2679                    && !fUseHostIOCache
     2680                    && (   enmFsTypeFile == RTFSTYPE_EXT4
     2681                        || enmFsTypeFile == RTFSTYPE_XFS))
     2682                {
     2683                    setVMRuntimeErrorCallbackF(pVM, this, 0,
     2684                            "Ext4PartitionDetected",
     2685                            N_("The host I/O cache for at least one controller is disabled "
     2686                            "and the medium '%ls' for this VM "
     2687                            "is located on an %s partition. There is a known Linux "
     2688                            "kernel bug which can lead to the corruption of the virtual "
     2689                            "disk image under these conditions.\n"
     2690                            "Either enable the host I/O cache permanently in the VM "
     2691                            "settings or put the disk image and the snapshot folder "
     2692                            "onto a different file system.\n"
     2693                            "The host I/O cache will now be enabled for this medium"),
     2694                            strFile.raw(), enmFsTypeFile == RTFSTYPE_EXT4 ? "ext4" : "xfs");
     2695                    fUseHostIOCache = true;
     2696                }
     2697                else if (   (uCaps & MediumFormatCapabilities_Asynchronous)
     2698                        && !fUseHostIOCache
     2699                        && (   enmFsTypeSnap == RTFSTYPE_EXT4
     2700                            || enmFsTypeSnap == RTFSTYPE_XFS)
     2701                        && !mfSnapshotFolderExt4WarningShown)
     2702                {
     2703                    setVMRuntimeErrorCallbackF(pVM, this, 0,
     2704                            "Ext4PartitionDetected",
     2705                            N_("The host I/O cache for at least one controller is disabled "
     2706                            "and the snapshot folder for this VM "
     2707                            "is located on an %s partition. There is a known Linux "
     2708                            "kernel bug which can lead to the corruption of the virtual "
     2709                            "disk image under these conditions.\n"
     2710                            "Either enable the host I/O cache permanently in the VM "
     2711                            "settings or put the disk image and the snapshot folder "
     2712                            "onto a different file system.\n"
     2713                            "The host I/O cache will now be enabled for this medium"),
     2714                            enmFsTypeSnap == RTFSTYPE_EXT4 ? "ext4" : "xfs");
     2715                    fUseHostIOCache = true;
     2716                    mfSnapshotFolderExt4WarningShown = true;
     2717                }
    25692718#endif
     2719            }
    25702720        }
     2721
     2722        BOOL fPassthrough;
     2723        hrc = pMediumAtt->COMGETTER(Passthrough)(&fPassthrough);                            H();
     2724        rc = configMedium(pLunL0,
     2725                        !!fPassthrough,
     2726                        lType,
     2727                        fUseHostIOCache,
     2728                        fSetupMerge,
     2729                        uMergeSource,
     2730                        uMergeTarget,
     2731                        pMedium,
     2732                        aMachineState,
     2733                        phrc);
     2734        if (RT_FAILURE(rc))
     2735            return rc;
     2736
     2737        if (fAttachDetach)
     2738        {
     2739            /* Attach the new driver. */
     2740            rc = PDMR3DeviceAttach(pVM, pcszDevice, 0, uLUN,
     2741                                PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
     2742            AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc);
     2743
     2744            /* There is no need to handle removable medium mounting, as we
     2745             * unconditionally replace everthing including the block driver level.
     2746             * This means the new medium will be picked up automatically. */
     2747        }
     2748
     2749        if (paLedDevType)
     2750            paLedDevType[uLUN] = lType;
    25712751    }
    2572 
    2573     BOOL fPassthrough;
    2574     hrc = pMediumAtt->COMGETTER(Passthrough)(&fPassthrough);                            H();
    2575     rc = configMedium(pLunL0,
    2576                       !!fPassthrough,
    2577                       lType,
    2578                       fUseHostIOCache,
    2579                       fSetupMerge,
    2580                       uMergeSource,
    2581                       uMergeTarget,
    2582                       pMedium,
    2583                       aMachineState,
    2584                       phrc);                                                            RC_CHECK();
    2585 
    2586     if (fAttachDetach)
     2752    catch (ConfigError &x)
    25872753    {
    2588         /* Attach the new driver. */
    2589         rc = PDMR3DeviceAttach(pVM, pcszDevice, 0, uLUN,
    2590                                PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);           RC_CHECK();
    2591 
    2592         /* There is no need to handle removable medium mounting, as we
    2593          * unconditionally replace everthing including the block driver level.
    2594          * This means the new medium will be picked up automatically. */
     2754        // InsertConfig threw something:
     2755        return x.m_vrc;
    25952756    }
    25962757
    2597     if (paLedDevType)
    2598         paLedDevType[uLUN] = lType;
    2599 
    26002758#undef H
    2601 #undef RC_CHECK
    26022759
    26032760    return VINF_SUCCESS;;
     
    26152772                          HRESULT *phrc)
    26162773{
    2617     int rc = VINF_SUCCESS;
    2618     HRESULT hrc;
    2619     Bstr bstr;
    2620 
    2621 #define RC_CHECK()  AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc)
     2774    // InsertConfig* throws
     2775    try
     2776    {
     2777        int rc = VINF_SUCCESS;
     2778        HRESULT hrc;
     2779        Bstr bstr;
     2780
    26222781#define H()         AssertMsgReturnStmt(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), if (phrc) *phrc = hrc, VERR_GENERAL_FAILURE)
    26232782
    2624     PCFGMNODE pLunL1 = NULL;
    2625     PCFGMNODE pCfg = NULL;
    2626 
    2627     BOOL fHostDrive = FALSE;
    2628     if (pMedium)
    2629     {
    2630         hrc = pMedium->COMGETTER(HostDrive)(&fHostDrive);                               H();
    2631     }
    2632 
    2633     if (fHostDrive)
    2634     {
    2635         Assert(pMedium);
    2636         if (enmType == DeviceType_DVD)
    2637         {
    2638             rc = CFGMR3InsertString(pLunL0, "Driver", "HostDVD");                       RC_CHECK();
    2639             rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                             RC_CHECK();
    2640 
    2641             hrc = pMedium->COMGETTER(Location)(bstr.asOutParam());                      H();
    2642             rc = CFGMR3InsertStringW(pCfg, "Path", bstr.raw());                         RC_CHECK();
    2643 
    2644             rc = CFGMR3InsertInteger(pCfg, "Passthrough", fPassthrough);                RC_CHECK();
    2645         }
    2646         else if (enmType == DeviceType_Floppy)
    2647         {
    2648             rc = CFGMR3InsertString(pLunL0, "Driver", "HostFloppy");                    RC_CHECK();
    2649             rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                             RC_CHECK();
    2650 
    2651             hrc = pMedium->COMGETTER(Location)(bstr.asOutParam());                      H();
    2652             rc = CFGMR3InsertStringW(pCfg, "Path", bstr.raw());                         RC_CHECK();
    2653         }
    2654     }
    2655     else
    2656     {
    2657         rc = CFGMR3InsertString(pLunL0, "Driver", "Block");                             RC_CHECK();
    2658         rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                                 RC_CHECK();
    2659         switch (enmType)
    2660         {
    2661             case DeviceType_DVD:
    2662                 rc = CFGMR3InsertString(pCfg, "Type", "DVD");                           RC_CHECK();
    2663                 rc = CFGMR3InsertInteger(pCfg, "Mountable", 1);                         RC_CHECK();
    2664                 break;
    2665             case DeviceType_Floppy:
    2666                 rc = CFGMR3InsertString(pCfg, "Type", "Floppy 1.44");                   RC_CHECK();
    2667                 rc = CFGMR3InsertInteger(pCfg, "Mountable", 1);                         RC_CHECK();
    2668                 break;
    2669             case DeviceType_HardDisk:
    2670             default:
    2671                 rc = CFGMR3InsertString(pCfg, "Type", "HardDisk");                      RC_CHECK();
    2672                 rc = CFGMR3InsertInteger(pCfg, "Mountable", 0);                         RC_CHECK();
    2673         }
    2674 
    2675         if (    pMedium
    2676              && (    enmType == DeviceType_DVD
    2677                   || enmType == DeviceType_Floppy
    2678            ))
    2679         {
    2680             // if this medium represents an ISO image and this image is inaccessible,
    2681             // the ignore it instead of causing a failure; this can happen when we
    2682             // restore a VM state and the ISO has disappeared, e.g. because the Guest
    2683             // Additions were mounted and the user upgraded VirtualBox. Previously
    2684             // we failed on startup, but that's not good because the only way out then
    2685             // would be to discard the VM state...
    2686             MediumState_T mediumState;
    2687             rc = pMedium->RefreshState(&mediumState);
    2688             RC_CHECK();
    2689             if (mediumState == MediumState_Inaccessible)
    2690             {
    2691                 Bstr loc;
    2692                 rc = pMedium->COMGETTER(Location)(loc.asOutParam());
    2693                 if (FAILED(rc)) return rc;
    2694 
    2695                 setVMRuntimeErrorCallbackF(mpVM,
    2696                                            this,
    2697                                            0,
    2698                                            "DvdOrFloppyImageInaccessible",
    2699                                            "The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
    2700                                            loc.raw(),
    2701                                            (enmType == DeviceType_DVD) ? "DVD" : "floppy");
    2702                 pMedium = NULL;
    2703             }
    2704         }
    2705 
     2783        PCFGMNODE pLunL1 = NULL;
     2784        PCFGMNODE pCfg = NULL;
     2785
     2786        BOOL fHostDrive = FALSE;
    27062787        if (pMedium)
    27072788        {
    2708             /* Start with length of parent chain, as the list is reversed */
    2709             unsigned uImage = 0;
    2710             IMedium *pTmp = pMedium;
    2711             while (pTmp)
    2712             {
    2713                 uImage++;
    2714                 hrc = pTmp->COMGETTER(Parent)(&pTmp);                                   H();
    2715             }
    2716             /* Index of last image */
    2717             uImage--;
     2789            hrc = pMedium->COMGETTER(HostDrive)(&fHostDrive);                               H();
     2790        }
     2791
     2792        if (fHostDrive)
     2793        {
     2794            Assert(pMedium);
     2795            if (enmType == DeviceType_DVD)
     2796            {
     2797                InsertConfigString(pLunL0, "Driver", "HostDVD");
     2798                InsertConfigNode(pLunL0, "Config", &pCfg);
     2799
     2800                hrc = pMedium->COMGETTER(Location)(bstr.asOutParam());                      H();
     2801                InsertConfigString(pCfg, "Path", bstr);
     2802
     2803                InsertConfigInteger(pCfg, "Passthrough", fPassthrough);
     2804            }
     2805            else if (enmType == DeviceType_Floppy)
     2806            {
     2807                InsertConfigString(pLunL0, "Driver", "HostFloppy");
     2808                InsertConfigNode(pLunL0, "Config", &pCfg);
     2809
     2810                hrc = pMedium->COMGETTER(Location)(bstr.asOutParam());                      H();
     2811                InsertConfigString(pCfg, "Path", bstr);
     2812            }
     2813        }
     2814        else
     2815        {
     2816            InsertConfigString(pLunL0, "Driver", "Block");
     2817            InsertConfigNode(pLunL0, "Config", &pCfg);
     2818            switch (enmType)
     2819            {
     2820                case DeviceType_DVD:
     2821                    InsertConfigString(pCfg, "Type", "DVD");
     2822                    InsertConfigInteger(pCfg, "Mountable", 1);
     2823                    break;
     2824                case DeviceType_Floppy:
     2825                    InsertConfigString(pCfg, "Type", "Floppy 1.44");
     2826                    InsertConfigInteger(pCfg, "Mountable", 1);
     2827                    break;
     2828                case DeviceType_HardDisk:
     2829                default:
     2830                    InsertConfigString(pCfg, "Type", "HardDisk");
     2831                    InsertConfigInteger(pCfg, "Mountable", 0);
     2832            }
     2833
     2834            if (    pMedium
     2835                && (    enmType == DeviceType_DVD
     2836                    || enmType == DeviceType_Floppy
     2837            ))
     2838            {
     2839                // if this medium represents an ISO image and this image is inaccessible,
     2840                // the ignore it instead of causing a failure; this can happen when we
     2841                // restore a VM state and the ISO has disappeared, e.g. because the Guest
     2842                // Additions were mounted and the user upgraded VirtualBox. Previously
     2843                // we failed on startup, but that's not good because the only way out then
     2844                // would be to discard the VM state...
     2845                MediumState_T mediumState;
     2846                rc = pMedium->RefreshState(&mediumState);
     2847                AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc);
     2848
     2849                if (mediumState == MediumState_Inaccessible)
     2850                {
     2851                    Bstr loc;
     2852                    rc = pMedium->COMGETTER(Location)(loc.asOutParam());
     2853                    if (FAILED(rc)) return rc;
     2854
     2855                    setVMRuntimeErrorCallbackF(mpVM,
     2856                                            this,
     2857                                            0,
     2858                                            "DvdOrFloppyImageInaccessible",
     2859                                            "The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
     2860                                            loc.raw(),
     2861                                            (enmType == DeviceType_DVD) ? "DVD" : "floppy");
     2862                    pMedium = NULL;
     2863                }
     2864            }
     2865
     2866            if (pMedium)
     2867            {
     2868                /* Start with length of parent chain, as the list is reversed */
     2869                unsigned uImage = 0;
     2870                IMedium *pTmp = pMedium;
     2871                while (pTmp)
     2872                {
     2873                    uImage++;
     2874                    hrc = pTmp->COMGETTER(Parent)(&pTmp);                                   H();
     2875                }
     2876                /* Index of last image */
     2877                uImage--;
    27182878
    27192879#if 0 /* Enable for I/O debugging */
    2720             rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);                   RC_CHECK();
    2721             rc = CFGMR3InsertString(pLunL0, "Driver", "DiskIntegrity");                 RC_CHECK();
    2722             rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                             RC_CHECK();
    2723             rc = CFGMR3InsertInteger(pCfg, "CheckConsistency", 0);                      RC_CHECK();
    2724             rc = CFGMR3InsertInteger(pCfg, "CheckDoubleCompletions", 1);                RC_CHECK();
     2880                InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
     2881                InsertConfigString(pLunL0, "Driver", "DiskIntegrity");
     2882                InsertConfigNode(pLunL0, "Config", &pCfg);
     2883                InsertConfigInteger(pCfg, "CheckConsistency", 0);
     2884                InsertConfigInteger(pCfg, "CheckDoubleCompletions", 1);
    27252885#endif
    27262886
    2727             rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1);                   RC_CHECK();
    2728             rc = CFGMR3InsertString(pLunL1, "Driver", "VD");                            RC_CHECK();
    2729             rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg);                             RC_CHECK();
    2730 
    2731             hrc = pMedium->COMGETTER(Location)(bstr.asOutParam());                      H();
    2732             rc = CFGMR3InsertStringW(pCfg, "Path", bstr.raw());                         RC_CHECK();
    2733 
    2734             hrc = pMedium->COMGETTER(Format)(bstr.asOutParam());                        H();
    2735             rc = CFGMR3InsertStringW(pCfg, "Format", bstr.raw());                       RC_CHECK();
    2736 
    2737             /* DVDs are always readonly */
    2738             if (enmType == DeviceType_DVD)
    2739             {
    2740                 rc = CFGMR3InsertInteger(pCfg, "ReadOnly", 1);                          RC_CHECK();
    2741             }
    2742 
    2743             /* Start without exclusive write access to the images. */
    2744             /** @todo Live Migration: I don't quite like this, we risk screwing up when
    2745              *        we're resuming the VM if some 3rd dude have any of the VDIs open
    2746              *        with write sharing denied.  However, if the two VMs are sharing a
    2747              *        image it really is necessary....
    2748              *
    2749              *        So, on the "lock-media" command, the target teleporter should also
    2750              *        make DrvVD undo TempReadOnly.  It gets interesting if we fail after
    2751              *        that. Grumble. */
    2752             else if (aMachineState == MachineState_TeleportingIn)
    2753             {
    2754                 rc = CFGMR3InsertInteger(pCfg, "TempReadOnly", 1);                      RC_CHECK();
    2755             }
    2756 
    2757             if (!fUseHostIOCache)
    2758             {
    2759                 rc = CFGMR3InsertInteger(pCfg, "UseNewIo", 1);                          RC_CHECK();
    2760             }
    2761 
    2762             if (fSetupMerge)
    2763             {
    2764                 rc = CFGMR3InsertInteger(pCfg, "SetupMerge", 1);                        RC_CHECK();
    2765                 if (uImage == uMergeSource)
    2766                 {
    2767                     rc = CFGMR3InsertInteger(pCfg, "MergeSource", 1);                   RC_CHECK();
    2768                 }
    2769                 else if (uImage == uMergeTarget)
    2770                 {
    2771                     rc = CFGMR3InsertInteger(pCfg, "MergeTarget", 1);                   RC_CHECK();
    2772                 }
    2773             }
    2774 
    2775             /* Pass all custom parameters. */
    2776             bool fHostIP = true;
    2777             SafeArray<BSTR> names;
    2778             SafeArray<BSTR> values;
    2779             hrc = pMedium->GetProperties(NULL,
    2780                                          ComSafeArrayAsOutParam(names),
    2781                                          ComSafeArrayAsOutParam(values));               H();
    2782 
    2783             if (names.size() != 0)
    2784             {
    2785                 PCFGMNODE pVDC;
    2786                 rc = CFGMR3InsertNode(pCfg, "VDConfig", &pVDC);                         RC_CHECK();
    2787                 for (size_t ii = 0; ii < names.size(); ++ii)
    2788                 {
    2789                     if (values[ii] && *values[ii])
    2790                     {
    2791                         Utf8Str name = names[ii];
    2792                         Utf8Str value = values[ii];
    2793                         rc = CFGMR3InsertString(pVDC, name.c_str(), value.c_str());     RC_CHECK();
    2794                         if (    name.compare("HostIPStack") == 0
    2795                             &&  value.compare("0") == 0)
    2796                             fHostIP = false;
    2797                     }
    2798                 }
    2799             }
    2800 
    2801             /* Create an inversed list of parents. */
    2802             uImage--;
    2803             IMedium *pParentMedium = pMedium;
    2804             for (PCFGMNODE pParent = pCfg;; uImage--)
    2805             {
    2806                 hrc = pParentMedium->COMGETTER(Parent)(&pMedium);                       H();
    2807                 if (!pMedium)
    2808                     break;
    2809 
    2810                 PCFGMNODE pCur;
    2811                 rc = CFGMR3InsertNode(pParent, "Parent", &pCur);                        RC_CHECK();
    2812                 hrc = pMedium->COMGETTER(Location)(bstr.asOutParam());                  H();
    2813                 rc = CFGMR3InsertStringW(pCur, "Path", bstr.raw());                     RC_CHECK();
    2814 
    2815                 hrc = pMedium->COMGETTER(Format)(bstr.asOutParam());                    H();
    2816                 rc = CFGMR3InsertStringW(pCur, "Format", bstr.raw());                   RC_CHECK();
     2887                InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
     2888                InsertConfigString(pLunL1, "Driver", "VD");
     2889                InsertConfigNode(pLunL1, "Config", &pCfg);
     2890
     2891                hrc = pMedium->COMGETTER(Location)(bstr.asOutParam());                      H();
     2892                InsertConfigString(pCfg, "Path", bstr);
     2893
     2894                hrc = pMedium->COMGETTER(Format)(bstr.asOutParam());                        H();
     2895                InsertConfigString(pCfg, "Format", bstr);
     2896
     2897                /* DVDs are always readonly */
     2898                if (enmType == DeviceType_DVD)
     2899                {
     2900                    InsertConfigInteger(pCfg, "ReadOnly", 1);
     2901                }
     2902
     2903                /* Start without exclusive write access to the images. */
     2904                /** @todo Live Migration: I don't quite like this, we risk screwing up when
     2905                 *        we're resuming the VM if some 3rd dude have any of the VDIs open
     2906                 *        with write sharing denied.  However, if the two VMs are sharing a
     2907                 *        image it really is necessary....
     2908                 *
     2909                 *        So, on the "lock-media" command, the target teleporter should also
     2910                 *        make DrvVD undo TempReadOnly.  It gets interesting if we fail after
     2911                 *        that. Grumble. */
     2912                else if (aMachineState == MachineState_TeleportingIn)
     2913                {
     2914                    InsertConfigInteger(pCfg, "TempReadOnly", 1);
     2915                }
     2916
     2917                if (!fUseHostIOCache)
     2918                {
     2919                    InsertConfigInteger(pCfg, "UseNewIo", 1);
     2920                }
    28172921
    28182922                if (fSetupMerge)
    28192923                {
     2924                    InsertConfigInteger(pCfg, "SetupMerge", 1);
    28202925                    if (uImage == uMergeSource)
    28212926                    {
    2822                         rc = CFGMR3InsertInteger(pCur, "MergeSource", 1);               RC_CHECK();
     2927                        InsertConfigInteger(pCfg, "MergeSource", 1);
    28232928                    }
    28242929                    else if (uImage == uMergeTarget)
    28252930                    {
    2826                         rc = CFGMR3InsertInteger(pCur, "MergeTarget", 1);               RC_CHECK();
     2931                        InsertConfigInteger(pCfg, "MergeTarget", 1);
    28272932                    }
    28282933                }
    28292934
    28302935                /* Pass all custom parameters. */
    2831                 SafeArray<BSTR> aNames;
    2832                 SafeArray<BSTR> aValues;
     2936                bool fHostIP = true;
     2937                SafeArray<BSTR> names;
     2938                SafeArray<BSTR> values;
    28332939                hrc = pMedium->GetProperties(NULL,
    2834                                              ComSafeArrayAsOutParam(aNames),
    2835                                              ComSafeArrayAsOutParam(aValues));          H();
    2836 
    2837                 if (aNames.size() != 0)
     2940                                            ComSafeArrayAsOutParam(names),
     2941                                            ComSafeArrayAsOutParam(values));               H();
     2942
     2943                if (names.size() != 0)
    28382944                {
    28392945                    PCFGMNODE pVDC;
    2840                     rc = CFGMR3InsertNode(pCur, "VDConfig", &pVDC);                     RC_CHECK();
    2841                     for (size_t ii = 0; ii < aNames.size(); ++ii)
     2946                    InsertConfigNode(pCfg, "VDConfig", &pVDC);
     2947                    for (size_t ii = 0; ii < names.size(); ++ii)
    28422948                    {
    2843                         if (aValues[ii] && *aValues[ii])
     2949                        if (values[ii] && *values[ii])
    28442950                        {
    2845                             Utf8Str name = aNames[ii];
    2846                             Utf8Str value = aValues[ii];
    2847                             rc = CFGMR3InsertString(pVDC, name.c_str(), value.c_str()); RC_CHECK();
     2951                            Utf8Str name = names[ii];
     2952                            Utf8Str value = values[ii];
     2953                            InsertConfigString(pVDC, name.c_str(), value);
    28482954                            if (    name.compare("HostIPStack") == 0
    28492955                                &&  value.compare("0") == 0)
     
    28532959                }
    28542960
    2855                 /* Custom code: put marker to not use host IP stack to driver
    2856                  * configuration node. Simplifies life of DrvVD a bit. */
    2857                 if (!fHostIP)
    2858                 {
    2859                     rc = CFGMR3InsertInteger(pCfg, "HostIPStack", 0);                   RC_CHECK();
    2860                 }
    2861 
    2862                 /* next */
    2863                 pParent = pCur;
    2864                 pParentMedium = pMedium;
     2961                /* Create an inversed list of parents. */
     2962                uImage--;
     2963                IMedium *pParentMedium = pMedium;
     2964                for (PCFGMNODE pParent = pCfg;; uImage--)
     2965                {
     2966                    hrc = pParentMedium->COMGETTER(Parent)(&pMedium);                       H();
     2967                    if (!pMedium)
     2968                        break;
     2969
     2970                    PCFGMNODE pCur;
     2971                    InsertConfigNode(pParent, "Parent", &pCur);
     2972                    hrc = pMedium->COMGETTER(Location)(bstr.asOutParam());                  H();
     2973                    InsertConfigString(pCur, "Path", bstr);
     2974
     2975                    hrc = pMedium->COMGETTER(Format)(bstr.asOutParam());                    H();
     2976                    InsertConfigString(pCur, "Format", bstr);
     2977
     2978                    if (fSetupMerge)
     2979                    {
     2980                        if (uImage == uMergeSource)
     2981                        {
     2982                            InsertConfigInteger(pCur, "MergeSource", 1);
     2983                        }
     2984                        else if (uImage == uMergeTarget)
     2985                        {
     2986                            InsertConfigInteger(pCur, "MergeTarget", 1);
     2987                        }
     2988                    }
     2989
     2990                    /* Pass all custom parameters. */
     2991                    SafeArray<BSTR> aNames;
     2992                    SafeArray<BSTR> aValues;
     2993                    hrc = pMedium->GetProperties(NULL,
     2994                                                ComSafeArrayAsOutParam(aNames),
     2995                                                ComSafeArrayAsOutParam(aValues));          H();
     2996
     2997                    if (aNames.size() != 0)
     2998                    {
     2999                        PCFGMNODE pVDC;
     3000                        InsertConfigNode(pCur, "VDConfig", &pVDC);
     3001                        for (size_t ii = 0; ii < aNames.size(); ++ii)
     3002                        {
     3003                            if (aValues[ii] && *aValues[ii])
     3004                            {
     3005                                Utf8Str name = aNames[ii];
     3006                                Utf8Str value = aValues[ii];
     3007                                InsertConfigString(pVDC, name.c_str(), value);
     3008                                if (    name.compare("HostIPStack") == 0
     3009                                    &&  value.compare("0") == 0)
     3010                                    fHostIP = false;
     3011                            }
     3012                        }
     3013                    }
     3014
     3015                    /* Custom code: put marker to not use host IP stack to driver
     3016                     * configuration node. Simplifies life of DrvVD a bit. */
     3017                    if (!fHostIP)
     3018                    {
     3019                        InsertConfigInteger(pCfg, "HostIPStack", 0);
     3020                    }
     3021
     3022                    /* next */
     3023                    pParent = pCur;
     3024                    pParentMedium = pMedium;
     3025                }
    28653026            }
    28663027        }
    28673028    }
     3029    catch (ConfigError &x)
     3030    {
     3031        // InsertConfig threw something:
     3032        return x.m_vrc;
     3033    }
    28683034
    28693035#undef H
    2870 #undef RC_CHECK
    28713036
    28723037    return VINF_SUCCESS;
     
    28913056 *  @note Locks this object for writing.
    28923057 */
    2893 int Console::configNetwork(const char *pszDevice, unsigned uInstance,
    2894                            unsigned uLun, INetworkAdapter *aNetworkAdapter,
    2895                            PCFGMNODE pCfg, PCFGMNODE pLunL0, PCFGMNODE pInst,
     3058int Console::configNetwork(const char *pszDevice,
     3059                           unsigned uInstance,
     3060                           unsigned uLun,
     3061                           INetworkAdapter *aNetworkAdapter,
     3062                           PCFGMNODE pCfg,
     3063                           PCFGMNODE pLunL0,
     3064                           PCFGMNODE pInst,
    28963065                           bool fAttachDetach)
    28973066{
     
    28993068    AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
    29003069
    2901     int rc = VINF_SUCCESS;
    2902     HRESULT hrc;
    2903     Bstr bstr;
    2904 
    2905 #define RC_CHECK()  AssertMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc)
     3070    // InsertConfig* throws
     3071    try
     3072    {
     3073        int rc = VINF_SUCCESS;
     3074        HRESULT hrc;
     3075        Bstr bstr;
     3076
    29063077#define H()         AssertMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE)
    29073078
    2908     /*
    2909      * Locking the object before doing VMR3* calls is quite safe here, since
    2910      * we're on EMT. Write lock is necessary because we indirectly modify the
    2911      * meAttachmentType member.
    2912      */
    2913     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    2914 
    2915     PVM pVM = mpVM;
    2916 
    2917     ComPtr<IMachine> pMachine = machine();
    2918 
    2919     ComPtr<IVirtualBox> virtualBox;
    2920     hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam());
    2921     H();
    2922 
    2923     ComPtr<IHost> host;
    2924     hrc = virtualBox->COMGETTER(Host)(host.asOutParam());
    2925     H();
    2926 
    2927     BOOL fSniffer;
    2928     hrc = aNetworkAdapter->COMGETTER(TraceEnabled)(&fSniffer);
    2929     H();
    2930 
    2931     if (fAttachDetach && fSniffer)
    2932     {
    2933         const char *pszNetDriver = "IntNet";
    2934         if (meAttachmentType[uInstance] == NetworkAttachmentType_NAT)
    2935             pszNetDriver = "NAT";
     3079        /*
     3080         * Locking the object before doing VMR3* calls is quite safe here, since
     3081         * we're on EMT. Write lock is necessary because we indirectly modify the
     3082         * meAttachmentType member.
     3083         */
     3084        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3085
     3086        PVM pVM = mpVM;
     3087
     3088        ComPtr<IMachine> pMachine = machine();
     3089
     3090        ComPtr<IVirtualBox> virtualBox;
     3091        hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam());
     3092        H();
     3093
     3094        ComPtr<IHost> host;
     3095        hrc = virtualBox->COMGETTER(Host)(host.asOutParam());
     3096        H();
     3097
     3098        BOOL fSniffer;
     3099        hrc = aNetworkAdapter->COMGETTER(TraceEnabled)(&fSniffer);
     3100        H();
     3101
     3102        if (fAttachDetach && fSniffer)
     3103        {
     3104            const char *pszNetDriver = "IntNet";
     3105            if (meAttachmentType[uInstance] == NetworkAttachmentType_NAT)
     3106                pszNetDriver = "NAT";
    29363107#if !defined(VBOX_WITH_NETFLT) && defined(RT_OS_LINUX)
    2937         if (meAttachmentType[uInstance] == NetworkAttachmentType_Bridged)
    2938             pszNetDriver = "HostInterface";
     3108            if (meAttachmentType[uInstance] == NetworkAttachmentType_Bridged)
     3109                pszNetDriver = "HostInterface";
    29393110#endif
    29403111
    2941         rc = PDMR3DriverDetach(pVM, pszDevice, uInstance, uLun, pszNetDriver, 0, 0 /*fFlags*/);
    2942         if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN)
    2943             rc = VINF_SUCCESS;
    2944         AssertLogRelRCReturn(rc, rc);
    2945 
    2946         pLunL0 = CFGMR3GetChildF(pInst, "LUN#%u", uLun);
    2947         PCFGMNODE pLunAD = CFGMR3GetChildF(pLunL0, "AttachedDriver");
    2948         if (pLunAD)
     3112            rc = PDMR3DriverDetach(pVM, pszDevice, uInstance, uLun, pszNetDriver, 0, 0 /*fFlags*/);
     3113            if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN)
     3114                rc = VINF_SUCCESS;
     3115            AssertLogRelRCReturn(rc, rc);
     3116
     3117            pLunL0 = CFGMR3GetChildF(pInst, "LUN#%u", uLun);
     3118            PCFGMNODE pLunAD = CFGMR3GetChildF(pLunL0, "AttachedDriver");
     3119            if (pLunAD)
     3120            {
     3121                CFGMR3RemoveNode(pLunAD);
     3122            }
     3123            else
     3124            {
     3125                CFGMR3RemoveNode(pLunL0);
     3126                InsertConfigNode(pInst, "LUN#0", &pLunL0);
     3127                InsertConfigString(pLunL0, "Driver", "NetSniffer");
     3128                InsertConfigNode(pLunL0, "Config", &pCfg);
     3129                hrc = aNetworkAdapter->COMGETTER(TraceFile)(bstr.asOutParam());             H();
     3130                if (!bstr.isEmpty()) /* check convention for indicating default file. */
     3131                {
     3132                    InsertConfigString(pCfg, "File", bstr);
     3133                }
     3134            }
     3135        }
     3136        else if (fAttachDetach && !fSniffer)
    29493137        {
    2950             CFGMR3RemoveNode(pLunAD);
     3138            rc = PDMR3DeviceDetach(pVM, pszDevice, uInstance, uLun, 0 /*fFlags*/);
     3139            if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN)
     3140                rc = VINF_SUCCESS;
     3141            AssertLogRelRCReturn(rc, rc);
     3142
     3143            /* nuke anything which might have been left behind. */
     3144            CFGMR3RemoveNode(CFGMR3GetChildF(pInst, "LUN#%u", uLun));
    29513145        }
    2952         else
     3146        else if (!fAttachDetach && fSniffer)
    29533147        {
    2954             CFGMR3RemoveNode(pLunL0);
    2955             rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);                             RC_CHECK();
    2956             rc = CFGMR3InsertString(pLunL0, "Driver", "NetSniffer");                    RC_CHECK();
    2957             rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                             RC_CHECK();
    2958             hrc = aNetworkAdapter->COMGETTER(TraceFile)(bstr.asOutParam());             H();
     3148            /* insert the sniffer filter driver. */
     3149            InsertConfigNode(pInst, "LUN#0", &pLunL0);
     3150            InsertConfigString(pLunL0, "Driver", "NetSniffer");
     3151            InsertConfigNode(pLunL0, "Config", &pCfg);
     3152            hrc = aNetworkAdapter->COMGETTER(TraceFile)(bstr.asOutParam());                 H();
    29593153            if (!bstr.isEmpty()) /* check convention for indicating default file. */
    29603154            {
    2961                 rc = CFGMR3InsertStringW(pCfg, "File", bstr.raw());                     RC_CHECK();
     3155                InsertConfigString(pCfg, "File", bstr);
    29623156            }
    29633157        }
    2964     }
    2965     else if (fAttachDetach && !fSniffer)
    2966     {
    2967         rc = PDMR3DeviceDetach(pVM, pszDevice, uInstance, uLun, 0 /*fFlags*/);
    2968         if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN)
    2969             rc = VINF_SUCCESS;
    2970         AssertLogRelRCReturn(rc, rc);
    2971 
    2972         /* nuke anything which might have been left behind. */
    2973         CFGMR3RemoveNode(CFGMR3GetChildF(pInst, "LUN#%u", uLun));
    2974     }
    2975     else if (!fAttachDetach && fSniffer)
    2976     {
    2977         /* insert the sniffer filter driver. */
    2978         rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);                                 RC_CHECK();
    2979         rc = CFGMR3InsertString(pLunL0, "Driver", "NetSniffer");                        RC_CHECK();
    2980         rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                                 RC_CHECK();
    2981         hrc = aNetworkAdapter->COMGETTER(TraceFile)(bstr.asOutParam());                 H();
    2982         if (!bstr.isEmpty()) /* check convention for indicating default file. */
     3158
     3159        Bstr networkName, trunkName, trunkType;
     3160        NetworkAttachmentType_T eAttachmentType;
     3161        hrc = aNetworkAdapter->COMGETTER(AttachmentType)(&eAttachmentType);                 H();
     3162        switch (eAttachmentType)
    29833163        {
    2984             rc = CFGMR3InsertStringW(pCfg, "File", bstr.raw());                         RC_CHECK();
    2985         }
    2986     }
    2987 
    2988     Bstr networkName, trunkName, trunkType;
    2989     NetworkAttachmentType_T eAttachmentType;
    2990     hrc = aNetworkAdapter->COMGETTER(AttachmentType)(&eAttachmentType);                 H();
    2991     switch (eAttachmentType)
    2992     {
    2993         case NetworkAttachmentType_Null:
    2994             break;
    2995 
    2996         case NetworkAttachmentType_NAT:
    2997         {
    2998             ComPtr<INATEngine> natDriver;
    2999             hrc = aNetworkAdapter->COMGETTER(NatDriver)(natDriver.asOutParam());        H();
    3000             if (fSniffer)
    3001             {
    3002                 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);               RC_CHECK();
    3003             }
    3004             else
    3005             {
    3006                 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);                         RC_CHECK();
    3007             }
    3008             rc = CFGMR3InsertString(pLunL0, "Driver", "NAT");                           RC_CHECK();
    3009             rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                             RC_CHECK();
    3010 
    3011             /* Configure TFTP prefix and boot filename. */
    3012             hrc = virtualBox->COMGETTER(HomeFolder)(bstr.asOutParam());                 H();
    3013             if (!bstr.isEmpty())
    3014             {
    3015                 rc = CFGMR3InsertStringF(pCfg, "TFTPPrefix", "%ls%c%s", bstr.raw(), RTPATH_DELIMITER, "TFTP"); RC_CHECK();
    3016             }
    3017             hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                         H();
    3018             rc = CFGMR3InsertStringF(pCfg, "BootFile", "%ls.pxe", bstr.raw());          RC_CHECK();
    3019 
    3020             hrc = natDriver->COMGETTER(Network)(bstr.asOutParam());                     H();
    3021             if (!bstr.isEmpty())
    3022             {
    3023                 rc = CFGMR3InsertStringW(pCfg, "Network", bstr.raw());                  RC_CHECK();
    3024             }
    3025             else
    3026             {
    3027                 ULONG uSlot;
    3028                 hrc = aNetworkAdapter->COMGETTER(Slot)(&uSlot);                         H();
    3029                 rc = CFGMR3InsertStringF(pCfg, "Network", "10.0.%d.0/24", uSlot+2);     RC_CHECK();
    3030             }
    3031             hrc = natDriver->COMGETTER(HostIP)(bstr.asOutParam());                      H();
    3032             if (!bstr.isEmpty())
    3033             {
    3034                 rc = CFGMR3InsertStringW(pCfg, "BindIP", bstr.raw());                   RC_CHECK();
    3035             }
    3036             ULONG mtu = 0;
    3037             ULONG sockSnd = 0;
    3038             ULONG sockRcv = 0;
    3039             ULONG tcpSnd = 0;
    3040             ULONG tcpRcv = 0;
    3041             hrc = natDriver->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv); H();
    3042             if (mtu)
    3043             {
    3044                 rc = CFGMR3InsertInteger(pCfg, "SlirpMTU", mtu);                        RC_CHECK();
    3045             }
    3046             if (sockRcv)
    3047             {
    3048                 rc = CFGMR3InsertInteger(pCfg, "SockRcv", sockRcv);                     RC_CHECK();
    3049             }
    3050             if (sockSnd)
    3051             {
    3052                 rc = CFGMR3InsertInteger(pCfg, "SockSnd", sockSnd);                     RC_CHECK();
    3053             }
    3054             if (tcpRcv)
    3055             {
    3056                 rc = CFGMR3InsertInteger(pCfg, "TcpRcv", tcpRcv);                       RC_CHECK();
    3057             }
    3058             if (tcpSnd)
    3059             {
    3060                 rc = CFGMR3InsertInteger(pCfg, "TcpSnd", tcpSnd);                       RC_CHECK();
    3061             }
    3062             hrc = natDriver->COMGETTER(TftpPrefix)(bstr.asOutParam());                  H();
    3063             if (!bstr.isEmpty())
    3064             {
    3065                 rc = CFGMR3RemoveValue(pCfg, "TFTPPrefix");                             RC_CHECK();
    3066                 rc = CFGMR3InsertStringW(pCfg, "TFTPPrefix", bstr);                     RC_CHECK();
    3067             }
    3068             hrc = natDriver->COMGETTER(TftpBootFile)(bstr.asOutParam());                H();
    3069             if (!bstr.isEmpty())
    3070             {
    3071                 rc = CFGMR3RemoveValue(pCfg, "BootFile");                               RC_CHECK();
    3072                 rc = CFGMR3InsertStringW(pCfg, "BootFile", bstr);                       RC_CHECK();
    3073             }
    3074             hrc = natDriver->COMGETTER(TftpNextServer)(bstr.asOutParam());              H();
    3075             if (!bstr.isEmpty())
    3076             {
    3077                 rc = CFGMR3InsertStringW(pCfg, "NextServer", bstr);                     RC_CHECK();
    3078             }
    3079             BOOL fDnsFlag;
    3080             hrc = natDriver->COMGETTER(DnsPassDomain)(&fDnsFlag);                       H();
    3081             rc = CFGMR3InsertInteger(pCfg, "PassDomain", fDnsFlag);                     RC_CHECK();
    3082             hrc = natDriver->COMGETTER(DnsProxy)(&fDnsFlag);                            H();
    3083             rc = CFGMR3InsertInteger(pCfg, "DNSProxy", fDnsFlag);                       RC_CHECK();
    3084             hrc = natDriver->COMGETTER(DnsUseHostResolver)(&fDnsFlag);                  H();
    3085             rc = CFGMR3InsertInteger(pCfg, "UseHostResolver", fDnsFlag);                RC_CHECK();
    3086 
    3087             ULONG aliasMode;
    3088             hrc = natDriver->COMGETTER(AliasMode)(&aliasMode);                          H();
    3089             rc = CFGMR3InsertInteger(pCfg, "AliasMode", aliasMode);                     RC_CHECK();
    3090 
    3091             /* port-forwarding */
    3092             SafeArray<BSTR> pfs;
    3093             hrc = natDriver->COMGETTER(Redirects)(ComSafeArrayAsOutParam(pfs));         H();
    3094             PCFGMNODE pPF = NULL;          /* /Devices/Dev/.../Config/PF#0/ */
    3095             for (unsigned int i = 0; i < pfs.size(); ++i)
    3096             {
    3097                 uint16_t port = 0;
    3098                 BSTR r = pfs[i];
    3099                 Utf8Str utf = Utf8Str(r);
    3100                 Utf8Str strName;
    3101                 Utf8Str strProto;
    3102                 Utf8Str strHostPort;
    3103                 Utf8Str strHostIP;
    3104                 Utf8Str strGuestPort;
    3105                 Utf8Str strGuestIP;
    3106                 size_t pos, ppos;
    3107                 pos = ppos = 0;
     3164            case NetworkAttachmentType_Null:
     3165                break;
     3166
     3167            case NetworkAttachmentType_NAT:
     3168            {
     3169                ComPtr<INATEngine> natDriver;
     3170                hrc = aNetworkAdapter->COMGETTER(NatDriver)(natDriver.asOutParam());        H();
     3171                if (fSniffer)
     3172                {
     3173                    InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
     3174                }
     3175                else
     3176                {
     3177                    InsertConfigNode(pInst, "LUN#0", &pLunL0);
     3178                }
     3179                InsertConfigString(pLunL0, "Driver", "NAT");
     3180                InsertConfigNode(pLunL0, "Config", &pCfg);
     3181
     3182                /* Configure TFTP prefix and boot filename. */
     3183                hrc = virtualBox->COMGETTER(HomeFolder)(bstr.asOutParam());                 H();
     3184                if (!bstr.isEmpty())
     3185                {
     3186                    InsertConfigString(pCfg, "TFTPPrefix", Utf8StrFmt("%ls%c%s", bstr.raw(), RTPATH_DELIMITER, "TFTP"));
     3187                }
     3188                hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                         H();
     3189                InsertConfigString(pCfg, "BootFile", Utf8StrFmt("%ls.pxe", bstr.raw()));
     3190
     3191                hrc = natDriver->COMGETTER(Network)(bstr.asOutParam());                     H();
     3192                if (!bstr.isEmpty())
     3193                {
     3194                    InsertConfigString(pCfg, "Network", bstr);
     3195                }
     3196                else
     3197                {
     3198                    ULONG uSlot;
     3199                    hrc = aNetworkAdapter->COMGETTER(Slot)(&uSlot);                         H();
     3200                    InsertConfigString(pCfg, "Network", Utf8StrFmt("10.0.%d.0/24", uSlot+2));
     3201                }
     3202                hrc = natDriver->COMGETTER(HostIP)(bstr.asOutParam());                      H();
     3203                if (!bstr.isEmpty())
     3204                {
     3205                    InsertConfigString(pCfg, "BindIP", bstr);
     3206                }
     3207                ULONG mtu = 0;
     3208                ULONG sockSnd = 0;
     3209                ULONG sockRcv = 0;
     3210                ULONG tcpSnd = 0;
     3211                ULONG tcpRcv = 0;
     3212                hrc = natDriver->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv); H();
     3213                if (mtu)
     3214                {
     3215                    InsertConfigInteger(pCfg, "SlirpMTU", mtu);
     3216                }
     3217                if (sockRcv)
     3218                {
     3219                    InsertConfigInteger(pCfg, "SockRcv", sockRcv);
     3220                }
     3221                if (sockSnd)
     3222                {
     3223                    InsertConfigInteger(pCfg, "SockSnd", sockSnd);
     3224                }
     3225                if (tcpRcv)
     3226                {
     3227                    InsertConfigInteger(pCfg, "TcpRcv", tcpRcv);
     3228                }
     3229                if (tcpSnd)
     3230                {
     3231                    InsertConfigInteger(pCfg, "TcpSnd", tcpSnd);
     3232                }
     3233                hrc = natDriver->COMGETTER(TftpPrefix)(bstr.asOutParam());                  H();
     3234                if (!bstr.isEmpty())
     3235                {
     3236                    RemoveConfigValue(pCfg, "TFTPPrefix");
     3237                    InsertConfigString(pCfg, "TFTPPrefix", bstr);
     3238                }
     3239                hrc = natDriver->COMGETTER(TftpBootFile)(bstr.asOutParam());                H();
     3240                if (!bstr.isEmpty())
     3241                {
     3242                    RemoveConfigValue(pCfg, "BootFile");
     3243                    InsertConfigString(pCfg, "BootFile", bstr);
     3244                }
     3245                hrc = natDriver->COMGETTER(TftpNextServer)(bstr.asOutParam());              H();
     3246                if (!bstr.isEmpty())
     3247                {
     3248                    InsertConfigString(pCfg, "NextServer", bstr);
     3249                }
     3250                BOOL fDnsFlag;
     3251                hrc = natDriver->COMGETTER(DnsPassDomain)(&fDnsFlag);                       H();
     3252                InsertConfigInteger(pCfg, "PassDomain", fDnsFlag);
     3253                hrc = natDriver->COMGETTER(DnsProxy)(&fDnsFlag);                            H();
     3254                InsertConfigInteger(pCfg, "DNSProxy", fDnsFlag);
     3255                hrc = natDriver->COMGETTER(DnsUseHostResolver)(&fDnsFlag);                  H();
     3256                InsertConfigInteger(pCfg, "UseHostResolver", fDnsFlag);
     3257
     3258                ULONG aliasMode;
     3259                hrc = natDriver->COMGETTER(AliasMode)(&aliasMode);                          H();
     3260                InsertConfigInteger(pCfg, "AliasMode", aliasMode);
     3261
     3262                /* port-forwarding */
     3263                SafeArray<BSTR> pfs;
     3264                hrc = natDriver->COMGETTER(Redirects)(ComSafeArrayAsOutParam(pfs));         H();
     3265                PCFGMNODE pPF = NULL;          /* /Devices/Dev/.../Config/PF#0/ */
     3266                for (unsigned int i = 0; i < pfs.size(); ++i)
     3267                {
     3268                    uint16_t port = 0;
     3269                    BSTR r = pfs[i];
     3270                    Utf8Str utf = Utf8Str(r);
     3271                    Utf8Str strName;
     3272                    Utf8Str strProto;
     3273                    Utf8Str strHostPort;
     3274                    Utf8Str strHostIP;
     3275                    Utf8Str strGuestPort;
     3276                    Utf8Str strGuestIP;
     3277                    size_t pos, ppos;
     3278                    pos = ppos = 0;
    31083279#define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
    31093280    do { \
     
    31263297#undef ITERATE_TO_NEXT_TERM
    31273298
    3128                 uint32_t proto = strProto.toUInt32();
    3129                 bool fValid = true;
    3130                 switch (proto)
    3131                 {
    3132                     case NATProtocol_UDP:
    3133                         strProto = "UDP";
    3134                         break;
    3135                     case NATProtocol_TCP:
    3136                         strProto = "TCP";
    3137                         break;
    3138                     default:
    3139                         fValid = false;
    3140                 }
    3141                 /* continue with next rule if no valid proto was passed */
    3142                 if (!fValid)
    3143                     continue;
    3144 
    3145                 rc = CFGMR3InsertNode(pCfg, strName.raw(), &pPF);                       RC_CHECK();
    3146                 rc = CFGMR3InsertString(pPF, "Protocol", strProto.raw());               RC_CHECK();
    3147 
    3148                 if (!strHostIP.isEmpty())
    3149                 {
    3150                     rc = CFGMR3InsertString(pPF, "BindIP", strHostIP.raw());            RC_CHECK();
    3151                 }
    3152 
    3153                 if (!strGuestIP.isEmpty())
    3154                 {
    3155                     rc = CFGMR3InsertString(pPF, "GuestIP", strGuestIP.raw());          RC_CHECK();
    3156                 }
    3157 
    3158                 port = RTStrToUInt16(strHostPort.raw());
    3159                 if (port)
    3160                 {
    3161                     rc = CFGMR3InsertInteger(pPF, "HostPort", port);                    RC_CHECK();
    3162                 }
    3163 
    3164                 port = RTStrToUInt16(strGuestPort.raw());
    3165                 if (port)
    3166                 {
    3167                     rc = CFGMR3InsertInteger(pPF, "GuestPort", port);                   RC_CHECK();
    3168                 }
    3169             }
    3170             break;
    3171         }
    3172 
    3173         case NetworkAttachmentType_Bridged:
    3174         {
     3299                    uint32_t proto = strProto.toUInt32();
     3300                    bool fValid = true;
     3301                    switch (proto)
     3302                    {
     3303                        case NATProtocol_UDP:
     3304                            strProto = "UDP";
     3305                            break;
     3306                        case NATProtocol_TCP:
     3307                            strProto = "TCP";
     3308                            break;
     3309                        default:
     3310                            fValid = false;
     3311                    }
     3312                    /* continue with next rule if no valid proto was passed */
     3313                    if (!fValid)
     3314                        continue;
     3315
     3316                    InsertConfigNode(pCfg, strName.raw(), &pPF);
     3317                    InsertConfigString(pPF, "Protocol", strProto);
     3318
     3319                    if (!strHostIP.isEmpty())
     3320                        InsertConfigString(pPF, "BindIP", strHostIP);
     3321
     3322                    if (!strGuestIP.isEmpty())
     3323                        InsertConfigString(pPF, "GuestIP", strGuestIP);
     3324
     3325                    port = RTStrToUInt16(strHostPort.raw());
     3326                    if (port)
     3327                    {
     3328                        InsertConfigInteger(pPF, "HostPort", port);
     3329                    }
     3330
     3331                    port = RTStrToUInt16(strGuestPort.raw());
     3332                    if (port)
     3333                    {
     3334                        InsertConfigInteger(pPF, "GuestPort", port);
     3335                    }
     3336                }
     3337                break;
     3338            }
     3339
     3340            case NetworkAttachmentType_Bridged:
     3341            {
    31753342#if (defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)) && !defined(VBOX_WITH_NETFLT)
    3176             hrc = attachToTapInterface(aNetworkAdapter);
    3177             if (FAILED(hrc))
    3178             {
    3179                 switch (hrc)
    3180                 {
    3181                     case VERR_ACCESS_DENIED:
    3182                         return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,  N_(
    3183                                           "Failed to open '/dev/net/tun' for read/write access. Please check the "
    3184                                           "permissions of that node. Either run 'chmod 0666 /dev/net/tun' or "
    3185                                           "change the group of that node and make yourself a member of that group. Make "
    3186                                           "sure that these changes are permanent, especially if you are "
    3187                                           "using udev"));
    3188                     default:
    3189                         AssertMsgFailed(("Could not attach to host interface! Bad!\n"));
    3190                         return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
    3191                                           "Failed to initialize Host Interface Networking"));
    3192                 }
    3193             }
    3194 
    3195             Assert((int)maTapFD[uInstance] >= 0);
    3196             if ((int)maTapFD[uInstance] >= 0)
    3197             {
    3198                 if (fSniffer)
    3199                 {
    3200                     rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);           RC_CHECK();
    3201                 }
    3202                 else
    3203                 {
    3204                     rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);                     RC_CHECK();
    3205                 }
    3206                 rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface");             RC_CHECK();
    3207                 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                         RC_CHECK();
    3208                 rc = CFGMR3InsertInteger(pCfg, "FileHandle", maTapFD[uInstance]);       RC_CHECK();
    3209             }
    3210 
    3211 #elif defined(VBOX_WITH_NETFLT)
    3212             /*
    3213              * This is the new VBoxNetFlt+IntNet stuff.
    3214              */
    3215             if (fSniffer)
    3216             {
    3217                 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);               RC_CHECK();
    3218             }
    3219             else
    3220             {
    3221                 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);                         RC_CHECK();
    3222             }
    3223 
    3224             Bstr HifName;
    3225             hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
    3226             if (FAILED(hrc))
    3227             {
    3228                 LogRel(("NetworkAttachmentType_Bridged: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
    3229                 H();
    3230             }
    3231 
    3232             Utf8Str HifNameUtf8(HifName);
    3233             const char *pszHifName = HifNameUtf8.raw();
    3234 
    3235 # if defined(RT_OS_DARWIN)
    3236             /* The name is on the form 'ifX: long name', chop it off at the colon. */
    3237             char szTrunk[8];
    3238             strncpy(szTrunk, pszHifName, sizeof(szTrunk));
    3239             char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
    3240             if (!pszColon)
    3241             {
    3242                 /*
    3243                  * Dynamic changing of attachment causes an attempt to configure
    3244                  * network with invalid host adapter (as it is must be changed before
    3245                  * the attachment), calling Detach here will cause a deadlock.
    3246                  * See #4750.
    3247                  * hrc = aNetworkAdapter->Detach();                        H();
    3248                  */
    3249                 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
    3250                                   N_("Malformed host interface networking name '%ls'"),
    3251                                   HifName.raw());
    3252             }
    3253             *pszColon = '\0';
    3254             const char *pszTrunk = szTrunk;
    3255 
    3256 # elif defined(RT_OS_SOLARIS)
    3257             /* The name is on the form format 'ifX[:1] - long name, chop it off at space. */
    3258             char szTrunk[256];
    3259             strlcpy(szTrunk, pszHifName, sizeof(szTrunk));
    3260             char *pszSpace = (char *)memchr(szTrunk, ' ', sizeof(szTrunk));
    3261 
    3262             /*
    3263              * Currently don't bother about malformed names here for the sake of people using
    3264              * VBoxManage and setting only the NIC name from there. If there is a space we
    3265              * chop it off and proceed, otherwise just use whatever we've got.
    3266              */
    3267             if (pszSpace)
    3268                 *pszSpace = '\0';
    3269 
    3270             /* Chop it off at the colon (zone naming eg: e1000g:1 we need only the e1000g) */
    3271             char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
    3272             if (pszColon)
    3273                 *pszColon = '\0';
    3274 
    3275             const char *pszTrunk = szTrunk;
    3276 
    3277 # elif defined(RT_OS_WINDOWS)
    3278             ComPtr<IHostNetworkInterface> hostInterface;
    3279             hrc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
    3280             if (!SUCCEEDED(hrc))
    3281             {
    3282                 AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: FindByName failed, rc=%Rhrc (0x%x)", hrc, hrc));
    3283                 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
    3284                                   N_("Inexistent host networking interface, name '%ls'"),
    3285                                   HifName.raw());
    3286             }
    3287 
    3288             HostNetworkInterfaceType_T eIfType;
    3289             hrc = hostInterface->COMGETTER(InterfaceType)(&eIfType);
    3290             if (FAILED(hrc))
    3291             {
    3292                 LogRel(("NetworkAttachmentType_Bridged: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc));
    3293                 H();
    3294             }
    3295 
    3296             if (eIfType != HostNetworkInterfaceType_Bridged)
    3297             {
    3298                 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
    3299                                                       N_("Interface ('%ls') is not a Bridged Adapter interface"),
    3300                                                       HifName.raw());
    3301             }
    3302 
    3303             hrc = hostInterface->COMGETTER(Id)(bstr.asOutParam());
    3304             if (FAILED(hrc))
    3305             {
    3306                 LogRel(("NetworkAttachmentType_Bridged: COMGETTER(Id) failed, hrc (0x%x)", hrc));
    3307                 H();
    3308             }
    3309             Guid hostIFGuid(bstr);
    3310 
    3311             INetCfg              *pNc;
    3312             ComPtr<INetCfgComponent> pAdaptorComponent;
    3313             LPWSTR                pszApp;
    3314             int rc = VERR_INTNET_FLT_IF_NOT_FOUND;
    3315 
    3316             hrc = VBoxNetCfgWinQueryINetCfg(FALSE /*fGetWriteLock*/,
    3317                                             L"VirtualBox",
    3318                                             &pNc,
    3319                                             &pszApp);
    3320             Assert(hrc == S_OK);
    3321             if (hrc == S_OK)
    3322             {
    3323                 /* get the adapter's INetCfgComponent*/
    3324                 hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam());
    3325                 if (hrc != S_OK)
    3326                 {
    3327                     VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
    3328                     LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
    3329                     H();
    3330                 }
    3331             }
    3332 #define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
    3333             char szTrunkName[INTNET_MAX_TRUNK_NAME];
    3334             char *pszTrunkName = szTrunkName;
    3335             wchar_t * pswzBindName;
    3336             hrc = pAdaptorComponent->GetBindName(&pswzBindName);
    3337             Assert(hrc == S_OK);
    3338             if (hrc == S_OK)
    3339             {
    3340                 int cwBindName = (int)wcslen(pswzBindName) + 1;
    3341                 int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX);
    3342                 if (sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName)
    3343                 {
    3344                     strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX);
    3345                     pszTrunkName += cbFullBindNamePrefix-1;
    3346                     if (!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName,
    3347                                              sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL))
    3348                     {
    3349                         DWORD err = GetLastError();
    3350                         hrc = HRESULT_FROM_WIN32(err);
    3351                         AssertMsgFailed(("%hrc=%Rhrc %#x\n", hrc, hrc));
    3352                         AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: WideCharToMultiByte failed, hr=%Rhrc (0x%x) err=%u\n", hrc, hrc, err));
    3353                     }
    3354                 }
    3355                 else
    3356                 {
    3357                     AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: insufficient szTrunkName buffer space\n"));
    3358                     /** @todo set appropriate error code */
    3359                     hrc = E_FAIL;
    3360                 }
    3361 
    3362                 if (hrc != S_OK)
    3363                 {
    3364                     AssertFailed();
    3365                     CoTaskMemFree(pswzBindName);
    3366                     VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
    3367                     H();
    3368                 }
    3369 
    3370                 /* we're not freeing the bind name since we'll use it later for detecting wireless*/
    3371             }
    3372             else
    3373             {
    3374                 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
    3375                 AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
    3376                 H();
    3377             }
    3378             const char *pszTrunk = szTrunkName;
    3379             /* we're not releasing the INetCfg stuff here since we use it later to figure out whether it is wireless */
    3380 
    3381 # elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
    3382 #  if defined(RT_OS_FREEBSD)
    3383             /*
    3384              * If we bridge to a tap interface open it the `old' direct way.
    3385              * This works and performs better than bridging a physical
    3386              * interface via the current FreeBSD vboxnetflt implementation.
    3387              */
    3388             if (!strncmp(pszHifName, "tap", sizeof "tap" - 1)) {
    33893343                hrc = attachToTapInterface(aNetworkAdapter);
    33903344                if (FAILED(hrc))
     
    33943348                        case VERR_ACCESS_DENIED:
    33953349                            return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,  N_(
    3396                                               "Failed to open '/dev/%s' for read/write access. Please check the "
    3397                                               "permissions of that node, and that the net.link.tap.user_open "
    3398                                               "sysctl is set.  Either run 'chmod 0666 /dev/%s' or "
    3399                                               "change the group of that node to vboxusers and make yourself "
    3400                                               "a member of that group.  Make sure that these changes are permanent."), pszHifName, pszHifName);
     3350                                            "Failed to open '/dev/net/tun' for read/write access. Please check the "
     3351                                            "permissions of that node. Either run 'chmod 0666 /dev/net/tun' or "
     3352                                            "change the group of that node and make yourself a member of that group. Make "
     3353                                            "sure that these changes are permanent, especially if you are "
     3354                                            "using udev"));
    34013355                        default:
    3402                             AssertMsgFailed(("Could not attach to tap interface! Bad!\n"));
     3356                            AssertMsgFailed(("Could not attach to host interface! Bad!\n"));
    34033357                            return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
    3404                                               "Failed to initialize Host Interface Networking"));
     3358                                            "Failed to initialize Host Interface Networking"));
    34053359                    }
    34063360                }
     
    34093363                if ((int)maTapFD[uInstance] >= 0)
    34103364                {
    3411                     rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface");         RC_CHECK();
    3412                     rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                     RC_CHECK();
    3413                     rc = CFGMR3InsertInteger(pCfg, "FileHandle", maTapFD[uInstance]);   RC_CHECK();
    3414                 }
    3415                 break;
    3416             }
     3365                    if (fSniffer)
     3366                    {
     3367                        InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
     3368                    }
     3369                    else
     3370                    {
     3371                        InsertConfigNode(pInst, "LUN#0", &pLunL0);
     3372                    }
     3373                    InsertConfigString(pLunL0, "Driver", "HostInterface");
     3374                    InsertConfigNode(pLunL0, "Config", &pCfg);
     3375                    InsertConfigInteger(pCfg, "FileHandle", maTapFD[uInstance]);
     3376                }
     3377
     3378#elif defined(VBOX_WITH_NETFLT)
     3379                /*
     3380                 * This is the new VBoxNetFlt+IntNet stuff.
     3381                 */
     3382                if (fSniffer)
     3383                {
     3384                    InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
     3385                }
     3386                else
     3387                {
     3388                    InsertConfigNode(pInst, "LUN#0", &pLunL0);
     3389                }
     3390
     3391                Bstr HifName;
     3392                hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
     3393                if (FAILED(hrc))
     3394                {
     3395                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
     3396                    H();
     3397                }
     3398
     3399                Utf8Str HifNameUtf8(HifName);
     3400                const char *pszHifName = HifNameUtf8.raw();
     3401
     3402# if defined(RT_OS_DARWIN)
     3403                /* The name is on the form 'ifX: long name', chop it off at the colon. */
     3404                char szTrunk[8];
     3405                strncpy(szTrunk, pszHifName, sizeof(szTrunk));
     3406                char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
     3407                if (!pszColon)
     3408                {
     3409                    /*
     3410                    * Dynamic changing of attachment causes an attempt to configure
     3411                    * network with invalid host adapter (as it is must be changed before
     3412                    * the attachment), calling Detach here will cause a deadlock.
     3413                    * See #4750.
     3414                    * hrc = aNetworkAdapter->Detach();                        H();
     3415                    */
     3416                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     3417                                    N_("Malformed host interface networking name '%ls'"),
     3418                                    HifName.raw());
     3419                }
     3420                *pszColon = '\0';
     3421                const char *pszTrunk = szTrunk;
     3422
     3423# elif defined(RT_OS_SOLARIS)
     3424                /* The name is on the form format 'ifX[:1] - long name, chop it off at space. */
     3425                char szTrunk[256];
     3426                strlcpy(szTrunk, pszHifName, sizeof(szTrunk));
     3427                char *pszSpace = (char *)memchr(szTrunk, ' ', sizeof(szTrunk));
     3428
     3429                /*
     3430                 * Currently don't bother about malformed names here for the sake of people using
     3431                 * VBoxManage and setting only the NIC name from there. If there is a space we
     3432                 * chop it off and proceed, otherwise just use whatever we've got.
     3433                 */
     3434                if (pszSpace)
     3435                    *pszSpace = '\0';
     3436
     3437                /* Chop it off at the colon (zone naming eg: e1000g:1 we need only the e1000g) */
     3438                char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
     3439                if (pszColon)
     3440                    *pszColon = '\0';
     3441
     3442                const char *pszTrunk = szTrunk;
     3443
     3444# elif defined(RT_OS_WINDOWS)
     3445                ComPtr<IHostNetworkInterface> hostInterface;
     3446                hrc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
     3447                if (!SUCCEEDED(hrc))
     3448                {
     3449                    AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: FindByName failed, rc=%Rhrc (0x%x)", hrc, hrc));
     3450                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     3451                                    N_("Inexistent host networking interface, name '%ls'"),
     3452                                    HifName.raw());
     3453                }
     3454
     3455                HostNetworkInterfaceType_T eIfType;
     3456                hrc = hostInterface->COMGETTER(InterfaceType)(&eIfType);
     3457                if (FAILED(hrc))
     3458                {
     3459                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc));
     3460                    H();
     3461                }
     3462
     3463                if (eIfType != HostNetworkInterfaceType_Bridged)
     3464                {
     3465                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     3466                                                        N_("Interface ('%ls') is not a Bridged Adapter interface"),
     3467                                                        HifName.raw());
     3468                }
     3469
     3470                hrc = hostInterface->COMGETTER(Id)(bstr.asOutParam());
     3471                if (FAILED(hrc))
     3472                {
     3473                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(Id) failed, hrc (0x%x)", hrc));
     3474                    H();
     3475                }
     3476                Guid hostIFGuid(bstr);
     3477
     3478                INetCfg              *pNc;
     3479                ComPtr<INetCfgComponent> pAdaptorComponent;
     3480                LPWSTR                pszApp;
     3481                int rc = VERR_INTNET_FLT_IF_NOT_FOUND;
     3482
     3483                hrc = VBoxNetCfgWinQueryINetCfg(FALSE /*fGetWriteLock*/,
     3484                                                L"VirtualBox",
     3485                                                &pNc,
     3486                                                &pszApp);
     3487                Assert(hrc == S_OK);
     3488                if (hrc == S_OK)
     3489                {
     3490                    /* get the adapter's INetCfgComponent*/
     3491                    hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam());
     3492                    if (hrc != S_OK)
     3493                    {
     3494                        VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
     3495                        LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
     3496                        H();
     3497                    }
     3498                }
     3499#define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
     3500                char szTrunkName[INTNET_MAX_TRUNK_NAME];
     3501                char *pszTrunkName = szTrunkName;
     3502                wchar_t * pswzBindName;
     3503                hrc = pAdaptorComponent->GetBindName(&pswzBindName);
     3504                Assert(hrc == S_OK);
     3505                if (hrc == S_OK)
     3506                {
     3507                    int cwBindName = (int)wcslen(pswzBindName) + 1;
     3508                    int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX);
     3509                    if (sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName)
     3510                    {
     3511                        strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX);
     3512                        pszTrunkName += cbFullBindNamePrefix-1;
     3513                        if (!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName,
     3514                                                sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL))
     3515                        {
     3516                            DWORD err = GetLastError();
     3517                            hrc = HRESULT_FROM_WIN32(err);
     3518                            AssertMsgFailed(("%hrc=%Rhrc %#x\n", hrc, hrc));
     3519                            AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: WideCharToMultiByte failed, hr=%Rhrc (0x%x) err=%u\n", hrc, hrc, err));
     3520                        }
     3521                    }
     3522                    else
     3523                    {
     3524                        AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: insufficient szTrunkName buffer space\n"));
     3525                        /** @todo set appropriate error code */
     3526                        hrc = E_FAIL;
     3527                    }
     3528
     3529                    if (hrc != S_OK)
     3530                    {
     3531                        AssertFailed();
     3532                        CoTaskMemFree(pswzBindName);
     3533                        VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
     3534                        H();
     3535                    }
     3536
     3537                    /* we're not freeing the bind name since we'll use it later for detecting wireless*/
     3538                }
     3539                else
     3540                {
     3541                    VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
     3542                    AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
     3543                    H();
     3544                }
     3545                const char *pszTrunk = szTrunkName;
     3546                /* we're not releasing the INetCfg stuff here since we use it later to figure out whether it is wireless */
     3547
     3548# elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
     3549#  if defined(RT_OS_FREEBSD)
     3550                /*
     3551                 * If we bridge to a tap interface open it the `old' direct way.
     3552                 * This works and performs better than bridging a physical
     3553                 * interface via the current FreeBSD vboxnetflt implementation.
     3554                 */
     3555                if (!strncmp(pszHifName, "tap", sizeof "tap" - 1)) {
     3556                    hrc = attachToTapInterface(aNetworkAdapter);
     3557                    if (FAILED(hrc))
     3558                    {
     3559                        switch (hrc)
     3560                        {
     3561                            case VERR_ACCESS_DENIED:
     3562                                return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,  N_(
     3563                                                "Failed to open '/dev/%s' for read/write access.  Please check the "
     3564                                                "permissions of that node, and that the net.link.tap.user_open "
     3565                                                "sysctl is set.  Either run 'chmod 0666 /dev/%s' or "
     3566                                                "change the group of that node to vboxusers and make yourself "
     3567                                                "a member of that group.  Make sure that these changes are permanent."), pszHifName, pszHifName);
     3568                            default:
     3569                                AssertMsgFailed(("Could not attach to tap interface! Bad!\n"));
     3570                                return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
     3571                                                "Failed to initialize Host Interface Networking"));
     3572                        }
     3573                    }
     3574
     3575                    Assert((int)maTapFD[uInstance] >= 0);
     3576                    if ((int)maTapFD[uInstance] >= 0)
     3577                    {
     3578                        InsertConfigString(pLunL0, "Driver", "HostInterface");
     3579                        InsertConfigNode(pLunL0, "Config", &pCfg);
     3580                        InsertConfigInteger(pCfg, "FileHandle", maTapFD[uInstance]);
     3581                    }
     3582                    break;
     3583                }
    34173584#  endif
    3418             /** @todo Check for malformed names. */
    3419             const char *pszTrunk = pszHifName;
    3420 
    3421             /* Issue a warning if the interface is down */
    3422             {
    3423                 int iSock = socket(AF_INET, SOCK_DGRAM, 0);
    3424                 if (iSock >= 0)
    3425                 {
    3426                     struct ifreq Req;
    3427 
    3428                     memset(&Req, 0, sizeof(Req));
    3429                     strncpy(Req.ifr_name, pszHifName, sizeof(Req.ifr_name) - 1);
    3430                     if (ioctl(iSock, SIOCGIFFLAGS, &Req) >= 0)
    3431                         if ((Req.ifr_flags & IFF_UP) == 0)
    3432                         {
    3433                             setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown", "Bridged interface %s is down. Guest will not be able to use this interface", pszHifName);
    3434                         }
    3435 
    3436                     close(iSock);
    3437                 }
    3438             }
     3585                /** @todo Check for malformed names. */
     3586                const char *pszTrunk = pszHifName;
     3587
     3588                /* Issue a warning if the interface is down */
     3589                {
     3590                    int iSock = socket(AF_INET, SOCK_DGRAM, 0);
     3591                    if (iSock >= 0)
     3592                    {
     3593                        struct ifreq Req;
     3594
     3595                        memset(&Req, 0, sizeof(Req));
     3596                        strncpy(Req.ifr_name, pszHifName, sizeof(Req.ifr_name) - 1);
     3597                        if (ioctl(iSock, SIOCGIFFLAGS, &Req) >= 0)
     3598                            if ((Req.ifr_flags & IFF_UP) == 0)
     3599                            {
     3600                                setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown", "Bridged interface %s is down. Guest will not be able to use this interface", pszHifName);
     3601                            }
     3602
     3603                        close(iSock);
     3604                    }
     3605                }
    34393606
    34403607# else
     
    34423609# endif
    34433610
    3444             rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");                        RC_CHECK();
    3445             rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                             RC_CHECK();
    3446             rc = CFGMR3InsertString(pCfg, "Trunk", pszTrunk);                           RC_CHECK();
    3447             rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);
    3448             RC_CHECK();
    3449             char szNetwork[INTNET_MAX_NETWORK_NAME];
    3450             RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
    3451             rc = CFGMR3InsertString(pCfg, "Network", szNetwork);                        RC_CHECK();
    3452             networkName = Bstr(szNetwork);
    3453             trunkName = Bstr(pszTrunk);
    3454             trunkType = Bstr(TRUNKTYPE_NETFLT);
     3611                InsertConfigString(pLunL0, "Driver", "IntNet");
     3612                InsertConfigNode(pLunL0, "Config", &pCfg);
     3613                InsertConfigString(pCfg, "Trunk", pszTrunk);
     3614                InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);
     3615                char szNetwork[INTNET_MAX_NETWORK_NAME];
     3616                RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
     3617                InsertConfigString(pCfg, "Network", szNetwork);
     3618                networkName = Bstr(szNetwork);
     3619                trunkName = Bstr(pszTrunk);
     3620                trunkType = Bstr(TRUNKTYPE_NETFLT);
    34553621
    34563622# if defined(RT_OS_DARWIN)
    3457             /** @todo Come up with a better deal here. Problem is that IHostNetworkInterface is completely useless here. */
    3458             if (    strstr(pszHifName, "Wireless")
    3459                 ||  strstr(pszHifName, "AirPort" ))
    3460             {
    3461                 rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);                RC_CHECK();
    3462             }
     3623                /** @todo Come up with a better deal here. Problem is that IHostNetworkInterface is completely useless here. */
     3624                if (    strstr(pszHifName, "Wireless")
     3625                    ||  strstr(pszHifName, "AirPort" ))
     3626                {
     3627                    InsertConfigInteger(pCfg, "SharedMacOnWire", true);
     3628                }
    34633629# elif defined(RT_OS_LINUX)
    3464             int iSock = socket(AF_INET, SOCK_DGRAM, 0);
    3465             if (iSock >= 0)
    3466             {
    3467                 struct iwreq WRq;
    3468 
    3469                 memset(&WRq, 0, sizeof(WRq));
    3470                 strncpy(WRq.ifr_name, pszHifName, IFNAMSIZ);
    3471                 bool fSharedMacOnWire = ioctl(iSock, SIOCGIWNAME, &WRq) >= 0;
    3472                 close(iSock);
    3473                 if (fSharedMacOnWire)
    3474                 {
    3475                     rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);
    3476                     RC_CHECK();
    3477                     Log(("Set SharedMacOnWire\n"));
     3630                int iSock = socket(AF_INET, SOCK_DGRAM, 0);
     3631                if (iSock >= 0)
     3632                {
     3633                    struct iwreq WRq;
     3634
     3635                    memset(&WRq, 0, sizeof(WRq));
     3636                    strncpy(WRq.ifr_name, pszHifName, IFNAMSIZ);
     3637                    bool fSharedMacOnWire = ioctl(iSock, SIOCGIWNAME, &WRq) >= 0;
     3638                    close(iSock);
     3639                    if (fSharedMacOnWire)
     3640                    {
     3641                        InsertConfigInteger(pCfg, "SharedMacOnWire", true);
     3642                        Log(("Set SharedMacOnWire\n"));
     3643                    }
     3644                    else
     3645                        Log(("Failed to get wireless name\n"));
    34783646                }
    34793647                else
    3480                     Log(("Failed to get wireless name\n"));
    3481             }
    3482             else
    3483                 Log(("Failed to open wireless socket\n"));
     3648                    Log(("Failed to open wireless socket\n"));
    34843649# elif defined(RT_OS_FREEBSD)
    3485             int iSock = socket(AF_INET, SOCK_DGRAM, 0);
    3486             if (iSock >= 0)
    3487             {
    3488                 struct ieee80211req WReq;
    3489                 uint8_t abData[32];
    3490 
    3491                 memset(&WReq, 0, sizeof(WReq));
    3492                 strncpy(WReq.i_name, pszHifName, sizeof(WReq.i_name));
    3493                 WReq.i_type = IEEE80211_IOC_SSID;
    3494                 WReq.i_val = -1;
    3495                 WReq.i_data = abData;
    3496                 WReq.i_len = sizeof(abData);
    3497 
    3498                 bool fSharedMacOnWire = ioctl(iSock, SIOCG80211, &WReq) >= 0;
    3499                 close(iSock);
    3500                 if (fSharedMacOnWire)
    3501                 {
    3502                     rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);
    3503                     RC_CHECK();
    3504                     Log(("Set SharedMacOnWire\n"));
     3650                int iSock = socket(AF_INET, SOCK_DGRAM, 0);
     3651                if (iSock >= 0)
     3652                {
     3653                    struct ieee80211req WReq;
     3654                    uint8_t abData[32];
     3655
     3656                    memset(&WReq, 0, sizeof(WReq));
     3657                    strncpy(WReq.i_name, pszHifName, sizeof(WReq.i_name));
     3658                    WReq.i_type = IEEE80211_IOC_SSID;
     3659                    WReq.i_val = -1;
     3660                    WReq.i_data = abData;
     3661                    WReq.i_len = sizeof(abData);
     3662
     3663                    bool fSharedMacOnWire = ioctl(iSock, SIOCG80211, &WReq) >= 0;
     3664                    close(iSock);
     3665                    if (fSharedMacOnWire)
     3666                    {
     3667                        InsertConfigInteger(pCfg, "SharedMacOnWire", true);
     3668                        Log(("Set SharedMacOnWire\n"));
     3669                    }
     3670                    else
     3671                        Log(("Failed to get wireless name\n"));
    35053672                }
    35063673                else
    3507                     Log(("Failed to get wireless name\n"));
    3508             }
    3509             else
    3510                 Log(("Failed to open wireless socket\n"));
     3674                    Log(("Failed to open wireless socket\n"));
    35113675# elif defined(RT_OS_WINDOWS)
    35123676#  define DEVNAME_PREFIX L"\\\\.\\"
    3513             /* we are getting the medium type via IOCTL_NDIS_QUERY_GLOBAL_STATS Io Control
    3514              * there is a pretty long way till there though since we need to obtain the symbolic link name
    3515              * for the adapter device we are going to query given the device Guid */
    3516 
    3517 
    3518             /* prepend the "\\\\.\\" to the bind name to obtain the link name */
    3519 
    3520             wchar_t FileName[MAX_PATH];
    3521             wcscpy(FileName, DEVNAME_PREFIX);
    3522             wcscpy((wchar_t*)(((char*)FileName) + sizeof(DEVNAME_PREFIX) - sizeof(FileName[0])), pswzBindName);
    3523 
    3524             /* open the device */
    3525             HANDLE hDevice = CreateFile(FileName,
    3526                                         GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
    3527                                         NULL,
    3528                                         OPEN_EXISTING,
    3529                                         FILE_ATTRIBUTE_NORMAL,
    3530                                         NULL);
    3531 
    3532             if (hDevice != INVALID_HANDLE_VALUE)
    3533             {
    3534                 bool fSharedMacOnWire = false;
    3535 
    3536                 /* now issue the OID_GEN_PHYSICAL_MEDIUM query */
    3537                 DWORD Oid = OID_GEN_PHYSICAL_MEDIUM;
    3538                 NDIS_PHYSICAL_MEDIUM PhMedium;
    3539                 DWORD cbResult;
    3540                 if (DeviceIoControl(hDevice,
    3541                                     IOCTL_NDIS_QUERY_GLOBAL_STATS,
    3542                                     &Oid,
    3543                                     sizeof(Oid),
    3544                                     &PhMedium,
    3545                                     sizeof(PhMedium),
    3546                                     &cbResult,
    3547                                     NULL))
    3548                 {
    3549                     /* that was simple, now examine PhMedium */
    3550                     if (   PhMedium == NdisPhysicalMediumWirelessWan
    3551                         || PhMedium == NdisPhysicalMediumWirelessLan
    3552                         || PhMedium == NdisPhysicalMediumNative802_11
    3553                         || PhMedium == NdisPhysicalMediumBluetooth)
    3554                         fSharedMacOnWire = true;
     3677                /* we are getting the medium type via IOCTL_NDIS_QUERY_GLOBAL_STATS Io Control
     3678                 * there is a pretty long way till there though since we need to obtain the symbolic link name
     3679                 * for the adapter device we are going to query given the device Guid */
     3680
     3681
     3682                /* prepend the "\\\\.\\" to the bind name to obtain the link name */
     3683
     3684                wchar_t FileName[MAX_PATH];
     3685                wcscpy(FileName, DEVNAME_PREFIX);
     3686                wcscpy((wchar_t*)(((char*)FileName) + sizeof(DEVNAME_PREFIX) - sizeof(FileName[0])), pswzBindName);
     3687
     3688                /* open the device */
     3689                HANDLE hDevice = CreateFile(FileName,
     3690                                            GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
     3691                                            NULL,
     3692                                            OPEN_EXISTING,
     3693                                            FILE_ATTRIBUTE_NORMAL,
     3694                                            NULL);
     3695
     3696                if (hDevice != INVALID_HANDLE_VALUE)
     3697                {
     3698                    bool fSharedMacOnWire = false;
     3699
     3700                    /* now issue the OID_GEN_PHYSICAL_MEDIUM query */
     3701                    DWORD Oid = OID_GEN_PHYSICAL_MEDIUM;
     3702                    NDIS_PHYSICAL_MEDIUM PhMedium;
     3703                    DWORD cbResult;
     3704                    if (DeviceIoControl(hDevice,
     3705                                        IOCTL_NDIS_QUERY_GLOBAL_STATS,
     3706                                        &Oid,
     3707                                        sizeof(Oid),
     3708                                        &PhMedium,
     3709                                        sizeof(PhMedium),
     3710                                        &cbResult,
     3711                                        NULL))
     3712                    {
     3713                        /* that was simple, now examine PhMedium */
     3714                        if (   PhMedium == NdisPhysicalMediumWirelessWan
     3715                            || PhMedium == NdisPhysicalMediumWirelessLan
     3716                            || PhMedium == NdisPhysicalMediumNative802_11
     3717                            || PhMedium == NdisPhysicalMediumBluetooth)
     3718                            fSharedMacOnWire = true;
     3719                    }
     3720                    else
     3721                    {
     3722                        int winEr = GetLastError();
     3723                        LogRel(("Console::configConstructor: DeviceIoControl failed, err (0x%x), ignoring\n", winEr));
     3724                        Assert(winEr == ERROR_INVALID_PARAMETER || winEr == ERROR_NOT_SUPPORTED || winEr == ERROR_BAD_COMMAND);
     3725                    }
     3726                    CloseHandle(hDevice);
     3727
     3728                    if (fSharedMacOnWire)
     3729                    {
     3730                        Log(("this is a wireless adapter"));
     3731                        InsertConfigInteger(pCfg, "SharedMacOnWire", true);
     3732                        Log(("Set SharedMacOnWire\n"));
     3733                    }
     3734                    else
     3735                        Log(("this is NOT a wireless adapter"));
    35553736                }
    35563737                else
    35573738                {
    35583739                    int winEr = GetLastError();
    3559                     LogRel(("Console::configConstructor: DeviceIoControl failed, err (0x%x), ignoring\n", winEr));
    3560                     Assert(winEr == ERROR_INVALID_PARAMETER || winEr == ERROR_NOT_SUPPORTED || winEr == ERROR_BAD_COMMAND);
    3561                 }
    3562                 CloseHandle(hDevice);
    3563 
    3564                 if (fSharedMacOnWire)
    3565                 {
    3566                     Log(("this is a wireless adapter"));
    3567                     rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);            RC_CHECK();
    3568                     Log(("Set SharedMacOnWire\n"));
    3569                 }
    3570                 else
    3571                     Log(("this is NOT a wireless adapter"));
    3572             }
    3573             else
    3574             {
    3575                 int winEr = GetLastError();
    3576                 AssertLogRelMsgFailed(("Console::configConstructor: CreateFile failed, err (0x%x), ignoring\n", winEr));
    3577             }
    3578 
    3579             CoTaskMemFree(pswzBindName);
    3580 
    3581             pAdaptorComponent.setNull();
    3582             /* release the pNc finally */
    3583             VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
     3740                    AssertLogRelMsgFailed(("Console::configConstructor: CreateFile failed, err (0x%x), ignoring\n", winEr));
     3741                }
     3742
     3743                CoTaskMemFree(pswzBindName);
     3744
     3745                pAdaptorComponent.setNull();
     3746                /* release the pNc finally */
     3747                VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
    35843748# else
    3585             /** @todo PORTME: wireless detection */
     3749                /** @todo PORTME: wireless detection */
    35863750# endif
    35873751
     
    35923756            if (ZoneId != GLOBAL_ZONEID)
    35933757            {
    3594                 rc = CFGMR3InsertInteger(pCfg, "IgnoreAllPromisc", true);               RC_CHECK();
     3758                InsertConfigInteger(pCfg, "IgnoreAllPromisc", true);
    35953759            }
    35963760#  endif
     
    36063770# error "Port me"
    36073771#endif
    3608             break;
    3609         }
    3610 
    3611         case NetworkAttachmentType_Internal:
    3612         {
    3613             hrc = aNetworkAdapter->COMGETTER(InternalNetwork)(bstr.asOutParam());       H();
    3614             if (!bstr.isEmpty())
     3772                break;
     3773            }
     3774
     3775            case NetworkAttachmentType_Internal:
     3776            {
     3777                hrc = aNetworkAdapter->COMGETTER(InternalNetwork)(bstr.asOutParam());       H();
     3778                if (!bstr.isEmpty())
     3779                {
     3780                    if (fSniffer)
     3781                        InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
     3782                    else
     3783                        InsertConfigNode(pInst, "LUN#0", &pLunL0);
     3784                    InsertConfigString(pLunL0, "Driver", "IntNet");
     3785                    InsertConfigNode(pLunL0, "Config", &pCfg);
     3786                    InsertConfigString(pCfg, "Network", bstr);
     3787                    InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_WhateverNone);
     3788                    networkName = bstr;
     3789                    trunkType = Bstr(TRUNKTYPE_WHATEVER);
     3790                }
     3791                break;
     3792            }
     3793
     3794            case NetworkAttachmentType_HostOnly:
    36153795            {
    36163796                if (fSniffer)
    3617                 {
    3618                     rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
    3619                     RC_CHECK();
    3620                 }
     3797                    InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
    36213798                else
    3622                 {
    3623                     rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
    3624                     RC_CHECK();
    3625                 }
    3626                 rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");                    RC_CHECK();
    3627                 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                         RC_CHECK();
    3628                 rc = CFGMR3InsertStringW(pCfg, "Network", bstr);                        RC_CHECK();
    3629                 rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_WhateverNone); RC_CHECK();
    3630                 networkName = bstr;
    3631                 trunkType = Bstr(TRUNKTYPE_WHATEVER);
    3632             }
    3633             break;
    3634         }
    3635 
    3636         case NetworkAttachmentType_HostOnly:
    3637         {
    3638             if (fSniffer)
    3639             {
    3640                 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
    3641                 RC_CHECK();
    3642             }
    3643             else
    3644             {
    3645                 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
    3646                 RC_CHECK();
    3647             }
    3648 
    3649             rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");                        RC_CHECK();
    3650             rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                             RC_CHECK();
    3651 
    3652             Bstr HifName;
    3653             hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
    3654             if (FAILED(hrc))
    3655             {
    3656                 LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)\n", hrc));
    3657                 H();
    3658             }
    3659 
    3660             Utf8Str HifNameUtf8(HifName);
    3661             const char *pszHifName = HifNameUtf8.raw();
    3662             ComPtr<IHostNetworkInterface> hostInterface;
    3663             rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
    3664             if (!SUCCEEDED(rc))
    3665             {
    3666                 LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)\n", rc));
    3667                 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
    3668                                   N_("Inexistent host networking interface, name '%ls'"),
    3669                                   HifName.raw());
    3670             }
    3671 
    3672             char szNetwork[INTNET_MAX_NETWORK_NAME];
    3673             RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
     3799                    InsertConfigNode(pInst, "LUN#0", &pLunL0);
     3800
     3801                InsertConfigString(pLunL0, "Driver", "IntNet");
     3802                InsertConfigNode(pLunL0, "Config", &pCfg);
     3803
     3804                Bstr HifName;
     3805                hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
     3806                if (FAILED(hrc))
     3807                {
     3808                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)\n", hrc));
     3809                    H();
     3810                }
     3811
     3812                Utf8Str HifNameUtf8(HifName);
     3813                const char *pszHifName = HifNameUtf8.raw();
     3814                ComPtr<IHostNetworkInterface> hostInterface;
     3815                rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
     3816                if (!SUCCEEDED(rc))
     3817                {
     3818                    LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)\n", rc));
     3819                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     3820                                    N_("Inexistent host networking interface, name '%ls'"),
     3821                                    HifName.raw());
     3822                }
     3823
     3824                char szNetwork[INTNET_MAX_NETWORK_NAME];
     3825                RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
    36743826
    36753827#if defined(RT_OS_WINDOWS)
    36763828# ifndef VBOX_WITH_NETFLT
    3677             hrc = E_NOTIMPL;
    3678             LogRel(("NetworkAttachmentType_HostOnly: Not Implemented\n"));
    3679             H();
     3829                hrc = E_NOTIMPL;
     3830                LogRel(("NetworkAttachmentType_HostOnly: Not Implemented\n"));
     3831                H();
    36803832# else  /* defined VBOX_WITH_NETFLT*/
    3681             /** @todo r=bird: Put this in a function. */
    3682 
    3683             HostNetworkInterfaceType_T eIfType;
    3684             hrc = hostInterface->COMGETTER(InterfaceType)(&eIfType);
    3685             if (FAILED(hrc))
    3686             {
    3687                 LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(InterfaceType) failed, hrc (0x%x)\n", hrc));
    3688                 H();
    3689             }
    3690 
    3691             if (eIfType != HostNetworkInterfaceType_HostOnly)
    3692                 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
    3693                                   N_("Interface ('%ls') is not a Host-Only Adapter interface"),
    3694                                   HifName.raw());
    3695 
    3696             hrc = hostInterface->COMGETTER(Id)(bstr.asOutParam());
    3697             if (FAILED(hrc))
    3698             {
    3699                 LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(Id) failed, hrc (0x%x)\n", hrc));
    3700                 H();
    3701             }
    3702             Guid hostIFGuid(bstr);
    3703 
    3704             INetCfg *pNc;
    3705             ComPtr<INetCfgComponent> pAdaptorComponent;
    3706             LPWSTR pszApp;
    3707             rc = VERR_INTNET_FLT_IF_NOT_FOUND;
    3708 
    3709             hrc = VBoxNetCfgWinQueryINetCfg(FALSE,
    3710                                             L"VirtualBox",
    3711                                             &pNc,
    3712                                             &pszApp);
    3713             Assert(hrc == S_OK);
    3714             if (hrc == S_OK)
    3715             {
    3716                 /* get the adapter's INetCfgComponent*/
    3717                 hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam());
    3718                 if (hrc != S_OK)
     3833                /** @todo r=bird: Put this in a function. */
     3834
     3835                HostNetworkInterfaceType_T eIfType;
     3836                hrc = hostInterface->COMGETTER(InterfaceType)(&eIfType);
     3837                if (FAILED(hrc))
     3838                {
     3839                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(InterfaceType) failed, hrc (0x%x)\n", hrc));
     3840                    H();
     3841                }
     3842
     3843                if (eIfType != HostNetworkInterfaceType_HostOnly)
     3844                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
     3845                                    N_("Interface ('%ls') is not a Host-Only Adapter interface"),
     3846                                    HifName.raw());
     3847
     3848                hrc = hostInterface->COMGETTER(Id)(bstr.asOutParam());
     3849                if (FAILED(hrc))
     3850                {
     3851                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(Id) failed, hrc (0x%x)\n", hrc));
     3852                    H();
     3853                }
     3854                Guid hostIFGuid(bstr);
     3855
     3856                INetCfg *pNc;
     3857                ComPtr<INetCfgComponent> pAdaptorComponent;
     3858                LPWSTR pszApp;
     3859                rc = VERR_INTNET_FLT_IF_NOT_FOUND;
     3860
     3861                hrc = VBoxNetCfgWinQueryINetCfg(FALSE,
     3862                                                L"VirtualBox",
     3863                                                &pNc,
     3864                                                &pszApp);
     3865                Assert(hrc == S_OK);
     3866                if (hrc == S_OK)
     3867                {
     3868                    /* get the adapter's INetCfgComponent*/
     3869                    hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam());
     3870                    if (hrc != S_OK)
     3871                    {
     3872                        VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
     3873                        LogRel(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc=%Rhrc (0x%x)\n", hrc, hrc));
     3874                        H();
     3875                    }
     3876                }
     3877#define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
     3878                char szTrunkName[INTNET_MAX_TRUNK_NAME];
     3879                char *pszTrunkName = szTrunkName;
     3880                wchar_t * pswzBindName;
     3881                hrc = pAdaptorComponent->GetBindName(&pswzBindName);
     3882                Assert(hrc == S_OK);
     3883                if (hrc == S_OK)
     3884                {
     3885                    int cwBindName = (int)wcslen(pswzBindName) + 1;
     3886                    int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX);
     3887                    if (sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName)
     3888                    {
     3889                        strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX);
     3890                        pszTrunkName += cbFullBindNamePrefix-1;
     3891                        if (!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName,
     3892                                                sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL))
     3893                        {
     3894                            DWORD err = GetLastError();
     3895                            hrc = HRESULT_FROM_WIN32(err);
     3896                            AssertLogRelMsgFailed(("NetworkAttachmentType_HostOnly: WideCharToMultiByte failed, hr=%Rhrc (0x%x) err=%u\n", hrc, hrc, err));
     3897                        }
     3898                    }
     3899                    else
     3900                    {
     3901                        AssertLogRelMsgFailed(("NetworkAttachmentType_HostOnly: insufficient szTrunkName buffer space\n"));
     3902                        /** @todo set appropriate error code */
     3903                        hrc = E_FAIL;
     3904                    }
     3905
     3906                    if (hrc != S_OK)
     3907                    {
     3908                        AssertFailed();
     3909                        CoTaskMemFree(pswzBindName);
     3910                        VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
     3911                        H();
     3912                    }
     3913                }
     3914                else
    37193915                {
    37203916                    VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
    3721                     LogRel(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc=%Rhrc (0x%x)\n", hrc, hrc));
     3917                    AssertLogRelMsgFailed(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc=%Rhrc (0x%x)\n", hrc, hrc));
    37223918                    H();
    37233919                }
    3724             }
    3725 #define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
    3726             char szTrunkName[INTNET_MAX_TRUNK_NAME];
    3727             char *pszTrunkName = szTrunkName;
    3728             wchar_t * pswzBindName;
    3729             hrc = pAdaptorComponent->GetBindName(&pswzBindName);
    3730             Assert(hrc == S_OK);
    3731             if (hrc == S_OK)
    3732             {
    3733                 int cwBindName = (int)wcslen(pswzBindName) + 1;
    3734                 int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX);
    3735                 if (sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName)
    3736                 {
    3737                     strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX);
    3738                     pszTrunkName += cbFullBindNamePrefix-1;
    3739                     if (!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName,
    3740                                              sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL))
    3741                     {
    3742                         DWORD err = GetLastError();
    3743                         hrc = HRESULT_FROM_WIN32(err);
    3744                         AssertLogRelMsgFailed(("NetworkAttachmentType_HostOnly: WideCharToMultiByte failed, hr=%Rhrc (0x%x) err=%u\n", hrc, hrc, err));
    3745                     }
    3746                 }
    3747                 else
    3748                 {
    3749                     AssertLogRelMsgFailed(("NetworkAttachmentType_HostOnly: insufficient szTrunkName buffer space\n"));
    3750                     /** @todo set appropriate error code */
    3751                     hrc = E_FAIL;
    3752                 }
    3753 
    3754                 if (hrc != S_OK)
    3755                 {
    3756                     AssertFailed();
    3757                     CoTaskMemFree(pswzBindName);
    3758                     VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
    3759                     H();
    3760                 }
    3761             }
    3762             else
    3763             {
     3920
     3921
     3922                CoTaskMemFree(pswzBindName);
     3923
     3924                pAdaptorComponent.setNull();
     3925                /* release the pNc finally */
    37643926                VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
    3765                 AssertLogRelMsgFailed(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc=%Rhrc (0x%x)\n", hrc, hrc));
    3766                 H();
    3767             }
    3768 
    3769 
    3770             CoTaskMemFree(pswzBindName);
    3771 
    3772             pAdaptorComponent.setNull();
    3773             /* release the pNc finally */
    3774             VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
    3775 
    3776             const char *pszTrunk = szTrunkName;
    3777 
    3778             rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);       RC_CHECK();
    3779             rc = CFGMR3InsertString(pCfg, "Trunk", pszTrunk);                           RC_CHECK();
    3780             rc = CFGMR3InsertString(pCfg, "Network", szNetwork);                        RC_CHECK();
    3781             networkName = Bstr(szNetwork);
    3782             trunkName   = Bstr(pszTrunk);
    3783             trunkType   = TRUNKTYPE_NETADP;
     3927
     3928                const char *pszTrunk = szTrunkName;
     3929
     3930                InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);
     3931                InsertConfigString(pCfg, "Trunk", pszTrunk);
     3932                InsertConfigString(pCfg, "Network", szNetwork);
     3933                networkName = Bstr(szNetwork);
     3934                trunkName   = Bstr(pszTrunk);
     3935                trunkType   = TRUNKTYPE_NETADP;
    37843936# endif /* defined VBOX_WITH_NETFLT*/
    37853937#elif defined(RT_OS_DARWIN)
    3786             rc = CFGMR3InsertString(pCfg, "Trunk", pszHifName);                         RC_CHECK();
    3787             rc = CFGMR3InsertString(pCfg, "Network", szNetwork);                        RC_CHECK();
    3788             rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);       RC_CHECK();
    3789             networkName = Bstr(szNetwork);
    3790             trunkName   = Bstr(pszHifName);
    3791             trunkType   = TRUNKTYPE_NETADP;
     3938                InsertConfigString(pCfg, "Trunk", pszHifName);
     3939                InsertConfigString(pCfg, "Network", szNetwork);
     3940                InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);
     3941                networkName = Bstr(szNetwork);
     3942                trunkName   = Bstr(pszHifName);
     3943                trunkType   = TRUNKTYPE_NETADP;
    37923944#else
    3793             rc = CFGMR3InsertString(pCfg, "Trunk", pszHifName);                         RC_CHECK();
    3794             rc = CFGMR3InsertString(pCfg, "Network", szNetwork);                        RC_CHECK();
    3795             rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);       RC_CHECK();
    3796             networkName = Bstr(szNetwork);
    3797             trunkName   = Bstr(pszHifName);
    3798             trunkType   = TRUNKTYPE_NETFLT;
     3945                InsertConfigString(pCfg, "Trunk", pszHifName);
     3946                InsertConfigString(pCfg, "Network", szNetwork);
     3947                InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);
     3948                networkName = Bstr(szNetwork);
     3949                trunkName   = Bstr(pszHifName);
     3950                trunkType   = TRUNKTYPE_NETFLT;
    37993951#endif
    38003952#if !defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
    38013953
    3802             Bstr tmpAddr, tmpMask;
    3803 
    3804             hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPAddress", pszHifName), tmpAddr.asOutParam());
    3805             if (SUCCEEDED(hrc) && !tmpAddr.isEmpty())
    3806             {
    3807                 hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPNetMask", pszHifName), tmpMask.asOutParam());
    3808                 if (SUCCEEDED(hrc) && !tmpMask.isEmpty())
    3809                     hrc = hostInterface->EnableStaticIpConfig(tmpAddr, tmpMask);
     3954                Bstr tmpAddr, tmpMask;
     3955
     3956                hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPAddress", pszHifName), tmpAddr.asOutParam());
     3957                if (SUCCEEDED(hrc) && !tmpAddr.isEmpty())
     3958                {
     3959                    hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPNetMask", pszHifName), tmpMask.asOutParam());
     3960                    if (SUCCEEDED(hrc) && !tmpMask.isEmpty())
     3961                        hrc = hostInterface->EnableStaticIpConfig(tmpAddr, tmpMask);
     3962                    else
     3963                        hrc = hostInterface->EnableStaticIpConfig(tmpAddr,
     3964                                                                Bstr(VBOXNET_IPV4MASK_DEFAULT));
     3965                }
    38103966                else
    3811                     hrc = hostInterface->EnableStaticIpConfig(tmpAddr,
    3812                                                               Bstr(VBOXNET_IPV4MASK_DEFAULT));
    3813             }
    3814             else
    3815             {
    3816                 /* Grab the IP number from the 'vboxnetX' instance number (see netif.h) */
    3817                 hrc = hostInterface->EnableStaticIpConfig(getDefaultIPv4Address(Bstr(pszHifName)),
    3818                                                           Bstr(VBOXNET_IPV4MASK_DEFAULT));
    3819             }
    3820 
    3821             ComAssertComRC(hrc); /** @todo r=bird: Why this isn't fatal? (H()) */
    3822 
    3823             hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6Address", pszHifName), tmpAddr.asOutParam());
    3824             if (SUCCEEDED(hrc))
    3825                 hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask", pszHifName), tmpMask.asOutParam());
    3826             if (SUCCEEDED(hrc) && !tmpAddr.isEmpty() && !tmpMask.isEmpty())
    3827             {
    3828                 hrc = hostInterface->EnableStaticIpConfigV6(tmpAddr, Utf8Str(tmpMask).toUInt32());
     3967                {
     3968                    /* Grab the IP number from the 'vboxnetX' instance number (see netif.h) */
     3969                    hrc = hostInterface->EnableStaticIpConfig(getDefaultIPv4Address(Bstr(pszHifName)),
     3970                                                            Bstr(VBOXNET_IPV4MASK_DEFAULT));
     3971                }
     3972
    38293973                ComAssertComRC(hrc); /** @todo r=bird: Why this isn't fatal? (H()) */
    3830             }
     3974
     3975                hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6Address", pszHifName), tmpAddr.asOutParam());
     3976                if (SUCCEEDED(hrc))
     3977                    hrc = virtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask", pszHifName), tmpMask.asOutParam());
     3978                if (SUCCEEDED(hrc) && !tmpAddr.isEmpty() && !tmpMask.isEmpty())
     3979                {
     3980                    hrc = hostInterface->EnableStaticIpConfigV6(tmpAddr, Utf8Str(tmpMask).toUInt32());
     3981                    ComAssertComRC(hrc); /** @todo r=bird: Why this isn't fatal? (H()) */
     3982                }
    38313983#endif
    3832             break;
     3984                break;
     3985            }
     3986
     3987#if defined(VBOX_WITH_VDE)
     3988            case NetworkAttachmentType_VDE:
     3989            {
     3990                hrc = aNetworkAdapter->COMGETTER(VDENetwork)(bstr.asOutParam());            H();
     3991                InsertConfigNode(pInst, "LUN#0", &pLunL0);
     3992                InsertConfigString(pLunL0, "Driver", "VDE");
     3993                InsertConfigNode(pLunL0, "Config", &pCfg);
     3994                if (!bstr.isEmpty())
     3995                {
     3996                    InsertConfigString(pCfg, "Network", bstr);
     3997                    networkName = bstr;
     3998                }
     3999                break;
     4000            }
     4001#endif
     4002
     4003            default:
     4004                AssertMsgFailed(("should not get here!\n"));
     4005                break;
    38334006        }
    38344007
     4008        /*
     4009         * Attempt to attach the driver.
     4010         */
     4011        switch (eAttachmentType)
     4012        {
     4013            case NetworkAttachmentType_Null:
     4014                break;
     4015
     4016            case NetworkAttachmentType_Bridged:
     4017            case NetworkAttachmentType_Internal:
     4018            case NetworkAttachmentType_HostOnly:
     4019            case NetworkAttachmentType_NAT:
    38354020#if defined(VBOX_WITH_VDE)
    3836         case NetworkAttachmentType_VDE:
    3837         {
    3838             hrc = aNetworkAdapter->COMGETTER(VDENetwork)(bstr.asOutParam());            H();
    3839             rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);                             RC_CHECK();
    3840             rc = CFGMR3InsertString(pLunL0, "Driver", "VDE");                           RC_CHECK();
    3841             rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                             RC_CHECK();
    3842             if (!bstr.isEmpty())
    3843             {
    3844                 rc = CFGMR3InsertStringW(pCfg, "Network", bstr);                        RC_CHECK();
    3845                 networkName = bstr;
    3846             }
    3847             break;
     4021            case NetworkAttachmentType_VDE:
     4022#endif
     4023            {
     4024                if (SUCCEEDED(hrc) && SUCCEEDED(rc))
     4025                {
     4026                    if (fAttachDetach)
     4027                    {
     4028                        rc = PDMR3DriverAttach(pVM, pszDevice, uInstance, uLun, 0 /*fFlags*/, NULL /* ppBase */);
     4029                        //AssertRC(rc);
     4030                    }
     4031
     4032                    {
     4033                        /** @todo pritesh: get the dhcp server name from the
     4034                         * previous network configuration and then stop the server
     4035                         * else it may conflict with the dhcp server running  with
     4036                         * the current attachment type
     4037                         */
     4038                        /* Stop the hostonly DHCP Server */
     4039                    }
     4040
     4041                    if (!networkName.isEmpty())
     4042                    {
     4043                        /*
     4044                         * Until we implement service reference counters DHCP Server will be stopped
     4045                         * by DHCPServerRunner destructor.
     4046                         */
     4047                        ComPtr<IDHCPServer> dhcpServer;
     4048                        hrc = virtualBox->FindDHCPServerByNetworkName(networkName, dhcpServer.asOutParam());
     4049                        if (SUCCEEDED(hrc))
     4050                        {
     4051                            /* there is a DHCP server available for this network */
     4052                            BOOL fEnabled;
     4053                            hrc = dhcpServer->COMGETTER(Enabled)(&fEnabled);
     4054                            if (FAILED(hrc))
     4055                            {
     4056                                LogRel(("DHCP svr: COMGETTER(Enabled) failed, hrc (%Rhrc)", hrc));
     4057                                H();
     4058                            }
     4059
     4060                            if (fEnabled)
     4061                                hrc = dhcpServer->Start(networkName, trunkName, trunkType);
     4062                        }
     4063                        else
     4064                            hrc = S_OK;
     4065                    }
     4066                }
     4067
     4068                break;
     4069            }
     4070
     4071            default:
     4072                AssertMsgFailed(("should not get here!\n"));
     4073                break;
    38484074        }
    3849 #endif
    3850 
    3851         default:
    3852             AssertMsgFailed(("should not get here!\n"));
    3853             break;
     4075
     4076        meAttachmentType[uInstance] = eAttachmentType;
    38544077    }
    3855 
    3856     /*
    3857      * Attempt to attach the driver.
    3858      */
    3859     switch (eAttachmentType)
     4078    catch (ConfigError &x)
    38604079    {
    3861         case NetworkAttachmentType_Null:
    3862             break;
    3863 
    3864         case NetworkAttachmentType_Bridged:
    3865         case NetworkAttachmentType_Internal:
    3866         case NetworkAttachmentType_HostOnly:
    3867         case NetworkAttachmentType_NAT:
    3868 #if defined(VBOX_WITH_VDE)
    3869         case NetworkAttachmentType_VDE:
    3870 #endif
    3871         {
    3872             if (SUCCEEDED(hrc) && SUCCEEDED(rc))
    3873             {
    3874                 if (fAttachDetach)
    3875                 {
    3876                     rc = PDMR3DriverAttach(pVM, pszDevice, uInstance, uLun, 0 /*fFlags*/, NULL /* ppBase */);
    3877                     //AssertRC(rc);
    3878                 }
    3879 
    3880                 {
    3881                     /** @todo pritesh: get the dhcp server name from the
    3882                      * previous network configuration and then stop the server
    3883                      * else it may conflict with the dhcp server running  with
    3884                      * the current attachment type
    3885                      */
    3886                     /* Stop the hostonly DHCP Server */
    3887                 }
    3888 
    3889                 if (!networkName.isEmpty())
    3890                 {
    3891                     /*
    3892                      * Until we implement service reference counters DHCP Server will be stopped
    3893                      * by DHCPServerRunner destructor.
    3894                      */
    3895                     ComPtr<IDHCPServer> dhcpServer;
    3896                     hrc = virtualBox->FindDHCPServerByNetworkName(networkName, dhcpServer.asOutParam());
    3897                     if (SUCCEEDED(hrc))
    3898                     {
    3899                         /* there is a DHCP server available for this network */
    3900                         BOOL fEnabled;
    3901                         hrc = dhcpServer->COMGETTER(Enabled)(&fEnabled);
    3902                         if (FAILED(hrc))
    3903                         {
    3904                             LogRel(("DHCP svr: COMGETTER(Enabled) failed, hrc (%Rhrc)", hrc));
    3905                             H();
    3906                         }
    3907 
    3908                         if (fEnabled)
    3909                             hrc = dhcpServer->Start(networkName, trunkName, trunkType);
    3910                     }
    3911                     else
    3912                         hrc = S_OK;
    3913                 }
    3914             }
    3915 
    3916             break;
    3917         }
    3918 
    3919         default:
    3920             AssertMsgFailed(("should not get here!\n"));
    3921             break;
     4080        // InsertConfig threw something:
     4081        return x.m_vrc;
    39224082    }
    39234083
    3924     meAttachmentType[uInstance] = eAttachmentType;
    3925 
    39264084#undef H
    3927 #undef RC_CHECK
    39284085
    39294086    return VINF_SUCCESS;
     
    39344091 * Set an array of guest properties
    39354092 */
    3936 static void configSetProperties(VMMDev * const pVMMDev, void *names,
    3937                                 void *values, void *timestamps, void *flags)
     4093static void configSetProperties(VMMDev * const pVMMDev,
     4094                                void *names,
     4095                                void *values,
     4096                                void *timestamps,
     4097                                void *flags)
    39384098{
    39394099    VBOXHGCMSVCPARM parms[4];
  • trunk/src/VBox/Main/VirtualBoxImpl.cpp

    r30742 r30746  
    40824082        throw;
    40834083    }
    4084     catch (const xml::Error &err)
     4084    catch (const iprt::Error &err)      // includes all XML exceptions
    40854085    {
    40864086        return setErrorStatic(E_FAIL,
  • trunk/src/VBox/Runtime/r3/xml.cpp

    r29873 r30746  
    13841384    }
    13851385
    1386     void setError(const xml::Error &x)
     1386    void setError(const iprt::Error &x)
    13871387    {
    13881388        error = x.what();
     
    14561456    }
    14571457    catch (const xml::EIPRTFailure &err) { pContext->setError(err); }
    1458     catch (const xml::Error &err) { pContext->setError(err); }
     1458    catch (const iprt::Error &err) { pContext->setError(err); }
    14591459    catch (const std::exception &err) { pContext->setError(err); }
    14601460    catch (...) { pContext->setError(xml::LogicError(RT_SRC_POS)); }
     
    15811581    }
    15821582    catch (const xml::EIPRTFailure &err) { pContext->setError(err); }
    1583     catch (const xml::Error &err) { pContext->setError(err); }
     1583    catch (const iprt::Error &err) { pContext->setError(err); }
    15841584    catch (const std::exception &err) { pContext->setError(err); }
    15851585    catch (...) { pContext->setError(xml::LogicError(RT_SRC_POS)); }
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