VirtualBox

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

Last change on this file since 107402 was 107116, checked in by vboxsync, 2 months ago

/Config.kmk,Main: Added VBOX_WITH_X86_ON_ARM_ENABLED to the build system so the feature can be enabled via LocalConfig.kmk. jiraref:VBP-1466

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