diff options
Diffstat (limited to 'src/VBox/Main/src-server/SystemPropertiesImpl.cpp')
-rw-r--r-- | src/VBox/Main/src-server/SystemPropertiesImpl.cpp | 2402 |
1 files changed, 2402 insertions, 0 deletions
diff --git a/src/VBox/Main/src-server/SystemPropertiesImpl.cpp b/src/VBox/Main/src-server/SystemPropertiesImpl.cpp new file mode 100644 index 00000000..6ed056b9 --- /dev/null +++ b/src/VBox/Main/src-server/SystemPropertiesImpl.cpp @@ -0,0 +1,2402 @@ +/* $Id: SystemPropertiesImpl.cpp $ */ +/** @file + * VirtualBox COM class implementation + */ + +/* + * Copyright (C) 2006-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#define LOG_GROUP LOG_GROUP_MAIN_SYSTEMPROPERTIES +#include "SystemPropertiesImpl.h" +#include "VirtualBoxImpl.h" +#include "MachineImpl.h" +#ifdef VBOX_WITH_EXTPACK +# include "ExtPackManagerImpl.h" +#endif +#include "CPUProfileImpl.h" +#include "AutoCaller.h" +#include "Global.h" +#include "LoggingNew.h" +#include "AutostartDb.h" +#include "VirtualBoxTranslator.h" + +// generated header +#include "SchemaDefs.h" + +#include <iprt/dir.h> +#include <iprt/ldr.h> +#include <iprt/locale.h> +#include <iprt/path.h> +#include <iprt/string.h> +#include <iprt/uri.h> +#include <iprt/cpp/utils.h> + +#include <iprt/errcore.h> +#include <VBox/param.h> +#include <VBox/settings.h> +#include <VBox/vd.h> +#include <VBox/vmm/cpum.h> + +// defines +///////////////////////////////////////////////////////////////////////////// + +// constructor / destructor +///////////////////////////////////////////////////////////////////////////// + +SystemProperties::SystemProperties() + : mParent(NULL) + , m(new settings::SystemProperties) + , m_fLoadedX86CPUProfiles(false) +{ +} + +SystemProperties::~SystemProperties() +{ + delete m; +} + + +HRESULT SystemProperties::FinalConstruct() +{ + return BaseFinalConstruct(); +} + +void SystemProperties::FinalRelease() +{ + uninit(); + BaseFinalRelease(); +} + +// public methods only for internal purposes +///////////////////////////////////////////////////////////////////////////// + +/** + * Initializes the system information object. + * + * @returns COM result indicator + */ +HRESULT SystemProperties::init(VirtualBox *aParent) +{ + LogFlowThisFunc(("aParent=%p\n", aParent)); + + ComAssertRet(aParent, E_FAIL); + + /* Enclose the state transition NotReady->InInit->Ready */ + AutoInitSpan autoInitSpan(this); + AssertReturn(autoInitSpan.isOk(), E_FAIL); + + unconst(mParent) = aParent; + + i_setDefaultMachineFolder(Utf8Str::Empty); + i_setLoggingLevel(Utf8Str::Empty); + i_setDefaultHardDiskFormat(Utf8Str::Empty); + + i_setVRDEAuthLibrary(Utf8Str::Empty); + i_setDefaultVRDEExtPack(Utf8Str::Empty); + i_setDefaultCryptoExtPack(Utf8Str::Empty); + + m->uLogHistoryCount = 3; + + + /* On Windows, OS X and Solaris, HW virtualization use isn't exclusive + * by default so that VT-x or AMD-V can be shared with other + * hypervisors without requiring user intervention. + * NB: See also SystemProperties constructor in settings.h + */ +#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS) + m->fExclusiveHwVirt = false; +#else + m->fExclusiveHwVirt = true; +#endif + + HRESULT rc = S_OK; + + /* Fetch info of all available hd backends. */ + + /// @todo NEWMEDIA VDBackendInfo needs to be improved to let us enumerate + /// any number of backends + + VDBACKENDINFO aVDInfo[100]; + unsigned cEntries; + int vrc = VDBackendInfo(RT_ELEMENTS(aVDInfo), aVDInfo, &cEntries); + AssertRC(vrc); + if (RT_SUCCESS(vrc)) + { + for (unsigned i = 0; i < cEntries; ++ i) + { + ComObjPtr<MediumFormat> hdf; + rc = hdf.createObject(); + if (FAILED(rc)) break; + + rc = hdf->init(&aVDInfo[i]); + if (FAILED(rc)) break; + + m_llMediumFormats.push_back(hdf); + } + } + + /* Confirm a successful initialization */ + if (SUCCEEDED(rc)) + autoInitSpan.setSucceeded(); + + return rc; +} + +/** + * Uninitializes the instance and sets the ready flag to FALSE. + * Called either from FinalRelease() or by the parent when it gets destroyed. + */ +void SystemProperties::uninit() +{ + LogFlowThisFunc(("\n")); + + /* Enclose the state transition Ready->InUninit->NotReady */ + AutoUninitSpan autoUninitSpan(this); + if (autoUninitSpan.uninitDone()) + return; + + unconst(mParent) = NULL; +} + +// wrapped ISystemProperties properties +///////////////////////////////////////////////////////////////////////////// + +HRESULT SystemProperties::getMinGuestRAM(ULONG *minRAM) + +{ + /* no need to lock, this is const */ + AssertCompile(MM_RAM_MIN_IN_MB >= SchemaDefs::MinGuestRAM); + *minRAM = MM_RAM_MIN_IN_MB; + + return S_OK; +} + +HRESULT SystemProperties::getMaxGuestRAM(ULONG *maxRAM) +{ + /* no need to lock, this is const */ + AssertCompile(MM_RAM_MAX_IN_MB <= SchemaDefs::MaxGuestRAM); + ULONG maxRAMSys = MM_RAM_MAX_IN_MB; + ULONG maxRAMArch = maxRAMSys; + *maxRAM = RT_MIN(maxRAMSys, maxRAMArch); + + return S_OK; +} + +HRESULT SystemProperties::getMinGuestVRAM(ULONG *minVRAM) +{ + /* no need to lock, this is const */ + *minVRAM = SchemaDefs::MinGuestVRAM; + + return S_OK; +} + +HRESULT SystemProperties::getMaxGuestVRAM(ULONG *maxVRAM) +{ + /* no need to lock, this is const */ + *maxVRAM = SchemaDefs::MaxGuestVRAM; + + return S_OK; +} + +HRESULT SystemProperties::getMinGuestCPUCount(ULONG *minCPUCount) +{ + /* no need to lock, this is const */ + *minCPUCount = SchemaDefs::MinCPUCount; // VMM_MIN_CPU_COUNT + + return S_OK; +} + +HRESULT SystemProperties::getMaxGuestCPUCount(ULONG *maxCPUCount) +{ + /* no need to lock, this is const */ + *maxCPUCount = SchemaDefs::MaxCPUCount; // VMM_MAX_CPU_COUNT + + return S_OK; +} + +HRESULT SystemProperties::getMaxGuestMonitors(ULONG *maxMonitors) +{ + + /* no need to lock, this is const */ + *maxMonitors = SchemaDefs::MaxGuestMonitors; + + return S_OK; +} + + +HRESULT SystemProperties::getInfoVDSize(LONG64 *infoVDSize) +{ + /* + * The BIOS supports currently 32 bit LBA numbers (implementing the full + * 48 bit range is in theory trivial, but the crappy compiler makes things + * more difficult). This translates to almost 2 TiBytes (to be on the safe + * side, the reported limit is 1 MiByte less than that, as the total number + * of sectors should fit in 32 bits, too), which should be enough for the + * moment. Since the MBR partition tables support only 32bit sector numbers + * and thus the BIOS can only boot from disks smaller than 2T this is a + * rather hard limit. + * + * The virtual ATA/SATA disks support complete LBA48, and SCSI supports + * LBA64 (almost, more like LBA55 in practice), so the theoretical maximum + * disk size is 128 PiByte/16 EiByte. The GUI works nicely with 6 orders + * of magnitude, but not with 11..13 orders of magnitude. + */ + /* no need to lock, this is const */ + *infoVDSize = 2 * _1T - _1M; + + return S_OK; +} + + +HRESULT SystemProperties::getSerialPortCount(ULONG *count) +{ + /* no need to lock, this is const */ + *count = SchemaDefs::SerialPortCount; + + return S_OK; +} + + +HRESULT SystemProperties::getParallelPortCount(ULONG *count) +{ + /* no need to lock, this is const */ + *count = SchemaDefs::ParallelPortCount; + + return S_OK; +} + + +HRESULT SystemProperties::getMaxBootPosition(ULONG *aMaxBootPosition) +{ + /* no need to lock, this is const */ + *aMaxBootPosition = SchemaDefs::MaxBootPosition; + + return S_OK; +} + + +HRESULT SystemProperties::getRawModeSupported(BOOL *aRawModeSupported) +{ + *aRawModeSupported = FALSE; + return S_OK; +} + + +HRESULT SystemProperties::getExclusiveHwVirt(BOOL *aExclusiveHwVirt) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + *aExclusiveHwVirt = m->fExclusiveHwVirt; + + return S_OK; +} + +HRESULT SystemProperties::setExclusiveHwVirt(BOOL aExclusiveHwVirt) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + m->fExclusiveHwVirt = !!aExclusiveHwVirt; + alock.release(); + + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + HRESULT rc = mParent->i_saveSettings(); + + return rc; +} + +HRESULT SystemProperties::getMaxNetworkAdapters(ChipsetType_T aChipset, ULONG *aMaxNetworkAdapters) +{ + /* no need for locking, no state */ + uint32_t uResult = Global::getMaxNetworkAdapters(aChipset); + if (uResult == 0) + AssertMsgFailed(("Invalid chipset type %d\n", aChipset)); + *aMaxNetworkAdapters = uResult; + return S_OK; +} + +HRESULT SystemProperties::getMaxNetworkAdaptersOfType(ChipsetType_T aChipset, NetworkAttachmentType_T aType, ULONG *count) +{ + /* no need for locking, no state */ + uint32_t uResult = Global::getMaxNetworkAdapters(aChipset); + if (uResult == 0) + AssertMsgFailed(("Invalid chipset type %d\n", aChipset)); + + switch (aType) + { + case NetworkAttachmentType_NAT: + case NetworkAttachmentType_Internal: + case NetworkAttachmentType_NATNetwork: + /* chipset default is OK */ + break; + case NetworkAttachmentType_Bridged: + /* Maybe use current host interface count here? */ + break; + case NetworkAttachmentType_HostOnly: + uResult = RT_MIN(uResult, 8); + break; + default: + AssertMsgFailed(("Unhandled attachment type %d\n", aType)); + } + + *count = uResult; + + return S_OK; +} + + +HRESULT SystemProperties::getMaxDevicesPerPortForStorageBus(StorageBus_T aBus, + ULONG *aMaxDevicesPerPort) +{ + /* no need to lock, this is const */ + switch (aBus) + { + case StorageBus_SATA: + case StorageBus_SCSI: + case StorageBus_SAS: + case StorageBus_USB: + case StorageBus_PCIe: + case StorageBus_VirtioSCSI: + { + /* SATA and both SCSI controllers only support one device per port. */ + *aMaxDevicesPerPort = 1; + break; + } + case StorageBus_IDE: + case StorageBus_Floppy: + { + /* The IDE and Floppy controllers support 2 devices. One as master + * and one as slave (or floppy drive 0 and 1). */ + *aMaxDevicesPerPort = 2; + break; + } + default: + AssertMsgFailed(("Invalid bus type %d\n", aBus)); + } + + return S_OK; +} + +HRESULT SystemProperties::getMinPortCountForStorageBus(StorageBus_T aBus, + ULONG *aMinPortCount) +{ + /* no need to lock, this is const */ + switch (aBus) + { + case StorageBus_SATA: + case StorageBus_SAS: + case StorageBus_PCIe: + case StorageBus_VirtioSCSI: + { + *aMinPortCount = 1; + break; + } + case StorageBus_SCSI: + { + *aMinPortCount = 16; + break; + } + case StorageBus_IDE: + { + *aMinPortCount = 2; + break; + } + case StorageBus_Floppy: + { + *aMinPortCount = 1; + break; + } + case StorageBus_USB: + { + *aMinPortCount = 8; + break; + } + default: + AssertMsgFailed(("Invalid bus type %d\n", aBus)); + } + + return S_OK; +} + +HRESULT SystemProperties::getMaxPortCountForStorageBus(StorageBus_T aBus, + ULONG *aMaxPortCount) +{ + /* no need to lock, this is const */ + switch (aBus) + { + case StorageBus_SATA: + { + *aMaxPortCount = 30; + break; + } + case StorageBus_SCSI: + { + *aMaxPortCount = 16; + break; + } + case StorageBus_IDE: + { + *aMaxPortCount = 2; + break; + } + case StorageBus_Floppy: + { + *aMaxPortCount = 1; + break; + } + case StorageBus_SAS: + case StorageBus_PCIe: + { + *aMaxPortCount = 255; + break; + } + case StorageBus_USB: + { + *aMaxPortCount = 8; + break; + } + case StorageBus_VirtioSCSI: + { + *aMaxPortCount = 256; + break; + } + default: + AssertMsgFailed(("Invalid bus type %d\n", aBus)); + } + + return S_OK; +} + +HRESULT SystemProperties::getMaxInstancesOfStorageBus(ChipsetType_T aChipset, + StorageBus_T aBus, + ULONG *aMaxInstances) +{ + ULONG cCtrs = 0; + + /* no need to lock, this is const */ + switch (aBus) + { + case StorageBus_SATA: + case StorageBus_SCSI: + case StorageBus_SAS: + case StorageBus_PCIe: + case StorageBus_VirtioSCSI: + cCtrs = aChipset == ChipsetType_ICH9 ? 8 : 1; + break; + case StorageBus_USB: + case StorageBus_IDE: + case StorageBus_Floppy: + { + cCtrs = 1; + break; + } + default: + AssertMsgFailed(("Invalid bus type %d\n", aBus)); + } + + *aMaxInstances = cCtrs; + + return S_OK; +} + +HRESULT SystemProperties::getDeviceTypesForStorageBus(StorageBus_T aBus, + std::vector<DeviceType_T> &aDeviceTypes) +{ + aDeviceTypes.resize(0); + + /* no need to lock, this is const */ + switch (aBus) + { + case StorageBus_IDE: + case StorageBus_SATA: + case StorageBus_SCSI: + case StorageBus_SAS: + case StorageBus_USB: + case StorageBus_VirtioSCSI: + { + aDeviceTypes.resize(2); + aDeviceTypes[0] = DeviceType_DVD; + aDeviceTypes[1] = DeviceType_HardDisk; + break; + } + case StorageBus_Floppy: + { + aDeviceTypes.resize(1); + aDeviceTypes[0] = DeviceType_Floppy; + break; + } + case StorageBus_PCIe: + { + aDeviceTypes.resize(1); + aDeviceTypes[0] = DeviceType_HardDisk; + break; + } + default: + AssertMsgFailed(("Invalid bus type %d\n", aBus)); + } + + return S_OK; +} + +HRESULT SystemProperties::getStorageBusForStorageControllerType(StorageControllerType_T aStorageControllerType, + StorageBus_T *aStorageBus) +{ + /* no need to lock, this is const */ + switch (aStorageControllerType) + { + case StorageControllerType_LsiLogic: + case StorageControllerType_BusLogic: + *aStorageBus = StorageBus_SCSI; + break; + case StorageControllerType_IntelAhci: + *aStorageBus = StorageBus_SATA; + break; + case StorageControllerType_PIIX3: + case StorageControllerType_PIIX4: + case StorageControllerType_ICH6: + *aStorageBus = StorageBus_IDE; + break; + case StorageControllerType_I82078: + *aStorageBus = StorageBus_Floppy; + break; + case StorageControllerType_LsiLogicSas: + *aStorageBus = StorageBus_SAS; + break; + case StorageControllerType_USB: + *aStorageBus = StorageBus_USB; + break; + case StorageControllerType_NVMe: + *aStorageBus = StorageBus_PCIe; + break; + case StorageControllerType_VirtioSCSI: + *aStorageBus = StorageBus_VirtioSCSI; + break; + default: + return setError(E_FAIL, tr("Invalid storage controller type %d\n"), aStorageBus); + } + + return S_OK; +} + +HRESULT SystemProperties::getStorageControllerTypesForStorageBus(StorageBus_T aStorageBus, + std::vector<StorageControllerType_T> &aStorageControllerTypes) +{ + aStorageControllerTypes.resize(0); + + /* no need to lock, this is const */ + switch (aStorageBus) + { + case StorageBus_IDE: + aStorageControllerTypes.resize(3); + aStorageControllerTypes[0] = StorageControllerType_PIIX4; + aStorageControllerTypes[1] = StorageControllerType_PIIX3; + aStorageControllerTypes[2] = StorageControllerType_ICH6; + break; + case StorageBus_SATA: + aStorageControllerTypes.resize(1); + aStorageControllerTypes[0] = StorageControllerType_IntelAhci; + break; + case StorageBus_SCSI: + aStorageControllerTypes.resize(2); + aStorageControllerTypes[0] = StorageControllerType_LsiLogic; + aStorageControllerTypes[1] = StorageControllerType_BusLogic; + break; + case StorageBus_Floppy: + aStorageControllerTypes.resize(1); + aStorageControllerTypes[0] = StorageControllerType_I82078; + break; + case StorageBus_SAS: + aStorageControllerTypes.resize(1); + aStorageControllerTypes[0] = StorageControllerType_LsiLogicSas; + break; + case StorageBus_USB: + aStorageControllerTypes.resize(1); + aStorageControllerTypes[0] = StorageControllerType_USB; + break; + case StorageBus_PCIe: + aStorageControllerTypes.resize(1); + aStorageControllerTypes[0] = StorageControllerType_NVMe; + break; + case StorageBus_VirtioSCSI: + aStorageControllerTypes.resize(1); + aStorageControllerTypes[0] = StorageControllerType_VirtioSCSI; + break; + default: + return setError(E_FAIL, tr("Invalid storage bus %d\n"), aStorageBus); + } + + return S_OK; +} + +HRESULT SystemProperties::getDefaultIoCacheSettingForStorageController(StorageControllerType_T aControllerType, + BOOL *aEnabled) +{ + /* no need to lock, this is const */ + switch (aControllerType) + { + case StorageControllerType_LsiLogic: + case StorageControllerType_BusLogic: + case StorageControllerType_IntelAhci: + case StorageControllerType_LsiLogicSas: + case StorageControllerType_USB: + case StorageControllerType_NVMe: + case StorageControllerType_VirtioSCSI: + *aEnabled = false; + break; + case StorageControllerType_PIIX3: + case StorageControllerType_PIIX4: + case StorageControllerType_ICH6: + case StorageControllerType_I82078: + *aEnabled = true; + break; + default: + AssertMsgFailed(("Invalid controller type %d\n", aControllerType)); + } + return S_OK; +} + +HRESULT SystemProperties::getStorageControllerHotplugCapable(StorageControllerType_T aControllerType, + BOOL *aHotplugCapable) +{ + switch (aControllerType) + { + case StorageControllerType_IntelAhci: + case StorageControllerType_USB: + *aHotplugCapable = true; + break; + case StorageControllerType_LsiLogic: + case StorageControllerType_LsiLogicSas: + case StorageControllerType_BusLogic: + case StorageControllerType_NVMe: + case StorageControllerType_VirtioSCSI: + case StorageControllerType_PIIX3: + case StorageControllerType_PIIX4: + case StorageControllerType_ICH6: + case StorageControllerType_I82078: + *aHotplugCapable = false; + break; + default: + AssertMsgFailedReturn(("Invalid controller type %d\n", aControllerType), E_FAIL); + } + + return S_OK; +} + +HRESULT SystemProperties::getMaxInstancesOfUSBControllerType(ChipsetType_T aChipset, + USBControllerType_T aType, + ULONG *aMaxInstances) +{ + NOREF(aChipset); + ULONG cCtrs = 0; + + /* no need to lock, this is const */ + switch (aType) + { + case USBControllerType_OHCI: + case USBControllerType_EHCI: + case USBControllerType_XHCI: + { + cCtrs = 1; + break; + } + default: + AssertMsgFailed(("Invalid bus type %d\n", aType)); + } + + *aMaxInstances = cCtrs; + + return S_OK; +} + +HRESULT SystemProperties::getCPUProfiles(CPUArchitecture_T aArchitecture, const com::Utf8Str &aNamePattern, + std::vector<ComPtr<ICPUProfile> > &aProfiles) +{ + /* + * Validate and adjust the architecture. + */ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + CPUArchitecture_T enmSecondaryArch = aArchitecture; + bool fLoaded; + switch (aArchitecture) + { + case CPUArchitecture_Any: + aArchitecture = CPUArchitecture_AMD64; + RT_FALL_THROUGH(); + case CPUArchitecture_AMD64: + enmSecondaryArch = CPUArchitecture_x86; + RT_FALL_THROUGH(); + case CPUArchitecture_x86: + fLoaded = m_fLoadedX86CPUProfiles; + break; + default: + return setError(E_INVALIDARG, tr("Invalid or unsupported architecture value: %d"), aArchitecture); + } + + /* + * Do we need to load the profiles? + */ + HRESULT hrc; + if (fLoaded) + hrc = S_OK; + else + { + alock.release(); + AutoWriteLock alockWrite(this COMMA_LOCKVAL_SRC_POS); + + /* + * Translate the architecture to a VMM module handle. + */ + const char *pszVMM; + switch (aArchitecture) + { + case CPUArchitecture_AMD64: + case CPUArchitecture_x86: + pszVMM = "VBoxVMM"; + fLoaded = m_fLoadedX86CPUProfiles; + break; + default: + AssertFailedReturn(E_INVALIDARG); + } + if (fLoaded) + hrc = S_OK; + else + { + char szPath[RTPATH_MAX]; + int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath)); + if (RT_SUCCESS(vrc)) + vrc = RTPathAppend(szPath, sizeof(szPath), pszVMM); + if (RT_SUCCESS(vrc)) + vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff()); + if (RT_SUCCESS(vrc)) + { + RTLDRMOD hMod = NIL_RTLDRMOD; + vrc = RTLdrLoad(szPath, &hMod); + if (RT_SUCCESS(vrc)) + { + /* + * Resolve the CPUMDb APIs we need. + */ + PFNCPUMDBGETENTRIES pfnGetEntries + = (PFNCPUMDBGETENTRIES)RTLdrGetFunction(hMod, "CPUMR3DbGetEntries"); + PFNCPUMDBGETENTRYBYINDEX pfnGetEntryByIndex + = (PFNCPUMDBGETENTRYBYINDEX)RTLdrGetFunction(hMod, "CPUMR3DbGetEntryByIndex"); + if (pfnGetEntries && pfnGetEntryByIndex) + { + size_t const cExistingProfiles = m_llCPUProfiles.size(); + + /* + * Instantate the profiles. + */ + hrc = S_OK; + uint32_t const cEntries = pfnGetEntries(); + for (uint32_t i = 0; i < cEntries; i++) + { + PCCPUMDBENTRY pDbEntry = pfnGetEntryByIndex(i); + AssertBreakStmt(pDbEntry, hrc = setError(E_UNEXPECTED, "CPUMR3DbGetEntryByIndex failed for %i", i)); + + ComObjPtr<CPUProfile> ptrProfile; + hrc = ptrProfile.createObject(); + if (SUCCEEDED(hrc)) + { + hrc = ptrProfile->initFromDbEntry(pDbEntry); + if (SUCCEEDED(hrc)) + { + try + { + m_llCPUProfiles.push_back(ptrProfile); + continue; + } + catch (std::bad_alloc &) + { + hrc = E_OUTOFMEMORY; + } + } + } + break; + } + + /* + * On success update the flag and retake the read lock. + * If we fail, drop the profiles we added to the list. + */ + if (SUCCEEDED(hrc)) + { + switch (aArchitecture) + { + case CPUArchitecture_AMD64: + case CPUArchitecture_x86: + m_fLoadedX86CPUProfiles = true; + break; + default: + AssertFailedStmt(hrc = E_INVALIDARG); + } + + alockWrite.release(); + alock.acquire(); + } + else + m_llCPUProfiles.resize(cExistingProfiles); + } + else + hrc = setErrorVrc(VERR_SYMBOL_NOT_FOUND, + tr("'%s' is missing symbols: CPUMR3DbGetEntries, CPUMR3DbGetEntryByIndex"), szPath); + RTLdrClose(hMod); + } + else + hrc = setErrorVrc(vrc, tr("Failed to construct load '%s': %Rrc"), szPath, vrc); + } + else + hrc = setErrorVrc(vrc, tr("Failed to construct path to the VMM DLL/Dylib/SharedObject: %Rrc"), vrc); + } + } + if (SUCCEEDED(hrc)) + { + /* + * Return the matching profiles. + */ + /* Count matches: */ + size_t cMatches = 0; + for (CPUProfileList_T::const_iterator it = m_llCPUProfiles.begin(); it != m_llCPUProfiles.end(); ++it) + if ((*it)->i_match(aArchitecture, enmSecondaryArch, aNamePattern)) + cMatches++; + + /* Resize the output array. */ + try + { + aProfiles.resize(cMatches); + } + catch (std::bad_alloc &) + { + aProfiles.resize(0); + hrc = E_OUTOFMEMORY; + } + + /* Get the return objects: */ + if (SUCCEEDED(hrc) && cMatches > 0) + { + size_t iMatch = 0; + for (CPUProfileList_T::const_iterator it = m_llCPUProfiles.begin(); it != m_llCPUProfiles.end(); ++it) + if ((*it)->i_match(aArchitecture, enmSecondaryArch, aNamePattern)) + { + AssertBreakStmt(iMatch < cMatches, hrc = E_UNEXPECTED); + hrc = (*it).queryInterfaceTo(aProfiles[iMatch].asOutParam()); + if (SUCCEEDED(hrc)) + iMatch++; + else + break; + } + AssertStmt(iMatch == cMatches || FAILED(hrc), hrc = E_UNEXPECTED); + } + } + return hrc; +} + + +HRESULT SystemProperties::getDefaultMachineFolder(com::Utf8Str &aDefaultMachineFolder) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + aDefaultMachineFolder = m->strDefaultMachineFolder; + return S_OK; +} + +HRESULT SystemProperties::setDefaultMachineFolder(const com::Utf8Str &aDefaultMachineFolder) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + HRESULT rc = i_setDefaultMachineFolder(aDefaultMachineFolder); + alock.release(); + if (SUCCEEDED(rc)) + { + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + rc = mParent->i_saveSettings(); + } + + return rc; +} + +HRESULT SystemProperties::getLoggingLevel(com::Utf8Str &aLoggingLevel) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + aLoggingLevel = m->strLoggingLevel; + + if (aLoggingLevel.isEmpty()) + aLoggingLevel = VBOXSVC_LOG_DEFAULT; + + return S_OK; +} + + +HRESULT SystemProperties::setLoggingLevel(const com::Utf8Str &aLoggingLevel) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + HRESULT rc = i_setLoggingLevel(aLoggingLevel); + alock.release(); + + if (SUCCEEDED(rc)) + { + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + rc = mParent->i_saveSettings(); + } + else + LogRel(("Cannot set passed logging level=%s, or the default one - Error=%Rhrc \n", aLoggingLevel.c_str(), rc)); + + return rc; +} + +HRESULT SystemProperties::getMediumFormats(std::vector<ComPtr<IMediumFormat> > &aMediumFormats) +{ + MediumFormatList mediumFormats(m_llMediumFormats); + aMediumFormats.resize(mediumFormats.size()); + size_t i = 0; + for (MediumFormatList::const_iterator it = mediumFormats.begin(); it != mediumFormats.end(); ++it, ++i) + (*it).queryInterfaceTo(aMediumFormats[i].asOutParam()); + return S_OK; +} + +HRESULT SystemProperties::getDefaultHardDiskFormat(com::Utf8Str &aDefaultHardDiskFormat) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + aDefaultHardDiskFormat = m->strDefaultHardDiskFormat; + return S_OK; +} + + +HRESULT SystemProperties::setDefaultHardDiskFormat(const com::Utf8Str &aDefaultHardDiskFormat) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + HRESULT rc = i_setDefaultHardDiskFormat(aDefaultHardDiskFormat); + alock.release(); + if (SUCCEEDED(rc)) + { + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + rc = mParent->i_saveSettings(); + } + + return rc; +} + +HRESULT SystemProperties::getFreeDiskSpaceWarning(LONG64 *aFreeSpace) +{ + NOREF(aFreeSpace); + ReturnComNotImplemented(); +} + +HRESULT SystemProperties::setFreeDiskSpaceWarning(LONG64 /* aFreeSpace */) +{ + ReturnComNotImplemented(); +} + +HRESULT SystemProperties::getFreeDiskSpacePercentWarning(ULONG *aFreeSpacePercent) +{ + NOREF(aFreeSpacePercent); + ReturnComNotImplemented(); +} + +HRESULT SystemProperties::setFreeDiskSpacePercentWarning(ULONG /* aFreeSpacePercent */) +{ + ReturnComNotImplemented(); +} + +HRESULT SystemProperties::getFreeDiskSpaceError(LONG64 *aFreeSpace) +{ + NOREF(aFreeSpace); + ReturnComNotImplemented(); +} + +HRESULT SystemProperties::setFreeDiskSpaceError(LONG64 /* aFreeSpace */) +{ + ReturnComNotImplemented(); +} + +HRESULT SystemProperties::getFreeDiskSpacePercentError(ULONG *aFreeSpacePercent) +{ + NOREF(aFreeSpacePercent); + ReturnComNotImplemented(); +} + +HRESULT SystemProperties::setFreeDiskSpacePercentError(ULONG /* aFreeSpacePercent */) +{ + ReturnComNotImplemented(); +} + +HRESULT SystemProperties::getVRDEAuthLibrary(com::Utf8Str &aVRDEAuthLibrary) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + aVRDEAuthLibrary = m->strVRDEAuthLibrary; + + return S_OK; +} + +HRESULT SystemProperties::setVRDEAuthLibrary(const com::Utf8Str &aVRDEAuthLibrary) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + HRESULT rc = i_setVRDEAuthLibrary(aVRDEAuthLibrary); + alock.release(); + if (SUCCEEDED(rc)) + { + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + rc = mParent->i_saveSettings(); + } + + return rc; +} + +HRESULT SystemProperties::getWebServiceAuthLibrary(com::Utf8Str &aWebServiceAuthLibrary) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + aWebServiceAuthLibrary = m->strWebServiceAuthLibrary; + + return S_OK; +} + +HRESULT SystemProperties::setWebServiceAuthLibrary(const com::Utf8Str &aWebServiceAuthLibrary) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + HRESULT rc = i_setWebServiceAuthLibrary(aWebServiceAuthLibrary); + alock.release(); + + if (SUCCEEDED(rc)) + { + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + rc = mParent->i_saveSettings(); + } + + return rc; +} + +HRESULT SystemProperties::getDefaultVRDEExtPack(com::Utf8Str &aExtPack) +{ + HRESULT hrc = S_OK; + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + Utf8Str strExtPack(m->strDefaultVRDEExtPack); + if (strExtPack.isNotEmpty()) + { + if (strExtPack.equals(VBOXVRDP_KLUDGE_EXTPACK_NAME)) + hrc = S_OK; + else +#ifdef VBOX_WITH_EXTPACK + hrc = mParent->i_getExtPackManager()->i_checkVrdeExtPack(&strExtPack); +#else + hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), strExtPack.c_str()); +#endif + } + else + { +#ifdef VBOX_WITH_EXTPACK + hrc = mParent->i_getExtPackManager()->i_getDefaultVrdeExtPack(&strExtPack); +#endif + if (strExtPack.isEmpty()) + { + /* + * Klugde - check if VBoxVRDP.dll/.so/.dylib is installed. + * This is hardcoded uglyness, sorry. + */ + char szPath[RTPATH_MAX]; + int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath)); + if (RT_SUCCESS(vrc)) + vrc = RTPathAppend(szPath, sizeof(szPath), "VBoxVRDP"); + if (RT_SUCCESS(vrc)) + vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff()); + if (RT_SUCCESS(vrc) && RTFileExists(szPath)) + { + /* Illegal extpack name, so no conflict. */ + strExtPack = VBOXVRDP_KLUDGE_EXTPACK_NAME; + } + } + } + + if (SUCCEEDED(hrc)) + aExtPack = strExtPack; + + return S_OK; +} + + +HRESULT SystemProperties::setDefaultVRDEExtPack(const com::Utf8Str &aExtPack) +{ + HRESULT hrc = S_OK; + if (aExtPack.isNotEmpty()) + { + if (aExtPack.equals(VBOXVRDP_KLUDGE_EXTPACK_NAME)) + hrc = S_OK; + else +#ifdef VBOX_WITH_EXTPACK + hrc = mParent->i_getExtPackManager()->i_checkVrdeExtPack(&aExtPack); +#else + hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), aExtPack.c_str()); +#endif + } + if (SUCCEEDED(hrc)) + { + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + hrc = i_setDefaultVRDEExtPack(aExtPack); + if (SUCCEEDED(hrc)) + { + /* VirtualBox::i_saveSettings() needs the VirtualBox write lock. */ + alock.release(); + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + hrc = mParent->i_saveSettings(); + } + } + + return hrc; +} + + +HRESULT SystemProperties::getDefaultCryptoExtPack(com::Utf8Str &aExtPack) +{ + HRESULT hrc = S_OK; + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + Utf8Str strExtPack(m->strDefaultCryptoExtPack); + if (strExtPack.isNotEmpty()) + { + if (strExtPack.equals(VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME)) + hrc = S_OK; + else +#ifdef VBOX_WITH_EXTPACK + hrc = mParent->i_getExtPackManager()->i_checkCryptoExtPack(&strExtPack); +#else + hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), strExtPack.c_str()); +#endif + } + else + { +#ifdef VBOX_WITH_EXTPACK + hrc = mParent->i_getExtPackManager()->i_getDefaultCryptoExtPack(&strExtPack); +#endif + if (strExtPack.isEmpty()) + { + /* + * Klugde - check if VBoxPuelCrypto.dll/.so/.dylib is installed. + * This is hardcoded uglyness, sorry. + */ + char szPath[RTPATH_MAX]; + int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath)); + if (RT_SUCCESS(vrc)) + vrc = RTPathAppend(szPath, sizeof(szPath), "VBoxPuelCrypto"); + if (RT_SUCCESS(vrc)) + vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff()); + if (RT_SUCCESS(vrc) && RTFileExists(szPath)) + { + /* Illegal extpack name, so no conflict. */ + strExtPack = VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME; + } + } + } + + if (SUCCEEDED(hrc)) + aExtPack = strExtPack; + + return S_OK; +} + + +HRESULT SystemProperties::setDefaultCryptoExtPack(const com::Utf8Str &aExtPack) +{ + HRESULT hrc = S_OK; + if (aExtPack.isNotEmpty()) + { + if (aExtPack.equals(VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME)) + hrc = S_OK; + else +#ifdef VBOX_WITH_EXTPACK + hrc = mParent->i_getExtPackManager()->i_checkCryptoExtPack(&aExtPack); +#else + hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), aExtPack.c_str()); +#endif + } + if (SUCCEEDED(hrc)) + { + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + hrc = i_setDefaultCryptoExtPack(aExtPack); + if (SUCCEEDED(hrc)) + { + /* VirtualBox::i_saveSettings() needs the VirtualBox write lock. */ + alock.release(); + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + hrc = mParent->i_saveSettings(); + } + } + + return hrc; +} + + +HRESULT SystemProperties::getLogHistoryCount(ULONG *count) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + *count = m->uLogHistoryCount; + + return S_OK; +} + + +HRESULT SystemProperties::setLogHistoryCount(ULONG count) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + m->uLogHistoryCount = count; + alock.release(); + + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + HRESULT rc = mParent->i_saveSettings(); + + return rc; +} + +HRESULT SystemProperties::getDefaultAudioDriver(AudioDriverType_T *aAudioDriver) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + *aAudioDriver = settings::MachineConfigFile::getHostDefaultAudioDriver(); + + return S_OK; +} + +HRESULT SystemProperties::getAutostartDatabasePath(com::Utf8Str &aAutostartDbPath) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + aAutostartDbPath = m->strAutostartDatabasePath; + + return S_OK; +} + +HRESULT SystemProperties::setAutostartDatabasePath(const com::Utf8Str &aAutostartDbPath) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + HRESULT rc = i_setAutostartDatabasePath(aAutostartDbPath); + alock.release(); + + if (SUCCEEDED(rc)) + { + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + rc = mParent->i_saveSettings(); + } + + return rc; +} + +HRESULT SystemProperties::getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO) +{ + return i_getDefaultAdditionsISO(aDefaultAdditionsISO); +} + +HRESULT SystemProperties::setDefaultAdditionsISO(const com::Utf8Str &aDefaultAdditionsISO) +{ + RT_NOREF(aDefaultAdditionsISO); + /** @todo not yet implemented, settings handling is missing */ + ReturnComNotImplemented(); +#if 0 /* not implemented */ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + HRESULT rc = i_setDefaultAdditionsISO(aDefaultAdditionsISO); + alock.release(); + + if (SUCCEEDED(rc)) + { + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + rc = mParent->i_saveSettings(); + } + + return rc; +#endif +} + +HRESULT SystemProperties::getDefaultFrontend(com::Utf8Str &aDefaultFrontend) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + aDefaultFrontend = m->strDefaultFrontend; + return S_OK; +} + +HRESULT SystemProperties::setDefaultFrontend(const com::Utf8Str &aDefaultFrontend) +{ + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + if (m->strDefaultFrontend == aDefaultFrontend) + return S_OK; + HRESULT rc = i_setDefaultFrontend(aDefaultFrontend); + alock.release(); + + if (SUCCEEDED(rc)) + { + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + rc = mParent->i_saveSettings(); + } + + return rc; +} + +HRESULT SystemProperties::getScreenShotFormats(std::vector<BitmapFormat_T> &aBitmapFormats) +{ + aBitmapFormats.push_back(BitmapFormat_BGR0); + aBitmapFormats.push_back(BitmapFormat_BGRA); + aBitmapFormats.push_back(BitmapFormat_RGBA); + aBitmapFormats.push_back(BitmapFormat_PNG); + return S_OK; +} + +HRESULT SystemProperties::getProxyMode(ProxyMode_T *pProxyMode) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + ProxyMode_T enmMode = *pProxyMode = (ProxyMode_T)m->uProxyMode; + AssertMsgReturn(enmMode == ProxyMode_System || enmMode == ProxyMode_NoProxy || enmMode == ProxyMode_Manual, + ("enmMode=%d\n", enmMode), E_UNEXPECTED); + return S_OK; +} + +HRESULT SystemProperties::setProxyMode(ProxyMode_T aProxyMode) +{ + /* Validate input. */ + switch (aProxyMode) + { + case ProxyMode_System: + case ProxyMode_NoProxy: + case ProxyMode_Manual: + break; + default: + return setError(E_INVALIDARG, tr("Invalid ProxyMode value: %d"), (int)aProxyMode); + } + + /* Set and write out settings. */ + { + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + m->uProxyMode = aProxyMode; + } + AutoWriteLock alock(mParent COMMA_LOCKVAL_SRC_POS); /* required for saving. */ + return mParent->i_saveSettings(); +} + +HRESULT SystemProperties::getProxyURL(com::Utf8Str &aProxyURL) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + aProxyURL = m->strProxyUrl; + return S_OK; +} + +HRESULT SystemProperties::setProxyURL(const com::Utf8Str &aProxyURL) +{ + /* + * Validate input. + */ + Utf8Str const *pStrProxyUrl = &aProxyURL; + Utf8Str strTmp; + if (pStrProxyUrl->isNotEmpty()) + { + /* RTUriParse requires a scheme, so append 'http://' if none seems present: */ + if (pStrProxyUrl->find("://") == RTCString::npos) + { + strTmp.printf("http://%s", aProxyURL.c_str()); + pStrProxyUrl = &strTmp; + } + + /* Use RTUriParse to check the format. There must be a hostname, but nothing + can follow it and the port. */ + RTURIPARSED Parsed; + int vrc = RTUriParse(pStrProxyUrl->c_str(), &Parsed); + if (RT_FAILURE(vrc)) + return setErrorBoth(E_INVALIDARG, vrc, tr("Failed to parse proxy URL: %Rrc"), vrc); + if ( Parsed.cchAuthorityHost == 0 + && !RTUriIsSchemeMatch(pStrProxyUrl->c_str(), "direct")) + return setError(E_INVALIDARG, tr("Proxy URL must include a hostname")); + if (Parsed.cchPath > 0) + return setError(E_INVALIDARG, tr("Proxy URL must not include a path component (%.*s)"), + Parsed.cchPath, pStrProxyUrl->c_str() + Parsed.offPath); + if (Parsed.cchQuery > 0) + return setError(E_INVALIDARG, tr("Proxy URL must not include a query component (?%.*s)"), + Parsed.cchQuery, pStrProxyUrl->c_str() + Parsed.offQuery); + if (Parsed.cchFragment > 0) + return setError(E_INVALIDARG, tr("Proxy URL must not include a fragment component (#%.*s)"), + Parsed.cchFragment, pStrProxyUrl->c_str() + Parsed.offFragment); + } + + /* + * Set and write out settings. + */ + { + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + m->strProxyUrl = *pStrProxyUrl; + } + AutoWriteLock alock(mParent COMMA_LOCKVAL_SRC_POS); /* required for saving. */ + return mParent->i_saveSettings(); +} + +HRESULT SystemProperties::getSupportedParavirtProviders(std::vector<ParavirtProvider_T> &aSupportedParavirtProviders) +{ + static const ParavirtProvider_T aParavirtProviders[] = + { + ParavirtProvider_None, + ParavirtProvider_Default, + ParavirtProvider_Legacy, + ParavirtProvider_Minimal, + ParavirtProvider_HyperV, + ParavirtProvider_KVM, + }; + aSupportedParavirtProviders.assign(aParavirtProviders, + aParavirtProviders + RT_ELEMENTS(aParavirtProviders)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedClipboardModes(std::vector<ClipboardMode_T> &aSupportedClipboardModes) +{ + static const ClipboardMode_T aClipboardModes[] = + { + ClipboardMode_Disabled, + ClipboardMode_HostToGuest, + ClipboardMode_GuestToHost, + ClipboardMode_Bidirectional, + }; + aSupportedClipboardModes.assign(aClipboardModes, + aClipboardModes + RT_ELEMENTS(aClipboardModes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedDnDModes(std::vector<DnDMode_T> &aSupportedDnDModes) +{ + static const DnDMode_T aDnDModes[] = + { + DnDMode_Disabled, + DnDMode_HostToGuest, + DnDMode_GuestToHost, + DnDMode_Bidirectional, + }; + aSupportedDnDModes.assign(aDnDModes, + aDnDModes + RT_ELEMENTS(aDnDModes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedFirmwareTypes(std::vector<FirmwareType_T> &aSupportedFirmwareTypes) +{ + static const FirmwareType_T aFirmwareTypes[] = + { + FirmwareType_BIOS, + FirmwareType_EFI, + FirmwareType_EFI32, + FirmwareType_EFI64, + FirmwareType_EFIDUAL, + }; + aSupportedFirmwareTypes.assign(aFirmwareTypes, + aFirmwareTypes + RT_ELEMENTS(aFirmwareTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedPointingHIDTypes(std::vector<PointingHIDType_T> &aSupportedPointingHIDTypes) +{ + static const PointingHIDType_T aPointingHIDTypes[] = + { + PointingHIDType_PS2Mouse, +#ifdef DEBUG + PointingHIDType_USBMouse, +#endif + PointingHIDType_USBTablet, +#ifdef DEBUG + PointingHIDType_ComboMouse, +#endif + PointingHIDType_USBMultiTouch, + PointingHIDType_USBMultiTouchScreenPlusPad, + }; + aSupportedPointingHIDTypes.assign(aPointingHIDTypes, + aPointingHIDTypes + RT_ELEMENTS(aPointingHIDTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedKeyboardHIDTypes(std::vector<KeyboardHIDType_T> &aSupportedKeyboardHIDTypes) +{ + static const KeyboardHIDType_T aKeyboardHIDTypes[] = + { + KeyboardHIDType_PS2Keyboard, + KeyboardHIDType_USBKeyboard, +#ifdef DEBUG + KeyboardHIDType_ComboKeyboard, +#endif + }; + aSupportedKeyboardHIDTypes.assign(aKeyboardHIDTypes, + aKeyboardHIDTypes + RT_ELEMENTS(aKeyboardHIDTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedVFSTypes(std::vector<VFSType_T> &aSupportedVFSTypes) +{ + static const VFSType_T aVFSTypes[] = + { + VFSType_File, + VFSType_Cloud, + VFSType_S3, +#ifdef DEBUG + VFSType_WebDav, +#endif + }; + aSupportedVFSTypes.assign(aVFSTypes, + aVFSTypes + RT_ELEMENTS(aVFSTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedImportOptions(std::vector<ImportOptions_T> &aSupportedImportOptions) +{ + static const ImportOptions_T aImportOptions[] = + { + ImportOptions_KeepAllMACs, + ImportOptions_KeepNATMACs, + ImportOptions_ImportToVDI, + }; + aSupportedImportOptions.assign(aImportOptions, + aImportOptions + RT_ELEMENTS(aImportOptions)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedExportOptions(std::vector<ExportOptions_T> &aSupportedExportOptions) +{ + static const ExportOptions_T aExportOptions[] = + { + ExportOptions_CreateManifest, + ExportOptions_ExportDVDImages, + ExportOptions_StripAllMACs, + ExportOptions_StripAllNonNATMACs, + }; + aSupportedExportOptions.assign(aExportOptions, + aExportOptions + RT_ELEMENTS(aExportOptions)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedRecordingFeatures(std::vector<RecordingFeature_T> &aSupportedRecordingFeatures) +{ +#ifdef VBOX_WITH_RECORDING + static const RecordingFeature_T aRecordingFeatures[] = + { +# ifdef VBOX_WITH_AUDIO_RECORDING + RecordingFeature_Audio, +# endif + RecordingFeature_Video, + }; + aSupportedRecordingFeatures.assign(aRecordingFeatures, + aRecordingFeatures + RT_ELEMENTS(aRecordingFeatures)); +#else /* !VBOX_WITH_RECORDING */ + aSupportedRecordingFeatures.clear(); +#endif /* VBOX_WITH_RECORDING */ + return S_OK; +} + +HRESULT SystemProperties::getSupportedRecordingAudioCodecs(std::vector<RecordingAudioCodec_T> &aSupportedRecordingAudioCodecs) +{ + static const RecordingAudioCodec_T aRecordingAudioCodecs[] = + { + RecordingAudioCodec_None, +#ifdef DEBUG + RecordingAudioCodec_WavPCM, +#endif +#ifdef VBOX_WITH_LIBVORBIS + RecordingAudioCodec_OggVorbis, +#endif + }; + aSupportedRecordingAudioCodecs.assign(aRecordingAudioCodecs, + aRecordingAudioCodecs + RT_ELEMENTS(aRecordingAudioCodecs)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedRecordingVideoCodecs(std::vector<RecordingVideoCodec_T> &aSupportedRecordingVideoCodecs) +{ + static const RecordingVideoCodec_T aRecordingVideoCodecs[] = + { + RecordingVideoCodec_None, +#ifdef VBOX_WITH_LIBVPX + RecordingVideoCodec_VP8, +#endif +#ifdef DEBUG + RecordingVideoCodec_VP9, + RecordingVideoCodec_AV1, +#endif + }; + aSupportedRecordingVideoCodecs.assign(aRecordingVideoCodecs, + aRecordingVideoCodecs + RT_ELEMENTS(aRecordingVideoCodecs)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedRecordingVSModes(std::vector<RecordingVideoScalingMode_T> &aSupportedRecordingVideoScalingModes) +{ + static const RecordingVideoScalingMode_T aRecordingVideoScalingModes[] = + { + RecordingVideoScalingMode_None, +#ifdef DEBUG + RecordingVideoScalingMode_NearestNeighbor, + RecordingVideoScalingMode_Bilinear, + RecordingVideoScalingMode_Bicubic, +#endif + }; + aSupportedRecordingVideoScalingModes.assign(aRecordingVideoScalingModes, + aRecordingVideoScalingModes + RT_ELEMENTS(aRecordingVideoScalingModes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedRecordingARCModes(std::vector<RecordingRateControlMode_T> &aSupportedRecordingAudioRateControlModes) +{ + static const RecordingRateControlMode_T aRecordingAudioRateControlModes[] = + { +#ifdef DEBUG + RecordingRateControlMode_ABR, + RecordingRateControlMode_CBR, +#endif + RecordingRateControlMode_VBR + }; + aSupportedRecordingAudioRateControlModes.assign(aRecordingAudioRateControlModes, + aRecordingAudioRateControlModes + RT_ELEMENTS(aRecordingAudioRateControlModes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedRecordingVRCModes(std::vector<RecordingRateControlMode_T> &aSupportedRecordingVideoRateControlModes) +{ + static const RecordingRateControlMode_T aRecordingVideoRateControlModes[] = + { +#ifdef DEBUG + RecordingRateControlMode_ABR, + RecordingRateControlMode_CBR, +#endif + RecordingRateControlMode_VBR + }; + aSupportedRecordingVideoRateControlModes.assign(aRecordingVideoRateControlModes, + aRecordingVideoRateControlModes + RT_ELEMENTS(aRecordingVideoRateControlModes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedGraphicsControllerTypes(std::vector<GraphicsControllerType_T> &aSupportedGraphicsControllerTypes) +{ + static const GraphicsControllerType_T aGraphicsControllerTypes[] = + { + GraphicsControllerType_VBoxVGA, + GraphicsControllerType_VMSVGA, + GraphicsControllerType_VBoxSVGA, + GraphicsControllerType_Null, + }; + aSupportedGraphicsControllerTypes.assign(aGraphicsControllerTypes, + aGraphicsControllerTypes + RT_ELEMENTS(aGraphicsControllerTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedCloneOptions(std::vector<CloneOptions_T> &aSupportedCloneOptions) +{ + static const CloneOptions_T aCloneOptions[] = + { + CloneOptions_Link, + CloneOptions_KeepAllMACs, + CloneOptions_KeepNATMACs, + CloneOptions_KeepDiskNames, + CloneOptions_KeepHwUUIDs, + }; + aSupportedCloneOptions.assign(aCloneOptions, + aCloneOptions + RT_ELEMENTS(aCloneOptions)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedAutostopTypes(std::vector<AutostopType_T> &aSupportedAutostopTypes) +{ + static const AutostopType_T aAutostopTypes[] = + { + AutostopType_Disabled, + AutostopType_SaveState, + AutostopType_PowerOff, + AutostopType_AcpiShutdown, + }; + aSupportedAutostopTypes.assign(aAutostopTypes, + aAutostopTypes + RT_ELEMENTS(aAutostopTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedVMProcPriorities(std::vector<VMProcPriority_T> &aSupportedVMProcPriorities) +{ + static const VMProcPriority_T aVMProcPriorities[] = + { + VMProcPriority_Default, + VMProcPriority_Flat, + VMProcPriority_Low, + VMProcPriority_Normal, + VMProcPriority_High, + }; + aSupportedVMProcPriorities.assign(aVMProcPriorities, + aVMProcPriorities + RT_ELEMENTS(aVMProcPriorities)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedNetworkAttachmentTypes(std::vector<NetworkAttachmentType_T> &aSupportedNetworkAttachmentTypes) +{ + static const NetworkAttachmentType_T aNetworkAttachmentTypes[] = + { + NetworkAttachmentType_NAT, + NetworkAttachmentType_Bridged, + NetworkAttachmentType_Internal, + NetworkAttachmentType_HostOnly, +#ifdef VBOX_WITH_VMNET + NetworkAttachmentType_HostOnlyNetwork, +#endif /* VBOX_WITH_VMNET */ + NetworkAttachmentType_Generic, + NetworkAttachmentType_NATNetwork, +#ifdef VBOX_WITH_CLOUD_NET + NetworkAttachmentType_Cloud, +#endif + NetworkAttachmentType_Null, + }; + aSupportedNetworkAttachmentTypes.assign(aNetworkAttachmentTypes, + aNetworkAttachmentTypes + RT_ELEMENTS(aNetworkAttachmentTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedNetworkAdapterTypes(std::vector<NetworkAdapterType_T> &aSupportedNetworkAdapterTypes) +{ + static const NetworkAdapterType_T aNetworkAdapterTypes[] = + { + NetworkAdapterType_Am79C970A, + NetworkAdapterType_Am79C973, + NetworkAdapterType_I82540EM, + NetworkAdapterType_I82543GC, + NetworkAdapterType_I82545EM, + NetworkAdapterType_Virtio, + }; + aSupportedNetworkAdapterTypes.assign(aNetworkAdapterTypes, + aNetworkAdapterTypes + RT_ELEMENTS(aNetworkAdapterTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedPortModes(std::vector<PortMode_T> &aSupportedPortModes) +{ + static const PortMode_T aPortModes[] = + { + PortMode_Disconnected, + PortMode_HostPipe, + PortMode_HostDevice, + PortMode_RawFile, + PortMode_TCP, + }; + aSupportedPortModes.assign(aPortModes, + aPortModes + RT_ELEMENTS(aPortModes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedUartTypes(std::vector<UartType_T> &aSupportedUartTypes) +{ + static const UartType_T aUartTypes[] = + { + UartType_U16450, + UartType_U16550A, + UartType_U16750, + }; + aSupportedUartTypes.assign(aUartTypes, + aUartTypes + RT_ELEMENTS(aUartTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedUSBControllerTypes(std::vector<USBControllerType_T> &aSupportedUSBControllerTypes) +{ + static const USBControllerType_T aUSBControllerTypes[] = + { + USBControllerType_OHCI, + USBControllerType_EHCI, + USBControllerType_XHCI, + }; + aSupportedUSBControllerTypes.assign(aUSBControllerTypes, + aUSBControllerTypes + RT_ELEMENTS(aUSBControllerTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedAudioDriverTypes(std::vector<AudioDriverType_T> &aSupportedAudioDriverTypes) +{ + static const AudioDriverType_T aAudioDriverTypes[] = + { + AudioDriverType_Default, +#ifdef RT_OS_WINDOWS +# if 0 /* deprecated for many years now */ + AudioDriverType_WinMM, +# endif + AudioDriverType_WAS, + AudioDriverType_DirectSound, +#endif +#ifdef RT_OS_DARWIN + AudioDriverType_CoreAudio, +#endif +#ifdef RT_OS_OS2 + AudioDriverType_MMPM, +#endif +#ifdef RT_OS_SOLARIS +# if 0 /* deprecated for many years now */ + AudioDriverType_SolAudio, +# endif +#endif +#ifdef VBOX_WITH_AUDIO_ALSA + AudioDriverType_ALSA, +#endif +#ifdef VBOX_WITH_AUDIO_OSS + AudioDriverType_OSS, +#endif +#ifdef VBOX_WITH_AUDIO_PULSE + AudioDriverType_Pulse, +#endif + AudioDriverType_Null, + }; + aSupportedAudioDriverTypes.assign(aAudioDriverTypes, + aAudioDriverTypes + RT_ELEMENTS(aAudioDriverTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedAudioControllerTypes(std::vector<AudioControllerType_T> &aSupportedAudioControllerTypes) +{ + static const AudioControllerType_T aAudioControllerTypes[] = + { + AudioControllerType_AC97, + AudioControllerType_SB16, + AudioControllerType_HDA, + }; + aSupportedAudioControllerTypes.assign(aAudioControllerTypes, + aAudioControllerTypes + RT_ELEMENTS(aAudioControllerTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedStorageBuses(std::vector<StorageBus_T> &aSupportedStorageBuses) +{ + static const StorageBus_T aStorageBuses[] = + { + StorageBus_SATA, + StorageBus_IDE, + StorageBus_SCSI, + StorageBus_Floppy, + StorageBus_SAS, + StorageBus_USB, + StorageBus_PCIe, + StorageBus_VirtioSCSI, + }; + aSupportedStorageBuses.assign(aStorageBuses, + aStorageBuses + RT_ELEMENTS(aStorageBuses)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedStorageControllerTypes(std::vector<StorageControllerType_T> &aSupportedStorageControllerTypes) +{ + static const StorageControllerType_T aStorageControllerTypes[] = + { + StorageControllerType_IntelAhci, + StorageControllerType_PIIX4, + StorageControllerType_PIIX3, + StorageControllerType_ICH6, + StorageControllerType_LsiLogic, + StorageControllerType_BusLogic, + StorageControllerType_I82078, + StorageControllerType_LsiLogicSas, + StorageControllerType_USB, + StorageControllerType_NVMe, + StorageControllerType_VirtioSCSI, + }; + aSupportedStorageControllerTypes.assign(aStorageControllerTypes, + aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedChipsetTypes(std::vector<ChipsetType_T> &aSupportedChipsetTypes) +{ + static const ChipsetType_T aChipsetTypes[] = + { + ChipsetType_PIIX3, + ChipsetType_ICH9, + }; + aSupportedChipsetTypes.assign(aChipsetTypes, + aChipsetTypes + RT_ELEMENTS(aChipsetTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedIommuTypes(std::vector<IommuType_T> &aSupportedIommuTypes) +{ + static const IommuType_T aIommuTypes[] = + { + IommuType_None, + IommuType_Automatic, + IommuType_AMD, + /** @todo Add Intel when it's supported. */ + }; + aSupportedIommuTypes.assign(aIommuTypes, + aIommuTypes + RT_ELEMENTS(aIommuTypes)); + return S_OK; +} + +HRESULT SystemProperties::getSupportedTpmTypes(std::vector<TpmType_T> &aSupportedTpmTypes) +{ + static const TpmType_T aTpmTypes[] = + { + TpmType_None, + TpmType_v1_2, + TpmType_v2_0 + }; + aSupportedTpmTypes.assign(aTpmTypes, + aTpmTypes + RT_ELEMENTS(aTpmTypes)); + return S_OK; +} + + +// public methods only for internal purposes +///////////////////////////////////////////////////////////////////////////// + +HRESULT SystemProperties::i_loadSettings(const settings::SystemProperties &data) +{ + AutoCaller autoCaller(this); + if (FAILED(autoCaller.rc())) return autoCaller.rc(); + + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + HRESULT rc = S_OK; + rc = i_setDefaultMachineFolder(data.strDefaultMachineFolder); + if (FAILED(rc)) return rc; + + rc = i_setLoggingLevel(data.strLoggingLevel); + if (FAILED(rc)) return rc; + + rc = i_setDefaultHardDiskFormat(data.strDefaultHardDiskFormat); + if (FAILED(rc)) return rc; + + rc = i_setVRDEAuthLibrary(data.strVRDEAuthLibrary); + if (FAILED(rc)) return rc; + + rc = i_setWebServiceAuthLibrary(data.strWebServiceAuthLibrary); + if (FAILED(rc)) return rc; + + rc = i_setDefaultVRDEExtPack(data.strDefaultVRDEExtPack); + if (FAILED(rc)) return rc; + + rc = i_setDefaultCryptoExtPack(data.strDefaultCryptoExtPack); + if (FAILED(rc)) return rc; + + m->uLogHistoryCount = data.uLogHistoryCount; + m->fExclusiveHwVirt = data.fExclusiveHwVirt; + m->uProxyMode = data.uProxyMode; + m->strProxyUrl = data.strProxyUrl; + + m->strLanguageId = data.strLanguageId; + + rc = i_setAutostartDatabasePath(data.strAutostartDatabasePath); + if (FAILED(rc)) return rc; + + { + /* must ignore errors signalled here, because the guest additions + * file may not exist, and in this case keep the empty string */ + ErrorInfoKeeper eik; + (void)i_setDefaultAdditionsISO(data.strDefaultAdditionsISO); + } + + rc = i_setDefaultFrontend(data.strDefaultFrontend); + if (FAILED(rc)) return rc; + + return S_OK; +} + +HRESULT SystemProperties::i_saveSettings(settings::SystemProperties &data) +{ + AutoCaller autoCaller(this); + if (FAILED(autoCaller.rc())) return autoCaller.rc(); + + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + data = *m; + + return S_OK; +} + +/** + * Returns a medium format object corresponding to the given format + * identifier or null if no such format. + * + * @param aFormat Format identifier. + * + * @return ComObjPtr<MediumFormat> + */ +ComObjPtr<MediumFormat> SystemProperties::i_mediumFormat(const Utf8Str &aFormat) +{ + ComObjPtr<MediumFormat> format; + + AutoCaller autoCaller(this); + AssertComRCReturn (autoCaller.rc(), format); + + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + for (MediumFormatList::const_iterator it = m_llMediumFormats.begin(); + it != m_llMediumFormats.end(); + ++ it) + { + /* MediumFormat is all const, no need to lock */ + + if ((*it)->i_getId().compare(aFormat, Utf8Str::CaseInsensitive) == 0) + { + format = *it; + break; + } + } + + return format; +} + +/** + * Returns a medium format object corresponding to the given file extension or + * null if no such format. + * + * @param aExt File extension. + * + * @return ComObjPtr<MediumFormat> + */ +ComObjPtr<MediumFormat> SystemProperties::i_mediumFormatFromExtension(const Utf8Str &aExt) +{ + ComObjPtr<MediumFormat> format; + + AutoCaller autoCaller(this); + AssertComRCReturn (autoCaller.rc(), format); + + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + + bool fFound = false; + for (MediumFormatList::const_iterator it = m_llMediumFormats.begin(); + it != m_llMediumFormats.end() && !fFound; + ++it) + { + /* MediumFormat is all const, no need to lock */ + MediumFormat::StrArray aFileList = (*it)->i_getFileExtensions(); + for (MediumFormat::StrArray::const_iterator it1 = aFileList.begin(); + it1 != aFileList.end(); + ++it1) + { + if ((*it1).compare(aExt, Utf8Str::CaseInsensitive) == 0) + { + format = *it; + fFound = true; + break; + } + } + } + + return format; +} + + +/** + * VD plugin load + */ +int SystemProperties::i_loadVDPlugin(const char *pszPluginLibrary) +{ + int vrc = VDPluginLoadFromFilename(pszPluginLibrary); + LogFlowFunc(("pszPluginLibrary='%s' -> %Rrc\n", pszPluginLibrary, vrc)); + return vrc; +} + +/** + * VD plugin unload + */ +int SystemProperties::i_unloadVDPlugin(const char *pszPluginLibrary) +{ + int vrc = VDPluginUnloadFromFilename(pszPluginLibrary); + LogFlowFunc(("pszPluginLibrary='%s' -> %Rrc\n", pszPluginLibrary, vrc)); + return vrc; +} + +/** + * Internally usable version of getDefaultAdditionsISO. + */ +HRESULT SystemProperties::i_getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO) +{ + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + if (m->strDefaultAdditionsISO.isNotEmpty()) + aDefaultAdditionsISO = m->strDefaultAdditionsISO; + else + { + /* no guest additions, check if it showed up in the mean time */ + alock.release(); + AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS); + if (m->strDefaultAdditionsISO.isEmpty()) + { + ErrorInfoKeeper eik; + (void)i_setDefaultAdditionsISO(""); + } + aDefaultAdditionsISO = m->strDefaultAdditionsISO; + } + return S_OK; +} + +// private methods +///////////////////////////////////////////////////////////////////////////// + +/** + * Returns the user's home directory. Wrapper around RTPathUserHome(). + * @param strPath + * @return + */ +HRESULT SystemProperties::i_getUserHomeDirectory(Utf8Str &strPath) +{ + char szHome[RTPATH_MAX]; + int vrc = RTPathUserHome(szHome, sizeof(szHome)); + if (RT_FAILURE(vrc)) + return setErrorBoth(E_FAIL, vrc, + tr("Cannot determine user home directory (%Rrc)"), + vrc); + strPath = szHome; + return S_OK; +} + +/** + * Internal implementation to set the default machine folder. Gets called + * from the public attribute setter as well as loadSettings(). With 4.0, + * the "default default" machine folder has changed, and we now require + * a full path always. + * @param strPath + * @return + */ +HRESULT SystemProperties::i_setDefaultMachineFolder(const Utf8Str &strPath) +{ + Utf8Str path(strPath); // make modifiable + if ( path.isEmpty() // used by API calls to reset the default + || path == "Machines" // this value (exactly like this, without path) is stored + // in VirtualBox.xml if user upgrades from before 4.0 and + // has not changed the default machine folder + ) + { + // new default with VirtualBox 4.0: "$HOME/VirtualBox VMs" + HRESULT rc = i_getUserHomeDirectory(path); + if (FAILED(rc)) return rc; + path += RTPATH_SLASH_STR "VirtualBox VMs"; + } + + if (!RTPathStartsWithRoot(path.c_str())) + return setError(E_INVALIDARG, + tr("Given default machine folder '%s' is not fully qualified"), + path.c_str()); + + m->strDefaultMachineFolder = path; + + return S_OK; +} + +HRESULT SystemProperties::i_setLoggingLevel(const com::Utf8Str &aLoggingLevel) +{ + Utf8Str useLoggingLevel(aLoggingLevel); + if (useLoggingLevel.isEmpty()) + useLoggingLevel = VBOXSVC_LOG_DEFAULT; + int rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), useLoggingLevel.c_str()); + // If failed and not the default logging level - try to use the default logging level. + if (RT_FAILURE(rc)) + { + // If failed write message to the release log. + LogRel(("Cannot set passed logging level=%s Error=%Rrc \n", useLoggingLevel.c_str(), rc)); + // If attempted logging level not the default one then try the default one. + if (!useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT)) + { + rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), VBOXSVC_LOG_DEFAULT); + // If failed report this to the release log. + if (RT_FAILURE(rc)) + LogRel(("Cannot set default logging level Error=%Rrc \n", rc)); + } + // On any failure - set default level as the one to be stored. + useLoggingLevel = VBOXSVC_LOG_DEFAULT; + } + // Set to passed value or if default used/attempted (even if error condition) use empty string. + m->strLoggingLevel = (useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT) ? "" : useLoggingLevel); + return RT_SUCCESS(rc) ? S_OK : E_FAIL; +} + +HRESULT SystemProperties::i_setDefaultHardDiskFormat(const com::Utf8Str &aFormat) +{ + if (!aFormat.isEmpty()) + m->strDefaultHardDiskFormat = aFormat; + else + m->strDefaultHardDiskFormat = "VDI"; + + return S_OK; +} + +HRESULT SystemProperties::i_setVRDEAuthLibrary(const com::Utf8Str &aPath) +{ + if (!aPath.isEmpty()) + m->strVRDEAuthLibrary = aPath; + else + m->strVRDEAuthLibrary = "VBoxAuth"; + + return S_OK; +} + +HRESULT SystemProperties::i_setWebServiceAuthLibrary(const com::Utf8Str &aPath) +{ + if (!aPath.isEmpty()) + m->strWebServiceAuthLibrary = aPath; + else + m->strWebServiceAuthLibrary = "VBoxAuth"; + + return S_OK; +} + +HRESULT SystemProperties::i_setDefaultVRDEExtPack(const com::Utf8Str &aExtPack) +{ + m->strDefaultVRDEExtPack = aExtPack; + + return S_OK; +} + +HRESULT SystemProperties::i_setDefaultCryptoExtPack(const com::Utf8Str &aExtPack) +{ + m->strDefaultCryptoExtPack = aExtPack; + + return S_OK; +} + +HRESULT SystemProperties::i_setAutostartDatabasePath(const com::Utf8Str &aPath) +{ + HRESULT rc = S_OK; + AutostartDb *autostartDb = this->mParent->i_getAutostartDb(); + + if (!aPath.isEmpty()) + { + /* Update path in the autostart database. */ + int vrc = autostartDb->setAutostartDbPath(aPath.c_str()); + if (RT_SUCCESS(vrc)) + m->strAutostartDatabasePath = aPath; + else + rc = setErrorBoth(E_FAIL, vrc, + tr("Cannot set the autostart database path (%Rrc)"), + vrc); + } + else + { + int vrc = autostartDb->setAutostartDbPath(NULL); + if (RT_SUCCESS(vrc) || vrc == VERR_NOT_SUPPORTED) + m->strAutostartDatabasePath = ""; + else + rc = setErrorBoth(E_FAIL, vrc, + tr("Deleting the autostart database path failed (%Rrc)"), + vrc); + } + + return rc; +} + +HRESULT SystemProperties::i_setDefaultAdditionsISO(const com::Utf8Str &aPath) +{ + com::Utf8Str path(aPath); + if (path.isEmpty()) + { + char strTemp[RTPATH_MAX]; + int vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp)); + AssertRC(vrc); + Utf8Str strSrc1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso"); + + vrc = RTPathExecDir(strTemp, sizeof(strTemp)); + AssertRC(vrc); + Utf8Str strSrc2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso"); + + vrc = RTPathUserHome(strTemp, sizeof(strTemp)); + AssertRC(vrc); + Utf8Str strSrc3 = Utf8StrFmt("%s/VBoxGuestAdditions_%s.iso", strTemp, VirtualBox::i_getVersionNormalized().c_str()); + + /* Check the standard image locations */ + if (RTFileExists(strSrc1.c_str())) + path = strSrc1; + else if (RTFileExists(strSrc2.c_str())) + path = strSrc2; + else if (RTFileExists(strSrc3.c_str())) + path = strSrc3; + else + return setError(E_FAIL, + tr("Cannot determine default Guest Additions ISO location. Most likely they are not available")); + } + + if (!RTPathStartsWithRoot(path.c_str())) + return setError(E_INVALIDARG, + tr("Given default machine Guest Additions ISO file '%s' is not fully qualified"), + path.c_str()); + + if (!RTFileExists(path.c_str())) + return setError(E_INVALIDARG, + tr("Given default machine Guest Additions ISO file '%s' does not exist"), + path.c_str()); + + m->strDefaultAdditionsISO = path; + + return S_OK; +} + +HRESULT SystemProperties::i_setDefaultFrontend(const com::Utf8Str &aDefaultFrontend) +{ + m->strDefaultFrontend = aDefaultFrontend; + + return S_OK; +} + +HRESULT SystemProperties::getLanguageId(com::Utf8Str &aLanguageId) +{ +#ifdef VBOX_WITH_MAIN_NLS + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + aLanguageId = m->strLanguageId; + alock.release(); + + HRESULT hrc = S_OK; + if (aLanguageId.isEmpty()) + { + char szLocale[256]; + memset(szLocale, 0, sizeof(szLocale)); + int vrc = RTLocaleQueryNormalizedBaseLocaleName(szLocale, sizeof(szLocale)); + if (RT_SUCCESS(vrc)) + aLanguageId = szLocale; + else + hrc = Global::vboxStatusCodeToCOM(vrc); + } + return hrc; +#else + aLanguageId = "C"; + return S_OK; +#endif +} + +HRESULT SystemProperties::setLanguageId(const com::Utf8Str &aLanguageId) +{ +#ifdef VBOX_WITH_MAIN_NLS + VirtualBoxTranslator *pTranslator = VirtualBoxTranslator::instance(); + if (!pTranslator) + return E_FAIL; + + HRESULT hrc = S_OK; + int vrc = pTranslator->i_loadLanguage(aLanguageId.c_str()); + if (RT_SUCCESS(vrc)) + { + AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + m->strLanguageId = aLanguageId; + alock.release(); + + // VirtualBox::i_saveSettings() needs vbox write lock + AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); + hrc = mParent->i_saveSettings(); + } + else + hrc = Global::vboxStatusCodeToCOM(vrc); + + pTranslator->release(); + + if (SUCCEEDED(hrc)) + mParent->i_onLanguageChanged(aLanguageId); + + return hrc; +#else + NOREF(aLanguageId); + return E_NOTIMPL; +#endif +} |