summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-client/ConsoleImpl2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/src-client/ConsoleImpl2.cpp')
-rw-r--r--src/VBox/Main/src-client/ConsoleImpl2.cpp1403
1 files changed, 934 insertions, 469 deletions
diff --git a/src/VBox/Main/src-client/ConsoleImpl2.cpp b/src/VBox/Main/src-client/ConsoleImpl2.cpp
index 515ba2bd..78feac8f 100644
--- a/src/VBox/Main/src-client/ConsoleImpl2.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl2.cpp
@@ -9,7 +9,7 @@
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -46,6 +46,7 @@
#include "AutoCaller.h"
#include "Logging.h"
+#include <iprt/base64.h>
#include <iprt/buildconfig.h>
#include <iprt/ctype.h>
#include <iprt/dir.h>
@@ -113,15 +114,24 @@
# endif
#endif /* VBOX_WITH_NETFLT */
-#include "DHCPServerRunner.h"
+#include "NetworkServiceRunner.h"
#include "BusAssignmentManager.h"
#ifdef VBOX_WITH_EXTPACK
# include "ExtPackManagerImpl.h"
#endif
-
#if defined(RT_OS_DARWIN)
-
# include "IOKit/IOKitLib.h"
+#endif
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+static Utf8Str *GetExtraDataBoth(IVirtualBox *pVirtualBox, IMachine *pMachine, const char *pszName, Utf8Str *pStrValue);
+
+
+
+#if defined(RT_OS_DARWIN)
static int DarwinSmcKey(char *pabKey, uint32_t cbKey)
{
@@ -160,7 +170,7 @@ static int DarwinSmcKey(char *pabKey, uint32_t cbKey)
for (int i = 0; i < 2; i++)
{
- inputStruct.key = (uint32_t)((i == 0) ? 'OSK0' : 'OSK1');
+ inputStruct.key = (uint32_t)(i == 0 ? 'OSK0' : 'OSK1');
kr = IOConnectCallStructMethod((mach_port_t)port,
(uint32_t)2,
(const void *)&inputStruct,
@@ -246,20 +256,18 @@ static int findEfiRom(IVirtualBox* vbox, FirmwareType_T aFirmwareType, Utf8Str *
return VINF_SUCCESS;
}
-static int getSmcDeviceKey(IMachine *pMachine, BSTR *aKey, bool *pfGetKeyFromRealSMC)
+/**
+ * @throws HRESULT on extra data retrival error.
+ */
+static int getSmcDeviceKey(IVirtualBox *pVirtualBox, IMachine *pMachine, Utf8Str *pStrKey, bool *pfGetKeyFromRealSMC)
{
*pfGetKeyFromRealSMC = false;
/*
* The extra data takes precedence (if non-zero).
*/
- HRESULT hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/SmcDeviceKey").raw(),
- aKey);
- if (FAILED(hrc))
- return Global::vboxStatusCodeFromCOM(hrc);
- if ( SUCCEEDED(hrc)
- && *aKey
- && **aKey)
+ GetExtraDataBoth(pVirtualBox, pMachine, "VBoxInternal2/SmcDeviceKey", pStrKey);
+ if (pStrKey->isNotEmpty())
return VINF_SUCCESS;
#ifdef RT_OS_DARWIN
@@ -270,7 +278,8 @@ static int getSmcDeviceKey(IMachine *pMachine, BSTR *aKey, bool *pfGetKeyFromRea
int rc = DarwinSmcKey(abKeyBuf, sizeof(abKeyBuf));
if (SUCCEEDED(rc))
{
- Bstr(abKeyBuf).detachTo(aKey);
+ *pStrKey = abKeyBuf;
+ *pfGetKeyFromRealSMC = true;
return rc;
}
LogRel(("Warning: DarwinSmcKey failed with rc=%Rrc!\n", rc));
@@ -296,10 +305,10 @@ static int getSmcDeviceKey(IMachine *pMachine, BSTR *aKey, bool *pfGetKeyFromRea
char szProdName[256];
szProdName[0] = '\0';
RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_NAME, szProdName, sizeof(szProdName));
- if ( ( !strncmp(szProdName, "Mac", 3)
- || !strncmp(szProdName, "iMac", 4)
- || !strncmp(szProdName, "iMac", 4)
- || !strncmp(szProdName, "Xserve", 6)
+ if ( ( !strncmp(szProdName, RT_STR_TUPLE("Mac"))
+ || !strncmp(szProdName, RT_STR_TUPLE("iMac"))
+ || !strncmp(szProdName, RT_STR_TUPLE("iMac"))
+ || !strncmp(szProdName, RT_STR_TUPLE("Xserve"))
)
&& !strchr(szProdName, ' ') /* no spaces */
&& RT_C_IS_DIGIT(szProdName[strlen(szProdName) - 1]) /* version number */
@@ -464,10 +473,137 @@ static void RemoveConfigValue(PCFGMNODE pNode,
throw ConfigError("CFGMR3RemoveValue", vrc, pcszName);
}
+/**
+ * Gets an extra data value, consulting both machine and global extra data.
+ *
+ * @throws HRESULT on failure
+ * @returns pStrValue for the callers convenience.
+ * @param pVirtualBox Pointer to the IVirtualBox interface.
+ * @param pMachine Pointer to the IMachine interface.
+ * @param pszName The value to get.
+ * @param pStrValue Where to return it's value (empty string if not
+ * found).
+ */
+static Utf8Str *GetExtraDataBoth(IVirtualBox *pVirtualBox, IMachine *pMachine, const char *pszName, Utf8Str *pStrValue)
+{
+ pStrValue->setNull();
+
+ Bstr bstrName(pszName);
+ Bstr bstrValue;
+ HRESULT hrc = pMachine->GetExtraData(bstrName.raw(), bstrValue.asOutParam());
+ if (FAILED(hrc))
+ throw hrc;
+ if (bstrValue.isEmpty())
+ {
+ hrc = pVirtualBox->GetExtraData(bstrName.raw(), bstrValue.asOutParam());
+ if (FAILED(hrc))
+ throw hrc;
+ }
+
+ if (bstrValue.isNotEmpty())
+ *pStrValue = bstrValue;
+ return pStrValue;
+}
+
+
+/** Helper that finds out the next HBA port used
+ */
+static LONG GetNextUsedPort(LONG aPortUsed[30], LONG lBaseVal, uint32_t u32Size)
+{
+ LONG lNextPortUsed = 30;
+ for (size_t j = 0; j < u32Size; ++j)
+ {
+ if ( aPortUsed[j] > lBaseVal
+ && aPortUsed[j] <= lNextPortUsed)
+ lNextPortUsed = aPortUsed[j];
+ }
+ return lNextPortUsed;
+}
+
+#define MAX_BIOS_LUN_COUNT 4
+
+static int SetBiosDiskInfo(ComPtr<IMachine> pMachine, PCFGMNODE pCfg, PCFGMNODE pBiosCfg,
+ Bstr controllerName, const char * const s_apszBiosConfig[4])
+{
+ HRESULT hrc;
+#define MAX_DEVICES 30
+#define H() AssertMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE)
+
+ LONG lPortLUN[MAX_BIOS_LUN_COUNT];
+ LONG lPortUsed[MAX_DEVICES];
+ uint32_t u32HDCount = 0;
+
+ /* init to max value */
+ lPortLUN[0] = MAX_DEVICES;
+
+ com::SafeIfaceArray<IMediumAttachment> atts;
+ hrc = pMachine->GetMediumAttachmentsOfController(controllerName.raw(),
+ ComSafeArrayAsOutParam(atts)); H();
+ size_t uNumAttachments = atts.size();
+ if (uNumAttachments > MAX_DEVICES)
+ {
+ LogRel(("Number of Attachments > Max=%d.\n", uNumAttachments));
+ uNumAttachments = MAX_DEVICES;
+ }
+
+ /* Find the relevant ports/IDs, i.e the ones to which a HD is attached. */
+ for (size_t j = 0; j < uNumAttachments; ++j)
+ {
+ IMediumAttachment *pMediumAtt = atts[j];
+ LONG lPortNum = 0;
+ hrc = pMediumAtt->COMGETTER(Port)(&lPortNum); H();
+ if (SUCCEEDED(hrc))
+ {
+ DeviceType_T lType;
+ hrc = pMediumAtt->COMGETTER(Type)(&lType); H();
+ if (SUCCEEDED(hrc) && lType == DeviceType_HardDisk)
+ {
+ /* find min port number used for HD */
+ if (lPortNum < lPortLUN[0])
+ lPortLUN[0] = lPortNum;
+ lPortUsed[u32HDCount++] = lPortNum;
+ LogFlowFunc(("HD port Count=%d\n", u32HDCount));
+ }
+
+ /* Configure the hotpluggable flag for the port. */
+ BOOL fHotPluggable = FALSE;
+ hrc = pMediumAtt->COMGETTER(HotPluggable)(&fHotPluggable); H();
+ if (SUCCEEDED(hrc))
+ {
+ PCFGMNODE pPortCfg;
+ char szName[24];
+ RTStrPrintf(szName, sizeof(szName), "Port%d", lPortNum);
+
+ InsertConfigNode(pCfg, szName, &pPortCfg);
+ InsertConfigInteger(pPortCfg, "Hotpluggable", fHotPluggable ? 1 : 0);
+ }
+ }
+ }
+
+
+ /* Pick only the top 4 used HD Ports as CMOS doesn't have space
+ * to save details for all 30 ports
+ */
+ uint32_t u32MaxPortCount = MAX_BIOS_LUN_COUNT;
+ if (u32HDCount < MAX_BIOS_LUN_COUNT)
+ u32MaxPortCount = u32HDCount;
+ for (size_t j = 1; j < u32MaxPortCount; j++)
+ lPortLUN[j] = GetNextUsedPort(lPortUsed,
+ lPortLUN[j-1],
+ u32HDCount);
+ if (pBiosCfg)
+ {
+ for (size_t j = 0; j < u32MaxPortCount; j++)
+ {
+ InsertConfigInteger(pBiosCfg, s_apszBiosConfig[j], lPortLUN[j]);
+ LogFlowFunc(("Top %d HBA ports = %s, %d\n", j, s_apszBiosConfig[j], lPortLUN[j]));
+ }
+ }
+ return VINF_SUCCESS;
+}
+
#ifdef VBOX_WITH_PCI_PASSTHROUGH
-HRESULT Console::attachRawPCIDevices(PVM pVM,
- BusAssignmentManager *BusMgr,
- PCFGMNODE pDevices)
+HRESULT Console::attachRawPCIDevices(PUVM pUVM, BusAssignmentManager *pBusMgr, PCFGMNODE pDevices)
{
HRESULT hrc = S_OK;
PCFGMNODE pInst, pCfg, pLunL0, pLunL1;
@@ -491,14 +627,12 @@ HRESULT Console::attachRawPCIDevices(PVM pVM,
# ifdef VBOX_WITH_EXTPACK
static const char *s_pszPCIRawExtPackName = "Oracle VM VirtualBox Extension Pack";
if (!mptrExtPackManager->isExtPackUsable(s_pszPCIRawExtPackName))
- {
/* Always fatal! */
- return VMSetError(pVM, VERR_NOT_FOUND, RT_SRC_POS,
+ return VMR3SetError(pUVM, VERR_NOT_FOUND, RT_SRC_POS,
N_("Implementation of the PCI passthrough framework not found!\n"
"The VM cannot be started. To fix this problem, either "
"install the '%s' or disable PCI passthrough via VBoxManage"),
s_pszPCIRawExtPackName);
- }
# endif
PCFGMNODE pBridges = CFGMR3GetChild(pDevices, "ich9pcibridge");
@@ -520,7 +654,7 @@ HRESULT Console::attachRawPCIDevices(PVM pVM,
int iBridgesMissed = 0;
int iBase = GuestPCIAddress.miBus - 1;
- while (!BusMgr->hasPCIDevice("ich9pcibridge", iBase) && iBase > 0)
+ while (!pBusMgr->hasPCIDevice("ich9pcibridge", iBase) && iBase > 0)
{
iBridgesMissed++; iBase--;
}
@@ -530,7 +664,7 @@ HRESULT Console::attachRawPCIDevices(PVM pVM,
{
InsertConfigNode(pBridges, Utf8StrFmt("%d", iBase + iBridge).c_str(), &pInst);
InsertConfigInteger(pInst, "Trusted", 1);
- hrc = BusMgr->assignPCIDevice("ich9pcibridge", pInst);
+ hrc = pBusMgr->assignPCIDevice("ich9pcibridge", pInst);
}
}
}
@@ -583,7 +717,7 @@ HRESULT Console::attachRawPCIDevices(PVM pVM,
GuestPCIAddress.fromLong(guest);
Assert(GuestPCIAddress.valid());
- hrc = BusMgr->assignHostPCIDevice("pciraw", pInst, HostPCIAddress, GuestPCIAddress, true);
+ hrc = pBusMgr->assignHostPCIDevice("pciraw", pInst, HostPCIAddress, GuestPCIAddress, true);
if (hrc != S_OK)
return hrc;
@@ -638,13 +772,14 @@ void Console::attachStatusDriver(PCFGMNODE pCtlInst, PPDMLED *papLeds,
* in the emulation thread (EMT). Any per thread COM/XPCOM initialization
* is done here.
*
- * @param pVM VM handle.
+ * @param pUVM The user mode VM handle.
+ * @param pVM The cross context VM handle.
* @param pvConsole Pointer to the VMPowerUpTask object.
* @return VBox status code.
*
* @note Locks the Console object for writing.
*/
-DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole)
+DECLCALLBACK(int) Console::configConstructor(PUVM pUVM, PVM pVM, void *pvConsole)
{
LogFlowFuncEnter();
@@ -661,12 +796,12 @@ DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole)
* Set the VM handle and do the rest of the job in an worker method so we
* can easily reset the VM handle on failure.
*/
- PUVM pUVM = pConsole->mpUVM = VMR3GetUVM(pVM);
+ pConsole->mpUVM = pUVM;
VMR3RetainUVM(pUVM);
int vrc;
try
{
- vrc = pConsole->configConstructorInner(pVM, &alock);
+ vrc = pConsole->configConstructorInner(pUVM, pVM, &alock);
}
catch (...)
{
@@ -686,20 +821,20 @@ DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole)
* Worker for configConstructor.
*
* @return VBox status code.
- * @param pVM The VM handle.
+ * @param pUVM The user mode VM handle.
+ * @param pVM The cross context VM handle.
* @param pAlock The automatic lock instance. This is for when we have
* to leave it in order to avoid deadlocks (ext packs and
* more).
*/
-int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
+int Console::configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
{
- VMMDev *pVMMDev = m_pVMMDev;
- Assert(pVMMDev);
-
+ VMMDev *pVMMDev = m_pVMMDev; Assert(pVMMDev);
ComPtr<IMachine> pMachine = machine();
int rc;
HRESULT hrc;
+ Utf8Str strTmp;
Bstr bstr;
#define H() AssertMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE)
@@ -746,7 +881,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
uMcfgBase = _4G - cbRamHole;
}
- BusAssignmentManager* BusMgr = mBusMgr = BusAssignmentManager::createInstance(chipsetType);
+ BusAssignmentManager *pBusMgr = mBusMgr = BusAssignmentManager::createInstance(chipsetType);
ULONG cCpus = 1;
hrc = pMachine->COMGETTER(CPUCount)(&cCpus); H();
@@ -756,6 +891,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
Bstr osTypeId;
hrc = pMachine->COMGETTER(OSTypeId)(osTypeId.asOutParam()); H();
+ LogRel(("Guest OS type: '%s'\n", Utf8Str(osTypeId).c_str()));
BOOL fIOAPIC;
hrc = biosSettings->COMGETTER(IOAPICEnabled)(&fIOAPIC); H();
@@ -773,7 +909,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
* Get root node first.
* This is the only node in the tree.
*/
- PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
+ PCFGMNODE pRoot = CFGMR3GetRootU(pUVM);
Assert(pRoot);
// InsertConfigString throws
@@ -798,6 +934,15 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pRoot, "PATMEnabled", 1); /* boolean */
InsertConfigInteger(pRoot, "CSAMEnabled", 1); /* boolean */
#endif
+
+#ifdef VBOX_WITH_RAW_RING1
+ if (osTypeId == "QNX")
+ {
+ /* QNX needs special treatment in raw mode due to its use of ring-1. */
+ InsertConfigInteger(pRoot, "RawR1Enabled", 1); /* boolean */
+ }
+#endif
+
/* Not necessary, but to make sure these two settings end up in the release log. */
BOOL fPageFusion = FALSE;
hrc = pMachine->COMGETTER(PageFusionEnabled)(&fPageFusion); H();
@@ -844,6 +989,14 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pCPUM, "NT4LeafLimit", true);
}
+ /* Expose CMPXCHG16B. Currently a hack. */
+ if ( osTypeId == "Windows81_64"
+ || osTypeId == "Windows2012_64")
+ {
+ LogRel(("Enabling CMPXCHG16B for Windows 8.1 / 2k12 guests\n"));
+ InsertConfigInteger(pCPUM, "CMPXCHG16B", true);
+ }
+
/* Expose extended MWAIT features to Mac OS X guests. */
if (fOsXGuest)
{
@@ -851,128 +1004,188 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pCPUM, "MWaitExtensions", true);
}
+ if (fOsXGuest)
+ {
+ InsertConfigInteger(pCPUM, "EnableHVP", 1);
+
+ /* Fake the CPU family/model so the guest works. This is partly
+ because older mac releases really doesn't work on newer cpus,
+ and partly because mac os x expects more from systems with newer
+ cpus (MSRs, power features, whatever). */
+ uint32_t uMaxIntelFamilyModelStep = UINT32_MAX;
+ if ( osTypeId == "MacOS"
+ || osTypeId == "MacOS_64")
+ uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482. */
+ else if ( osTypeId == "MacOS106"
+ || osTypeId == "MacOS106_64")
+ uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482 */
+ else if ( osTypeId == "MacOS107"
+ || osTypeId == "MacOS107_64")
+ uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482 */ /** @todo figure out what is required here. */
+ else if ( osTypeId == "MacOS108"
+ || osTypeId == "MacOS108_64")
+ uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482 */ /** @todo figure out what is required here. */
+ else if ( osTypeId == "MacOS109"
+ || osTypeId == "MacOS109_64")
+ uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482 */ /** @todo figure out what is required here. */
+ if (uMaxIntelFamilyModelStep != UINT32_MAX)
+ InsertConfigInteger(pCPUM, "MaxIntelFamilyModelStep", uMaxIntelFamilyModelStep);
+ }
+
+
+ /* Synthetic CPU */
+ BOOL fSyntheticCpu = false;
+ hrc = pMachine->GetCPUProperty(CPUPropertyType_Synthetic, &fSyntheticCpu); H();
+ InsertConfigInteger(pCPUM, "SyntheticCpu", fSyntheticCpu);
+
+ /* Physical Address Extension (PAE) */
+ BOOL fEnablePAE = false;
+ hrc = pMachine->GetCPUProperty(CPUPropertyType_PAE, &fEnablePAE); H();
+ InsertConfigInteger(pRoot, "EnablePAE", fEnablePAE);
+
+
/*
* Hardware virtualization extensions.
*/
- BOOL fHWVirtExEnabled;
- BOOL fHwVirtExtForced = false;
+ BOOL fSupportsHwVirtEx;
+ hrc = host->GetProcessorFeature(ProcessorFeature_HWVirtEx, &fSupportsHwVirtEx); H();
+
+ BOOL fIsGuest64Bit;
+ hrc = pMachine->GetCPUProperty(CPUPropertyType_LongMode, &fIsGuest64Bit); H();
+ if (fIsGuest64Bit)
+ {
+ BOOL fSupportsLongMode;
+ hrc = host->GetProcessorFeature(ProcessorFeature_LongMode, &fSupportsLongMode); H();
+ if (!fSupportsLongMode)
+ {
+ LogRel(("WARNING! 64-bit guest type selected but the host CPU does NOT support 64-bit.\n"));
+ fIsGuest64Bit = FALSE;
+ }
+ if (!fSupportsHwVirtEx)
+ {
+ LogRel(("WARNING! 64-bit guest type selected but the host CPU does NOT support HW virtualization.\n"));
+ fIsGuest64Bit = FALSE;
+ }
+ }
+
+ BOOL fHMEnabled;
+ hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &fHMEnabled); H();
+ if (cCpus > 1 && !fHMEnabled)
+ {
+ LogRel(("Forced fHMEnabled to TRUE by SMP guest.\n"));
+ fHMEnabled = TRUE;
+ }
+
+ BOOL fHMForced;
#ifdef VBOX_WITH_RAW_MODE
- hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &fHWVirtExEnabled); H();
- if (cCpus > 1) /** @todo SMP: This isn't nice, but things won't work on mac otherwise. */
- fHWVirtExEnabled = TRUE;
-# ifdef RT_OS_DARWIN
- fHwVirtExtForced = fHWVirtExEnabled;
-# else
/* - With more than 4GB PGM will use different RAMRANGE sizes for raw
mode and hv mode to optimize lookup times.
- - With more than one virtual CPU, raw-mode isn't a fallback option. */
- fHwVirtExtForced = fHWVirtExEnabled
- && ( cbRam + cbRamHole > _4G
- || cCpus > 1);
+ - With more than one virtual CPU, raw-mode isn't a fallback option.
+ - With a 64-bit guest, raw-mode isn't a fallback option either. */
+ fHMForced = fHMEnabled
+ && ( cbRam + cbRamHole > _4G
+ || cCpus > 1
+ || fIsGuest64Bit);
+# ifdef RT_OS_DARWIN
+ fHMForced = fHMEnabled;
# endif
+ if (fHMForced)
+ {
+ if (cbRam + cbRamHole > _4G)
+ LogRel(("fHMForced=true - Lots of RAM\n"));
+ if (cCpus > 1)
+ LogRel(("fHMForced=true - SMP\n"));
+ if (fIsGuest64Bit)
+ LogRel(("fHMForced=true - 64-bit guest\n"));
+# ifdef RT_OS_DARWIN
+ LogRel(("fHMForced=true - Darwin host\n"));
+# endif
+ }
#else /* !VBOX_WITH_RAW_MODE */
- fHWVirtExEnabled = fHwVirtExtForced = true;
+ fHMEnabled = fHMForced = TRUE;
+ LogRel(("fHMForced=true - No raw-mode support in this build!\n"));
#endif /* !VBOX_WITH_RAW_MODE */
- /* only honor the property value if there was no other reason to enable it */
- if (!fHwVirtExtForced)
+ if (!fHMForced) /* No need to query if already forced above. */
{
- hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Force, &fHwVirtExtForced); H();
+ hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Force, &fHMForced); H();
+ if (fHMForced)
+ LogRel(("fHMForced=true - HWVirtExPropertyType_Force\n"));
}
- InsertConfigInteger(pRoot, "HwVirtExtForced", fHwVirtExtForced);
-
-
- /*
- * MM values.
- */
- PCFGMNODE pMM;
- InsertConfigNode(pRoot, "MM", &pMM);
- InsertConfigInteger(pMM, "CanUseLargerHeap", chipsetType == ChipsetType_ICH9);
-
- /*
- * Hardware virtualization settings.
- */
- BOOL fIsGuest64Bit = false;
- PCFGMNODE pHWVirtExt;
- InsertConfigNode(pRoot, "HWVirtExt", &pHWVirtExt);
- if (fHWVirtExEnabled)
+ InsertConfigInteger(pRoot, "HMEnabled", fHMEnabled);
+
+ /* /EM/xzy */
+ PCFGMNODE pEM;
+ InsertConfigNode(pRoot, "EM", &pEM);
+
+ /* Triple fault behavior. */
+ BOOL fTripleFaultReset = false;
+ hrc = pMachine->GetCPUProperty(CPUPropertyType_TripleFaultReset, &fTripleFaultReset); H();
+ InsertConfigInteger(pEM, "TripleFaultReset", fTripleFaultReset);
+
+ /* /HM/xzy */
+ PCFGMNODE pHM;
+ InsertConfigNode(pRoot, "HM", &pHM);
+ InsertConfigInteger(pHM, "HMForced", fHMForced);
+ if (fHMEnabled)
{
- InsertConfigInteger(pHWVirtExt, "Enabled", 1);
-
/* Indicate whether 64-bit guests are supported or not. */
- /** @todo This is currently only forced off on 32-bit hosts only because it
- * makes a lof of difference there (REM and Solaris performance).
- */
- BOOL fSupportsLongMode = false;
- hrc = host->GetProcessorFeature(ProcessorFeature_LongMode,
- &fSupportsLongMode); H();
- hrc = guestOSType->COMGETTER(Is64Bit)(&fIsGuest64Bit); H();
-
- if (fSupportsLongMode && fIsGuest64Bit)
- {
- InsertConfigInteger(pHWVirtExt, "64bitEnabled", 1);
+ InsertConfigInteger(pHM, "64bitEnabled", fIsGuest64Bit);
#if ARCH_BITS == 32 /* The recompiler must use VBoxREM64 (32-bit host only). */
- PCFGMNODE pREM;
- InsertConfigNode(pRoot, "REM", &pREM);
- InsertConfigInteger(pREM, "64bitEnabled", 1);
-#endif
- }
-#if ARCH_BITS == 32 /* 32-bit guests only. */
- else
- {
- InsertConfigInteger(pHWVirtExt, "64bitEnabled", 0);
- }
+ PCFGMNODE pREM;
+ InsertConfigNode(pRoot, "REM", &pREM);
+ InsertConfigInteger(pREM, "64bitEnabled", 1);
#endif
/** @todo Not exactly pretty to check strings; VBOXOSTYPE would be better, but that requires quite a bit of API change in Main. */
- if ( !fIsGuest64Bit
- && fIOAPIC
+ if ( fIOAPIC
&& ( osTypeId == "WindowsNT4"
- || osTypeId == "Windows2000"
- || osTypeId == "WindowsXP"
- || osTypeId == "Windows2003"))
+ || osTypeId == "Windows2000"
+ || osTypeId == "WindowsXP"
+ || osTypeId == "Windows2003"))
{
/* Only allow TPR patching for NT, Win2k, XP and Windows Server 2003. (32 bits mode)
* We may want to consider adding more guest OSes (Solaris) later on.
*/
- InsertConfigInteger(pHWVirtExt, "TPRPatchingEnabled", 1);
+ InsertConfigInteger(pHM, "TPRPatchingEnabled", 1);
}
}
/* HWVirtEx exclusive mode */
- BOOL fHWVirtExExclusive = true;
- hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Exclusive, &fHWVirtExExclusive); H();
- InsertConfigInteger(pHWVirtExt, "Exclusive", fHWVirtExExclusive);
+ BOOL fHMExclusive = true;
+ hrc = systemProperties->COMGETTER(ExclusiveHwVirt)(&fHMExclusive); H();
+ InsertConfigInteger(pHM, "Exclusive", fHMExclusive);
/* Nested paging (VT-x/AMD-V) */
BOOL fEnableNestedPaging = false;
hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &fEnableNestedPaging); H();
- InsertConfigInteger(pHWVirtExt, "EnableNestedPaging", fEnableNestedPaging);
+ InsertConfigInteger(pHM, "EnableNestedPaging", fEnableNestedPaging);
/* Large pages; requires nested paging */
BOOL fEnableLargePages = false;
hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &fEnableLargePages); H();
- InsertConfigInteger(pHWVirtExt, "EnableLargePages", fEnableLargePages);
+ InsertConfigInteger(pHM, "EnableLargePages", fEnableLargePages);
/* VPID (VT-x) */
BOOL fEnableVPID = false;
hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_VPID, &fEnableVPID); H();
- InsertConfigInteger(pHWVirtExt, "EnableVPID", fEnableVPID);
+ InsertConfigInteger(pHM, "EnableVPID", fEnableVPID);
- /* Physical Address Extension (PAE) */
- BOOL fEnablePAE = false;
- hrc = pMachine->GetCPUProperty(CPUPropertyType_PAE, &fEnablePAE); H();
- InsertConfigInteger(pRoot, "EnablePAE", fEnablePAE);
+ /* Unrestricted execution aka UX (VT-x) */
+ BOOL fEnableUX = false;
+ hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, &fEnableUX); H();
+ InsertConfigInteger(pHM, "EnableUX", fEnableUX);
- /* Synthetic CPU */
- BOOL fSyntheticCpu = false;
- hrc = pMachine->GetCPUProperty(CPUPropertyType_Synthetic, &fSyntheticCpu); H();
- InsertConfigInteger(pCPUM, "SyntheticCpu", fSyntheticCpu);
+ /* Reset overwrite. */
+ if (isResetTurnedIntoPowerOff())
+ InsertConfigInteger(pRoot, "PowerOffInsteadOfReset", 1);
- if (fOsXGuest)
- InsertConfigInteger(pCPUM, "EnableHVP", 1);
- BOOL fPXEDebug;
- hrc = biosSettings->COMGETTER(PXEDebugEnabled)(&fPXEDebug); H();
+ /*
+ * MM values.
+ */
+ PCFGMNODE pMM;
+ InsertConfigNode(pRoot, "MM", &pMM);
+ InsertConfigInteger(pMM, "CanUseLargerHeap", chipsetType == ChipsetType_ICH9);
/*
* PDM config.
@@ -1039,7 +1252,11 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
hrc = bwGroups[i]->COMGETTER(Name)(strName.asOutParam()); H();
hrc = bwGroups[i]->COMGETTER(Type)(&enmType); H();
- hrc = bwGroups[i]->COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec); H();
+ hrc = bwGroups[i]->COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec); H();
+
+ if (strName.isEmpty())
+ return VMR3SetError(pUVM, VERR_CFGM_NO_NODE, RT_SRC_POS,
+ N_("No bandwidth group name specified"));
if (enmType == BandwidthGroupType_Disk)
{
@@ -1072,6 +1289,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
PCFGMNODE pLunL2 = NULL; /* /Devices/Dev/0/LUN#0/AttachedDriver/Config/ */
PCFGMNODE pBiosCfg = NULL; /* /Devices/pcbios/0/Config/ */
PCFGMNODE pNetBootCfg = NULL; /* /Devices/pcbios/0/Config/NetBoot/ */
+ bool fHaveBiosScsiConfig = false;
InsertConfigNode(pRoot, "Devices", &pDevices);
@@ -1133,15 +1351,15 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDevices, "ich9pcibridge", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPCIDevice("ich9pcibridge", pInst); H();
+ hrc = pBusMgr->assignPCIDevice("ich9pcibridge", pInst); H();
InsertConfigNode(pDev, "1", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPCIDevice("ich9pcibridge", pInst); H();
+ hrc = pBusMgr->assignPCIDevice("ich9pcibridge", pInst); H();
#ifdef VBOX_WITH_PCI_PASSTHROUGH
/* Add PCI passthrough devices */
- hrc = attachRawPCIDevices(pVM, BusMgr, pDevices); H();
+ hrc = attachRawPCIDevices(pUVM, pBusMgr, pDevices); H();
#endif
}
@@ -1181,11 +1399,11 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pInst, "Config", &pCfg);
bool fGetKeyFromRealSMC;
- Bstr bstrKey;
- rc = getSmcDeviceKey(pMachine, bstrKey.asOutParam(), &fGetKeyFromRealSMC);
+ Utf8Str strKey;
+ rc = getSmcDeviceKey(virtualBox, pMachine, &strKey, &fGetKeyFromRealSMC);
AssertRCReturn(rc, rc);
- InsertConfigString(pCfg, "DeviceKey", bstrKey);
+ InsertConfigString(pCfg, "DeviceKey", strKey);
InsertConfigInteger(pCfg, "GetKeyFromRealSMC", fGetKeyFromRealSMC);
}
@@ -1199,7 +1417,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
InsertConfigNode(pDevices, "lpc", &pDev);
InsertConfigNode(pDev, "0", &pInst);
- hrc = BusMgr->assignPCIDevice("lpc", pInst); H();
+ hrc = pBusMgr->assignPCIDevice("lpc", pInst); H();
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
}
@@ -1225,6 +1443,9 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
Keyboard *pKeyboard = mKeyboard;
InsertConfigInteger(pCfg, "Object", (uintptr_t)pKeyboard);
+ Mouse *pMouse = mMouse;
+ PointingHIDType_T aPointingHID;
+ hrc = pMachine->COMGETTER(PointingHIDType)(&aPointingHID); H();
InsertConfigNode(pInst, "LUN#1", &pLunL0);
InsertConfigString(pLunL0, "Driver", "MouseQueue");
InsertConfigNode(pLunL0, "Config", &pCfg);
@@ -1233,7 +1454,6 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
InsertConfigString(pLunL1, "Driver", "MainMouse");
InsertConfigNode(pLunL1, "Config", &pCfg);
- Mouse *pMouse = mMouse;
InsertConfigInteger(pCfg, "Object", (uintptr_t)pMouse);
/*
@@ -1291,87 +1511,26 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* VGA.
*/
- InsertConfigNode(pDevices, "vga", &pDev);
- InsertConfigNode(pDev, "0", &pInst);
- InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
-
- hrc = BusMgr->assignPCIDevice("vga", pInst); H();
- InsertConfigNode(pInst, "Config", &pCfg);
- ULONG cVRamMBs;
- hrc = pMachine->COMGETTER(VRAMSize)(&cVRamMBs); H();
- InsertConfigInteger(pCfg, "VRamSize", cVRamMBs * _1M);
- ULONG cMonitorCount;
- hrc = pMachine->COMGETTER(MonitorCount)(&cMonitorCount); H();
- InsertConfigInteger(pCfg, "MonitorCount", cMonitorCount);
-#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
- InsertConfigInteger(pCfg, "R0Enabled", fHWVirtExEnabled);
-#endif
-
- /*
- * BIOS logo
- */
- BOOL fFadeIn;
- hrc = biosSettings->COMGETTER(LogoFadeIn)(&fFadeIn); H();
- InsertConfigInteger(pCfg, "FadeIn", fFadeIn ? 1 : 0);
- BOOL fFadeOut;
- hrc = biosSettings->COMGETTER(LogoFadeOut)(&fFadeOut); H();
- InsertConfigInteger(pCfg, "FadeOut", fFadeOut ? 1: 0);
- ULONG logoDisplayTime;
- hrc = biosSettings->COMGETTER(LogoDisplayTime)(&logoDisplayTime); H();
- InsertConfigInteger(pCfg, "LogoTime", logoDisplayTime);
- Bstr logoImagePath;
- hrc = biosSettings->COMGETTER(LogoImagePath)(logoImagePath.asOutParam()); H();
- InsertConfigString(pCfg, "LogoFile", Utf8Str(!logoImagePath.isEmpty() ? logoImagePath : "") );
-
- /*
- * Boot menu
- */
- BIOSBootMenuMode_T eBootMenuMode;
- int iShowBootMenu;
- biosSettings->COMGETTER(BootMenuMode)(&eBootMenuMode);
- switch (eBootMenuMode)
- {
- case BIOSBootMenuMode_Disabled: iShowBootMenu = 0; break;
- case BIOSBootMenuMode_MenuOnly: iShowBootMenu = 1; break;
- default: iShowBootMenu = 2; break;
- }
- InsertConfigInteger(pCfg, "ShowBootMenu", iShowBootMenu);
-
- /* Custom VESA mode list */
- unsigned cModes = 0;
- for (unsigned iMode = 1; iMode <= 16; ++iMode)
+ GraphicsControllerType_T graphicsController;
+ hrc = pMachine->COMGETTER(GraphicsControllerType)(&graphicsController); H();
+ switch (graphicsController)
{
- char szExtraDataKey[sizeof("CustomVideoModeXX")];
- RTStrPrintf(szExtraDataKey, sizeof(szExtraDataKey), "CustomVideoMode%u", iMode);
- hrc = pMachine->GetExtraData(Bstr(szExtraDataKey).raw(), bstr.asOutParam()); H();
- if (bstr.isEmpty())
+ case GraphicsControllerType_Null:
break;
- InsertConfigString(pCfg, szExtraDataKey, bstr);
- ++cModes;
- }
- InsertConfigInteger(pCfg, "CustomVideoModes", cModes);
-
- /* VESA height reduction */
- ULONG ulHeightReduction;
- IFramebuffer *pFramebuffer = getDisplay()->getFramebuffer();
- if (pFramebuffer)
- {
- hrc = pFramebuffer->COMGETTER(HeightReduction)(&ulHeightReduction); H();
- }
- else
- {
- /* If framebuffer is not available, there is no height reduction. */
- ulHeightReduction = 0;
+ case GraphicsControllerType_VBoxVGA:
+#ifdef VBOX_WITH_VMSVGA
+ case GraphicsControllerType_VMSVGA:
+#endif
+ rc = configGraphicsController(pDevices, graphicsController, pBusMgr, pMachine, biosSettings,
+ RT_BOOL(fHMEnabled));
+ if (FAILED(rc))
+ return rc;
+ break;
+ default:
+ AssertMsgFailed(("Invalid graphicsController=%d\n", graphicsController));
+ return VMR3SetError(pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
+ N_("Invalid graphics controller type '%d'"), graphicsController);
}
- InsertConfigInteger(pCfg, "HeightReduction", ulHeightReduction);
-
- /* Attach the display. */
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MainDisplay");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- Display *pDisplay = mDisplay;
- InsertConfigInteger(pCfg, "Object", (uintptr_t)pDisplay);
-
/*
* Firmware.
@@ -1399,6 +1558,8 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigString(pBiosCfg, "HardDiskDevice", "piix3ide");
InsertConfigString(pBiosCfg, "FloppyDevice", "i82078");
InsertConfigInteger(pBiosCfg, "IOAPIC", fIOAPIC);
+ BOOL fPXEDebug;
+ hrc = biosSettings->COMGETTER(PXEDebugEnabled)(&fPXEDebug); H();
InsertConfigInteger(pBiosCfg, "PXEDebug", fPXEDebug);
InsertConfigBytes(pBiosCfg, "UUID", &HardwareUuid,sizeof(HardwareUuid));
InsertConfigNode(pBiosCfg, "NetBoot", &pNetBootCfg);
@@ -1406,12 +1567,8 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pBiosCfg, "McfgLength", cbMcfgLength);
DeviceType_T bootDevice;
- if (SchemaDefs::MaxBootPosition > 9)
- {
- AssertMsgFailed(("Too many boot devices %d\n",
- SchemaDefs::MaxBootPosition));
- return VERR_INVALID_PARAMETER;
- }
+ AssertMsgReturn(SchemaDefs::MaxBootPosition <= 9, ("Too many boot devices %d\n", SchemaDefs::MaxBootPosition),
+ VERR_INVALID_PARAMETER);
for (ULONG pos = 1; pos <= SchemaDefs::MaxBootPosition; ++pos)
{
@@ -1440,11 +1597,16 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
break;
default:
AssertMsgFailed(("Invalid bootDevice=%d\n", bootDevice));
- return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
- N_("Invalid boot device '%d'"), bootDevice);
+ return VMR3SetError(pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
+ N_("Invalid boot device '%d'"), bootDevice);
}
InsertConfigString(pBiosCfg, szParamName, pszBootDevice);
}
+
+ /** @todo @bugref{7145}: We might want to enable this by default for new VMs. For now,
+ * this is required for Windows 2012 guests. */
+ if (osTypeId == "Windows2012_64")
+ InsertConfigInteger(pBiosCfg, "DmiExposeMemoryTable", 1); /* boolean */
}
else
{
@@ -1462,29 +1624,29 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
AssertRCReturn(rc, rc);
/* Get boot args */
- Bstr bootArgs;
- hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiBootArgs").raw(), bootArgs.asOutParam()); H();
+ Utf8Str bootArgs;
+ GetExtraDataBoth(virtualBox, pMachine, "VBoxInternal2/EfiBootArgs", &bootArgs);
/* Get device props */
- Bstr deviceProps;
- hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiDeviceProps").raw(), deviceProps.asOutParam()); H();
+ Utf8Str deviceProps;
+ GetExtraDataBoth(virtualBox, pMachine, "VBoxInternal2/EfiDeviceProps", &deviceProps);
/* Get GOP mode settings */
uint32_t u32GopMode = UINT32_MAX;
- hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiGopMode").raw(), bstr.asOutParam()); H();
- if (!bstr.isEmpty())
- u32GopMode = Utf8Str(bstr).toUInt32();
+ GetExtraDataBoth(virtualBox, pMachine, "VBoxInternal2/EfiGopMode", &strTmp);
+ if (!strTmp.isEmpty())
+ u32GopMode = strTmp.toUInt32();
/* UGA mode settings */
uint32_t u32UgaHorisontal = 0;
- hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiUgaHorizontalResolution").raw(), bstr.asOutParam()); H();
- if (!bstr.isEmpty())
- u32UgaHorisontal = Utf8Str(bstr).toUInt32();
+ GetExtraDataBoth(virtualBox, pMachine, "VBoxInternal2/EfiUgaHorizontalResolution", &strTmp);
+ if (!strTmp.isEmpty())
+ u32UgaHorisontal = strTmp.toUInt32();
uint32_t u32UgaVertical = 0;
- hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EfiUgaVerticalResolution").raw(), bstr.asOutParam()); H();
- if (!bstr.isEmpty())
- u32UgaVertical = Utf8Str(bstr).toUInt32();
+ GetExtraDataBoth(virtualBox, pMachine, "VBoxInternal2/EfiUgaVerticalResolution", &strTmp);
+ if (!strTmp.isEmpty())
+ u32UgaVertical = strTmp.toUInt32();
/*
* EFI subtree.
@@ -1512,11 +1674,10 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pCfg, "DmiUseHostInfo", 1);
InsertConfigInteger(pCfg, "DmiExposeMemoryTable", 1);
}
- PCFGMNODE pDrv;
InsertConfigNode(pInst, "LUN#0", &pLunL0);
InsertConfigString(pLunL0, "Driver", "NvramStorage");
InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "Object", (uint64_t)mNvram);
+ InsertConfigInteger(pCfg, "Object", (uintptr_t)mNvram);
#ifdef DEBUG_vvl
InsertConfigInteger(pCfg, "PermanentSave", 1);
#endif
@@ -1570,14 +1731,32 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pCtlInst, "Trusted", 1);
InsertConfigNode(pCtlInst, "Config", &pCfg);
+ static const char * const apszBiosConfigScsi[MAX_BIOS_LUN_COUNT] =
+ { "ScsiLUN1", "ScsiLUN2", "ScsiLUN3", "ScsiLUN4" };
+
+ static const char * const apszBiosConfigSata[MAX_BIOS_LUN_COUNT] =
+ { "SataLUN1", "SataLUN2", "SataLUN3", "SataLUN4" };
+
switch (enmCtrlType)
{
case StorageControllerType_LsiLogic:
{
- hrc = BusMgr->assignPCIDevice("lsilogic", pCtlInst); H();
+ hrc = pBusMgr->assignPCIDevice("lsilogic", pCtlInst); H();
InsertConfigInteger(pCfg, "Bootable", fBootable);
+ /* BIOS configuration values, first controller only. */
+ if (!pBusMgr->hasPCIDevice("lsilogicscsi", 1) && pBiosCfg)
+ {
+ if (!fHaveBiosScsiConfig)
+ {
+ fHaveBiosScsiConfig = true;
+ InsertConfigString(pBiosCfg, "ScsiHardDiskDevice", "lsilogicscsi");
+
+ hrc = SetBiosDiskInfo(pMachine, pCfg, pBiosCfg, controllerName, apszBiosConfigScsi); H();
+ }
+ }
+
/* Attach the status driver */
Assert(cLedScsi >= 16);
attachStatusDriver(pCtlInst, &mapStorageLeds[iLedScsi], 0, 15,
@@ -1588,10 +1767,22 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
case StorageControllerType_BusLogic:
{
- hrc = BusMgr->assignPCIDevice("buslogic", pCtlInst); H();
+ hrc = pBusMgr->assignPCIDevice("buslogic", pCtlInst); H();
InsertConfigInteger(pCfg, "Bootable", fBootable);
+ /* BIOS configuration values, first controller only. */
+ if (!pBusMgr->hasPCIDevice("buslogic", 1) && pBiosCfg)
+ {
+ if (!fHaveBiosScsiConfig)
+ {
+ fHaveBiosScsiConfig = true;
+ InsertConfigString(pBiosCfg, "ScsiHardDiskDevice", "buslogic");
+
+ hrc = SetBiosDiskInfo(pMachine, pCfg, pBiosCfg, controllerName, apszBiosConfigScsi); H();
+ }
+ }
+
/* Attach the status driver */
Assert(cLedScsi >= 16);
attachStatusDriver(pCtlInst, &mapStorageLeds[iLedScsi], 0, 15,
@@ -1602,7 +1793,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
case StorageControllerType_IntelAhci:
{
- hrc = BusMgr->assignPCIDevice("ahci", pCtlInst); H();
+ hrc = pBusMgr->assignPCIDevice("ahci", pCtlInst); H();
ULONG cPorts = 0;
hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts); H();
@@ -1610,12 +1801,14 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigInteger(pCfg, "Bootable", fBootable);
/* Needed configuration values for the bios, only first controller. */
- if (!BusMgr->hasPCIDevice("ahci", 1))
+ if (!pBusMgr->hasPCIDevice("ahci", 1))
{
if (pBiosCfg)
{
InsertConfigString(pBiosCfg, "SataHardDiskDevice", "ahci");
}
+
+ hrc = SetBiosDiskInfo(pMachine, pCfg, pBiosCfg, controllerName, apszBiosConfigSata); H();
}
/* Attach the status driver */
@@ -1633,7 +1826,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* IDE (update this when the main interface changes)
*/
- hrc = BusMgr->assignPCIDevice("piix3ide", pCtlInst); H();
+ hrc = pBusMgr->assignPCIDevice("piix3ide", pCtlInst); H();
InsertConfigString(pCfg, "Type", controllerString(enmCtrlType));
/* Attach the status driver */
Assert(cLedIde >= 4);
@@ -1669,11 +1862,27 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
case StorageControllerType_LsiLogicSas:
{
- hrc = BusMgr->assignPCIDevice("lsilogicsas", pCtlInst); H();
+ hrc = pBusMgr->assignPCIDevice("lsilogicsas", pCtlInst); H();
InsertConfigString(pCfg, "ControllerType", "SAS1068");
InsertConfigInteger(pCfg, "Bootable", fBootable);
+ /* BIOS configuration values, first controller only. */
+ if (!pBusMgr->hasPCIDevice("lsilogicsas", 1) && pBiosCfg)
+ {
+ if (!fHaveBiosScsiConfig)
+ {
+ fHaveBiosScsiConfig = true;
+ InsertConfigString(pBiosCfg, "ScsiHardDiskDevice", "lsilogicsas");
+
+ hrc = SetBiosDiskInfo(pMachine, pCfg, pBiosCfg, controllerName, apszBiosConfigScsi); H();
+ }
+ }
+
+ ULONG cPorts = 0;
+ hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts); H();
+ InsertConfigInteger(pCfg, "NumPorts", cPorts);
+
/* Attach the status driver */
Assert(cLedSas >= 8);
attachStatusDriver(pCtlInst, &mapStorageLeds[iLedSas], 0, 7,
@@ -1714,8 +1923,9 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
false /* fAttachDetach */,
false /* fForceUnmount */,
false /* fHotplug */,
- pVM,
- paLedDevType);
+ pUVM,
+ paLedDevType,
+ NULL /* ppLunL0 */);
if (RT_FAILURE(rc))
return rc;
}
@@ -1778,9 +1988,9 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
default:
AssertMsgFailed(("Invalid network adapter type '%d' for slot '%d'",
adapterType, ulInstance));
- return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
- N_("Invalid network adapter type '%d' for slot '%d'"),
- adapterType, ulInstance);
+ return VMR3SetError(pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
+ N_("Invalid network adapter type '%d' for slot '%d'"),
+ adapterType, ulInstance);
}
InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
@@ -1807,7 +2017,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
#ifdef VMWARE_NET_IN_SLOT_11
/*
* Dirty hack for PCI slot compatibility with VMWare,
- * it assigns slot 11 to the first network controller.
+ * it assigns slot 0x11 to the first network controller.
*/
if (iPCIDeviceNo == 3 && adapterType == NetworkAdapterType_I82545EM)
{
@@ -1818,7 +2028,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
iPCIDeviceNo = 3;
#endif
PCIBusAddress PCIAddr = PCIBusAddress(0, iPCIDeviceNo, 0);
- hrc = BusMgr->assignPCIDevice(pszAdapterName, pInst, PCIAddr); H();
+ hrc = pBusMgr->assignPCIDevice(pszAdapterName, pInst, PCIAddr); H();
InsertConfigNode(pInst, "Config", &pCfg);
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE /* not safe here yet. */ /** @todo Make PCNet ring-0 safe on 32-bit mac kernels! */
@@ -1872,7 +2082,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
char *macStr = (char*)macAddrUtf8.c_str();
Assert(strlen(macStr) == 12);
RTMAC Mac;
- memset(&Mac, 0, sizeof(Mac));
+ RT_ZERO(Mac);
char *pMac = (char*)&Mac;
for (uint32_t i = 0; i < 6; ++i)
{
@@ -2051,7 +2261,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDev, "0", &pInst);
InsertConfigNode(pInst, "Config", &pCfg);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPCIDevice("VMMDev", pInst); H();
+ hrc = pBusMgr->assignPCIDevice("VMMDev", pInst); H();
Bstr hwVersion;
hrc = pMachine->COMGETTER(HardwareVersion)(hwVersion.asOutParam()); H();
@@ -2108,7 +2318,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDevices, "ichac97", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPCIDevice("ichac97", pInst); H();
+ hrc = pBusMgr->assignPCIDevice("ichac97", pInst); H();
InsertConfigNode(pInst, "Config", &pCfg);
break;
}
@@ -2132,7 +2342,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDevices, "hda", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPCIDevice("hda", pInst); H();
+ hrc = pBusMgr->assignPCIDevice("hda", pInst); H();
InsertConfigNode(pInst, "Config", &pCfg);
}
}
@@ -2217,34 +2427,55 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
}
/*
- * The USB Controller.
+ * The USB Controllers.
*/
- ComPtr<IUSBController> USBCtlPtr;
- hrc = pMachine->COMGETTER(USBController)(USBCtlPtr.asOutParam());
- if (USBCtlPtr)
+ com::SafeIfaceArray<IUSBController> usbCtrls;
+ hrc = pMachine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(usbCtrls)); H();
+ bool fOhciPresent = false; /**< Flag whether at least one OHCI controller is presnet. */
+
+ for (size_t i = 0; i < usbCtrls.size(); ++i)
{
- BOOL fOhciEnabled;
- hrc = USBCtlPtr->COMGETTER(Enabled)(&fOhciEnabled); H();
- if (fOhciEnabled)
+ USBControllerType_T enmCtrlType;
+ rc = usbCtrls[i]->COMGETTER(Type)(&enmCtrlType); H();
+ if (enmCtrlType == USBControllerType_OHCI)
{
- InsertConfigNode(pDevices, "usb-ohci", &pDev);
- InsertConfigNode(pDev, "0", &pInst);
- InsertConfigNode(pInst, "Config", &pCfg);
- InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPCIDevice("usb-ohci", pInst); H();
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "VUSBRootHub");
- InsertConfigNode(pLunL0, "Config", &pCfg);
+ fOhciPresent = true;
+ break;
+ }
+ }
- /*
- * Attach the status driver.
- */
- attachStatusDriver(pInst, &mapUSBLed[0], 0, 0, NULL, NULL, 0);
+ /*
+ * Currently EHCI is only enabled when a OHCI controller is present too.
+ * This might change when XHCI is supported.
+ */
+ if (fOhciPresent)
+ mfVMHasUsbController = true;
+
+ if (mfVMHasUsbController)
+ {
+ for (size_t i = 0; i < usbCtrls.size(); ++i)
+ {
+ USBControllerType_T enmCtrlType;
+ rc = usbCtrls[i]->COMGETTER(Type)(&enmCtrlType); H();
+
+ if (enmCtrlType == USBControllerType_OHCI)
+ {
+ InsertConfigNode(pDevices, "usb-ohci", &pDev);
+ InsertConfigNode(pDev, "0", &pInst);
+ InsertConfigNode(pInst, "Config", &pCfg);
+ InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
+ hrc = pBusMgr->assignPCIDevice("usb-ohci", pInst); H();
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+ InsertConfigString(pLunL0, "Driver", "VUSBRootHub");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ /*
+ * Attach the status driver.
+ */
+ attachStatusDriver(pInst, &mapUSBLed[0], 0, 0, NULL, NULL, 0);
+ }
#ifdef VBOX_WITH_EHCI
- BOOL fEHCIEnabled;
- hrc = USBCtlPtr->COMGETTER(EnabledEHCI)(&fEHCIEnabled); H();
- if (fEHCIEnabled)
+ else if (enmCtrlType == USBControllerType_EHCI)
{
/*
* USB 2.0 is only available if the proper ExtPack is installed.
@@ -2263,7 +2494,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
InsertConfigNode(pDev, "0", &pInst);
InsertConfigNode(pInst, "Config", &pCfg);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- hrc = BusMgr->assignPCIDevice("usb-ehci", pInst); H();
+ hrc = pBusMgr->assignPCIDevice("usb-ehci", pInst); H();
InsertConfigNode(pInst, "LUN#0", &pLunL0);
InsertConfigString(pLunL0, "Driver", "VUSBRootHub");
@@ -2279,7 +2510,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
/* Always fatal! Up to VBox 4.0.4 we allowed to start the VM anyway
* but this induced problems when the user saved + restored the VM! */
- return VMSetError(pVM, VERR_NOT_FOUND, RT_SRC_POS,
+ return VMR3SetError(pUVM, VERR_NOT_FOUND, RT_SRC_POS,
N_("Implementation of the USB 2.0 controller not found!\n"
"Because the USB 2.0 controller state is part of the saved "
"VM state, the VM cannot be started. To fix "
@@ -2290,142 +2521,134 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
# endif
}
#endif
+ } /* for every USB controller. */
- /*
- * Virtual USB Devices.
- */
- PCFGMNODE pUsbDevices = NULL;
- InsertConfigNode(pRoot, "USB", &pUsbDevices);
+
+ /*
+ * Virtual USB Devices.
+ */
+ PCFGMNODE pUsbDevices = NULL;
+ InsertConfigNode(pRoot, "USB", &pUsbDevices);
#ifdef VBOX_WITH_USB
- {
- /*
- * Global USB options, currently unused as we'll apply the 2.0 -> 1.1 morphing
- * on a per device level now.
- */
- InsertConfigNode(pUsbDevices, "USBProxy", &pCfg);
- InsertConfigNode(pCfg, "GlobalConfig", &pCfg);
- // This globally enables the 2.0 -> 1.1 device morphing of proxied devices to keep windows quiet.
- //InsertConfigInteger(pCfg, "Force11Device", true);
- // The following breaks stuff, but it makes MSDs work in vista. (I include it here so
- // that it's documented somewhere.) Users needing it can use:
- // VBoxManage setextradata "myvm" "VBoxInternal/USB/USBProxy/GlobalConfig/Force11PacketSize" 1
- //InsertConfigInteger(pCfg, "Force11PacketSize", true);
- }
+ {
+ /*
+ * Global USB options, currently unused as we'll apply the 2.0 -> 1.1 morphing
+ * on a per device level now.
+ */
+ InsertConfigNode(pUsbDevices, "USBProxy", &pCfg);
+ InsertConfigNode(pCfg, "GlobalConfig", &pCfg);
+ // This globally enables the 2.0 -> 1.1 device morphing of proxied devices to keep windows quiet.
+ //InsertConfigInteger(pCfg, "Force11Device", true);
+ // The following breaks stuff, but it makes MSDs work in vista. (I include it here so
+ // that it's documented somewhere.) Users needing it can use:
+ // VBoxManage setextradata "myvm" "VBoxInternal/USB/USBProxy/GlobalConfig/Force11PacketSize" 1
+ //InsertConfigInteger(pCfg, "Force11PacketSize", true);
+ }
#endif
-#ifdef VBOX_WITH_USB_VIDEO
-
- InsertConfigNode(pUsbDevices, "Webcam", &pDev);
+#ifdef VBOX_WITH_USB_CARDREADER
+ BOOL aEmulatedUSBCardReaderEnabled = FALSE;
+ hrc = pMachine->COMGETTER(EmulatedUSBCardReaderEnabled)(&aEmulatedUSBCardReaderEnabled); H();
+ if (aEmulatedUSBCardReaderEnabled)
+ {
+ InsertConfigNode(pUsbDevices, "CardReader", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigNode(pInst, "Config", &pCfg);
-# if 0 /* Experiments with attaching */
- InsertConfigInteger(pCfg, "USBVER", RT_BIT(2));
-# endif
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
-# ifdef VBOX_WITH_USB_VIDEO_TEST
- InsertConfigString(pLunL0, "Driver", "WebcamFileFeeder");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigString(pCfg, "DirToFeed", "out");
-# else
- InsertConfigString(pLunL0, "Driver", "UsbWebcamInterface");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "Object", mUsbWebcamInterface);
-# endif
-#endif
-#ifdef VBOX_WITH_USB_CARDREADER
- BOOL aEmulatedUSBCardReaderEnabled = FALSE;
- hrc = pMachine->COMGETTER(EmulatedUSBCardReaderEnabled)(&aEmulatedUSBCardReaderEnabled); H();
- if (aEmulatedUSBCardReaderEnabled)
- {
- InsertConfigNode(pUsbDevices, "CardReader", &pDev);
- InsertConfigNode(pDev, "0", &pInst);
- InsertConfigNode(pInst, "Config", &pCfg);
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
# ifdef VBOX_WITH_USB_CARDREADER_TEST
- InsertConfigString(pLunL0, "Driver", "DrvDirectCardReader");
- InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigString(pLunL0, "Driver", "DrvDirectCardReader");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
# else
- InsertConfigString(pLunL0, "Driver", "UsbCardReader");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "Object", (uintptr_t)mUsbCardReader);
+ InsertConfigString(pLunL0, "Driver", "UsbCardReader");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "Object", (uintptr_t)mUsbCardReader);
# endif
- }
+ }
#endif
# if 0 /* Virtual MSD*/
+ InsertConfigNode(pUsbDevices, "Msd", &pDev);
+ InsertConfigNode(pDev, "0", &pInst);
+ InsertConfigNode(pInst, "Config", &pCfg);
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+
+ InsertConfigString(pLunL0, "Driver", "SCSI");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+
+ InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
+ InsertConfigString(pLunL1, "Driver", "Block");
+ InsertConfigNode(pLunL1, "Config", &pCfg);
+ InsertConfigString(pCfg, "Type", "HardDisk");
+ InsertConfigInteger(pCfg, "Mountable", 0);
+
+ InsertConfigNode(pLunL1, "AttachedDriver", &pLunL2);
+ InsertConfigString(pLunL2, "Driver", "VD");
+ InsertConfigNode(pLunL2, "Config", &pCfg);
+ InsertConfigString(pCfg, "Path", "/Volumes/DataHFS/bird/VDIs/linux.vdi");
+ InsertConfigString(pCfg, "Format", "VDI");
+# endif
- InsertConfigNode(pUsbDevices, "Msd", &pDev);
+ /* Virtual USB Mouse/Tablet */
+ if ( aPointingHID == PointingHIDType_USBMouse
+ || aPointingHID == PointingHIDType_USBTablet
+ || aPointingHID == PointingHIDType_USBMultiTouch)
+ {
+ InsertConfigNode(pUsbDevices, "HidMouse", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigNode(pInst, "Config", &pCfg);
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "SCSI");
+ if (aPointingHID == PointingHIDType_USBMouse)
+ InsertConfigString(pCfg, "Mode", "relative");
+ else
+ InsertConfigString(pCfg, "Mode", "absolute");
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+ InsertConfigString(pLunL0, "Driver", "MouseQueue");
InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "QueueSize", 128);
InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
- InsertConfigString(pLunL1, "Driver", "Block");
+ InsertConfigString(pLunL1, "Driver", "MainMouse");
InsertConfigNode(pLunL1, "Config", &pCfg);
- InsertConfigString(pCfg, "Type", "HardDisk");
- InsertConfigInteger(pCfg, "Mountable", 0);
-
- InsertConfigNode(pLunL1, "AttachedDriver", &pLunL2);
- InsertConfigString(pLunL2, "Driver", "VD");
- InsertConfigNode(pLunL2, "Config", &pCfg);
- InsertConfigString(pCfg, "Path", "/Volumes/DataHFS/bird/VDIs/linux.vdi");
- InsertConfigString(pCfg, "Format", "VDI");
-# endif
-
- /* Virtual USB Mouse/Tablet */
- PointingHIDType_T aPointingHID;
- hrc = pMachine->COMGETTER(PointingHIDType)(&aPointingHID); H();
- if (aPointingHID == PointingHIDType_USBMouse || aPointingHID == PointingHIDType_USBTablet)
- {
- InsertConfigNode(pUsbDevices, "HidMouse", &pDev);
- InsertConfigNode(pDev, "0", &pInst);
- InsertConfigNode(pInst, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "Object", (uintptr_t)pMouse);
+ }
+ if (aPointingHID == PointingHIDType_USBMultiTouch)
+ {
+ InsertConfigNode(pDev, "1", &pInst);
+ InsertConfigNode(pInst, "Config", &pCfg);
- if (aPointingHID == PointingHIDType_USBTablet)
- {
- InsertConfigInteger(pCfg, "Absolute", 1);
- }
- else
- {
- InsertConfigInteger(pCfg, "Absolute", 0);
- }
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "MouseQueue");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "QueueSize", 128);
+ InsertConfigString(pCfg, "Mode", "multitouch");
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+ InsertConfigString(pLunL0, "Driver", "MouseQueue");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "QueueSize", 128);
- InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
- InsertConfigString(pLunL1, "Driver", "MainMouse");
- InsertConfigNode(pLunL1, "Config", &pCfg);
- pMouse = mMouse;
- InsertConfigInteger(pCfg, "Object", (uintptr_t)pMouse);
- }
+ InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
+ InsertConfigString(pLunL1, "Driver", "MainMouse");
+ InsertConfigNode(pLunL1, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "Object", (uintptr_t)pMouse);
+ }
- /* Virtual USB Keyboard */
- KeyboardHIDType_T aKbdHID;
- hrc = pMachine->COMGETTER(KeyboardHIDType)(&aKbdHID); H();
- if (aKbdHID == KeyboardHIDType_USBKeyboard)
- {
- InsertConfigNode(pUsbDevices, "HidKeyboard", &pDev);
- InsertConfigNode(pDev, "0", &pInst);
- InsertConfigNode(pInst, "Config", &pCfg);
+ /* Virtual USB Keyboard */
+ KeyboardHIDType_T aKbdHID;
+ hrc = pMachine->COMGETTER(KeyboardHIDType)(&aKbdHID); H();
+ if (aKbdHID == KeyboardHIDType_USBKeyboard)
+ {
+ InsertConfigNode(pUsbDevices, "HidKeyboard", &pDev);
+ InsertConfigNode(pDev, "0", &pInst);
+ InsertConfigNode(pInst, "Config", &pCfg);
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
- InsertConfigString(pLunL0, "Driver", "KeyboardQueue");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "QueueSize", 64);
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+ InsertConfigString(pLunL0, "Driver", "KeyboardQueue");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "QueueSize", 64);
- InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
- InsertConfigString(pLunL1, "Driver", "MainKeyboard");
- InsertConfigNode(pLunL1, "Config", &pCfg);
- pKeyboard = mKeyboard;
- InsertConfigInteger(pCfg, "Object", (uintptr_t)pKeyboard);
- }
+ InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
+ InsertConfigString(pLunL1, "Driver", "MainKeyboard");
+ InsertConfigNode(pLunL1, "Config", &pCfg);
+ pKeyboard = mKeyboard;
+ InsertConfigInteger(pCfg, "Object", (uintptr_t)pKeyboard);
}
}
@@ -2530,7 +2753,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
BOOL fSupports3D = VBoxOglIs3DAccelerationSupported();
if (!fSupports3D)
- return VMSetError(pVM, VERR_NOT_AVAILABLE, RT_SRC_POS,
+ return VMR3SetError(pUVM, VERR_NOT_AVAILABLE, RT_SRC_POS,
N_("This VM was configured to use 3D acceleration. However, the "
"3D support of the host is not working properly and the "
"VM cannot be started. To fix this problem, either "
@@ -2576,7 +2799,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
* Guest property service
*/
- rc = configGuestProperties(this, pVM);
+ rc = configGuestProperties(this, pUVM);
#endif /* VBOX_WITH_GUEST_PROPS defined */
#ifdef VBOX_WITH_GUEST_CONTROL
@@ -2594,22 +2817,22 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
hrc = biosSettings->COMGETTER(ACPIEnabled)(&fACPI); H();
if (fACPI)
{
- BOOL fCpuHotPlug = false;
- BOOL fShowCpu = fOsXGuest;
/* Always show the CPU leafs when we have multiple VCPUs or when the IO-APIC is enabled.
* The Windows SMP kernel needs a CPU leaf or else its idle loop will burn cpu cycles; the
* intelppm driver refuses to register an idle state handler.
- */
- if ((cCpus > 1) || fIOAPIC)
+ * Always show CPU leafs for OS X guests. */
+ BOOL fShowCpu = fOsXGuest;
+ if (cCpus > 1 || fIOAPIC)
fShowCpu = true;
+ BOOL fCpuHotPlug;
hrc = pMachine->COMGETTER(CPUHotPlugEnabled)(&fCpuHotPlug); H();
InsertConfigNode(pDevices, "acpi", &pDev);
InsertConfigNode(pDev, "0", &pInst);
InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
InsertConfigNode(pInst, "Config", &pCfg);
- hrc = BusMgr->assignPCIDevice("acpi", pInst); H();
+ hrc = pBusMgr->assignPCIDevice("acpi", pInst); H();
InsertConfigInteger(pCfg, "RamSize", cbRam);
InsertConfigInteger(pCfg, "RamHoleSize", cbRamHole);
@@ -2629,7 +2852,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
if (fOsXGuest && fAudioEnabled)
{
PCIBusAddress Address;
- if (BusMgr->findPCIAddress("hda", 0, Address))
+ if (pBusMgr->findPCIAddress("hda", 0, Address))
{
uint32_t u32AudioPCIAddr = (Address.miDevice << 16) | Address.miFn;
InsertConfigInteger(pCfg, "AudioPciAddress", u32AudioPCIAddr);
@@ -2720,6 +2943,10 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
// InsertConfig threw something:
return x.m_vrc;
}
+ catch (HRESULT hrcXcpt)
+ {
+ AssertMsgFailedReturn(("hrc=%Rhrc\n", hrcXcpt), VERR_GENERAL_FAILURE);
+ }
#ifdef VBOX_WITH_EXTPACK
/*
@@ -2737,7 +2964,13 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
* Apply the CFGM overlay.
*/
if (RT_SUCCESS(rc))
- rc = configCfgmOverlay(pVM, virtualBox, pMachine);
+ rc = configCfgmOverlay(pRoot, virtualBox, pMachine);
+
+ /*
+ * Dump all extradata API settings tweaks, both global and per VM.
+ */
+ if (RT_SUCCESS(rc))
+ rc = configDumpAPISettingsTweaks(virtualBox, pMachine);
#undef H
@@ -2746,7 +2979,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* Register VM state change handler.
*/
- int rc2 = VMR3AtStateRegister(pVM, Console::vmstateChangeCallback, this);
+ int rc2 = VMR3AtStateRegister(pUVM, Console::vmstateChangeCallback, this);
AssertRC(rc2);
if (RT_SUCCESS(rc))
rc = rc2;
@@ -2754,7 +2987,7 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
/*
* Register VM runtime error handler.
*/
- rc2 = VMR3AtRuntimeErrorRegister(pVM, Console::setVMRuntimeErrorCallback, this);
+ rc2 = VMR3AtRuntimeErrorRegister(pUVM, Console::setVMRuntimeErrorCallback, this);
AssertRC(rc2);
if (RT_SUCCESS(rc))
rc = rc2;
@@ -2768,16 +3001,16 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
}
/**
- * Applies the CFGM overlay as specified by /VBoxInternal/XXX extra data
+ * Applies the CFGM overlay as specified by VBoxInternal/XXX extra data
* values.
*
* @returns VBox status code.
- * @param pVM The VM handle.
+ * @param pRoot The root of the configuration tree.
* @param pVirtualBox Pointer to the IVirtualBox interface.
* @param pMachine Pointer to the IMachine interface.
*/
/* static */
-int Console::configCfgmOverlay(PVM pVM, IVirtualBox *pVirtualBox, IMachine *pMachine)
+int Console::configCfgmOverlay(PCFGMNODE pRoot, IVirtualBox *pVirtualBox, IMachine *pMachine)
{
/*
* CFGM overlay handling.
@@ -2792,8 +3025,7 @@ int Console::configCfgmOverlay(PVM pVM, IVirtualBox *pVirtualBox, IMachine *pMac
* We first perform a run on global extra data, then on the machine
* extra data to support global settings with local overrides.
*/
- PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
- int rc = VINF_SUCCESS;
+ int rc = VINF_SUCCESS;
try
{
/** @todo add support for removing nodes and byte blobs. */
@@ -2809,7 +3041,7 @@ int Console::configCfgmOverlay(PVM pVM, IVirtualBox *pVirtualBox, IMachine *pMac
size_t cGlobalValues = aGlobalExtraDataKeys.size();
hrc = pMachine->GetExtraDataKeys(ComSafeArrayAsOutParam(aMachineExtraDataKeys));
- AssertMsg(SUCCEEDED(hrc), ("VirtualBox::GetExtraDataKeys failed with %Rhrc\n", hrc));
+ AssertMsg(SUCCEEDED(hrc), ("Machine::GetExtraDataKeys failed with %Rhrc\n", hrc));
// build a combined list from global keys...
std::list<Utf8Str> llExtraDataKeys;
@@ -2845,7 +3077,7 @@ int Console::configCfgmOverlay(PVM pVM, IVirtualBox *pVirtualBox, IMachine *pMac
hrc = pMachine->GetExtraData(Bstr(strKey).raw(),
bstrExtraDataValue.asOutParam());
if (FAILED(hrc))
- LogRel(("Warning: Cannot get extra data key %s, rc = %Rrc\n", strKey.c_str(), hrc));
+ LogRel(("Warning: Cannot get extra data key %s, rc = %Rhrc\n", strKey.c_str(), hrc));
/*
* The key will be in the format "Node1/Node2/Value" or simply "Value".
@@ -2897,16 +3129,36 @@ int Console::configCfgmOverlay(PVM pVM, IVirtualBox *pVirtualBox, IMachine *pMac
uint64_t u64Value;
/* check for type prefix first. */
- if (!strncmp(strCFGMValueUtf8.c_str(), "string:", sizeof("string:") - 1))
+ if (!strncmp(strCFGMValueUtf8.c_str(), RT_STR_TUPLE("string:")))
InsertConfigString(pNode, pszCFGMValueName, strCFGMValueUtf8.c_str() + sizeof("string:") - 1);
- else if (!strncmp(strCFGMValueUtf8.c_str(), "integer:", sizeof("integer:") - 1))
+ else if (!strncmp(strCFGMValueUtf8.c_str(), RT_STR_TUPLE("integer:")))
{
rc = RTStrToUInt64Full(strCFGMValueUtf8.c_str() + sizeof("integer:") - 1, 0, &u64Value);
if (RT_SUCCESS(rc))
rc = CFGMR3InsertInteger(pNode, pszCFGMValueName, u64Value);
}
- else if (!strncmp(strCFGMValueUtf8.c_str(), "bytes:", sizeof("bytes:") - 1))
- rc = VERR_NOT_IMPLEMENTED;
+ else if (!strncmp(strCFGMValueUtf8.c_str(), RT_STR_TUPLE("bytes:")))
+ {
+ char const *pszBase64 = strCFGMValueUtf8.c_str() + sizeof("bytes:") - 1;
+ ssize_t cbValue = RTBase64DecodedSize(pszBase64, NULL);
+ if (cbValue > 0)
+ {
+ void *pvBytes = RTMemTmpAlloc(cbValue);
+ if (pvBytes)
+ {
+ rc = RTBase64Decode(pszBase64, pvBytes, cbValue, NULL, NULL);
+ if (RT_SUCCESS(rc))
+ rc = CFGMR3InsertBytes(pNode, pszCFGMValueName, pvBytes, cbValue);
+ RTMemTmpFree(pvBytes);
+ }
+ else
+ rc = VERR_NO_TMP_MEMORY;
+ }
+ else if (cbValue == 0)
+ rc = CFGMR3InsertBytes(pNode, pszCFGMValueName, NULL, 0);
+ else
+ rc = VERR_INVALID_BASE64_ENCODING;
+ }
/* auto detect type. */
else if (RT_SUCCESS(RTStrToUInt64Full(strCFGMValueUtf8.c_str(), 0, &u64Value)))
rc = CFGMR3InsertInteger(pNode, pszCFGMValueName, u64Value);
@@ -2925,14 +3177,205 @@ int Console::configCfgmOverlay(PVM pVM, IVirtualBox *pVirtualBox, IMachine *pMac
}
/**
+ * Dumps the API settings tweaks as specified by VBoxInternal2/XXX extra data
+ * values.
+ *
+ * @returns VBox status code.
+ * @param pVirtualBox Pointer to the IVirtualBox interface.
+ * @param pMachine Pointer to the IMachine interface.
+ */
+/* static */
+int Console::configDumpAPISettingsTweaks(IVirtualBox *pVirtualBox, IMachine *pMachine)
+{
+ {
+ SafeArray<BSTR> aGlobalExtraDataKeys;
+ HRESULT hrc = pVirtualBox->GetExtraDataKeys(ComSafeArrayAsOutParam(aGlobalExtraDataKeys));
+ AssertMsg(SUCCEEDED(hrc), ("VirtualBox::GetExtraDataKeys failed with %Rhrc\n", hrc));
+ bool hasKey = false;
+ for (size_t i = 0; i < aGlobalExtraDataKeys.size(); i++)
+ {
+ Utf8Str strKey(aGlobalExtraDataKeys[i]);
+ if (!strKey.startsWith("VBoxInternal2/"))
+ continue;
+
+ Bstr bstrValue;
+ hrc = pVirtualBox->GetExtraData(Bstr(strKey).raw(),
+ bstrValue.asOutParam());
+ if (FAILED(hrc))
+ continue;
+ if (!hasKey)
+ LogRel(("Global extradata API settings:\n"));
+ LogRel((" %s=\"%ls\"\n", strKey.c_str(), bstrValue.raw()));
+ hasKey = true;
+ }
+ }
+
+ {
+ SafeArray<BSTR> aMachineExtraDataKeys;
+ HRESULT hrc = pMachine->GetExtraDataKeys(ComSafeArrayAsOutParam(aMachineExtraDataKeys));
+ AssertMsg(SUCCEEDED(hrc), ("Machine::GetExtraDataKeys failed with %Rhrc\n", hrc));
+ bool hasKey = false;
+ for (size_t i = 0; i < aMachineExtraDataKeys.size(); i++)
+ {
+ Utf8Str strKey(aMachineExtraDataKeys[i]);
+ if (!strKey.startsWith("VBoxInternal2/"))
+ continue;
+
+ Bstr bstrValue;
+ hrc = pMachine->GetExtraData(Bstr(strKey).raw(),
+ bstrValue.asOutParam());
+ if (FAILED(hrc))
+ continue;
+ if (!hasKey)
+ LogRel(("Per-VM extradata API settings:\n"));
+ LogRel((" %s=\"%ls\"\n", strKey.c_str(), bstrValue.raw()));
+ hasKey = true;
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+int Console::configGraphicsController(PCFGMNODE pDevices,
+ const GraphicsControllerType_T graphicsController,
+ BusAssignmentManager *pBusMgr,
+ const ComPtr<IMachine> &pMachine,
+ const ComPtr<IBIOSSettings> &biosSettings,
+ bool fHMEnabled)
+{
+ // InsertConfig* throws
+ try
+ {
+ PCFGMNODE pDev, pInst, pCfg, pLunL0;
+ HRESULT hrc;
+ Bstr bstr;
+ const char *pcszDevice = "vga";
+
+#define H() AssertMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE)
+ InsertConfigNode(pDevices, pcszDevice, &pDev);
+ InsertConfigNode(pDev, "0", &pInst);
+ InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
+
+ hrc = pBusMgr->assignPCIDevice(pcszDevice, pInst); H();
+ InsertConfigNode(pInst, "Config", &pCfg);
+ ULONG cVRamMBs;
+ hrc = pMachine->COMGETTER(VRAMSize)(&cVRamMBs); H();
+ InsertConfigInteger(pCfg, "VRamSize", cVRamMBs * _1M);
+ ULONG cMonitorCount;
+ hrc = pMachine->COMGETTER(MonitorCount)(&cMonitorCount); H();
+ InsertConfigInteger(pCfg, "MonitorCount", cMonitorCount);
+#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
+ InsertConfigInteger(pCfg, "R0Enabled", fHMEnabled);
+#else
+ NOREF(fHMEnabled);
+#endif
+
+#ifdef VBOX_WITH_VMSVGA
+ if (graphicsController == GraphicsControllerType_VMSVGA)
+ {
+ InsertConfigInteger(pCfg, "VMSVGAEnabled", true);
+#ifdef VBOX_WITH_VMSVGA3D
+ IFramebuffer *pFramebuffer = getDisplay()->getFramebuffer();
+ if (pFramebuffer)
+ {
+ LONG64 winId = 0;
+ /* @todo deal with multimonitor setup */
+ Assert(cMonitorCount == 1);
+ hrc = pFramebuffer->COMGETTER(WinId)(&winId);
+ InsertConfigInteger(pCfg, "HostWindowId", winId);
+ }
+ BOOL f3DEnabled;
+ pMachine->COMGETTER(Accelerate3DEnabled)(&f3DEnabled);
+ InsertConfigInteger(pCfg, "VMSVGA3dEnabled", f3DEnabled);
+#endif
+ }
+#endif
+
+ /* Custom VESA mode list */
+ unsigned cModes = 0;
+ for (unsigned iMode = 1; iMode <= 16; ++iMode)
+ {
+ char szExtraDataKey[sizeof("CustomVideoModeXX")];
+ RTStrPrintf(szExtraDataKey, sizeof(szExtraDataKey), "CustomVideoMode%u", iMode);
+ hrc = pMachine->GetExtraData(Bstr(szExtraDataKey).raw(), bstr.asOutParam()); H();
+ if (bstr.isEmpty())
+ break;
+ InsertConfigString(pCfg, szExtraDataKey, bstr);
+ ++cModes;
+ }
+ InsertConfigInteger(pCfg, "CustomVideoModes", cModes);
+
+ /* VESA height reduction */
+ ULONG ulHeightReduction;
+ IFramebuffer *pFramebuffer = getDisplay()->getFramebuffer();
+ if (pFramebuffer)
+ {
+ hrc = pFramebuffer->COMGETTER(HeightReduction)(&ulHeightReduction); H();
+ }
+ else
+ {
+ /* If framebuffer is not available, there is no height reduction. */
+ ulHeightReduction = 0;
+ }
+ InsertConfigInteger(pCfg, "HeightReduction", ulHeightReduction);
+
+ /*
+ * BIOS logo
+ */
+ BOOL fFadeIn;
+ hrc = biosSettings->COMGETTER(LogoFadeIn)(&fFadeIn); H();
+ InsertConfigInteger(pCfg, "FadeIn", fFadeIn ? 1 : 0);
+ BOOL fFadeOut;
+ hrc = biosSettings->COMGETTER(LogoFadeOut)(&fFadeOut); H();
+ InsertConfigInteger(pCfg, "FadeOut", fFadeOut ? 1: 0);
+ ULONG logoDisplayTime;
+ hrc = biosSettings->COMGETTER(LogoDisplayTime)(&logoDisplayTime); H();
+ InsertConfigInteger(pCfg, "LogoTime", logoDisplayTime);
+ Bstr logoImagePath;
+ hrc = biosSettings->COMGETTER(LogoImagePath)(logoImagePath.asOutParam()); H();
+ InsertConfigString(pCfg, "LogoFile", Utf8Str(!logoImagePath.isEmpty() ? logoImagePath : "") );
+
+ /*
+ * Boot menu
+ */
+ BIOSBootMenuMode_T eBootMenuMode;
+ int iShowBootMenu;
+ biosSettings->COMGETTER(BootMenuMode)(&eBootMenuMode);
+ switch (eBootMenuMode)
+ {
+ case BIOSBootMenuMode_Disabled: iShowBootMenu = 0; break;
+ case BIOSBootMenuMode_MenuOnly: iShowBootMenu = 1; break;
+ default: iShowBootMenu = 2; break;
+ }
+ InsertConfigInteger(pCfg, "ShowBootMenu", iShowBootMenu);
+
+ /* Attach the display. */
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+ InsertConfigString(pLunL0, "Driver", "MainDisplay");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ Display *pDisplay = mDisplay;
+ InsertConfigInteger(pCfg, "Object", (uintptr_t)pDisplay);
+ }
+ catch (ConfigError &x)
+ {
+ // InsertConfig threw something:
+ return x.m_vrc;
+ }
+
+#undef H
+
+ return VINF_SUCCESS;
+}
+
+
+/**
* Ellipsis to va_list wrapper for calling setVMRuntimeErrorCallback.
*/
-/*static*/
-void Console::setVMRuntimeErrorCallbackF(PVM pVM, void *pvConsole, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
+void Console::setVMRuntimeErrorCallbackF(uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
{
va_list va;
va_start(va, pszFormat);
- setVMRuntimeErrorCallback(pVM, pvConsole, fFlags, pszErrorId, pszFormat, va);
+ setVMRuntimeErrorCallback(NULL, this, fFlags, pszErrorId, pszFormat, va);
va_end(va);
}
@@ -2971,8 +3414,9 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
bool fAttachDetach,
bool fForceUnmount,
bool fHotplug,
- PVM pVM,
- DeviceType_T *paLedDevType)
+ PUVM pUVM,
+ DeviceType_T *paLedDevType,
+ PCFGMNODE *ppLunL0)
{
// InsertConfig* throws
try
@@ -3009,7 +3453,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
{
/* Unmount existing media only for floppy and DVD drives. */
PPDMIBASE pBase;
- rc = PDMR3QueryLun(pVM, pcszDevice, uInstance, uLUN, &pBase);
+ rc = PDMR3QueryLun(pUVM, pcszDevice, uInstance, uLUN, &pBase);
if (RT_FAILURE(rc))
{
if (rc == VERR_PDM_LUN_NOT_FOUND || rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
@@ -3031,7 +3475,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
}
}
- rc = PDMR3DeviceDetach(pVM, pcszDevice, uInstance, uLUN, fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG);
+ rc = PDMR3DeviceDetach(pUVM, pcszDevice, uInstance, uLUN, fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG);
if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
rc = VINF_SUCCESS;
AssertRCReturn(rc, rc);
@@ -3043,6 +3487,8 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
}
InsertConfigNode(pCtlInst, Utf8StrFmt("LUN#%u", uLUN).c_str(), &pLunL0);
+ if (ppLunL0)
+ *ppLunL0 = pLunL0;
PCFGMNODE pCfg = CFGMR3GetChild(pCtlInst, "Config");
if (pCfg)
@@ -3101,8 +3547,13 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
*/
ComPtr<IMediumFormat> pMediumFormat;
hrc = pMedium->COMGETTER(MediumFormat)(pMediumFormat.asOutParam()); H();
- ULONG uCaps;
- hrc = pMediumFormat->COMGETTER(Capabilities)(&uCaps); H();
+ ULONG uCaps = 0;
+ com::SafeArray <MediumFormatCapabilities_T> mediumFormatCap;
+ hrc = pMediumFormat->COMGETTER(Capabilities)(ComSafeArrayAsOutParam(mediumFormatCap)); H();
+
+ for (ULONG j = 0; j < mediumFormatCap.size(); j++)
+ uCaps |= mediumFormatCap[j];
+
if (uCaps & MediumFormatCapabilities_File)
{
Bstr strFile;
@@ -3135,8 +3586,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
{
const char *pszUnit;
uint64_t u64Print = formatDiskSize((uint64_t)i64Size, &pszUnit);
- setVMRuntimeErrorCallbackF(pVM, this, 0,
- "FatPartitionDetected",
+ setVMRuntimeErrorCallbackF(0, "FatPartitionDetected",
N_("The medium '%ls' has a logical size of %RU64%s "
"but the file system the medium is located on seems "
"to be FAT(32) which cannot handle files bigger than 4GB.\n"
@@ -3167,8 +3617,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
const char *pszUnitMax;
uint64_t u64PrintSiz = formatDiskSize((LONG64)i64Size, &pszUnitSiz);
uint64_t u64PrintMax = formatDiskSize(maxSize, &pszUnitMax);
- setVMRuntimeErrorCallbackF(pVM, this, 0,
- "FatPartitionDetected", /* <= not exact but ... */
+ setVMRuntimeErrorCallbackF(0, "FatPartitionDetected", /* <= not exact but ... */
N_("The medium '%ls' has a logical size of %RU64%s "
"but the file system the medium is located on can "
"only handle files up to %RU64%s in theory.\n"
@@ -3191,8 +3640,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
{
const char *pszUnit;
uint64_t u64Print = formatDiskSize(i64Size, &pszUnit);
- setVMRuntimeErrorCallbackF(pVM, this, 0,
- "FatPartitionDetected",
+ setVMRuntimeErrorCallbackF(0, "FatPartitionDetected",
#ifdef RT_OS_WINDOWS
N_("The snapshot folder of this VM '%ls' seems to be located on "
"a FAT(32) file system. The logical size of the medium '%ls' "
@@ -3233,8 +3681,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
if ( enmFsTypeFile == RTFSTYPE_EXT4
|| enmFsTypeFile == RTFSTYPE_XFS)
{
- setVMRuntimeErrorCallbackF(pVM, this, 0,
- "Ext4PartitionDetected",
+ setVMRuntimeErrorCallbackF(0, "Ext4PartitionDetected",
N_("The host I/O cache for at least one controller is disabled "
"and the medium '%ls' for this VM "
"is located on an %s partition. There is a known Linux "
@@ -3251,8 +3698,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
|| enmFsTypeSnap == RTFSTYPE_XFS)
&& !mfSnapshotFolderExt4WarningShown)
{
- setVMRuntimeErrorCallbackF(pVM, this, 0,
- "Ext4PartitionDetected",
+ setVMRuntimeErrorCallbackF(0, "Ext4PartitionDetected",
N_("The host I/O cache for at least one controller is disabled "
"and the snapshot folder for this VM "
"is located on an %s partition. There is a known Linux "
@@ -3271,19 +3717,17 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
}
}
- if ( pMedium
- && ( lType == DeviceType_DVD
- || lType == DeviceType_Floppy))
+ if (pMedium)
{
- /*
- * Informative logging.
- */
- ComPtr<IMediumFormat> pMediumFormat;
- hrc = pMedium->COMGETTER(MediumFormat)(pMediumFormat.asOutParam()); H();
- ULONG uCaps;
- hrc = pMediumFormat->COMGETTER(Capabilities)(&uCaps); H();
- if (uCaps & MediumFormatCapabilities_File)
+ BOOL fHostDrive;
+ hrc = pMedium->COMGETTER(HostDrive)(&fHostDrive); H();
+ if ( ( lType == DeviceType_DVD
+ || lType == DeviceType_Floppy)
+ && !fHostDrive)
{
+ /*
+ * Informative logging.
+ */
Bstr strFile;
hrc = pMedium->COMGETTER(Location)(strFile.asOutParam()); H();
Utf8Str utfFile = Utf8Str(strFile);
@@ -3326,8 +3770,8 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
if (fAttachDetach)
{
/* Attach the new driver. */
- rc = PDMR3DeviceAttach(pVM, pcszDevice, uInstance, uLUN,
- fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
+ rc = PDMR3DeviceAttach(pUVM, pcszDevice, uInstance, uLUN,
+ fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
AssertRCReturn(rc, rc);
/* There is no need to handle removable medium mounting, as we
@@ -3346,7 +3790,7 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
#undef H
- return VINF_SUCCESS;;
+ return VINF_SUCCESS;
}
int Console::configMedium(PCFGMNODE pLunL0,
@@ -3443,10 +3887,7 @@ int Console::configMedium(PCFGMNODE pLunL0,
{
Bstr loc;
hrc = pMedium->COMGETTER(Location)(loc.asOutParam()); H();
- setVMRuntimeErrorCallbackF(VMR3GetVM(mpUVM),
- this,
- 0,
- "DvdOrFloppyImageInaccessible",
+ setVMRuntimeErrorCallbackF(0, "DvdOrFloppyImageInaccessible",
"The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
loc.raw(),
enmType == DeviceType_DVD ? "DVD" : "floppy");
@@ -3700,8 +4141,6 @@ int Console::configNetwork(const char *pszDevice,
*/
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- PVM pVM = VMR3GetVM(mpUVM); /* We're on an EMT, so this is safe. */
-
ComPtr<IMachine> pMachine = machine();
ComPtr<IVirtualBox> virtualBox;
@@ -3726,7 +4165,7 @@ int Console::configNetwork(const char *pszDevice,
if (fAttachDetach)
{
- rc = PDMR3DeviceDetach(pVM, pszDevice, uInstance, uLun, 0 /*fFlags*/);
+ rc = PDMR3DeviceDetach(mpUVM, pszDevice, uInstance, uLun, 0 /*fFlags*/);
if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN)
rc = VINF_SUCCESS;
AssertLogRelRCReturn(rc, rc);
@@ -3903,6 +4342,10 @@ int Console::configNetwork(const char *pszDevice,
if (!fValid)
continue;
+ if (strName.isEmpty())
+ VMSetError(VMR3GetVM(mpUVM), VERR_CFGM_NO_NODE, RT_SRC_POS,
+ N_("NAT redirection rule without a name"));
+
InsertConfigNode(pCfg, strName.c_str(), &pPF);
InsertConfigString(pPF, "Protocol", strProto);
@@ -3932,7 +4375,7 @@ int Console::configNetwork(const char *pszDevice,
switch (hrc)
{
case VERR_ACCESS_DENIED:
- return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
+ return VMSetError(VMR3GetVM(mpUVM), VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
"Failed to open '/dev/net/tun' for read/write access. Please check the "
"permissions of that node. Either run 'chmod 0666 /dev/net/tun' or "
"change the group of that node and make yourself a member of that group. Make "
@@ -3940,7 +4383,7 @@ int Console::configNetwork(const char *pszDevice,
"using udev"));
default:
AssertMsgFailed(("Could not attach to host interface! Bad!\n"));
- return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
+ return VMSetError(VMR3GetVM(mpUVM), VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
"Failed to initialize Host Interface Networking"));
}
}
@@ -3961,7 +4404,7 @@ int Console::configNetwork(const char *pszDevice,
hrc = aNetworkAdapter->COMGETTER(BridgedInterface)(BridgedIfName.asOutParam());
if (FAILED(hrc))
{
- LogRel(("NetworkAttachmentType_Bridged: COMGETTER(BridgedInterface) failed, hrc (0x%x)", hrc));
+ LogRel(("NetworkAttachmentType_Bridged: COMGETTER(BridgedInterface) failed, hrc (0x%x)\n", hrc));
H();
}
@@ -3983,7 +4426,7 @@ int Console::configNetwork(const char *pszDevice,
// * See @bugref{4750}.
// * hrc = aNetworkAdapter->Detach(); H();
// */
-// return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+// return VMSetError(VMR3GetVM(mpUVM), VERR_INTERNAL_ERROR, RT_SRC_POS,
// N_("Malformed host interface networking name '%ls'"),
// BridgedIfName.raw());
// }
@@ -4019,7 +4462,7 @@ int Console::configNetwork(const char *pszDevice,
if (!SUCCEEDED(hrc))
{
AssertLogRelMsgFailed(("NetworkAttachmentType_Bridged: FindByName failed, rc=%Rhrc (0x%x)", hrc, hrc));
- return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+ return VMSetError(VMR3GetVM(mpUVM), VERR_INTERNAL_ERROR, RT_SRC_POS,
N_("Nonexistent host networking interface, name '%ls'"),
BridgedIfName.raw());
}
@@ -4028,13 +4471,13 @@ int Console::configNetwork(const char *pszDevice,
hrc = hostInterface->COMGETTER(InterfaceType)(&eIfType);
if (FAILED(hrc))
{
- LogRel(("NetworkAttachmentType_Bridged: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc));
+ LogRel(("NetworkAttachmentType_Bridged: COMGETTER(InterfaceType) failed, hrc (0x%x)\n", hrc));
H();
}
if (eIfType != HostNetworkInterfaceType_Bridged)
{
- return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+ return VMSetError(VMR3GetVM(mpUVM), VERR_INTERNAL_ERROR, RT_SRC_POS,
N_("Interface ('%ls') is not a Bridged Adapter interface"),
BridgedIfName.raw());
}
@@ -4042,7 +4485,7 @@ int Console::configNetwork(const char *pszDevice,
hrc = hostInterface->COMGETTER(Id)(bstr.asOutParam());
if (FAILED(hrc))
{
- LogRel(("NetworkAttachmentType_Bridged: COMGETTER(Id) failed, hrc (0x%x)", hrc));
+ LogRel(("NetworkAttachmentType_Bridged: COMGETTER(Id) failed, hrc (0x%x)\n", hrc));
H();
}
Guid hostIFGuid(bstr);
@@ -4064,7 +4507,7 @@ int Console::configNetwork(const char *pszDevice,
if (hrc != S_OK)
{
VBoxNetCfgWinReleaseINetCfg(pNc, FALSE /*fHasWriteLock*/);
- LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
+ LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)\n", hrc));
H();
}
#define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
@@ -4124,14 +4567,14 @@ int Console::configNetwork(const char *pszDevice,
* This works and performs better than bridging a physical
* interface via the current FreeBSD vboxnetflt implementation.
*/
- if (!strncmp(pszBridgedIfName, "tap", sizeof "tap" - 1)) {
+ if (!strncmp(pszBridgedIfName, RT_STR_TUPLE("tap"))) {
hrc = attachToTapInterface(aNetworkAdapter);
if (FAILED(hrc))
{
switch (hrc)
{
case VERR_ACCESS_DENIED:
- return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
+ return VMSetError(VMR3GetVM(mpUVM), VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
"Failed to open '/dev/%s' for read/write access. Please check the "
"permissions of that node, and that the net.link.tap.user_open "
"sysctl is set. Either run 'chmod 0666 /dev/%s' or "
@@ -4139,7 +4582,7 @@ int Console::configNetwork(const char *pszDevice,
"a member of that group. Make sure that these changes are permanent."), pszBridgedIfName, pszBridgedIfName);
default:
AssertMsgFailed(("Could not attach to tap interface! Bad!\n"));
- return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
+ return VMSetError(VMR3GetVM(mpUVM), VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
"Failed to initialize Host Interface Networking"));
}
}
@@ -4164,12 +4607,12 @@ int Console::configNetwork(const char *pszDevice,
{
struct ifreq Req;
RT_ZERO(Req);
- strncpy(Req.ifr_name, pszBridgedIfName, sizeof(Req.ifr_name) - 1);
+ RTStrCopy(Req.ifr_name, sizeof(Req.ifr_name), pszBridgedIfName);
if (ioctl(iSock, SIOCGIFFLAGS, &Req) >= 0)
if ((Req.ifr_flags & IFF_UP) == 0)
- setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown",
- "Bridged interface %s is down. Guest will not be able to use this interface",
- pszBridgedIfName);
+ setVMRuntimeErrorCallbackF(0, "BridgedInterfaceDown",
+ N_("Bridged interface %s is down. Guest will not be able to use this interface"),
+ pszBridgedIfName);
close(iSock);
}
@@ -4213,7 +4656,7 @@ int Console::configNetwork(const char *pszDevice,
{
struct iwreq WRq;
- memset(&WRq, 0, sizeof(WRq));
+ RT_ZERO(WRq);
strncpy(WRq.ifr_name, pszBridgedIfName, IFNAMSIZ);
bool fSharedMacOnWire = ioctl(iSock, SIOCGIWNAME, &WRq) >= 0;
close(iSock);
@@ -4234,7 +4677,7 @@ int Console::configNetwork(const char *pszDevice,
struct ieee80211req WReq;
uint8_t abData[32];
- memset(&WReq, 0, sizeof(WReq));
+ RT_ZERO(WReq);
strncpy(WReq.i_name, pszBridgedIfName, sizeof(WReq.i_name));
WReq.i_type = IEEE80211_IOC_SSID;
WReq.i_val = -1;
@@ -4390,7 +4833,7 @@ int Console::configNetwork(const char *pszDevice,
if (!SUCCEEDED(rc))
{
LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)\n", rc));
- return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+ return VMSetError(VMR3GetVM(mpUVM), VERR_INTERNAL_ERROR, RT_SRC_POS,
N_("Nonexistent host networking interface, name '%ls'"),
HostOnlyName.raw());
}
@@ -4415,7 +4858,7 @@ int Console::configNetwork(const char *pszDevice,
}
if (eIfType != HostNetworkInterfaceType_HostOnly)
- return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+ return VMSetError(VMR3GetVM(mpUVM), VERR_INTERNAL_ERROR, RT_SRC_POS,
N_("Interface ('%ls') is not a Host-Only Adapter interface"),
HostOnlyName.raw());
@@ -4591,6 +5034,23 @@ int Console::configNetwork(const char *pszDevice,
break;
}
+ case NetworkAttachmentType_NATNetwork:
+ {
+ hrc = aNetworkAdapter->COMGETTER(NATNetwork)(bstr.asOutParam()); H();
+ if (!bstr.isEmpty())
+ {
+ /** @todo add intnet prefix to separate namespaces, and add trunk if dealing with vboxnatX */
+ InsertConfigString(pLunL0, "Driver", "IntNet");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigString(pCfg, "Network", bstr);
+ InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_WhateverNone);
+ InsertConfigString(pCfg, "IfPolicyPromisc", pszPromiscuousGuestPolicy);
+ networkName = bstr;
+ trunkType = Bstr(TRUNKTYPE_WHATEVER);
+ }
+ break;
+ }
+
default:
AssertMsgFailed(("should not get here!\n"));
break;
@@ -4609,12 +5069,13 @@ int Console::configNetwork(const char *pszDevice,
case NetworkAttachmentType_HostOnly:
case NetworkAttachmentType_NAT:
case NetworkAttachmentType_Generic:
+ case NetworkAttachmentType_NATNetwork:
{
if (SUCCEEDED(hrc) && SUCCEEDED(rc))
{
if (fAttachDetach)
{
- rc = PDMR3DriverAttach(pVM, pszDevice, uInstance, uLun, 0 /*fFlags*/, NULL /* ppBase */);
+ rc = PDMR3DriverAttach(mpUVM, pszDevice, uInstance, uLun, 0 /*fFlags*/, NULL /* ppBase */);
//AssertRC(rc);
}
@@ -4627,7 +5088,11 @@ int Console::configNetwork(const char *pszDevice,
/* Stop the hostonly DHCP Server */
}
- if (!networkName.isEmpty())
+ /*
+ * NAT networks start their DHCP server theirself, see NATNetwork::Start()
+ */
+ if ( !networkName.isEmpty()
+ && eAttachmentType != NetworkAttachmentType_NATNetwork)
{
/*
* Until we implement service reference counters DHCP Server will be stopped
@@ -4643,7 +5108,7 @@ int Console::configNetwork(const char *pszDevice,
hrc = dhcpServer->COMGETTER(Enabled)(&fEnabledDhcp);
if (FAILED(hrc))
{
- LogRel(("DHCP svr: COMGETTER(Enabled) failed, hrc (%Rhrc)", hrc));
+ LogRel(("DHCP svr: COMGETTER(Enabled) failed, hrc (%Rhrc)\n", hrc));
H();
}
@@ -4724,13 +5189,13 @@ static void configSetProperty(VMMDev * const pVMMDev,
AssertPtrReturnVoid(pszFlags);
parms[0].type = VBOX_HGCM_SVC_PARM_PTR;
parms[0].u.pointer.addr = (void *)pszName;
- parms[0].u.pointer.size = strlen(pszName) + 1;
+ parms[0].u.pointer.size = (uint32_t)strlen(pszName) + 1;
parms[1].type = VBOX_HGCM_SVC_PARM_PTR;
parms[1].u.pointer.addr = (void *)pszValue;
- parms[1].u.pointer.size = strlen(pszValue) + 1;
+ parms[1].u.pointer.size = (uint32_t)strlen(pszValue) + 1;
parms[2].type = VBOX_HGCM_SVC_PARM_PTR;
parms[2].u.pointer.addr = (void *)pszFlags;
- parms[2].u.pointer.size = strlen(pszFlags) + 1;
+ parms[2].u.pointer.size = (uint32_t)strlen(pszFlags) + 1;
pVMMDev->hgcmHostCall("VBoxGuestPropSvc", guestProp::SET_PROP_HOST, 3,
&parms[0]);
}
@@ -4766,7 +5231,7 @@ int configSetGlobalPropertyFlags(VMMDev * const pVMMDev,
* Set up the Guest Property service, populate it with properties read from
* the machine XML and set a couple of initial properties.
*/
-/* static */ int Console::configGuestProperties(void *pvConsole, PVM pVM)
+/* static */ int Console::configGuestProperties(void *pvConsole, PUVM pUVM)
{
#ifdef VBOX_WITH_GUEST_PROPS
AssertReturn(pvConsole, VERR_GENERAL_FAILURE);
@@ -4798,7 +5263,7 @@ int configSetGlobalPropertyFlags(VMMDev * const pVMMDev,
{
PFNDBGFHANDLEREXT pfnHandler = (PFNDBGFHANDLEREXT)(uintptr_t)Params[0].u.pointer.addr;
void *pService = (void*)Params[1].u.pointer.addr;
- DBGFR3InfoRegisterExternal(pVM, "guestprops", "Display the guest properties", pfnHandler, pService);
+ DBGFR3InfoRegisterExternal(pUVM, "guestprops", "Display the guest properties", pfnHandler, pService);
}
}
@@ -4822,7 +5287,7 @@ int configSetGlobalPropertyFlags(VMMDev * const pVMMDev,
ComSafeArrayAsOutParam(valuesOut),
ComSafeArrayAsOutParam(timestampsOut),
ComSafeArrayAsOutParam(flagsOut));
- AssertMsgReturn(SUCCEEDED(hrc), ("hrc=%Rrc\n", hrc), VERR_GENERAL_FAILURE);
+ AssertMsgReturn(SUCCEEDED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE);
size_t cProps = namesOut.size();
size_t cAlloc = cProps + 1;
if ( valuesOut.size() != cProps