VirtualBox

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

Last change on this file since 101068 was 101035, checked in by vboxsync, 18 months ago

Initial commit (based draft v2 / on patch v5) for implementing platform architecture support for x86 and ARM. bugref:10384

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.2 KB
Line 
1/* $Id: SystemPropertiesImpl.cpp 101035 2023-09-07 08:59:15Z 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::getSupportedClipboardModes(std::vector<ClipboardMode_T> &aSupportedClipboardModes)
1024{
1025 static const ClipboardMode_T aClipboardModes[] =
1026 {
1027 ClipboardMode_Disabled,
1028 ClipboardMode_HostToGuest,
1029 ClipboardMode_GuestToHost,
1030 ClipboardMode_Bidirectional,
1031 };
1032 aSupportedClipboardModes.assign(aClipboardModes,
1033 aClipboardModes + RT_ELEMENTS(aClipboardModes));
1034 return S_OK;
1035}
1036
1037HRESULT SystemProperties::getSupportedDnDModes(std::vector<DnDMode_T> &aSupportedDnDModes)
1038{
1039 static const DnDMode_T aDnDModes[] =
1040 {
1041 DnDMode_Disabled,
1042 DnDMode_HostToGuest,
1043 DnDMode_GuestToHost,
1044 DnDMode_Bidirectional,
1045 };
1046 aSupportedDnDModes.assign(aDnDModes,
1047 aDnDModes + RT_ELEMENTS(aDnDModes));
1048 return S_OK;
1049}
1050
1051HRESULT SystemProperties::getSupportedPointingHIDTypes(std::vector<PointingHIDType_T> &aSupportedPointingHIDTypes)
1052{
1053 static const PointingHIDType_T aPointingHIDTypes[] =
1054 {
1055 PointingHIDType_PS2Mouse,
1056#ifdef DEBUG
1057 PointingHIDType_USBMouse,
1058#endif
1059 PointingHIDType_USBTablet,
1060#ifdef DEBUG
1061 PointingHIDType_ComboMouse,
1062#endif
1063 PointingHIDType_USBMultiTouch,
1064 PointingHIDType_USBMultiTouchScreenPlusPad,
1065 };
1066 aSupportedPointingHIDTypes.assign(aPointingHIDTypes,
1067 aPointingHIDTypes + RT_ELEMENTS(aPointingHIDTypes));
1068 return S_OK;
1069}
1070
1071HRESULT SystemProperties::getSupportedKeyboardHIDTypes(std::vector<KeyboardHIDType_T> &aSupportedKeyboardHIDTypes)
1072{
1073 static const KeyboardHIDType_T aKeyboardHIDTypes[] =
1074 {
1075 KeyboardHIDType_PS2Keyboard,
1076 KeyboardHIDType_USBKeyboard,
1077#ifdef DEBUG
1078 KeyboardHIDType_ComboKeyboard,
1079#endif
1080 };
1081 aSupportedKeyboardHIDTypes.assign(aKeyboardHIDTypes,
1082 aKeyboardHIDTypes + RT_ELEMENTS(aKeyboardHIDTypes));
1083 return S_OK;
1084}
1085
1086HRESULT SystemProperties::getSupportedVFSTypes(std::vector<VFSType_T> &aSupportedVFSTypes)
1087{
1088 static const VFSType_T aVFSTypes[] =
1089 {
1090 VFSType_File,
1091 VFSType_Cloud,
1092 VFSType_S3,
1093#ifdef DEBUG
1094 VFSType_WebDav,
1095#endif
1096 };
1097 aSupportedVFSTypes.assign(aVFSTypes,
1098 aVFSTypes + RT_ELEMENTS(aVFSTypes));
1099 return S_OK;
1100}
1101
1102HRESULT SystemProperties::getSupportedImportOptions(std::vector<ImportOptions_T> &aSupportedImportOptions)
1103{
1104 static const ImportOptions_T aImportOptions[] =
1105 {
1106 ImportOptions_KeepAllMACs,
1107 ImportOptions_KeepNATMACs,
1108 ImportOptions_ImportToVDI,
1109 };
1110 aSupportedImportOptions.assign(aImportOptions,
1111 aImportOptions + RT_ELEMENTS(aImportOptions));
1112 return S_OK;
1113}
1114
1115HRESULT SystemProperties::getSupportedExportOptions(std::vector<ExportOptions_T> &aSupportedExportOptions)
1116{
1117 static const ExportOptions_T aExportOptions[] =
1118 {
1119 ExportOptions_CreateManifest,
1120 ExportOptions_ExportDVDImages,
1121 ExportOptions_StripAllMACs,
1122 ExportOptions_StripAllNonNATMACs,
1123 };
1124 aSupportedExportOptions.assign(aExportOptions,
1125 aExportOptions + RT_ELEMENTS(aExportOptions));
1126 return S_OK;
1127}
1128
1129HRESULT SystemProperties::getSupportedRecordingFeatures(std::vector<RecordingFeature_T> &aSupportedRecordingFeatures)
1130{
1131#ifdef VBOX_WITH_RECORDING
1132 static const RecordingFeature_T aRecordingFeatures[] =
1133 {
1134# ifdef VBOX_WITH_AUDIO_RECORDING
1135 RecordingFeature_Audio,
1136# endif
1137 RecordingFeature_Video,
1138 };
1139 aSupportedRecordingFeatures.assign(aRecordingFeatures,
1140 aRecordingFeatures + RT_ELEMENTS(aRecordingFeatures));
1141#else /* !VBOX_WITH_RECORDING */
1142 aSupportedRecordingFeatures.clear();
1143#endif /* VBOX_WITH_RECORDING */
1144 return S_OK;
1145}
1146
1147HRESULT SystemProperties::getSupportedRecordingAudioCodecs(std::vector<RecordingAudioCodec_T> &aSupportedRecordingAudioCodecs)
1148{
1149 static const RecordingAudioCodec_T aRecordingAudioCodecs[] =
1150 {
1151 RecordingAudioCodec_None,
1152#ifdef DEBUG
1153 RecordingAudioCodec_WavPCM,
1154#endif
1155#ifdef VBOX_WITH_LIBVORBIS
1156 RecordingAudioCodec_OggVorbis,
1157#endif
1158 };
1159 aSupportedRecordingAudioCodecs.assign(aRecordingAudioCodecs,
1160 aRecordingAudioCodecs + RT_ELEMENTS(aRecordingAudioCodecs));
1161 return S_OK;
1162}
1163
1164HRESULT SystemProperties::getSupportedRecordingVideoCodecs(std::vector<RecordingVideoCodec_T> &aSupportedRecordingVideoCodecs)
1165{
1166 static const RecordingVideoCodec_T aRecordingVideoCodecs[] =
1167 {
1168 RecordingVideoCodec_None,
1169#ifdef VBOX_WITH_LIBVPX
1170 RecordingVideoCodec_VP8,
1171#endif
1172#ifdef DEBUG
1173 RecordingVideoCodec_VP9,
1174 RecordingVideoCodec_AV1,
1175#endif
1176 };
1177 aSupportedRecordingVideoCodecs.assign(aRecordingVideoCodecs,
1178 aRecordingVideoCodecs + RT_ELEMENTS(aRecordingVideoCodecs));
1179 return S_OK;
1180}
1181
1182HRESULT SystemProperties::getSupportedRecordingVSModes(std::vector<RecordingVideoScalingMode_T> &aSupportedRecordingVideoScalingModes)
1183{
1184 static const RecordingVideoScalingMode_T aRecordingVideoScalingModes[] =
1185 {
1186 RecordingVideoScalingMode_None,
1187#ifdef DEBUG
1188 RecordingVideoScalingMode_NearestNeighbor,
1189 RecordingVideoScalingMode_Bilinear,
1190 RecordingVideoScalingMode_Bicubic,
1191#endif
1192 };
1193 aSupportedRecordingVideoScalingModes.assign(aRecordingVideoScalingModes,
1194 aRecordingVideoScalingModes + RT_ELEMENTS(aRecordingVideoScalingModes));
1195 return S_OK;
1196}
1197
1198HRESULT SystemProperties::getSupportedRecordingARCModes(std::vector<RecordingRateControlMode_T> &aSupportedRecordingAudioRateControlModes)
1199{
1200 static const RecordingRateControlMode_T aRecordingAudioRateControlModes[] =
1201 {
1202#ifdef DEBUG
1203 RecordingRateControlMode_ABR,
1204 RecordingRateControlMode_CBR,
1205#endif
1206 RecordingRateControlMode_VBR
1207 };
1208 aSupportedRecordingAudioRateControlModes.assign(aRecordingAudioRateControlModes,
1209 aRecordingAudioRateControlModes + RT_ELEMENTS(aRecordingAudioRateControlModes));
1210 return S_OK;
1211}
1212
1213HRESULT SystemProperties::getSupportedRecordingVRCModes(std::vector<RecordingRateControlMode_T> &aSupportedRecordingVideoRateControlModes)
1214{
1215 static const RecordingRateControlMode_T aRecordingVideoRateControlModes[] =
1216 {
1217#ifdef DEBUG
1218 RecordingRateControlMode_ABR,
1219 RecordingRateControlMode_CBR,
1220#endif
1221 RecordingRateControlMode_VBR
1222 };
1223 aSupportedRecordingVideoRateControlModes.assign(aRecordingVideoRateControlModes,
1224 aRecordingVideoRateControlModes + RT_ELEMENTS(aRecordingVideoRateControlModes));
1225 return S_OK;
1226}
1227
1228HRESULT SystemProperties::getSupportedCloneOptions(std::vector<CloneOptions_T> &aSupportedCloneOptions)
1229{
1230 static const CloneOptions_T aCloneOptions[] =
1231 {
1232 CloneOptions_Link,
1233 CloneOptions_KeepAllMACs,
1234 CloneOptions_KeepNATMACs,
1235 CloneOptions_KeepDiskNames,
1236 CloneOptions_KeepHwUUIDs,
1237 };
1238 aSupportedCloneOptions.assign(aCloneOptions,
1239 aCloneOptions + RT_ELEMENTS(aCloneOptions));
1240 return S_OK;
1241}
1242
1243HRESULT SystemProperties::getSupportedAutostopTypes(std::vector<AutostopType_T> &aSupportedAutostopTypes)
1244{
1245 static const AutostopType_T aAutostopTypes[] =
1246 {
1247 AutostopType_Disabled,
1248 AutostopType_SaveState,
1249 AutostopType_PowerOff,
1250 AutostopType_AcpiShutdown,
1251 };
1252 aSupportedAutostopTypes.assign(aAutostopTypes,
1253 aAutostopTypes + RT_ELEMENTS(aAutostopTypes));
1254 return S_OK;
1255}
1256
1257HRESULT SystemProperties::getSupportedVMProcPriorities(std::vector<VMProcPriority_T> &aSupportedVMProcPriorities)
1258{
1259 static const VMProcPriority_T aVMProcPriorities[] =
1260 {
1261 VMProcPriority_Default,
1262 VMProcPriority_Flat,
1263 VMProcPriority_Low,
1264 VMProcPriority_Normal,
1265 VMProcPriority_High,
1266 };
1267 aSupportedVMProcPriorities.assign(aVMProcPriorities,
1268 aVMProcPriorities + RT_ELEMENTS(aVMProcPriorities));
1269 return S_OK;
1270}
1271
1272HRESULT SystemProperties::getSupportedNetworkAttachmentTypes(std::vector<NetworkAttachmentType_T> &aSupportedNetworkAttachmentTypes)
1273{
1274 static const NetworkAttachmentType_T aNetworkAttachmentTypes[] =
1275 {
1276 NetworkAttachmentType_NAT,
1277 NetworkAttachmentType_Bridged,
1278 NetworkAttachmentType_Internal,
1279 NetworkAttachmentType_HostOnly,
1280#ifdef VBOX_WITH_VMNET
1281 NetworkAttachmentType_HostOnlyNetwork,
1282#endif /* VBOX_WITH_VMNET */
1283 NetworkAttachmentType_Generic,
1284 NetworkAttachmentType_NATNetwork,
1285#ifdef VBOX_WITH_CLOUD_NET
1286 NetworkAttachmentType_Cloud,
1287#endif
1288 NetworkAttachmentType_Null,
1289 };
1290 aSupportedNetworkAttachmentTypes.assign(aNetworkAttachmentTypes,
1291 aNetworkAttachmentTypes + RT_ELEMENTS(aNetworkAttachmentTypes));
1292 return S_OK;
1293}
1294
1295HRESULT SystemProperties::getSupportedPortModes(std::vector<PortMode_T> &aSupportedPortModes)
1296{
1297 static const PortMode_T aPortModes[] =
1298 {
1299 PortMode_Disconnected,
1300 PortMode_HostPipe,
1301 PortMode_HostDevice,
1302 PortMode_RawFile,
1303 PortMode_TCP,
1304 };
1305 aSupportedPortModes.assign(aPortModes,
1306 aPortModes + RT_ELEMENTS(aPortModes));
1307 return S_OK;
1308}
1309
1310HRESULT SystemProperties::getSupportedAudioDriverTypes(std::vector<AudioDriverType_T> &aSupportedAudioDriverTypes)
1311{
1312 static const AudioDriverType_T aAudioDriverTypes[] =
1313 {
1314 AudioDriverType_Default,
1315#ifdef RT_OS_WINDOWS
1316# if 0 /* deprecated for many years now */
1317 AudioDriverType_WinMM,
1318# endif
1319 AudioDriverType_WAS,
1320 AudioDriverType_DirectSound,
1321#endif
1322#ifdef RT_OS_DARWIN
1323 AudioDriverType_CoreAudio,
1324#endif
1325#ifdef RT_OS_OS2
1326 AudioDriverType_MMPM,
1327#endif
1328#ifdef RT_OS_SOLARIS
1329# if 0 /* deprecated for many years now */
1330 AudioDriverType_SolAudio,
1331# endif
1332#endif
1333#ifdef VBOX_WITH_AUDIO_ALSA
1334 AudioDriverType_ALSA,
1335#endif
1336#ifdef VBOX_WITH_AUDIO_OSS
1337 AudioDriverType_OSS,
1338#endif
1339#ifdef VBOX_WITH_AUDIO_PULSE
1340 AudioDriverType_Pulse,
1341#endif
1342 AudioDriverType_Null,
1343 };
1344 aSupportedAudioDriverTypes.assign(aAudioDriverTypes,
1345 aAudioDriverTypes + RT_ELEMENTS(aAudioDriverTypes));
1346 return S_OK;
1347}
1348
1349
1350// public methods only for internal purposes
1351/////////////////////////////////////////////////////////////////////////////
1352
1353HRESULT SystemProperties::i_loadSettings(const settings::SystemProperties &data)
1354{
1355 AutoCaller autoCaller(this);
1356 if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
1357
1358 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1359 HRESULT hrc = i_setDefaultMachineFolder(data.strDefaultMachineFolder);
1360 if (FAILED(hrc)) return hrc;
1361
1362 hrc = i_setLoggingLevel(data.strLoggingLevel);
1363 if (FAILED(hrc)) return hrc;
1364
1365 hrc = i_setDefaultHardDiskFormat(data.strDefaultHardDiskFormat);
1366 if (FAILED(hrc)) return hrc;
1367
1368 hrc = i_setVRDEAuthLibrary(data.strVRDEAuthLibrary);
1369 if (FAILED(hrc)) return hrc;
1370
1371 hrc = i_setWebServiceAuthLibrary(data.strWebServiceAuthLibrary);
1372 if (FAILED(hrc)) return hrc;
1373
1374 hrc = i_setDefaultVRDEExtPack(data.strDefaultVRDEExtPack);
1375 if (FAILED(hrc)) return hrc;
1376
1377 hrc = i_setDefaultCryptoExtPack(data.strDefaultCryptoExtPack);
1378 if (FAILED(hrc)) return hrc;
1379
1380 m->uLogHistoryCount = data.uLogHistoryCount;
1381 m->uProxyMode = data.uProxyMode;
1382 m->strProxyUrl = data.strProxyUrl;
1383
1384 m->strLanguageId = data.strLanguageId;
1385
1386 hrc = i_setAutostartDatabasePath(data.strAutostartDatabasePath);
1387 if (FAILED(hrc)) return hrc;
1388
1389 {
1390 /* must ignore errors signalled here, because the guest additions
1391 * file may not exist, and in this case keep the empty string */
1392 ErrorInfoKeeper eik;
1393 (void)i_setDefaultAdditionsISO(data.strDefaultAdditionsISO);
1394 }
1395
1396 hrc = i_setDefaultFrontend(data.strDefaultFrontend);
1397 if (FAILED(hrc)) return hrc;
1398
1399 return S_OK;
1400}
1401
1402HRESULT SystemProperties::i_saveSettings(settings::SystemProperties &data)
1403{
1404 AutoCaller autoCaller(this);
1405 if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
1406
1407 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1408
1409 data = *m;
1410
1411 return S_OK;
1412}
1413
1414/**
1415 * Returns a medium format object corresponding to the given format
1416 * identifier or null if no such format.
1417 *
1418 * @param aFormat Format identifier.
1419 *
1420 * @return ComObjPtr<MediumFormat>
1421 */
1422ComObjPtr<MediumFormat> SystemProperties::i_mediumFormat(const Utf8Str &aFormat)
1423{
1424 ComObjPtr<MediumFormat> format;
1425
1426 AutoCaller autoCaller(this);
1427 AssertComRCReturn (autoCaller.hrc(), format);
1428
1429 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1430
1431 for (MediumFormatList::const_iterator it = m_llMediumFormats.begin();
1432 it != m_llMediumFormats.end();
1433 ++ it)
1434 {
1435 /* MediumFormat is all const, no need to lock */
1436
1437 if ((*it)->i_getId().compare(aFormat, Utf8Str::CaseInsensitive) == 0)
1438 {
1439 format = *it;
1440 break;
1441 }
1442 }
1443
1444 return format;
1445}
1446
1447/**
1448 * Returns a medium format object corresponding to the given file extension or
1449 * null if no such format.
1450 *
1451 * @param aExt File extension.
1452 *
1453 * @return ComObjPtr<MediumFormat>
1454 */
1455ComObjPtr<MediumFormat> SystemProperties::i_mediumFormatFromExtension(const Utf8Str &aExt)
1456{
1457 ComObjPtr<MediumFormat> format;
1458
1459 AutoCaller autoCaller(this);
1460 AssertComRCReturn (autoCaller.hrc(), format);
1461
1462 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1463
1464 bool fFound = false;
1465 for (MediumFormatList::const_iterator it = m_llMediumFormats.begin();
1466 it != m_llMediumFormats.end() && !fFound;
1467 ++it)
1468 {
1469 /* MediumFormat is all const, no need to lock */
1470 MediumFormat::StrArray aFileList = (*it)->i_getFileExtensions();
1471 for (MediumFormat::StrArray::const_iterator it1 = aFileList.begin();
1472 it1 != aFileList.end();
1473 ++it1)
1474 {
1475 if ((*it1).compare(aExt, Utf8Str::CaseInsensitive) == 0)
1476 {
1477 format = *it;
1478 fFound = true;
1479 break;
1480 }
1481 }
1482 }
1483
1484 return format;
1485}
1486
1487
1488/**
1489 * VD plugin load
1490 */
1491int SystemProperties::i_loadVDPlugin(const char *pszPluginLibrary)
1492{
1493 int vrc = VDPluginLoadFromFilename(pszPluginLibrary);
1494 LogFlowFunc(("pszPluginLibrary='%s' -> %Rrc\n", pszPluginLibrary, vrc));
1495 return vrc;
1496}
1497
1498/**
1499 * VD plugin unload
1500 */
1501int SystemProperties::i_unloadVDPlugin(const char *pszPluginLibrary)
1502{
1503 int vrc = VDPluginUnloadFromFilename(pszPluginLibrary);
1504 LogFlowFunc(("pszPluginLibrary='%s' -> %Rrc\n", pszPluginLibrary, vrc));
1505 return vrc;
1506}
1507
1508/**
1509 * Internally usable version of getDefaultAdditionsISO.
1510 */
1511HRESULT SystemProperties::i_getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO)
1512{
1513 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1514 if (m->strDefaultAdditionsISO.isNotEmpty())
1515 aDefaultAdditionsISO = m->strDefaultAdditionsISO;
1516 else
1517 {
1518 /* no guest additions, check if it showed up in the mean time */
1519 alock.release();
1520 AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
1521 if (m->strDefaultAdditionsISO.isEmpty())
1522 {
1523 ErrorInfoKeeper eik;
1524 (void)i_setDefaultAdditionsISO("");
1525 }
1526 aDefaultAdditionsISO = m->strDefaultAdditionsISO;
1527 }
1528 return S_OK;
1529}
1530
1531// private methods
1532/////////////////////////////////////////////////////////////////////////////
1533
1534/**
1535 * Returns the user's home directory. Wrapper around RTPathUserHome().
1536 * @param strPath
1537 * @return
1538 */
1539HRESULT SystemProperties::i_getUserHomeDirectory(Utf8Str &strPath)
1540{
1541 char szHome[RTPATH_MAX];
1542 int vrc = RTPathUserHome(szHome, sizeof(szHome));
1543 if (RT_FAILURE(vrc))
1544 return setErrorBoth(E_FAIL, vrc,
1545 tr("Cannot determine user home directory (%Rrc)"),
1546 vrc);
1547 strPath = szHome;
1548 return S_OK;
1549}
1550
1551/**
1552 * Internal implementation to set the default machine folder. Gets called
1553 * from the public attribute setter as well as loadSettings(). With 4.0,
1554 * the "default default" machine folder has changed, and we now require
1555 * a full path always.
1556 * @param strPath
1557 * @return
1558 */
1559HRESULT SystemProperties::i_setDefaultMachineFolder(const Utf8Str &strPath)
1560{
1561 Utf8Str path(strPath); // make modifiable
1562 if ( path.isEmpty() // used by API calls to reset the default
1563 || path == "Machines" // this value (exactly like this, without path) is stored
1564 // in VirtualBox.xml if user upgrades from before 4.0 and
1565 // has not changed the default machine folder
1566 )
1567 {
1568 // new default with VirtualBox 4.0: "$HOME/VirtualBox VMs"
1569 HRESULT hrc = i_getUserHomeDirectory(path);
1570 if (FAILED(hrc)) return hrc;
1571 path += RTPATH_SLASH_STR "VirtualBox VMs";
1572 }
1573
1574 if (!RTPathStartsWithRoot(path.c_str()))
1575 return setError(E_INVALIDARG,
1576 tr("Given default machine folder '%s' is not fully qualified"),
1577 path.c_str());
1578
1579 m->strDefaultMachineFolder = path;
1580
1581 return S_OK;
1582}
1583
1584HRESULT SystemProperties::i_setLoggingLevel(const com::Utf8Str &aLoggingLevel)
1585{
1586 Utf8Str useLoggingLevel(aLoggingLevel);
1587 if (useLoggingLevel.isEmpty())
1588 useLoggingLevel = VBOXSVC_LOG_DEFAULT;
1589 int vrc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), useLoggingLevel.c_str());
1590 // If failed and not the default logging level - try to use the default logging level.
1591 if (RT_FAILURE(vrc))
1592 {
1593 // If failed write message to the release log.
1594 LogRel(("Cannot set passed logging level=%s Error=%Rrc \n", useLoggingLevel.c_str(), vrc));
1595 // If attempted logging level not the default one then try the default one.
1596 if (!useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT))
1597 {
1598 vrc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), VBOXSVC_LOG_DEFAULT);
1599 // If failed report this to the release log.
1600 if (RT_FAILURE(vrc))
1601 LogRel(("Cannot set default logging level Error=%Rrc \n", vrc));
1602 }
1603 // On any failure - set default level as the one to be stored.
1604 useLoggingLevel = VBOXSVC_LOG_DEFAULT;
1605 }
1606 // Set to passed value or if default used/attempted (even if error condition) use empty string.
1607 m->strLoggingLevel = (useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT) ? "" : useLoggingLevel);
1608 return RT_SUCCESS(vrc) ? S_OK : E_FAIL;
1609}
1610
1611HRESULT SystemProperties::i_setDefaultHardDiskFormat(const com::Utf8Str &aFormat)
1612{
1613 if (!aFormat.isEmpty())
1614 m->strDefaultHardDiskFormat = aFormat;
1615 else
1616 m->strDefaultHardDiskFormat = "VDI";
1617
1618 return S_OK;
1619}
1620
1621HRESULT SystemProperties::i_setVRDEAuthLibrary(const com::Utf8Str &aPath)
1622{
1623 if (!aPath.isEmpty())
1624 m->strVRDEAuthLibrary = aPath;
1625 else
1626 m->strVRDEAuthLibrary = "VBoxAuth";
1627
1628 return S_OK;
1629}
1630
1631HRESULT SystemProperties::i_setWebServiceAuthLibrary(const com::Utf8Str &aPath)
1632{
1633 if (!aPath.isEmpty())
1634 m->strWebServiceAuthLibrary = aPath;
1635 else
1636 m->strWebServiceAuthLibrary = "VBoxAuth";
1637
1638 return S_OK;
1639}
1640
1641HRESULT SystemProperties::i_setDefaultVRDEExtPack(const com::Utf8Str &aExtPack)
1642{
1643 m->strDefaultVRDEExtPack = aExtPack;
1644
1645 return S_OK;
1646}
1647
1648HRESULT SystemProperties::i_setDefaultCryptoExtPack(const com::Utf8Str &aExtPack)
1649{
1650 m->strDefaultCryptoExtPack = aExtPack;
1651
1652 return S_OK;
1653}
1654
1655HRESULT SystemProperties::i_setAutostartDatabasePath(const com::Utf8Str &aPath)
1656{
1657 HRESULT hrc = S_OK;
1658 AutostartDb *autostartDb = this->mParent->i_getAutostartDb();
1659
1660 if (!aPath.isEmpty())
1661 {
1662 /* Update path in the autostart database. */
1663 int vrc = autostartDb->setAutostartDbPath(aPath.c_str());
1664 if (RT_SUCCESS(vrc))
1665 m->strAutostartDatabasePath = aPath;
1666 else
1667 hrc = setErrorBoth(E_FAIL, vrc, tr("Cannot set the autostart database path (%Rrc)"), vrc);
1668 }
1669 else
1670 {
1671 int vrc = autostartDb->setAutostartDbPath(NULL);
1672 if (RT_SUCCESS(vrc) || vrc == VERR_NOT_SUPPORTED)
1673 m->strAutostartDatabasePath = "";
1674 else
1675 hrc = setErrorBoth(E_FAIL, vrc, tr("Deleting the autostart database path failed (%Rrc)"), vrc);
1676 }
1677
1678 return hrc;
1679}
1680
1681HRESULT SystemProperties::i_setDefaultAdditionsISO(const com::Utf8Str &aPath)
1682{
1683 com::Utf8Str path(aPath);
1684 if (path.isEmpty())
1685 {
1686 char strTemp[RTPATH_MAX];
1687 int vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));
1688 AssertRC(vrc);
1689 Utf8Str strSrc1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso");
1690
1691 vrc = RTPathExecDir(strTemp, sizeof(strTemp));
1692 AssertRC(vrc);
1693 Utf8Str strSrc2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso");
1694
1695 vrc = RTPathUserHome(strTemp, sizeof(strTemp));
1696 AssertRC(vrc);
1697 Utf8Str strSrc3 = Utf8StrFmt("%s/VBoxGuestAdditions_%s.iso", strTemp, VirtualBox::i_getVersionNormalized().c_str());
1698
1699 /* Check the standard image locations */
1700 if (RTFileExists(strSrc1.c_str()))
1701 path = strSrc1;
1702 else if (RTFileExists(strSrc2.c_str()))
1703 path = strSrc2;
1704 else if (RTFileExists(strSrc3.c_str()))
1705 path = strSrc3;
1706 else
1707 return setError(E_FAIL,
1708 tr("Cannot determine default Guest Additions ISO location. Most likely they are not available"));
1709 }
1710
1711 if (!RTPathStartsWithRoot(path.c_str()))
1712 return setError(E_INVALIDARG,
1713 tr("Given default machine Guest Additions ISO file '%s' is not fully qualified"),
1714 path.c_str());
1715
1716 if (!RTFileExists(path.c_str()))
1717 return setError(E_INVALIDARG,
1718 tr("Given default machine Guest Additions ISO file '%s' does not exist"),
1719 path.c_str());
1720
1721 m->strDefaultAdditionsISO = path;
1722
1723 return S_OK;
1724}
1725
1726HRESULT SystemProperties::i_setDefaultFrontend(const com::Utf8Str &aDefaultFrontend)
1727{
1728 m->strDefaultFrontend = aDefaultFrontend;
1729
1730 return S_OK;
1731}
1732
1733HRESULT SystemProperties::getLanguageId(com::Utf8Str &aLanguageId)
1734{
1735#ifdef VBOX_WITH_MAIN_NLS
1736 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1737 aLanguageId = m->strLanguageId;
1738 alock.release();
1739
1740 HRESULT hrc = S_OK;
1741 if (aLanguageId.isEmpty())
1742 {
1743 char szLocale[256];
1744 memset(szLocale, 0, sizeof(szLocale));
1745 int vrc = RTLocaleQueryNormalizedBaseLocaleName(szLocale, sizeof(szLocale));
1746 if (RT_SUCCESS(vrc))
1747 aLanguageId = szLocale;
1748 else
1749 hrc = Global::vboxStatusCodeToCOM(vrc);
1750 }
1751 return hrc;
1752#else
1753 aLanguageId = "C";
1754 return S_OK;
1755#endif
1756}
1757
1758HRESULT SystemProperties::setLanguageId(const com::Utf8Str &aLanguageId)
1759{
1760#ifdef VBOX_WITH_MAIN_NLS
1761 VirtualBoxTranslator *pTranslator = VirtualBoxTranslator::instance();
1762 if (!pTranslator)
1763 return E_FAIL;
1764
1765 HRESULT hrc = S_OK;
1766 int vrc = pTranslator->i_loadLanguage(aLanguageId.c_str());
1767 if (RT_SUCCESS(vrc))
1768 {
1769 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1770 m->strLanguageId = aLanguageId;
1771 alock.release();
1772
1773 // VirtualBox::i_saveSettings() needs vbox write lock
1774 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1775 hrc = mParent->i_saveSettings();
1776 }
1777 else
1778 hrc = Global::vboxStatusCodeToCOM(vrc);
1779
1780 pTranslator->release();
1781
1782 if (SUCCEEDED(hrc))
1783 mParent->i_onLanguageChanged(aLanguageId);
1784
1785 return hrc;
1786#else
1787 NOREF(aLanguageId);
1788 return E_NOTIMPL;
1789#endif
1790}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette