VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp

Last change on this file was 103097, checked in by vboxsync, 4 months ago

Main,FE/VBoxManage,FE/VirtualBox,ValidationKit: Allow setting the primary VM execution engine to make it easier to force particular engine for testing, ​bugref:10583 [fix for darwin.amd64 where hwvirt is not available]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 56.7 KB
Line 
1/* $Id: SystemPropertiesImpl.cpp 103097 2024-01-26 19:23:08Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define LOG_GROUP LOG_GROUP_MAIN_SYSTEMPROPERTIES
29#include "SystemPropertiesImpl.h"
30#include "VirtualBoxImpl.h"
31#include "MachineImpl.h"
32#ifdef VBOX_WITH_EXTPACK
33# include "ExtPackManagerImpl.h"
34#endif
35#include "CPUProfileImpl.h"
36#include "AutoCaller.h"
37#include "Global.h"
38#include "LoggingNew.h"
39#include "AutostartDb.h"
40#include "VirtualBoxTranslator.h"
41
42// generated header
43#include "SchemaDefs.h"
44
45#include <iprt/dir.h>
46#include <iprt/ldr.h>
47#include <iprt/locale.h>
48#include <iprt/path.h>
49#include <iprt/string.h>
50#include <iprt/uri.h>
51#include <iprt/cpp/utils.h>
52
53#include <iprt/errcore.h>
54#include <VBox/param.h>
55#include <VBox/settings.h>
56#include <VBox/vd.h>
57#include <VBox/vmm/cpum.h>
58
59// defines
60/////////////////////////////////////////////////////////////////////////////
61
62// constructor / destructor
63/////////////////////////////////////////////////////////////////////////////
64
65SystemProperties::SystemProperties()
66 : mParent(NULL)
67 , m(new settings::SystemProperties)
68 , m_fLoadedX86CPUProfiles(false)
69{
70}
71
72SystemProperties::~SystemProperties()
73{
74 delete m;
75}
76
77
78HRESULT SystemProperties::FinalConstruct()
79{
80 return BaseFinalConstruct();
81}
82
83void SystemProperties::FinalRelease()
84{
85 uninit();
86 BaseFinalRelease();
87}
88
89// public methods only for internal purposes
90/////////////////////////////////////////////////////////////////////////////
91
92/**
93 * Initializes the system information object.
94 *
95 * @returns COM result indicator
96 */
97HRESULT SystemProperties::init(VirtualBox *aParent)
98{
99 LogFlowThisFunc(("aParent=%p\n", aParent));
100
101 ComAssertRet(aParent, E_FAIL);
102
103 /* Enclose the state transition NotReady->InInit->Ready */
104 AutoInitSpan autoInitSpan(this);
105 AssertReturn(autoInitSpan.isOk(), E_FAIL);
106
107 unconst(mParent) = aParent;
108
109 i_setDefaultMachineFolder(Utf8Str::Empty);
110 i_setLoggingLevel(Utf8Str::Empty);
111 i_setDefaultHardDiskFormat(Utf8Str::Empty);
112
113 i_setVRDEAuthLibrary(Utf8Str::Empty);
114 i_setDefaultVRDEExtPack(Utf8Str::Empty);
115 i_setDefaultCryptoExtPack(Utf8Str::Empty);
116
117 m->uLogHistoryCount = 3;
118
119 HRESULT hrc = S_OK;
120
121 /* Fetch info of all available hd backends. */
122
123 /// @todo NEWMEDIA VDBackendInfo needs to be improved to let us enumerate
124 /// any number of backends
125
126 VDBACKENDINFO aVDInfo[100];
127 unsigned cEntries;
128 int vrc = VDBackendInfo(RT_ELEMENTS(aVDInfo), aVDInfo, &cEntries);
129 AssertRC(vrc);
130 if (RT_SUCCESS(vrc))
131 {
132 for (unsigned i = 0; i < cEntries; ++ i)
133 {
134 ComObjPtr<MediumFormat> hdf;
135 hrc = hdf.createObject();
136 if (FAILED(hrc)) break;
137
138 hrc = hdf->init(&aVDInfo[i]);
139 if (FAILED(hrc)) break;
140
141 m_llMediumFormats.push_back(hdf);
142 }
143 }
144
145 if (SUCCEEDED(hrc))
146 {
147 hrc = unconst(m_platformProperties).createObject();
148 if (SUCCEEDED(hrc))
149 {
150 hrc = m_platformProperties->init(mParent);
151 if (SUCCEEDED(hrc))
152 hrc = m_platformProperties->i_setArchitecture(PlatformProperties::s_getHostPlatformArchitecture());
153 }
154 }
155
156 /* Confirm a successful initialization */
157 if (SUCCEEDED(hrc))
158 autoInitSpan.setSucceeded();
159
160 return hrc;
161}
162
163/**
164 * Uninitializes the instance and sets the ready flag to FALSE.
165 * Called either from FinalRelease() or by the parent when it gets destroyed.
166 */
167void SystemProperties::uninit()
168{
169 LogFlowThisFunc(("\n"));
170
171 /* Enclose the state transition Ready->InUninit->NotReady */
172 AutoUninitSpan autoUninitSpan(this);
173 if (autoUninitSpan.uninitDone())
174 return;
175
176 unconst(mParent) = NULL;
177}
178
179// wrapped ISystemProperties properties
180/////////////////////////////////////////////////////////////////////////////
181
182HRESULT SystemProperties::getMinGuestRAM(ULONG *minRAM)
183
184{
185 /* no need to lock, this is const */
186 AssertCompile(MM_RAM_MIN_IN_MB >= SchemaDefs::MinGuestRAM);
187 *minRAM = MM_RAM_MIN_IN_MB;
188
189 return S_OK;
190}
191
192HRESULT SystemProperties::getMaxGuestRAM(ULONG *maxRAM)
193{
194 /* no need to lock, this is const */
195 AssertCompile(MM_RAM_MAX_IN_MB <= SchemaDefs::MaxGuestRAM);
196 ULONG maxRAMSys = MM_RAM_MAX_IN_MB;
197 ULONG maxRAMArch = maxRAMSys;
198 *maxRAM = RT_MIN(maxRAMSys, maxRAMArch);
199
200 return S_OK;
201}
202
203HRESULT SystemProperties::getMinGuestVRAM(ULONG *minVRAM)
204{
205 /* no need to lock, this is const */
206 *minVRAM = SchemaDefs::MinGuestVRAM;
207
208 return S_OK;
209}
210
211HRESULT SystemProperties::getMaxGuestVRAM(ULONG *maxVRAM)
212{
213 /* no need to lock, this is const */
214 *maxVRAM = SchemaDefs::MaxGuestVRAM;
215
216 return S_OK;
217}
218
219HRESULT SystemProperties::getMinGuestCPUCount(ULONG *minCPUCount)
220{
221 /* no need to lock, this is const */
222 *minCPUCount = SchemaDefs::MinCPUCount; // VMM_MIN_CPU_COUNT
223
224 return S_OK;
225}
226
227HRESULT SystemProperties::getMaxGuestCPUCount(ULONG *maxCPUCount)
228{
229 /* no need to lock, this is const */
230 *maxCPUCount = SchemaDefs::MaxCPUCount; // VMM_MAX_CPU_COUNT
231
232 return S_OK;
233}
234
235HRESULT SystemProperties::getMaxGuestMonitors(ULONG *maxMonitors)
236{
237
238 /* no need to lock, this is const */
239 *maxMonitors = SchemaDefs::MaxGuestMonitors;
240
241 return S_OK;
242}
243
244
245HRESULT SystemProperties::getInfoVDSize(LONG64 *infoVDSize)
246{
247 /*
248 * The BIOS supports currently 32 bit LBA numbers (implementing the full
249 * 48 bit range is in theory trivial, but the crappy compiler makes things
250 * more difficult). This translates to almost 2 TiBytes (to be on the safe
251 * side, the reported limit is 1 MiByte less than that, as the total number
252 * of sectors should fit in 32 bits, too), which should be enough for the
253 * moment. Since the MBR partition tables support only 32bit sector numbers
254 * and thus the BIOS can only boot from disks smaller than 2T this is a
255 * rather hard limit.
256 *
257 * The virtual ATA/SATA disks support complete LBA48, and SCSI supports
258 * LBA64 (almost, more like LBA55 in practice), so the theoretical maximum
259 * disk size is 128 PiByte/16 EiByte. The GUI works nicely with 6 orders
260 * of magnitude, but not with 11..13 orders of magnitude.
261 */
262 /* no need to lock, this is const */
263 *infoVDSize = 2 * _1T - _1M;
264
265 return S_OK;
266}
267
268
269HRESULT SystemProperties::getDefaultIoCacheSettingForStorageController(StorageControllerType_T aControllerType,
270 BOOL *aEnabled)
271{
272 /* no need to lock, this is const */
273 switch (aControllerType)
274 {
275 case StorageControllerType_LsiLogic:
276 case StorageControllerType_BusLogic:
277 case StorageControllerType_IntelAhci:
278 case StorageControllerType_LsiLogicSas:
279 case StorageControllerType_USB:
280 case StorageControllerType_NVMe:
281 case StorageControllerType_VirtioSCSI:
282 *aEnabled = false;
283 break;
284 case StorageControllerType_PIIX3:
285 case StorageControllerType_PIIX4:
286 case StorageControllerType_ICH6:
287 case StorageControllerType_I82078:
288 *aEnabled = true;
289 break;
290 default:
291 AssertMsgFailed(("Invalid controller type %d\n", aControllerType));
292 }
293 return S_OK;
294}
295
296HRESULT SystemProperties::getCPUProfiles(CPUArchitecture_T aArchitecture, const com::Utf8Str &aNamePattern,
297 std::vector<ComPtr<ICPUProfile> > &aProfiles)
298{
299 /*
300 * Validate and adjust the architecture.
301 */
302 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
303 CPUArchitecture_T enmSecondaryArch = aArchitecture;
304 bool fLoaded;
305 switch (aArchitecture)
306 {
307 case CPUArchitecture_Any:
308 aArchitecture = CPUArchitecture_AMD64;
309 RT_FALL_THROUGH();
310 case CPUArchitecture_AMD64:
311 enmSecondaryArch = CPUArchitecture_x86;
312 RT_FALL_THROUGH();
313 case CPUArchitecture_x86:
314 fLoaded = m_fLoadedX86CPUProfiles;
315 break;
316 default:
317 return setError(E_INVALIDARG, tr("Invalid or unsupported architecture value: %d"), aArchitecture);
318 }
319
320 /*
321 * Do we need to load the profiles?
322 */
323 HRESULT hrc;
324 if (fLoaded)
325 hrc = S_OK;
326 else
327 {
328 alock.release();
329 AutoWriteLock alockWrite(this COMMA_LOCKVAL_SRC_POS);
330
331 /*
332 * Translate the architecture to a VMM module handle.
333 */
334 const char *pszVMM;
335 switch (aArchitecture)
336 {
337 case CPUArchitecture_AMD64:
338 case CPUArchitecture_x86:
339 pszVMM = "VBoxVMM";
340 fLoaded = m_fLoadedX86CPUProfiles;
341 break;
342 default:
343 AssertFailedReturn(E_INVALIDARG);
344 }
345 if (fLoaded)
346 hrc = S_OK;
347 else
348 {
349 char szPath[RTPATH_MAX];
350 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
351 if (RT_SUCCESS(vrc))
352 vrc = RTPathAppend(szPath, sizeof(szPath), pszVMM);
353 if (RT_SUCCESS(vrc))
354 vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
355 if (RT_SUCCESS(vrc))
356 {
357 RTLDRMOD hMod = NIL_RTLDRMOD;
358 vrc = RTLdrLoad(szPath, &hMod);
359 if (RT_SUCCESS(vrc))
360 {
361 /*
362 * Resolve the CPUMDb APIs we need.
363 */
364 PFNCPUMDBGETENTRIES pfnGetEntries
365 = (PFNCPUMDBGETENTRIES)RTLdrGetFunction(hMod, "CPUMR3DbGetEntries");
366 PFNCPUMDBGETENTRYBYINDEX pfnGetEntryByIndex
367 = (PFNCPUMDBGETENTRYBYINDEX)RTLdrGetFunction(hMod, "CPUMR3DbGetEntryByIndex");
368 if (pfnGetEntries && pfnGetEntryByIndex)
369 {
370 size_t const cExistingProfiles = m_llCPUProfiles.size();
371
372 /*
373 * Instantate the profiles.
374 */
375 hrc = S_OK;
376 uint32_t const cEntries = pfnGetEntries();
377 for (uint32_t i = 0; i < cEntries; i++)
378 {
379 PCCPUMDBENTRY pDbEntry = pfnGetEntryByIndex(i);
380 AssertBreakStmt(pDbEntry, hrc = setError(E_UNEXPECTED, "CPUMR3DbGetEntryByIndex failed for %i", i));
381
382 ComObjPtr<CPUProfile> ptrProfile;
383 hrc = ptrProfile.createObject();
384 if (SUCCEEDED(hrc))
385 {
386 hrc = ptrProfile->initFromDbEntry(pDbEntry);
387 if (SUCCEEDED(hrc))
388 {
389 try
390 {
391 m_llCPUProfiles.push_back(ptrProfile);
392 continue;
393 }
394 catch (std::bad_alloc &)
395 {
396 hrc = E_OUTOFMEMORY;
397 }
398 }
399 }
400 break;
401 }
402
403 /*
404 * On success update the flag and retake the read lock.
405 * If we fail, drop the profiles we added to the list.
406 */
407 if (SUCCEEDED(hrc))
408 {
409 switch (aArchitecture)
410 {
411 case CPUArchitecture_AMD64:
412 case CPUArchitecture_x86:
413 m_fLoadedX86CPUProfiles = true;
414 break;
415 default:
416 AssertFailedStmt(hrc = E_INVALIDARG);
417 }
418
419 alockWrite.release();
420 alock.acquire();
421 }
422 else
423 m_llCPUProfiles.resize(cExistingProfiles);
424 }
425 else
426 hrc = setErrorVrc(VERR_SYMBOL_NOT_FOUND,
427 tr("'%s' is missing symbols: CPUMR3DbGetEntries, CPUMR3DbGetEntryByIndex"), szPath);
428 RTLdrClose(hMod);
429 }
430 else
431 hrc = setErrorVrc(vrc, tr("Failed to construct load '%s': %Rrc"), szPath, vrc);
432 }
433 else
434 hrc = setErrorVrc(vrc, tr("Failed to construct path to the VMM DLL/Dylib/SharedObject: %Rrc"), vrc);
435 }
436 }
437 if (SUCCEEDED(hrc))
438 {
439 /*
440 * Return the matching profiles.
441 */
442 /* Count matches: */
443 size_t cMatches = 0;
444 for (CPUProfileList_T::const_iterator it = m_llCPUProfiles.begin(); it != m_llCPUProfiles.end(); ++it)
445 if ((*it)->i_match(aArchitecture, enmSecondaryArch, aNamePattern))
446 cMatches++;
447
448 /* Resize the output array. */
449 try
450 {
451 aProfiles.resize(cMatches);
452 }
453 catch (std::bad_alloc &)
454 {
455 aProfiles.resize(0);
456 hrc = E_OUTOFMEMORY;
457 }
458
459 /* Get the return objects: */
460 if (SUCCEEDED(hrc) && cMatches > 0)
461 {
462 size_t iMatch = 0;
463 for (CPUProfileList_T::const_iterator it = m_llCPUProfiles.begin(); it != m_llCPUProfiles.end(); ++it)
464 if ((*it)->i_match(aArchitecture, enmSecondaryArch, aNamePattern))
465 {
466 AssertBreakStmt(iMatch < cMatches, hrc = E_UNEXPECTED);
467 hrc = (*it).queryInterfaceTo(aProfiles[iMatch].asOutParam());
468 if (SUCCEEDED(hrc))
469 iMatch++;
470 else
471 break;
472 }
473 AssertStmt(iMatch == cMatches || FAILED(hrc), hrc = E_UNEXPECTED);
474 }
475 }
476 return hrc;
477}
478
479
480HRESULT SystemProperties::getDefaultMachineFolder(com::Utf8Str &aDefaultMachineFolder)
481{
482 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
483 aDefaultMachineFolder = m->strDefaultMachineFolder;
484 return S_OK;
485}
486
487HRESULT SystemProperties::setDefaultMachineFolder(const com::Utf8Str &aDefaultMachineFolder)
488{
489 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
490 HRESULT hrc = i_setDefaultMachineFolder(aDefaultMachineFolder);
491 alock.release();
492 if (SUCCEEDED(hrc))
493 {
494 // VirtualBox::i_saveSettings() needs vbox write lock
495 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
496 hrc = mParent->i_saveSettings();
497 }
498
499 return hrc;
500}
501
502HRESULT SystemProperties::getLoggingLevel(com::Utf8Str &aLoggingLevel)
503{
504 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
505
506 aLoggingLevel = m->strLoggingLevel;
507
508 if (aLoggingLevel.isEmpty())
509 aLoggingLevel = VBOXSVC_LOG_DEFAULT;
510
511 return S_OK;
512}
513
514
515HRESULT SystemProperties::setLoggingLevel(const com::Utf8Str &aLoggingLevel)
516{
517 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
518 HRESULT hrc = i_setLoggingLevel(aLoggingLevel);
519 alock.release();
520
521 if (SUCCEEDED(hrc))
522 {
523 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
524 hrc = mParent->i_saveSettings();
525 }
526 else
527 LogRel(("Cannot set passed logging level=%s, or the default one - Error=%Rhrc \n", aLoggingLevel.c_str(), hrc));
528
529 return hrc;
530}
531
532HRESULT SystemProperties::getMediumFormats(std::vector<ComPtr<IMediumFormat> > &aMediumFormats)
533{
534 MediumFormatList mediumFormats(m_llMediumFormats);
535 aMediumFormats.resize(mediumFormats.size());
536 size_t i = 0;
537 for (MediumFormatList::const_iterator it = mediumFormats.begin(); it != mediumFormats.end(); ++it, ++i)
538 (*it).queryInterfaceTo(aMediumFormats[i].asOutParam());
539 return S_OK;
540}
541
542HRESULT SystemProperties::getDefaultHardDiskFormat(com::Utf8Str &aDefaultHardDiskFormat)
543{
544 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
545 aDefaultHardDiskFormat = m->strDefaultHardDiskFormat;
546 return S_OK;
547}
548
549
550HRESULT SystemProperties::setDefaultHardDiskFormat(const com::Utf8Str &aDefaultHardDiskFormat)
551{
552 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
553 HRESULT hrc = i_setDefaultHardDiskFormat(aDefaultHardDiskFormat);
554 alock.release();
555 if (SUCCEEDED(hrc))
556 {
557 // VirtualBox::i_saveSettings() needs vbox write lock
558 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
559 hrc = mParent->i_saveSettings();
560 }
561
562 return hrc;
563}
564
565HRESULT SystemProperties::getFreeDiskSpaceWarning(LONG64 *aFreeSpace)
566{
567 NOREF(aFreeSpace);
568 ReturnComNotImplemented();
569}
570
571HRESULT SystemProperties::setFreeDiskSpaceWarning(LONG64 /* aFreeSpace */)
572{
573 ReturnComNotImplemented();
574}
575
576HRESULT SystemProperties::getFreeDiskSpacePercentWarning(ULONG *aFreeSpacePercent)
577{
578 NOREF(aFreeSpacePercent);
579 ReturnComNotImplemented();
580}
581
582HRESULT SystemProperties::setFreeDiskSpacePercentWarning(ULONG /* aFreeSpacePercent */)
583{
584 ReturnComNotImplemented();
585}
586
587HRESULT SystemProperties::getFreeDiskSpaceError(LONG64 *aFreeSpace)
588{
589 NOREF(aFreeSpace);
590 ReturnComNotImplemented();
591}
592
593HRESULT SystemProperties::setFreeDiskSpaceError(LONG64 /* aFreeSpace */)
594{
595 ReturnComNotImplemented();
596}
597
598HRESULT SystemProperties::getFreeDiskSpacePercentError(ULONG *aFreeSpacePercent)
599{
600 NOREF(aFreeSpacePercent);
601 ReturnComNotImplemented();
602}
603
604HRESULT SystemProperties::setFreeDiskSpacePercentError(ULONG /* aFreeSpacePercent */)
605{
606 ReturnComNotImplemented();
607}
608
609HRESULT SystemProperties::getVRDEAuthLibrary(com::Utf8Str &aVRDEAuthLibrary)
610{
611 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
612
613 aVRDEAuthLibrary = m->strVRDEAuthLibrary;
614
615 return S_OK;
616}
617
618HRESULT SystemProperties::setVRDEAuthLibrary(const com::Utf8Str &aVRDEAuthLibrary)
619{
620 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
621 HRESULT hrc = i_setVRDEAuthLibrary(aVRDEAuthLibrary);
622 alock.release();
623 if (SUCCEEDED(hrc))
624 {
625 // VirtualBox::i_saveSettings() needs vbox write lock
626 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
627 hrc = mParent->i_saveSettings();
628 }
629
630 return hrc;
631}
632
633HRESULT SystemProperties::getWebServiceAuthLibrary(com::Utf8Str &aWebServiceAuthLibrary)
634{
635 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
636
637 aWebServiceAuthLibrary = m->strWebServiceAuthLibrary;
638
639 return S_OK;
640}
641
642HRESULT SystemProperties::setWebServiceAuthLibrary(const com::Utf8Str &aWebServiceAuthLibrary)
643{
644 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
645 HRESULT hrc = i_setWebServiceAuthLibrary(aWebServiceAuthLibrary);
646 alock.release();
647
648 if (SUCCEEDED(hrc))
649 {
650 // VirtualBox::i_saveSettings() needs vbox write lock
651 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
652 hrc = mParent->i_saveSettings();
653 }
654
655 return hrc;
656}
657
658HRESULT SystemProperties::getDefaultVRDEExtPack(com::Utf8Str &aExtPack)
659{
660 HRESULT hrc = S_OK;
661 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
662 Utf8Str strExtPack(m->strDefaultVRDEExtPack);
663 if (strExtPack.isNotEmpty())
664 {
665 if (strExtPack.equals(VBOXVRDP_KLUDGE_EXTPACK_NAME))
666 hrc = S_OK;
667 else
668#ifdef VBOX_WITH_EXTPACK
669 hrc = mParent->i_getExtPackManager()->i_checkVrdeExtPack(&strExtPack);
670#else
671 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), strExtPack.c_str());
672#endif
673 }
674 else
675 {
676#ifdef VBOX_WITH_EXTPACK
677 hrc = mParent->i_getExtPackManager()->i_getDefaultVrdeExtPack(&strExtPack);
678#endif
679 if (strExtPack.isEmpty())
680 {
681 /*
682 * Klugde - check if VBoxVRDP.dll/.so/.dylib is installed.
683 * This is hardcoded uglyness, sorry.
684 */
685 char szPath[RTPATH_MAX];
686 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
687 if (RT_SUCCESS(vrc))
688 vrc = RTPathAppend(szPath, sizeof(szPath), "VBoxVRDP");
689 if (RT_SUCCESS(vrc))
690 vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
691 if (RT_SUCCESS(vrc) && RTFileExists(szPath))
692 {
693 /* Illegal extpack name, so no conflict. */
694 strExtPack = VBOXVRDP_KLUDGE_EXTPACK_NAME;
695 }
696 }
697 }
698
699 if (SUCCEEDED(hrc))
700 aExtPack = strExtPack;
701
702 return S_OK;
703}
704
705
706HRESULT SystemProperties::setDefaultVRDEExtPack(const com::Utf8Str &aExtPack)
707{
708 HRESULT hrc = S_OK;
709 if (aExtPack.isNotEmpty())
710 {
711 if (aExtPack.equals(VBOXVRDP_KLUDGE_EXTPACK_NAME))
712 hrc = S_OK;
713 else
714#ifdef VBOX_WITH_EXTPACK
715 hrc = mParent->i_getExtPackManager()->i_checkVrdeExtPack(&aExtPack);
716#else
717 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), aExtPack.c_str());
718#endif
719 }
720 if (SUCCEEDED(hrc))
721 {
722 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
723 hrc = i_setDefaultVRDEExtPack(aExtPack);
724 if (SUCCEEDED(hrc))
725 {
726 /* VirtualBox::i_saveSettings() needs the VirtualBox write lock. */
727 alock.release();
728 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
729 hrc = mParent->i_saveSettings();
730 }
731 }
732
733 return hrc;
734}
735
736
737HRESULT SystemProperties::getDefaultCryptoExtPack(com::Utf8Str &aExtPack)
738{
739 HRESULT hrc = S_OK;
740 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
741 Utf8Str strExtPack(m->strDefaultCryptoExtPack);
742 if (strExtPack.isNotEmpty())
743 {
744 if (strExtPack.equals(VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME))
745 hrc = S_OK;
746 else
747#ifdef VBOX_WITH_EXTPACK
748 hrc = mParent->i_getExtPackManager()->i_checkCryptoExtPack(&strExtPack);
749#else
750 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), strExtPack.c_str());
751#endif
752 }
753 else
754 {
755#ifdef VBOX_WITH_EXTPACK
756 hrc = mParent->i_getExtPackManager()->i_getDefaultCryptoExtPack(&strExtPack);
757#endif
758 if (strExtPack.isEmpty())
759 {
760 /*
761 * Klugde - check if VBoxPuelCrypto.dll/.so/.dylib is installed.
762 * This is hardcoded uglyness, sorry.
763 */
764 char szPath[RTPATH_MAX];
765 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
766 if (RT_SUCCESS(vrc))
767 vrc = RTPathAppend(szPath, sizeof(szPath), "VBoxPuelCrypto");
768 if (RT_SUCCESS(vrc))
769 vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
770 if (RT_SUCCESS(vrc) && RTFileExists(szPath))
771 {
772 /* Illegal extpack name, so no conflict. */
773 strExtPack = VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME;
774 }
775 }
776 }
777
778 if (SUCCEEDED(hrc))
779 aExtPack = strExtPack;
780
781 return S_OK;
782}
783
784
785HRESULT SystemProperties::setDefaultCryptoExtPack(const com::Utf8Str &aExtPack)
786{
787 HRESULT hrc = S_OK;
788 if (aExtPack.isNotEmpty())
789 {
790 if (aExtPack.equals(VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME))
791 hrc = S_OK;
792 else
793#ifdef VBOX_WITH_EXTPACK
794 hrc = mParent->i_getExtPackManager()->i_checkCryptoExtPack(&aExtPack);
795#else
796 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), aExtPack.c_str());
797#endif
798 }
799 if (SUCCEEDED(hrc))
800 {
801 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
802 hrc = i_setDefaultCryptoExtPack(aExtPack);
803 if (SUCCEEDED(hrc))
804 {
805 /* VirtualBox::i_saveSettings() needs the VirtualBox write lock. */
806 alock.release();
807 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
808 hrc = mParent->i_saveSettings();
809 }
810 }
811
812 return hrc;
813}
814
815
816HRESULT SystemProperties::getLogHistoryCount(ULONG *count)
817{
818 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
819
820 *count = m->uLogHistoryCount;
821
822 return S_OK;
823}
824
825
826HRESULT SystemProperties::setLogHistoryCount(ULONG count)
827{
828 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
829 m->uLogHistoryCount = count;
830 alock.release();
831
832 // VirtualBox::i_saveSettings() needs vbox write lock
833 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
834 return mParent->i_saveSettings();
835}
836
837HRESULT SystemProperties::getDefaultAudioDriver(AudioDriverType_T *aAudioDriver)
838{
839 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
840
841 *aAudioDriver = settings::MachineConfigFile::getHostDefaultAudioDriver();
842
843 return S_OK;
844}
845
846HRESULT SystemProperties::getAutostartDatabasePath(com::Utf8Str &aAutostartDbPath)
847{
848 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
849
850 aAutostartDbPath = m->strAutostartDatabasePath;
851
852 return S_OK;
853}
854
855HRESULT SystemProperties::setAutostartDatabasePath(const com::Utf8Str &aAutostartDbPath)
856{
857 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
858 HRESULT hrc = i_setAutostartDatabasePath(aAutostartDbPath);
859 alock.release();
860
861 if (SUCCEEDED(hrc))
862 {
863 // VirtualBox::i_saveSettings() needs vbox write lock
864 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
865 hrc = mParent->i_saveSettings();
866 }
867
868 return hrc;
869}
870
871HRESULT SystemProperties::getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO)
872{
873 return i_getDefaultAdditionsISO(aDefaultAdditionsISO);
874}
875
876HRESULT SystemProperties::setDefaultAdditionsISO(const com::Utf8Str &aDefaultAdditionsISO)
877{
878 RT_NOREF(aDefaultAdditionsISO);
879 /** @todo not yet implemented, settings handling is missing */
880 ReturnComNotImplemented();
881#if 0 /* not implemented */
882 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
883 HRESULT hrc = i_setDefaultAdditionsISO(aDefaultAdditionsISO);
884 alock.release();
885
886 if (SUCCEEDED(hrc))
887 {
888 // VirtualBox::i_saveSettings() needs vbox write lock
889 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
890 hrc = mParent->i_saveSettings();
891 }
892
893 return hrc;
894#endif
895}
896
897HRESULT SystemProperties::getDefaultFrontend(com::Utf8Str &aDefaultFrontend)
898{
899 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
900 aDefaultFrontend = m->strDefaultFrontend;
901 return S_OK;
902}
903
904HRESULT SystemProperties::setDefaultFrontend(const com::Utf8Str &aDefaultFrontend)
905{
906 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
907 if (m->strDefaultFrontend == aDefaultFrontend)
908 return S_OK;
909 HRESULT hrc = i_setDefaultFrontend(aDefaultFrontend);
910 alock.release();
911
912 if (SUCCEEDED(hrc))
913 {
914 // VirtualBox::i_saveSettings() needs vbox write lock
915 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
916 hrc = mParent->i_saveSettings();
917 }
918
919 return hrc;
920}
921
922HRESULT SystemProperties::getScreenShotFormats(std::vector<BitmapFormat_T> &aBitmapFormats)
923{
924 aBitmapFormats.push_back(BitmapFormat_BGR0);
925 aBitmapFormats.push_back(BitmapFormat_BGRA);
926 aBitmapFormats.push_back(BitmapFormat_RGBA);
927 aBitmapFormats.push_back(BitmapFormat_PNG);
928 return S_OK;
929}
930
931HRESULT SystemProperties::getPlatform(ComPtr<IPlatformProperties> &aPlatformProperties)
932{
933 /* No need to lock, as m_platformProperties is const. */
934
935 return m_platformProperties.queryInterfaceTo(aPlatformProperties.asOutParam());
936}
937
938HRESULT SystemProperties::getProxyMode(ProxyMode_T *pProxyMode)
939{
940 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
941 ProxyMode_T enmMode = *pProxyMode = (ProxyMode_T)m->uProxyMode;
942 AssertMsgReturn(enmMode == ProxyMode_System || enmMode == ProxyMode_NoProxy || enmMode == ProxyMode_Manual,
943 ("enmMode=%d\n", enmMode), E_UNEXPECTED);
944 return S_OK;
945}
946
947HRESULT SystemProperties::setProxyMode(ProxyMode_T aProxyMode)
948{
949 /* Validate input. */
950 switch (aProxyMode)
951 {
952 case ProxyMode_System:
953 case ProxyMode_NoProxy:
954 case ProxyMode_Manual:
955 break;
956 default:
957 return setError(E_INVALIDARG, tr("Invalid ProxyMode value: %d"), (int)aProxyMode);
958 }
959
960 /* Set and write out settings. */
961 {
962 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
963 m->uProxyMode = aProxyMode;
964 }
965 AutoWriteLock alock(mParent COMMA_LOCKVAL_SRC_POS); /* required for saving. */
966 return mParent->i_saveSettings();
967}
968
969HRESULT SystemProperties::getProxyURL(com::Utf8Str &aProxyURL)
970{
971 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
972 aProxyURL = m->strProxyUrl;
973 return S_OK;
974}
975
976HRESULT SystemProperties::setProxyURL(const com::Utf8Str &aProxyURL)
977{
978 /*
979 * Validate input.
980 */
981 Utf8Str const *pStrProxyUrl = &aProxyURL;
982 Utf8Str strTmp;
983 if (pStrProxyUrl->isNotEmpty())
984 {
985 /* RTUriParse requires a scheme, so append 'http://' if none seems present: */
986 if (pStrProxyUrl->find("://") == RTCString::npos)
987 {
988 strTmp.printf("http://%s", aProxyURL.c_str());
989 pStrProxyUrl = &strTmp;
990 }
991
992 /* Use RTUriParse to check the format. There must be a hostname, but nothing
993 can follow it and the port. */
994 RTURIPARSED Parsed;
995 int vrc = RTUriParse(pStrProxyUrl->c_str(), &Parsed);
996 if (RT_FAILURE(vrc))
997 return setErrorBoth(E_INVALIDARG, vrc, tr("Failed to parse proxy URL: %Rrc"), vrc);
998 if ( Parsed.cchAuthorityHost == 0
999 && !RTUriIsSchemeMatch(pStrProxyUrl->c_str(), "direct"))
1000 return setError(E_INVALIDARG, tr("Proxy URL must include a hostname"));
1001 if (Parsed.cchPath > 0)
1002 return setError(E_INVALIDARG, tr("Proxy URL must not include a path component (%.*s)"),
1003 Parsed.cchPath, pStrProxyUrl->c_str() + Parsed.offPath);
1004 if (Parsed.cchQuery > 0)
1005 return setError(E_INVALIDARG, tr("Proxy URL must not include a query component (?%.*s)"),
1006 Parsed.cchQuery, pStrProxyUrl->c_str() + Parsed.offQuery);
1007 if (Parsed.cchFragment > 0)
1008 return setError(E_INVALIDARG, tr("Proxy URL must not include a fragment component (#%.*s)"),
1009 Parsed.cchFragment, pStrProxyUrl->c_str() + Parsed.offFragment);
1010 }
1011
1012 /*
1013 * Set and write out settings.
1014 */
1015 {
1016 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1017 m->strProxyUrl = *pStrProxyUrl;
1018 }
1019 AutoWriteLock alock(mParent COMMA_LOCKVAL_SRC_POS); /* required for saving. */
1020 return mParent->i_saveSettings();
1021}
1022
1023HRESULT SystemProperties::getSupportedPlatformArchitectures(std::vector<PlatformArchitecture_T> &aSupportedPlatformArchitectures)
1024{
1025 static const PlatformArchitecture_T aPlatformArchitectures[] =
1026 {
1027#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
1028 /* Currently x86 can run x86 VMs only. */
1029 PlatformArchitecture_x86
1030#elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
1031 /* Currently ARM can run x86 emulation and if enabled ARM VMs. */
1032 PlatformArchitecture_x86
1033# ifdef VBOX_WITH_VIRT_ARMV8
1034 , PlatformArchitecture_ARM
1035# endif
1036#else
1037# error "Port me!"
1038 PlatformArchitecture_None
1039#endif
1040 };
1041 aSupportedPlatformArchitectures.assign(aPlatformArchitectures,
1042 aPlatformArchitectures + RT_ELEMENTS(aPlatformArchitectures));
1043 return S_OK;
1044}
1045
1046HRESULT SystemProperties::getSupportedClipboardModes(std::vector<ClipboardMode_T> &aSupportedClipboardModes)
1047{
1048 static const ClipboardMode_T aClipboardModes[] =
1049 {
1050 ClipboardMode_Disabled,
1051 ClipboardMode_HostToGuest,
1052 ClipboardMode_GuestToHost,
1053 ClipboardMode_Bidirectional,
1054 };
1055 aSupportedClipboardModes.assign(aClipboardModes,
1056 aClipboardModes + RT_ELEMENTS(aClipboardModes));
1057 return S_OK;
1058}
1059
1060HRESULT SystemProperties::getSupportedDnDModes(std::vector<DnDMode_T> &aSupportedDnDModes)
1061{
1062 static const DnDMode_T aDnDModes[] =
1063 {
1064 DnDMode_Disabled,
1065 DnDMode_HostToGuest,
1066 DnDMode_GuestToHost,
1067 DnDMode_Bidirectional,
1068 };
1069 aSupportedDnDModes.assign(aDnDModes,
1070 aDnDModes + RT_ELEMENTS(aDnDModes));
1071 return S_OK;
1072}
1073
1074HRESULT SystemProperties::getSupportedPointingHIDTypes(std::vector<PointingHIDType_T> &aSupportedPointingHIDTypes)
1075{
1076 static const PointingHIDType_T aPointingHIDTypes[] =
1077 {
1078 PointingHIDType_PS2Mouse,
1079#ifdef DEBUG
1080 PointingHIDType_USBMouse,
1081#endif
1082 PointingHIDType_USBTablet,
1083#ifdef DEBUG
1084 PointingHIDType_ComboMouse,
1085#endif
1086 PointingHIDType_USBMultiTouch,
1087 PointingHIDType_USBMultiTouchScreenPlusPad,
1088 };
1089 aSupportedPointingHIDTypes.assign(aPointingHIDTypes,
1090 aPointingHIDTypes + RT_ELEMENTS(aPointingHIDTypes));
1091 return S_OK;
1092}
1093
1094HRESULT SystemProperties::getSupportedKeyboardHIDTypes(std::vector<KeyboardHIDType_T> &aSupportedKeyboardHIDTypes)
1095{
1096 static const KeyboardHIDType_T aKeyboardHIDTypes[] =
1097 {
1098 KeyboardHIDType_PS2Keyboard,
1099 KeyboardHIDType_USBKeyboard,
1100#ifdef DEBUG
1101 KeyboardHIDType_ComboKeyboard,
1102#endif
1103 };
1104 aSupportedKeyboardHIDTypes.assign(aKeyboardHIDTypes,
1105 aKeyboardHIDTypes + RT_ELEMENTS(aKeyboardHIDTypes));
1106 return S_OK;
1107}
1108
1109HRESULT SystemProperties::getSupportedVFSTypes(std::vector<VFSType_T> &aSupportedVFSTypes)
1110{
1111 static const VFSType_T aVFSTypes[] =
1112 {
1113 VFSType_File,
1114 VFSType_Cloud,
1115 VFSType_S3,
1116#ifdef DEBUG
1117 VFSType_WebDav,
1118#endif
1119 };
1120 aSupportedVFSTypes.assign(aVFSTypes,
1121 aVFSTypes + RT_ELEMENTS(aVFSTypes));
1122 return S_OK;
1123}
1124
1125HRESULT SystemProperties::getSupportedImportOptions(std::vector<ImportOptions_T> &aSupportedImportOptions)
1126{
1127 static const ImportOptions_T aImportOptions[] =
1128 {
1129 ImportOptions_KeepAllMACs,
1130 ImportOptions_KeepNATMACs,
1131 ImportOptions_ImportToVDI,
1132 };
1133 aSupportedImportOptions.assign(aImportOptions,
1134 aImportOptions + RT_ELEMENTS(aImportOptions));
1135 return S_OK;
1136}
1137
1138HRESULT SystemProperties::getSupportedExportOptions(std::vector<ExportOptions_T> &aSupportedExportOptions)
1139{
1140 static const ExportOptions_T aExportOptions[] =
1141 {
1142 ExportOptions_CreateManifest,
1143 ExportOptions_ExportDVDImages,
1144 ExportOptions_StripAllMACs,
1145 ExportOptions_StripAllNonNATMACs,
1146 };
1147 aSupportedExportOptions.assign(aExportOptions,
1148 aExportOptions + RT_ELEMENTS(aExportOptions));
1149 return S_OK;
1150}
1151
1152HRESULT SystemProperties::getSupportedRecordingFeatures(std::vector<RecordingFeature_T> &aSupportedRecordingFeatures)
1153{
1154#ifdef VBOX_WITH_RECORDING
1155 static const RecordingFeature_T aRecordingFeatures[] =
1156 {
1157# ifdef VBOX_WITH_AUDIO_RECORDING
1158 RecordingFeature_Audio,
1159# endif
1160 RecordingFeature_Video,
1161 };
1162 aSupportedRecordingFeatures.assign(aRecordingFeatures,
1163 aRecordingFeatures + RT_ELEMENTS(aRecordingFeatures));
1164#else /* !VBOX_WITH_RECORDING */
1165 aSupportedRecordingFeatures.clear();
1166#endif /* VBOX_WITH_RECORDING */
1167 return S_OK;
1168}
1169
1170HRESULT SystemProperties::getSupportedRecordingAudioCodecs(std::vector<RecordingAudioCodec_T> &aSupportedRecordingAudioCodecs)
1171{
1172 static const RecordingAudioCodec_T aRecordingAudioCodecs[] =
1173 {
1174 RecordingAudioCodec_None,
1175#ifdef DEBUG
1176 RecordingAudioCodec_WavPCM,
1177#endif
1178#ifdef VBOX_WITH_LIBVORBIS
1179 RecordingAudioCodec_OggVorbis,
1180#endif
1181 };
1182 aSupportedRecordingAudioCodecs.assign(aRecordingAudioCodecs,
1183 aRecordingAudioCodecs + RT_ELEMENTS(aRecordingAudioCodecs));
1184 return S_OK;
1185}
1186
1187HRESULT SystemProperties::getSupportedRecordingVideoCodecs(std::vector<RecordingVideoCodec_T> &aSupportedRecordingVideoCodecs)
1188{
1189 static const RecordingVideoCodec_T aRecordingVideoCodecs[] =
1190 {
1191 RecordingVideoCodec_None,
1192#ifdef VBOX_WITH_LIBVPX
1193 RecordingVideoCodec_VP8,
1194#endif
1195#ifdef DEBUG
1196 RecordingVideoCodec_VP9,
1197 RecordingVideoCodec_AV1,
1198#endif
1199 };
1200 aSupportedRecordingVideoCodecs.assign(aRecordingVideoCodecs,
1201 aRecordingVideoCodecs + RT_ELEMENTS(aRecordingVideoCodecs));
1202 return S_OK;
1203}
1204
1205HRESULT SystemProperties::getSupportedRecordingVSModes(std::vector<RecordingVideoScalingMode_T> &aSupportedRecordingVideoScalingModes)
1206{
1207 static const RecordingVideoScalingMode_T aRecordingVideoScalingModes[] =
1208 {
1209 RecordingVideoScalingMode_None,
1210#ifdef DEBUG
1211 RecordingVideoScalingMode_NearestNeighbor,
1212 RecordingVideoScalingMode_Bilinear,
1213 RecordingVideoScalingMode_Bicubic,
1214#endif
1215 };
1216 aSupportedRecordingVideoScalingModes.assign(aRecordingVideoScalingModes,
1217 aRecordingVideoScalingModes + RT_ELEMENTS(aRecordingVideoScalingModes));
1218 return S_OK;
1219}
1220
1221HRESULT SystemProperties::getSupportedRecordingARCModes(std::vector<RecordingRateControlMode_T> &aSupportedRecordingAudioRateControlModes)
1222{
1223 static const RecordingRateControlMode_T aRecordingAudioRateControlModes[] =
1224 {
1225#ifdef DEBUG
1226 RecordingRateControlMode_ABR,
1227 RecordingRateControlMode_CBR,
1228#endif
1229 RecordingRateControlMode_VBR
1230 };
1231 aSupportedRecordingAudioRateControlModes.assign(aRecordingAudioRateControlModes,
1232 aRecordingAudioRateControlModes + RT_ELEMENTS(aRecordingAudioRateControlModes));
1233 return S_OK;
1234}
1235
1236HRESULT SystemProperties::getSupportedRecordingVRCModes(std::vector<RecordingRateControlMode_T> &aSupportedRecordingVideoRateControlModes)
1237{
1238 static const RecordingRateControlMode_T aRecordingVideoRateControlModes[] =
1239 {
1240#ifdef DEBUG
1241 RecordingRateControlMode_ABR,
1242 RecordingRateControlMode_CBR,
1243#endif
1244 RecordingRateControlMode_VBR
1245 };
1246 aSupportedRecordingVideoRateControlModes.assign(aRecordingVideoRateControlModes,
1247 aRecordingVideoRateControlModes + RT_ELEMENTS(aRecordingVideoRateControlModes));
1248 return S_OK;
1249}
1250
1251HRESULT SystemProperties::getSupportedCloneOptions(std::vector<CloneOptions_T> &aSupportedCloneOptions)
1252{
1253 static const CloneOptions_T aCloneOptions[] =
1254 {
1255 CloneOptions_Link,
1256 CloneOptions_KeepAllMACs,
1257 CloneOptions_KeepNATMACs,
1258 CloneOptions_KeepDiskNames,
1259 CloneOptions_KeepHwUUIDs,
1260 };
1261 aSupportedCloneOptions.assign(aCloneOptions,
1262 aCloneOptions + RT_ELEMENTS(aCloneOptions));
1263 return S_OK;
1264}
1265
1266HRESULT SystemProperties::getSupportedAutostopTypes(std::vector<AutostopType_T> &aSupportedAutostopTypes)
1267{
1268 static const AutostopType_T aAutostopTypes[] =
1269 {
1270 AutostopType_Disabled,
1271 AutostopType_SaveState,
1272 AutostopType_PowerOff,
1273 AutostopType_AcpiShutdown,
1274 };
1275 aSupportedAutostopTypes.assign(aAutostopTypes,
1276 aAutostopTypes + RT_ELEMENTS(aAutostopTypes));
1277 return S_OK;
1278}
1279
1280HRESULT SystemProperties::getSupportedVMProcPriorities(std::vector<VMProcPriority_T> &aSupportedVMProcPriorities)
1281{
1282 static const VMProcPriority_T aVMProcPriorities[] =
1283 {
1284 VMProcPriority_Default,
1285 VMProcPriority_Flat,
1286 VMProcPriority_Low,
1287 VMProcPriority_Normal,
1288 VMProcPriority_High,
1289 };
1290 aSupportedVMProcPriorities.assign(aVMProcPriorities,
1291 aVMProcPriorities + RT_ELEMENTS(aVMProcPriorities));
1292 return S_OK;
1293}
1294
1295HRESULT SystemProperties::getSupportedNetworkAttachmentTypes(std::vector<NetworkAttachmentType_T> &aSupportedNetworkAttachmentTypes)
1296{
1297 static const NetworkAttachmentType_T aNetworkAttachmentTypes[] =
1298 {
1299 NetworkAttachmentType_NAT,
1300 NetworkAttachmentType_Bridged,
1301 NetworkAttachmentType_Internal,
1302 NetworkAttachmentType_HostOnly,
1303#ifdef VBOX_WITH_VMNET
1304 NetworkAttachmentType_HostOnlyNetwork,
1305#endif /* VBOX_WITH_VMNET */
1306 NetworkAttachmentType_Generic,
1307 NetworkAttachmentType_NATNetwork,
1308#ifdef VBOX_WITH_CLOUD_NET
1309 NetworkAttachmentType_Cloud,
1310#endif
1311 NetworkAttachmentType_Null,
1312 };
1313 aSupportedNetworkAttachmentTypes.assign(aNetworkAttachmentTypes,
1314 aNetworkAttachmentTypes + RT_ELEMENTS(aNetworkAttachmentTypes));
1315 return S_OK;
1316}
1317
1318HRESULT SystemProperties::getSupportedPortModes(std::vector<PortMode_T> &aSupportedPortModes)
1319{
1320 static const PortMode_T aPortModes[] =
1321 {
1322 PortMode_Disconnected,
1323 PortMode_HostPipe,
1324 PortMode_HostDevice,
1325 PortMode_RawFile,
1326 PortMode_TCP,
1327 };
1328 aSupportedPortModes.assign(aPortModes,
1329 aPortModes + RT_ELEMENTS(aPortModes));
1330 return S_OK;
1331}
1332
1333HRESULT SystemProperties::getSupportedAudioDriverTypes(std::vector<AudioDriverType_T> &aSupportedAudioDriverTypes)
1334{
1335 static const AudioDriverType_T aAudioDriverTypes[] =
1336 {
1337 AudioDriverType_Default,
1338#ifdef RT_OS_WINDOWS
1339# if 0 /* deprecated for many years now */
1340 AudioDriverType_WinMM,
1341# endif
1342 AudioDriverType_WAS,
1343 AudioDriverType_DirectSound,
1344#endif
1345#ifdef RT_OS_DARWIN
1346 AudioDriverType_CoreAudio,
1347#endif
1348#ifdef RT_OS_OS2
1349 AudioDriverType_MMPM,
1350#endif
1351#ifdef RT_OS_SOLARIS
1352# if 0 /* deprecated for many years now */
1353 AudioDriverType_SolAudio,
1354# endif
1355#endif
1356#ifdef VBOX_WITH_AUDIO_ALSA
1357 AudioDriverType_ALSA,
1358#endif
1359#ifdef VBOX_WITH_AUDIO_OSS
1360 AudioDriverType_OSS,
1361#endif
1362#ifdef VBOX_WITH_AUDIO_PULSE
1363 AudioDriverType_Pulse,
1364#endif
1365 AudioDriverType_Null,
1366 };
1367 aSupportedAudioDriverTypes.assign(aAudioDriverTypes,
1368 aAudioDriverTypes + RT_ELEMENTS(aAudioDriverTypes));
1369 return S_OK;
1370}
1371
1372HRESULT SystemProperties::getExecutionEnginesForVmCpuArchitecture(CPUArchitecture_T aCpuArchitecture,
1373 std::vector<VMExecutionEngine_T> &aExecutionEngines)
1374{
1375 switch (aCpuArchitecture)
1376 {
1377 case CPUArchitecture_x86:
1378 case CPUArchitecture_AMD64:
1379 {
1380 static const VMExecutionEngine_T aExecEngines[] =
1381 {
1382 VMExecutionEngine_Default,
1383#ifdef RT_ARCH_AMD64
1384# ifndef VBOX_WITH_DRIVERLESS_FORCED
1385 VMExecutionEngine_HwVirt,
1386# endif
1387# ifdef VBOX_WITH_NATIVE_NEM
1388 VMExecutionEngine_NativeApi,
1389# endif
1390#endif
1391 VMExecutionEngine_Interpreter,
1392#ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER
1393 VMExecutionEngine_Recompiler,
1394#endif
1395 };
1396 aExecutionEngines.assign(aExecEngines,
1397 aExecEngines + RT_ELEMENTS(aExecEngines));
1398 break;
1399 }
1400
1401 case CPUArchitecture_ARMv8_32:
1402 aExecutionEngines.clear(); /* Currently not supported at all. */
1403 break;
1404
1405 case CPUArchitecture_ARMv8_64:
1406 {
1407#ifdef VBOX_WITH_VIRT_ARMV8
1408 static const VMExecutionEngine_T aExecEngines[] =
1409 {
1410 VMExecutionEngine_Default,
1411# ifdef VBOX_WITH_NATIVE_NEM
1412 VMExecutionEngine_NativeApi,
1413# endif
1414 };
1415 aExecutionEngines.assign(aExecEngines,
1416 aExecEngines + RT_ELEMENTS(aExecEngines));
1417#else
1418 aExecutionEngines.clear();
1419#endif
1420 break;
1421 }
1422
1423 default:
1424 AssertFailedStmt(aExecutionEngines.clear());
1425 break;
1426 }
1427
1428 return S_OK;
1429}
1430
1431
1432// public methods only for internal purposes
1433/////////////////////////////////////////////////////////////////////////////
1434
1435HRESULT SystemProperties::i_loadSettings(const settings::SystemProperties &data)
1436{
1437 AutoCaller autoCaller(this);
1438 if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
1439
1440 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1441 HRESULT hrc = i_setDefaultMachineFolder(data.strDefaultMachineFolder);
1442 if (FAILED(hrc)) return hrc;
1443
1444 hrc = i_setLoggingLevel(data.strLoggingLevel);
1445 if (FAILED(hrc)) return hrc;
1446
1447 hrc = i_setDefaultHardDiskFormat(data.strDefaultHardDiskFormat);
1448 if (FAILED(hrc)) return hrc;
1449
1450 hrc = i_setVRDEAuthLibrary(data.strVRDEAuthLibrary);
1451 if (FAILED(hrc)) return hrc;
1452
1453 hrc = i_setWebServiceAuthLibrary(data.strWebServiceAuthLibrary);
1454 if (FAILED(hrc)) return hrc;
1455
1456 hrc = i_setDefaultVRDEExtPack(data.strDefaultVRDEExtPack);
1457 if (FAILED(hrc)) return hrc;
1458
1459 hrc = i_setDefaultCryptoExtPack(data.strDefaultCryptoExtPack);
1460 if (FAILED(hrc)) return hrc;
1461
1462 m->uLogHistoryCount = data.uLogHistoryCount;
1463 m->uProxyMode = data.uProxyMode;
1464 m->strProxyUrl = data.strProxyUrl;
1465
1466 m->strLanguageId = data.strLanguageId;
1467
1468 hrc = i_setAutostartDatabasePath(data.strAutostartDatabasePath);
1469 if (FAILED(hrc)) return hrc;
1470
1471 {
1472 /* must ignore errors signalled here, because the guest additions
1473 * file may not exist, and in this case keep the empty string */
1474 ErrorInfoKeeper eik;
1475 (void)i_setDefaultAdditionsISO(data.strDefaultAdditionsISO);
1476 }
1477
1478 hrc = i_setDefaultFrontend(data.strDefaultFrontend);
1479 if (FAILED(hrc)) return hrc;
1480
1481 return S_OK;
1482}
1483
1484HRESULT SystemProperties::i_saveSettings(settings::SystemProperties &data)
1485{
1486 AutoCaller autoCaller(this);
1487 if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
1488
1489 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1490
1491 data = *m;
1492
1493 return S_OK;
1494}
1495
1496/**
1497 * Returns a medium format object corresponding to the given format
1498 * identifier or null if no such format.
1499 *
1500 * @param aFormat Format identifier.
1501 *
1502 * @return ComObjPtr<MediumFormat>
1503 */
1504ComObjPtr<MediumFormat> SystemProperties::i_mediumFormat(const Utf8Str &aFormat)
1505{
1506 ComObjPtr<MediumFormat> format;
1507
1508 AutoCaller autoCaller(this);
1509 AssertComRCReturn (autoCaller.hrc(), format);
1510
1511 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1512
1513 for (MediumFormatList::const_iterator it = m_llMediumFormats.begin();
1514 it != m_llMediumFormats.end();
1515 ++ it)
1516 {
1517 /* MediumFormat is all const, no need to lock */
1518
1519 if ((*it)->i_getId().compare(aFormat, Utf8Str::CaseInsensitive) == 0)
1520 {
1521 format = *it;
1522 break;
1523 }
1524 }
1525
1526 return format;
1527}
1528
1529/**
1530 * Returns a medium format object corresponding to the given file extension or
1531 * null if no such format.
1532 *
1533 * @param aExt File extension.
1534 *
1535 * @return ComObjPtr<MediumFormat>
1536 */
1537ComObjPtr<MediumFormat> SystemProperties::i_mediumFormatFromExtension(const Utf8Str &aExt)
1538{
1539 ComObjPtr<MediumFormat> format;
1540
1541 AutoCaller autoCaller(this);
1542 AssertComRCReturn (autoCaller.hrc(), format);
1543
1544 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1545
1546 bool fFound = false;
1547 for (MediumFormatList::const_iterator it = m_llMediumFormats.begin();
1548 it != m_llMediumFormats.end() && !fFound;
1549 ++it)
1550 {
1551 /* MediumFormat is all const, no need to lock */
1552 MediumFormat::StrArray aFileList = (*it)->i_getFileExtensions();
1553 for (MediumFormat::StrArray::const_iterator it1 = aFileList.begin();
1554 it1 != aFileList.end();
1555 ++it1)
1556 {
1557 if ((*it1).compare(aExt, Utf8Str::CaseInsensitive) == 0)
1558 {
1559 format = *it;
1560 fFound = true;
1561 break;
1562 }
1563 }
1564 }
1565
1566 return format;
1567}
1568
1569
1570/**
1571 * VD plugin load
1572 */
1573int SystemProperties::i_loadVDPlugin(const char *pszPluginLibrary)
1574{
1575 int vrc = VDPluginLoadFromFilename(pszPluginLibrary);
1576 LogFlowFunc(("pszPluginLibrary='%s' -> %Rrc\n", pszPluginLibrary, vrc));
1577 return vrc;
1578}
1579
1580/**
1581 * VD plugin unload
1582 */
1583int SystemProperties::i_unloadVDPlugin(const char *pszPluginLibrary)
1584{
1585 int vrc = VDPluginUnloadFromFilename(pszPluginLibrary);
1586 LogFlowFunc(("pszPluginLibrary='%s' -> %Rrc\n", pszPluginLibrary, vrc));
1587 return vrc;
1588}
1589
1590/**
1591 * Internally usable version of getDefaultAdditionsISO.
1592 */
1593HRESULT SystemProperties::i_getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO)
1594{
1595 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1596 if (m->strDefaultAdditionsISO.isNotEmpty())
1597 aDefaultAdditionsISO = m->strDefaultAdditionsISO;
1598 else
1599 {
1600 /* no guest additions, check if it showed up in the mean time */
1601 alock.release();
1602 AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
1603 if (m->strDefaultAdditionsISO.isEmpty())
1604 {
1605 ErrorInfoKeeper eik;
1606 (void)i_setDefaultAdditionsISO("");
1607 }
1608 aDefaultAdditionsISO = m->strDefaultAdditionsISO;
1609 }
1610 return S_OK;
1611}
1612
1613// private methods
1614/////////////////////////////////////////////////////////////////////////////
1615
1616/**
1617 * Returns the user's home directory. Wrapper around RTPathUserHome().
1618 * @param strPath
1619 * @return
1620 */
1621HRESULT SystemProperties::i_getUserHomeDirectory(Utf8Str &strPath)
1622{
1623 char szHome[RTPATH_MAX];
1624 int vrc = RTPathUserHome(szHome, sizeof(szHome));
1625 if (RT_FAILURE(vrc))
1626 return setErrorBoth(E_FAIL, vrc,
1627 tr("Cannot determine user home directory (%Rrc)"),
1628 vrc);
1629 strPath = szHome;
1630 return S_OK;
1631}
1632
1633/**
1634 * Internal implementation to set the default machine folder. Gets called
1635 * from the public attribute setter as well as loadSettings(). With 4.0,
1636 * the "default default" machine folder has changed, and we now require
1637 * a full path always.
1638 * @param strPath
1639 * @return
1640 */
1641HRESULT SystemProperties::i_setDefaultMachineFolder(const Utf8Str &strPath)
1642{
1643 Utf8Str path(strPath); // make modifiable
1644 if ( path.isEmpty() // used by API calls to reset the default
1645 || path == "Machines" // this value (exactly like this, without path) is stored
1646 // in VirtualBox.xml if user upgrades from before 4.0 and
1647 // has not changed the default machine folder
1648 )
1649 {
1650 // new default with VirtualBox 4.0: "$HOME/VirtualBox VMs"
1651 HRESULT hrc = i_getUserHomeDirectory(path);
1652 if (FAILED(hrc)) return hrc;
1653 path += RTPATH_SLASH_STR "VirtualBox VMs";
1654 }
1655
1656 if (!RTPathStartsWithRoot(path.c_str()))
1657 return setError(E_INVALIDARG,
1658 tr("Given default machine folder '%s' is not fully qualified"),
1659 path.c_str());
1660
1661 m->strDefaultMachineFolder = path;
1662
1663 return S_OK;
1664}
1665
1666HRESULT SystemProperties::i_setLoggingLevel(const com::Utf8Str &aLoggingLevel)
1667{
1668 Utf8Str useLoggingLevel(aLoggingLevel);
1669 if (useLoggingLevel.isEmpty())
1670 useLoggingLevel = VBOXSVC_LOG_DEFAULT;
1671 int vrc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), useLoggingLevel.c_str());
1672 // If failed and not the default logging level - try to use the default logging level.
1673 if (RT_FAILURE(vrc))
1674 {
1675 // If failed write message to the release log.
1676 LogRel(("Cannot set passed logging level=%s Error=%Rrc \n", useLoggingLevel.c_str(), vrc));
1677 // If attempted logging level not the default one then try the default one.
1678 if (!useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT))
1679 {
1680 vrc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), VBOXSVC_LOG_DEFAULT);
1681 // If failed report this to the release log.
1682 if (RT_FAILURE(vrc))
1683 LogRel(("Cannot set default logging level Error=%Rrc \n", vrc));
1684 }
1685 // On any failure - set default level as the one to be stored.
1686 useLoggingLevel = VBOXSVC_LOG_DEFAULT;
1687 }
1688 // Set to passed value or if default used/attempted (even if error condition) use empty string.
1689 m->strLoggingLevel = (useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT) ? "" : useLoggingLevel);
1690 return RT_SUCCESS(vrc) ? S_OK : E_FAIL;
1691}
1692
1693HRESULT SystemProperties::i_setDefaultHardDiskFormat(const com::Utf8Str &aFormat)
1694{
1695 if (!aFormat.isEmpty())
1696 m->strDefaultHardDiskFormat = aFormat;
1697 else
1698 m->strDefaultHardDiskFormat = "VDI";
1699
1700 return S_OK;
1701}
1702
1703HRESULT SystemProperties::i_setVRDEAuthLibrary(const com::Utf8Str &aPath)
1704{
1705 if (!aPath.isEmpty())
1706 m->strVRDEAuthLibrary = aPath;
1707 else
1708 m->strVRDEAuthLibrary = "VBoxAuth";
1709
1710 return S_OK;
1711}
1712
1713HRESULT SystemProperties::i_setWebServiceAuthLibrary(const com::Utf8Str &aPath)
1714{
1715 if (!aPath.isEmpty())
1716 m->strWebServiceAuthLibrary = aPath;
1717 else
1718 m->strWebServiceAuthLibrary = "VBoxAuth";
1719
1720 return S_OK;
1721}
1722
1723HRESULT SystemProperties::i_setDefaultVRDEExtPack(const com::Utf8Str &aExtPack)
1724{
1725 m->strDefaultVRDEExtPack = aExtPack;
1726
1727 return S_OK;
1728}
1729
1730HRESULT SystemProperties::i_setDefaultCryptoExtPack(const com::Utf8Str &aExtPack)
1731{
1732 m->strDefaultCryptoExtPack = aExtPack;
1733
1734 return S_OK;
1735}
1736
1737HRESULT SystemProperties::i_setAutostartDatabasePath(const com::Utf8Str &aPath)
1738{
1739 HRESULT hrc = S_OK;
1740 AutostartDb *autostartDb = this->mParent->i_getAutostartDb();
1741
1742 if (!aPath.isEmpty())
1743 {
1744 /* Update path in the autostart database. */
1745 int vrc = autostartDb->setAutostartDbPath(aPath.c_str());
1746 if (RT_SUCCESS(vrc))
1747 m->strAutostartDatabasePath = aPath;
1748 else
1749 hrc = setErrorBoth(E_FAIL, vrc, tr("Cannot set the autostart database path (%Rrc)"), vrc);
1750 }
1751 else
1752 {
1753 int vrc = autostartDb->setAutostartDbPath(NULL);
1754 if (RT_SUCCESS(vrc) || vrc == VERR_NOT_SUPPORTED)
1755 m->strAutostartDatabasePath = "";
1756 else
1757 hrc = setErrorBoth(E_FAIL, vrc, tr("Deleting the autostart database path failed (%Rrc)"), vrc);
1758 }
1759
1760 return hrc;
1761}
1762
1763HRESULT SystemProperties::i_setDefaultAdditionsISO(const com::Utf8Str &aPath)
1764{
1765 com::Utf8Str path(aPath);
1766 if (path.isEmpty())
1767 {
1768 char strTemp[RTPATH_MAX];
1769 int vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));
1770 AssertRC(vrc);
1771 Utf8Str strSrc1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso");
1772
1773 vrc = RTPathExecDir(strTemp, sizeof(strTemp));
1774 AssertRC(vrc);
1775 Utf8Str strSrc2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso");
1776
1777 vrc = RTPathUserHome(strTemp, sizeof(strTemp));
1778 AssertRC(vrc);
1779 Utf8Str strSrc3 = Utf8StrFmt("%s/VBoxGuestAdditions_%s.iso", strTemp, VirtualBox::i_getVersionNormalized().c_str());
1780
1781 /* Check the standard image locations */
1782 if (RTFileExists(strSrc1.c_str()))
1783 path = strSrc1;
1784 else if (RTFileExists(strSrc2.c_str()))
1785 path = strSrc2;
1786 else if (RTFileExists(strSrc3.c_str()))
1787 path = strSrc3;
1788 else
1789 return setError(E_FAIL,
1790 tr("Cannot determine default Guest Additions ISO location. Most likely they are not available"));
1791 }
1792
1793 if (!RTPathStartsWithRoot(path.c_str()))
1794 return setError(E_INVALIDARG,
1795 tr("Given default machine Guest Additions ISO file '%s' is not fully qualified"),
1796 path.c_str());
1797
1798 if (!RTFileExists(path.c_str()))
1799 return setError(E_INVALIDARG,
1800 tr("Given default machine Guest Additions ISO file '%s' does not exist"),
1801 path.c_str());
1802
1803 m->strDefaultAdditionsISO = path;
1804
1805 return S_OK;
1806}
1807
1808HRESULT SystemProperties::i_setDefaultFrontend(const com::Utf8Str &aDefaultFrontend)
1809{
1810 m->strDefaultFrontend = aDefaultFrontend;
1811
1812 return S_OK;
1813}
1814
1815HRESULT SystemProperties::getLanguageId(com::Utf8Str &aLanguageId)
1816{
1817#ifdef VBOX_WITH_MAIN_NLS
1818 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1819 aLanguageId = m->strLanguageId;
1820 alock.release();
1821
1822 HRESULT hrc = S_OK;
1823 if (aLanguageId.isEmpty())
1824 {
1825 char szLocale[256];
1826 memset(szLocale, 0, sizeof(szLocale));
1827 int vrc = RTLocaleQueryNormalizedBaseLocaleName(szLocale, sizeof(szLocale));
1828 if (RT_SUCCESS(vrc))
1829 aLanguageId = szLocale;
1830 else
1831 hrc = Global::vboxStatusCodeToCOM(vrc);
1832 }
1833 return hrc;
1834#else
1835 aLanguageId = "C";
1836 return S_OK;
1837#endif
1838}
1839
1840HRESULT SystemProperties::setLanguageId(const com::Utf8Str &aLanguageId)
1841{
1842#ifdef VBOX_WITH_MAIN_NLS
1843 VirtualBoxTranslator *pTranslator = VirtualBoxTranslator::instance();
1844 if (!pTranslator)
1845 return E_FAIL;
1846
1847 HRESULT hrc = S_OK;
1848 int vrc = pTranslator->i_loadLanguage(aLanguageId.c_str());
1849 if (RT_SUCCESS(vrc))
1850 {
1851 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1852 m->strLanguageId = aLanguageId;
1853 alock.release();
1854
1855 // VirtualBox::i_saveSettings() needs vbox write lock
1856 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1857 hrc = mParent->i_saveSettings();
1858 }
1859 else
1860 hrc = Global::vboxStatusCodeToCOM(vrc);
1861
1862 pTranslator->release();
1863
1864 if (SUCCEEDED(hrc))
1865 mParent->i_onLanguageChanged(aLanguageId);
1866
1867 return hrc;
1868#else
1869 NOREF(aLanguageId);
1870 return E_NOTIMPL;
1871#endif
1872}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use