VirtualBox

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

Last change on this file since 109008 was 109008, checked in by vboxsync, 6 days ago

VMM,Main: Working on ARM CPU profile support, which is neede/useful for getting info about the host CPU as well. The CPUDBENTRY typedef is used externally by Main, so we can't have two definitions of it, so left the bits that are common to both x86 and ARM in CPUDBENTRY and created sub-structures for each of the two targets/platforms. Also started reworking the VBoxCpuReport tool so we can use it on arm as well (much left to do there, though). jiraref:VBP-1598

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

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