VirtualBox

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

Last change on this file since 95364 was 95364, checked in by vboxsync, 3 years ago

Main/FE: Added new audio driver type "default" to make it possible to move VMs (appliances) between different platforms without the need of changing the audio driver explicitly. When the "default" driver is selected, the best audio backend option for a platform will be used.

While at it, also added the "WAS" (Windows Audio Session) driver type for which we only had a hack so far. This now can be explicitly selected, also by the frontends. bugref:10051

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 70.8 KB
Line 
1/* $Id: SystemPropertiesImpl.cpp 95364 2022-06-24 16:51:21Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#define LOG_GROUP LOG_GROUP_MAIN_SYSTEMPROPERTIES
19#include "SystemPropertiesImpl.h"
20#include "VirtualBoxImpl.h"
21#include "MachineImpl.h"
22#ifdef VBOX_WITH_EXTPACK
23# include "ExtPackManagerImpl.h"
24#endif
25#include "CPUProfileImpl.h"
26#include "AutoCaller.h"
27#include "Global.h"
28#include "LoggingNew.h"
29#include "AutostartDb.h"
30#include "VirtualBoxTranslator.h"
31
32// generated header
33#include "SchemaDefs.h"
34
35#include <iprt/dir.h>
36#include <iprt/ldr.h>
37#include <iprt/locale.h>
38#include <iprt/path.h>
39#include <iprt/string.h>
40#include <iprt/uri.h>
41#include <iprt/cpp/utils.h>
42
43#include <iprt/errcore.h>
44#include <VBox/param.h>
45#include <VBox/settings.h>
46#include <VBox/vd.h>
47#include <VBox/vmm/cpum.h>
48
49// defines
50/////////////////////////////////////////////////////////////////////////////
51
52// constructor / destructor
53/////////////////////////////////////////////////////////////////////////////
54
55SystemProperties::SystemProperties()
56 : mParent(NULL)
57 , m(new settings::SystemProperties)
58 , m_fLoadedX86CPUProfiles(false)
59{
60}
61
62SystemProperties::~SystemProperties()
63{
64 delete m;
65}
66
67
68HRESULT SystemProperties::FinalConstruct()
69{
70 return BaseFinalConstruct();
71}
72
73void SystemProperties::FinalRelease()
74{
75 uninit();
76 BaseFinalRelease();
77}
78
79// public methods only for internal purposes
80/////////////////////////////////////////////////////////////////////////////
81
82/**
83 * Initializes the system information object.
84 *
85 * @returns COM result indicator
86 */
87HRESULT SystemProperties::init(VirtualBox *aParent)
88{
89 LogFlowThisFunc(("aParent=%p\n", aParent));
90
91 ComAssertRet(aParent, E_FAIL);
92
93 /* Enclose the state transition NotReady->InInit->Ready */
94 AutoInitSpan autoInitSpan(this);
95 AssertReturn(autoInitSpan.isOk(), E_FAIL);
96
97 unconst(mParent) = aParent;
98
99 i_setDefaultMachineFolder(Utf8Str::Empty);
100 i_setLoggingLevel(Utf8Str::Empty);
101 i_setDefaultHardDiskFormat(Utf8Str::Empty);
102
103 i_setVRDEAuthLibrary(Utf8Str::Empty);
104 i_setDefaultVRDEExtPack(Utf8Str::Empty);
105 i_setDefaultCryptoExtPack(Utf8Str::Empty);
106
107 m->uLogHistoryCount = 3;
108
109
110 /* On Windows, OS X and Solaris, HW virtualization use isn't exclusive
111 * by default so that VT-x or AMD-V can be shared with other
112 * hypervisors without requiring user intervention.
113 * NB: See also SystemProperties constructor in settings.h
114 */
115#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)
116 m->fExclusiveHwVirt = false;
117#else
118 m->fExclusiveHwVirt = true;
119#endif
120
121 HRESULT rc = S_OK;
122
123 /* Fetch info of all available hd backends. */
124
125 /// @todo NEWMEDIA VDBackendInfo needs to be improved to let us enumerate
126 /// any number of backends
127
128 VDBACKENDINFO aVDInfo[100];
129 unsigned cEntries;
130 int vrc = VDBackendInfo(RT_ELEMENTS(aVDInfo), aVDInfo, &cEntries);
131 AssertRC(vrc);
132 if (RT_SUCCESS(vrc))
133 {
134 for (unsigned i = 0; i < cEntries; ++ i)
135 {
136 ComObjPtr<MediumFormat> hdf;
137 rc = hdf.createObject();
138 if (FAILED(rc)) break;
139
140 rc = hdf->init(&aVDInfo[i]);
141 if (FAILED(rc)) break;
142
143 m_llMediumFormats.push_back(hdf);
144 }
145 }
146
147 /* Confirm a successful initialization */
148 if (SUCCEEDED(rc))
149 autoInitSpan.setSucceeded();
150
151 return rc;
152}
153
154/**
155 * Uninitializes the instance and sets the ready flag to FALSE.
156 * Called either from FinalRelease() or by the parent when it gets destroyed.
157 */
158void SystemProperties::uninit()
159{
160 LogFlowThisFunc(("\n"));
161
162 /* Enclose the state transition Ready->InUninit->NotReady */
163 AutoUninitSpan autoUninitSpan(this);
164 if (autoUninitSpan.uninitDone())
165 return;
166
167 unconst(mParent) = NULL;
168}
169
170// wrapped ISystemProperties properties
171/////////////////////////////////////////////////////////////////////////////
172
173HRESULT SystemProperties::getMinGuestRAM(ULONG *minRAM)
174
175{
176 /* no need to lock, this is const */
177 AssertCompile(MM_RAM_MIN_IN_MB >= SchemaDefs::MinGuestRAM);
178 *minRAM = MM_RAM_MIN_IN_MB;
179
180 return S_OK;
181}
182
183HRESULT SystemProperties::getMaxGuestRAM(ULONG *maxRAM)
184{
185 /* no need to lock, this is const */
186 AssertCompile(MM_RAM_MAX_IN_MB <= SchemaDefs::MaxGuestRAM);
187 ULONG maxRAMSys = MM_RAM_MAX_IN_MB;
188 ULONG maxRAMArch = maxRAMSys;
189 *maxRAM = RT_MIN(maxRAMSys, maxRAMArch);
190
191 return S_OK;
192}
193
194HRESULT SystemProperties::getMinGuestVRAM(ULONG *minVRAM)
195{
196 /* no need to lock, this is const */
197 *minVRAM = SchemaDefs::MinGuestVRAM;
198
199 return S_OK;
200}
201
202HRESULT SystemProperties::getMaxGuestVRAM(ULONG *maxVRAM)
203{
204 /* no need to lock, this is const */
205 *maxVRAM = SchemaDefs::MaxGuestVRAM;
206
207 return S_OK;
208}
209
210HRESULT SystemProperties::getMinGuestCPUCount(ULONG *minCPUCount)
211{
212 /* no need to lock, this is const */
213 *minCPUCount = SchemaDefs::MinCPUCount; // VMM_MIN_CPU_COUNT
214
215 return S_OK;
216}
217
218HRESULT SystemProperties::getMaxGuestCPUCount(ULONG *maxCPUCount)
219{
220 /* no need to lock, this is const */
221 *maxCPUCount = SchemaDefs::MaxCPUCount; // VMM_MAX_CPU_COUNT
222
223 return S_OK;
224}
225
226HRESULT SystemProperties::getMaxGuestMonitors(ULONG *maxMonitors)
227{
228
229 /* no need to lock, this is const */
230 *maxMonitors = SchemaDefs::MaxGuestMonitors;
231
232 return S_OK;
233}
234
235
236HRESULT SystemProperties::getInfoVDSize(LONG64 *infoVDSize)
237{
238 /*
239 * The BIOS supports currently 32 bit LBA numbers (implementing the full
240 * 48 bit range is in theory trivial, but the crappy compiler makes things
241 * more difficult). This translates to almost 2 TiBytes (to be on the safe
242 * side, the reported limit is 1 MiByte less than that, as the total number
243 * of sectors should fit in 32 bits, too), which should be enough for the
244 * moment. Since the MBR partition tables support only 32bit sector numbers
245 * and thus the BIOS can only boot from disks smaller than 2T this is a
246 * rather hard limit.
247 *
248 * The virtual ATA/SATA disks support complete LBA48, and SCSI supports
249 * LBA64 (almost, more like LBA55 in practice), so the theoretical maximum
250 * disk size is 128 PiByte/16 EiByte. The GUI works nicely with 6 orders
251 * of magnitude, but not with 11..13 orders of magnitude.
252 */
253 /* no need to lock, this is const */
254 *infoVDSize = 2 * _1T - _1M;
255
256 return S_OK;
257}
258
259
260HRESULT SystemProperties::getSerialPortCount(ULONG *count)
261{
262 /* no need to lock, this is const */
263 *count = SchemaDefs::SerialPortCount;
264
265 return S_OK;
266}
267
268
269HRESULT SystemProperties::getParallelPortCount(ULONG *count)
270{
271 /* no need to lock, this is const */
272 *count = SchemaDefs::ParallelPortCount;
273
274 return S_OK;
275}
276
277
278HRESULT SystemProperties::getMaxBootPosition(ULONG *aMaxBootPosition)
279{
280 /* no need to lock, this is const */
281 *aMaxBootPosition = SchemaDefs::MaxBootPosition;
282
283 return S_OK;
284}
285
286
287HRESULT SystemProperties::getRawModeSupported(BOOL *aRawModeSupported)
288{
289 *aRawModeSupported = FALSE;
290 return S_OK;
291}
292
293
294HRESULT SystemProperties::getExclusiveHwVirt(BOOL *aExclusiveHwVirt)
295{
296 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
297
298 *aExclusiveHwVirt = m->fExclusiveHwVirt;
299
300 return S_OK;
301}
302
303HRESULT SystemProperties::setExclusiveHwVirt(BOOL aExclusiveHwVirt)
304{
305 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
306 m->fExclusiveHwVirt = !!aExclusiveHwVirt;
307 alock.release();
308
309 // VirtualBox::i_saveSettings() needs vbox write lock
310 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
311 HRESULT rc = mParent->i_saveSettings();
312
313 return rc;
314}
315
316HRESULT SystemProperties::getMaxNetworkAdapters(ChipsetType_T aChipset, ULONG *aMaxNetworkAdapters)
317{
318 /* no need for locking, no state */
319 uint32_t uResult = Global::getMaxNetworkAdapters(aChipset);
320 if (uResult == 0)
321 AssertMsgFailed(("Invalid chipset type %d\n", aChipset));
322 *aMaxNetworkAdapters = uResult;
323 return S_OK;
324}
325
326HRESULT SystemProperties::getMaxNetworkAdaptersOfType(ChipsetType_T aChipset, NetworkAttachmentType_T aType, ULONG *count)
327{
328 /* no need for locking, no state */
329 uint32_t uResult = Global::getMaxNetworkAdapters(aChipset);
330 if (uResult == 0)
331 AssertMsgFailed(("Invalid chipset type %d\n", aChipset));
332
333 switch (aType)
334 {
335 case NetworkAttachmentType_NAT:
336 case NetworkAttachmentType_Internal:
337 case NetworkAttachmentType_NATNetwork:
338 /* chipset default is OK */
339 break;
340 case NetworkAttachmentType_Bridged:
341 /* Maybe use current host interface count here? */
342 break;
343 case NetworkAttachmentType_HostOnly:
344 uResult = RT_MIN(uResult, 8);
345 break;
346 default:
347 AssertMsgFailed(("Unhandled attachment type %d\n", aType));
348 }
349
350 *count = uResult;
351
352 return S_OK;
353}
354
355
356HRESULT SystemProperties::getMaxDevicesPerPortForStorageBus(StorageBus_T aBus,
357 ULONG *aMaxDevicesPerPort)
358{
359 /* no need to lock, this is const */
360 switch (aBus)
361 {
362 case StorageBus_SATA:
363 case StorageBus_SCSI:
364 case StorageBus_SAS:
365 case StorageBus_USB:
366 case StorageBus_PCIe:
367 case StorageBus_VirtioSCSI:
368 {
369 /* SATA and both SCSI controllers only support one device per port. */
370 *aMaxDevicesPerPort = 1;
371 break;
372 }
373 case StorageBus_IDE:
374 case StorageBus_Floppy:
375 {
376 /* The IDE and Floppy controllers support 2 devices. One as master
377 * and one as slave (or floppy drive 0 and 1). */
378 *aMaxDevicesPerPort = 2;
379 break;
380 }
381 default:
382 AssertMsgFailed(("Invalid bus type %d\n", aBus));
383 }
384
385 return S_OK;
386}
387
388HRESULT SystemProperties::getMinPortCountForStorageBus(StorageBus_T aBus,
389 ULONG *aMinPortCount)
390{
391 /* no need to lock, this is const */
392 switch (aBus)
393 {
394 case StorageBus_SATA:
395 case StorageBus_SAS:
396 case StorageBus_PCIe:
397 case StorageBus_VirtioSCSI:
398 {
399 *aMinPortCount = 1;
400 break;
401 }
402 case StorageBus_SCSI:
403 {
404 *aMinPortCount = 16;
405 break;
406 }
407 case StorageBus_IDE:
408 {
409 *aMinPortCount = 2;
410 break;
411 }
412 case StorageBus_Floppy:
413 {
414 *aMinPortCount = 1;
415 break;
416 }
417 case StorageBus_USB:
418 {
419 *aMinPortCount = 8;
420 break;
421 }
422 default:
423 AssertMsgFailed(("Invalid bus type %d\n", aBus));
424 }
425
426 return S_OK;
427}
428
429HRESULT SystemProperties::getMaxPortCountForStorageBus(StorageBus_T aBus,
430 ULONG *aMaxPortCount)
431{
432 /* no need to lock, this is const */
433 switch (aBus)
434 {
435 case StorageBus_SATA:
436 {
437 *aMaxPortCount = 30;
438 break;
439 }
440 case StorageBus_SCSI:
441 {
442 *aMaxPortCount = 16;
443 break;
444 }
445 case StorageBus_IDE:
446 {
447 *aMaxPortCount = 2;
448 break;
449 }
450 case StorageBus_Floppy:
451 {
452 *aMaxPortCount = 1;
453 break;
454 }
455 case StorageBus_SAS:
456 case StorageBus_PCIe:
457 {
458 *aMaxPortCount = 255;
459 break;
460 }
461 case StorageBus_USB:
462 {
463 *aMaxPortCount = 8;
464 break;
465 }
466 case StorageBus_VirtioSCSI:
467 {
468 *aMaxPortCount = 256;
469 break;
470 }
471 default:
472 AssertMsgFailed(("Invalid bus type %d\n", aBus));
473 }
474
475 return S_OK;
476}
477
478HRESULT SystemProperties::getMaxInstancesOfStorageBus(ChipsetType_T aChipset,
479 StorageBus_T aBus,
480 ULONG *aMaxInstances)
481{
482 ULONG cCtrs = 0;
483
484 /* no need to lock, this is const */
485 switch (aBus)
486 {
487 case StorageBus_SATA:
488 case StorageBus_SCSI:
489 case StorageBus_SAS:
490 case StorageBus_PCIe:
491 case StorageBus_VirtioSCSI:
492 cCtrs = aChipset == ChipsetType_ICH9 ? 8 : 1;
493 break;
494 case StorageBus_USB:
495 case StorageBus_IDE:
496 case StorageBus_Floppy:
497 {
498 cCtrs = 1;
499 break;
500 }
501 default:
502 AssertMsgFailed(("Invalid bus type %d\n", aBus));
503 }
504
505 *aMaxInstances = cCtrs;
506
507 return S_OK;
508}
509
510HRESULT SystemProperties::getDeviceTypesForStorageBus(StorageBus_T aBus,
511 std::vector<DeviceType_T> &aDeviceTypes)
512{
513 aDeviceTypes.resize(0);
514
515 /* no need to lock, this is const */
516 switch (aBus)
517 {
518 case StorageBus_IDE:
519 case StorageBus_SATA:
520 case StorageBus_SCSI:
521 case StorageBus_SAS:
522 case StorageBus_USB:
523 case StorageBus_VirtioSCSI:
524 {
525 aDeviceTypes.resize(2);
526 aDeviceTypes[0] = DeviceType_DVD;
527 aDeviceTypes[1] = DeviceType_HardDisk;
528 break;
529 }
530 case StorageBus_Floppy:
531 {
532 aDeviceTypes.resize(1);
533 aDeviceTypes[0] = DeviceType_Floppy;
534 break;
535 }
536 case StorageBus_PCIe:
537 {
538 aDeviceTypes.resize(1);
539 aDeviceTypes[0] = DeviceType_HardDisk;
540 break;
541 }
542 default:
543 AssertMsgFailed(("Invalid bus type %d\n", aBus));
544 }
545
546 return S_OK;
547}
548
549HRESULT SystemProperties::getStorageBusForStorageControllerType(StorageControllerType_T aStorageControllerType,
550 StorageBus_T *aStorageBus)
551{
552 /* no need to lock, this is const */
553 switch (aStorageControllerType)
554 {
555 case StorageControllerType_LsiLogic:
556 case StorageControllerType_BusLogic:
557 *aStorageBus = StorageBus_SCSI;
558 break;
559 case StorageControllerType_IntelAhci:
560 *aStorageBus = StorageBus_SATA;
561 break;
562 case StorageControllerType_PIIX3:
563 case StorageControllerType_PIIX4:
564 case StorageControllerType_ICH6:
565 *aStorageBus = StorageBus_IDE;
566 break;
567 case StorageControllerType_I82078:
568 *aStorageBus = StorageBus_Floppy;
569 break;
570 case StorageControllerType_LsiLogicSas:
571 *aStorageBus = StorageBus_SAS;
572 break;
573 case StorageControllerType_USB:
574 *aStorageBus = StorageBus_USB;
575 break;
576 case StorageControllerType_NVMe:
577 *aStorageBus = StorageBus_PCIe;
578 break;
579 case StorageControllerType_VirtioSCSI:
580 *aStorageBus = StorageBus_VirtioSCSI;
581 break;
582 default:
583 return setError(E_FAIL, tr("Invalid storage controller type %d\n"), aStorageBus);
584 }
585
586 return S_OK;
587}
588
589HRESULT SystemProperties::getStorageControllerTypesForStorageBus(StorageBus_T aStorageBus,
590 std::vector<StorageControllerType_T> &aStorageControllerTypes)
591{
592 aStorageControllerTypes.resize(0);
593
594 /* no need to lock, this is const */
595 switch (aStorageBus)
596 {
597 case StorageBus_IDE:
598 aStorageControllerTypes.resize(3);
599 aStorageControllerTypes[0] = StorageControllerType_PIIX4;
600 aStorageControllerTypes[1] = StorageControllerType_PIIX3;
601 aStorageControllerTypes[2] = StorageControllerType_ICH6;
602 break;
603 case StorageBus_SATA:
604 aStorageControllerTypes.resize(1);
605 aStorageControllerTypes[0] = StorageControllerType_IntelAhci;
606 break;
607 case StorageBus_SCSI:
608 aStorageControllerTypes.resize(2);
609 aStorageControllerTypes[0] = StorageControllerType_LsiLogic;
610 aStorageControllerTypes[1] = StorageControllerType_BusLogic;
611 break;
612 case StorageBus_Floppy:
613 aStorageControllerTypes.resize(1);
614 aStorageControllerTypes[0] = StorageControllerType_I82078;
615 break;
616 case StorageBus_SAS:
617 aStorageControllerTypes.resize(1);
618 aStorageControllerTypes[0] = StorageControllerType_LsiLogicSas;
619 break;
620 case StorageBus_USB:
621 aStorageControllerTypes.resize(1);
622 aStorageControllerTypes[0] = StorageControllerType_USB;
623 break;
624 case StorageBus_PCIe:
625 aStorageControllerTypes.resize(1);
626 aStorageControllerTypes[0] = StorageControllerType_NVMe;
627 break;
628 case StorageBus_VirtioSCSI:
629 aStorageControllerTypes.resize(1);
630 aStorageControllerTypes[0] = StorageControllerType_VirtioSCSI;
631 break;
632 default:
633 return setError(E_FAIL, tr("Invalid storage bus %d\n"), aStorageBus);
634 }
635
636 return S_OK;
637}
638
639HRESULT SystemProperties::getDefaultIoCacheSettingForStorageController(StorageControllerType_T aControllerType,
640 BOOL *aEnabled)
641{
642 /* no need to lock, this is const */
643 switch (aControllerType)
644 {
645 case StorageControllerType_LsiLogic:
646 case StorageControllerType_BusLogic:
647 case StorageControllerType_IntelAhci:
648 case StorageControllerType_LsiLogicSas:
649 case StorageControllerType_USB:
650 case StorageControllerType_NVMe:
651 case StorageControllerType_VirtioSCSI:
652 *aEnabled = false;
653 break;
654 case StorageControllerType_PIIX3:
655 case StorageControllerType_PIIX4:
656 case StorageControllerType_ICH6:
657 case StorageControllerType_I82078:
658 *aEnabled = true;
659 break;
660 default:
661 AssertMsgFailed(("Invalid controller type %d\n", aControllerType));
662 }
663 return S_OK;
664}
665
666HRESULT SystemProperties::getStorageControllerHotplugCapable(StorageControllerType_T aControllerType,
667 BOOL *aHotplugCapable)
668{
669 switch (aControllerType)
670 {
671 case StorageControllerType_IntelAhci:
672 case StorageControllerType_USB:
673 *aHotplugCapable = true;
674 break;
675 case StorageControllerType_LsiLogic:
676 case StorageControllerType_LsiLogicSas:
677 case StorageControllerType_BusLogic:
678 case StorageControllerType_NVMe:
679 case StorageControllerType_VirtioSCSI:
680 case StorageControllerType_PIIX3:
681 case StorageControllerType_PIIX4:
682 case StorageControllerType_ICH6:
683 case StorageControllerType_I82078:
684 *aHotplugCapable = false;
685 break;
686 default:
687 AssertMsgFailedReturn(("Invalid controller type %d\n", aControllerType), E_FAIL);
688 }
689
690 return S_OK;
691}
692
693HRESULT SystemProperties::getMaxInstancesOfUSBControllerType(ChipsetType_T aChipset,
694 USBControllerType_T aType,
695 ULONG *aMaxInstances)
696{
697 NOREF(aChipset);
698 ULONG cCtrs = 0;
699
700 /* no need to lock, this is const */
701 switch (aType)
702 {
703 case USBControllerType_OHCI:
704 case USBControllerType_EHCI:
705 case USBControllerType_XHCI:
706 {
707 cCtrs = 1;
708 break;
709 }
710 default:
711 AssertMsgFailed(("Invalid bus type %d\n", aType));
712 }
713
714 *aMaxInstances = cCtrs;
715
716 return S_OK;
717}
718
719HRESULT SystemProperties::getCPUProfiles(CPUArchitecture_T aArchitecture, const com::Utf8Str &aNamePattern,
720 std::vector<ComPtr<ICPUProfile> > &aProfiles)
721{
722 /*
723 * Validate and adjust the architecture.
724 */
725 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
726 CPUArchitecture_T enmSecondaryArch = aArchitecture;
727 bool fLoaded;
728 switch (aArchitecture)
729 {
730 case CPUArchitecture_Any:
731 aArchitecture = CPUArchitecture_AMD64;
732 RT_FALL_THROUGH();
733 case CPUArchitecture_AMD64:
734 enmSecondaryArch = CPUArchitecture_x86;
735 RT_FALL_THROUGH();
736 case CPUArchitecture_x86:
737 fLoaded = m_fLoadedX86CPUProfiles;
738 break;
739 default:
740 return setError(E_INVALIDARG, tr("Invalid or unsupported architecture value: %d"), aArchitecture);
741 }
742
743 /*
744 * Do we need to load the profiles?
745 */
746 HRESULT hrc;
747 if (fLoaded)
748 hrc = S_OK;
749 else
750 {
751 alock.release();
752 AutoWriteLock alockWrite(this COMMA_LOCKVAL_SRC_POS);
753
754 /*
755 * Translate the architecture to a VMM module handle.
756 */
757 const char *pszVMM;
758 switch (aArchitecture)
759 {
760 case CPUArchitecture_AMD64:
761 case CPUArchitecture_x86:
762 pszVMM = "VBoxVMM";
763 fLoaded = m_fLoadedX86CPUProfiles;
764 break;
765 default:
766 AssertFailedReturn(E_INVALIDARG);
767 }
768 if (fLoaded)
769 hrc = S_OK;
770 else
771 {
772 char szPath[RTPATH_MAX];
773 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
774 if (RT_SUCCESS(vrc))
775 vrc = RTPathAppend(szPath, sizeof(szPath), pszVMM);
776 if (RT_SUCCESS(vrc))
777 vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
778 if (RT_SUCCESS(vrc))
779 {
780 RTLDRMOD hMod = NIL_RTLDRMOD;
781 vrc = RTLdrLoad(szPath, &hMod);
782 if (RT_SUCCESS(vrc))
783 {
784 /*
785 * Resolve the CPUMDb APIs we need.
786 */
787 PFNCPUMDBGETENTRIES pfnGetEntries
788 = (PFNCPUMDBGETENTRIES)RTLdrGetFunction(hMod, "CPUMR3DbGetEntries");
789 PFNCPUMDBGETENTRYBYINDEX pfnGetEntryByIndex
790 = (PFNCPUMDBGETENTRYBYINDEX)RTLdrGetFunction(hMod, "CPUMR3DbGetEntryByIndex");
791 if (pfnGetEntries && pfnGetEntryByIndex)
792 {
793 size_t const cExistingProfiles = m_llCPUProfiles.size();
794
795 /*
796 * Instantate the profiles.
797 */
798 hrc = S_OK;
799 uint32_t const cEntries = pfnGetEntries();
800 for (uint32_t i = 0; i < cEntries; i++)
801 {
802 PCCPUMDBENTRY pDbEntry = pfnGetEntryByIndex(i);
803 AssertBreakStmt(pDbEntry, hrc = setError(E_UNEXPECTED, "CPUMR3DbGetEntryByIndex failed for %i", i));
804
805 ComObjPtr<CPUProfile> ptrProfile;
806 hrc = ptrProfile.createObject();
807 if (SUCCEEDED(hrc))
808 {
809 hrc = ptrProfile->initFromDbEntry(pDbEntry);
810 if (SUCCEEDED(hrc))
811 {
812 try
813 {
814 m_llCPUProfiles.push_back(ptrProfile);
815 continue;
816 }
817 catch (std::bad_alloc &)
818 {
819 hrc = E_OUTOFMEMORY;
820 }
821 }
822 }
823 break;
824 }
825
826 /*
827 * On success update the flag and retake the read lock.
828 * If we fail, drop the profiles we added to the list.
829 */
830 if (SUCCEEDED(hrc))
831 {
832 switch (aArchitecture)
833 {
834 case CPUArchitecture_AMD64:
835 case CPUArchitecture_x86:
836 m_fLoadedX86CPUProfiles = true;
837 break;
838 default:
839 AssertFailedStmt(hrc = E_INVALIDARG);
840 }
841
842 alockWrite.release();
843 alock.acquire();
844 }
845 else
846 m_llCPUProfiles.resize(cExistingProfiles);
847 }
848 else
849 hrc = setErrorVrc(VERR_SYMBOL_NOT_FOUND,
850 tr("'%s' is missing symbols: CPUMR3DbGetEntries, CPUMR3DbGetEntryByIndex"), szPath);
851 RTLdrClose(hMod);
852 }
853 else
854 hrc = setErrorVrc(vrc, tr("Failed to construct load '%s': %Rrc"), szPath, vrc);
855 }
856 else
857 hrc = setErrorVrc(vrc, tr("Failed to construct path to the VMM DLL/Dylib/SharedObject: %Rrc"), vrc);
858 }
859 }
860 if (SUCCEEDED(hrc))
861 {
862 /*
863 * Return the matching profiles.
864 */
865 /* Count matches: */
866 size_t cMatches = 0;
867 for (CPUProfileList_T::const_iterator it = m_llCPUProfiles.begin(); it != m_llCPUProfiles.end(); ++it)
868 if ((*it)->i_match(aArchitecture, enmSecondaryArch, aNamePattern))
869 cMatches++;
870
871 /* Resize the output array. */
872 try
873 {
874 aProfiles.resize(cMatches);
875 }
876 catch (std::bad_alloc &)
877 {
878 aProfiles.resize(0);
879 hrc = E_OUTOFMEMORY;
880 }
881
882 /* Get the return objects: */
883 if (SUCCEEDED(hrc) && cMatches > 0)
884 {
885 size_t iMatch = 0;
886 for (CPUProfileList_T::const_iterator it = m_llCPUProfiles.begin(); it != m_llCPUProfiles.end(); ++it)
887 if ((*it)->i_match(aArchitecture, enmSecondaryArch, aNamePattern))
888 {
889 AssertBreakStmt(iMatch < cMatches, hrc = E_UNEXPECTED);
890 hrc = (*it).queryInterfaceTo(aProfiles[iMatch].asOutParam());
891 if (SUCCEEDED(hrc))
892 iMatch++;
893 else
894 break;
895 }
896 AssertStmt(iMatch == cMatches || FAILED(hrc), hrc = E_UNEXPECTED);
897 }
898 }
899 return hrc;
900}
901
902
903HRESULT SystemProperties::getDefaultMachineFolder(com::Utf8Str &aDefaultMachineFolder)
904{
905 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
906 aDefaultMachineFolder = m->strDefaultMachineFolder;
907 return S_OK;
908}
909
910HRESULT SystemProperties::setDefaultMachineFolder(const com::Utf8Str &aDefaultMachineFolder)
911{
912 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
913 HRESULT rc = i_setDefaultMachineFolder(aDefaultMachineFolder);
914 alock.release();
915 if (SUCCEEDED(rc))
916 {
917 // VirtualBox::i_saveSettings() needs vbox write lock
918 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
919 rc = mParent->i_saveSettings();
920 }
921
922 return rc;
923}
924
925HRESULT SystemProperties::getLoggingLevel(com::Utf8Str &aLoggingLevel)
926{
927 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
928
929 aLoggingLevel = m->strLoggingLevel;
930
931 if (aLoggingLevel.isEmpty())
932 aLoggingLevel = VBOXSVC_LOG_DEFAULT;
933
934 return S_OK;
935}
936
937
938HRESULT SystemProperties::setLoggingLevel(const com::Utf8Str &aLoggingLevel)
939{
940 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
941 HRESULT rc = i_setLoggingLevel(aLoggingLevel);
942 alock.release();
943
944 if (SUCCEEDED(rc))
945 {
946 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
947 rc = mParent->i_saveSettings();
948 }
949 else
950 LogRel(("Cannot set passed logging level=%s, or the default one - Error=%Rhrc \n", aLoggingLevel.c_str(), rc));
951
952 return rc;
953}
954
955HRESULT SystemProperties::getMediumFormats(std::vector<ComPtr<IMediumFormat> > &aMediumFormats)
956{
957 MediumFormatList mediumFormats(m_llMediumFormats);
958 aMediumFormats.resize(mediumFormats.size());
959 size_t i = 0;
960 for (MediumFormatList::const_iterator it = mediumFormats.begin(); it != mediumFormats.end(); ++it, ++i)
961 (*it).queryInterfaceTo(aMediumFormats[i].asOutParam());
962 return S_OK;
963}
964
965HRESULT SystemProperties::getDefaultHardDiskFormat(com::Utf8Str &aDefaultHardDiskFormat)
966{
967 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
968 aDefaultHardDiskFormat = m->strDefaultHardDiskFormat;
969 return S_OK;
970}
971
972
973HRESULT SystemProperties::setDefaultHardDiskFormat(const com::Utf8Str &aDefaultHardDiskFormat)
974{
975 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
976 HRESULT rc = i_setDefaultHardDiskFormat(aDefaultHardDiskFormat);
977 alock.release();
978 if (SUCCEEDED(rc))
979 {
980 // VirtualBox::i_saveSettings() needs vbox write lock
981 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
982 rc = mParent->i_saveSettings();
983 }
984
985 return rc;
986}
987
988HRESULT SystemProperties::getFreeDiskSpaceWarning(LONG64 *aFreeSpace)
989{
990 NOREF(aFreeSpace);
991 ReturnComNotImplemented();
992}
993
994HRESULT SystemProperties::setFreeDiskSpaceWarning(LONG64 /* aFreeSpace */)
995{
996 ReturnComNotImplemented();
997}
998
999HRESULT SystemProperties::getFreeDiskSpacePercentWarning(ULONG *aFreeSpacePercent)
1000{
1001 NOREF(aFreeSpacePercent);
1002 ReturnComNotImplemented();
1003}
1004
1005HRESULT SystemProperties::setFreeDiskSpacePercentWarning(ULONG /* aFreeSpacePercent */)
1006{
1007 ReturnComNotImplemented();
1008}
1009
1010HRESULT SystemProperties::getFreeDiskSpaceError(LONG64 *aFreeSpace)
1011{
1012 NOREF(aFreeSpace);
1013 ReturnComNotImplemented();
1014}
1015
1016HRESULT SystemProperties::setFreeDiskSpaceError(LONG64 /* aFreeSpace */)
1017{
1018 ReturnComNotImplemented();
1019}
1020
1021HRESULT SystemProperties::getFreeDiskSpacePercentError(ULONG *aFreeSpacePercent)
1022{
1023 NOREF(aFreeSpacePercent);
1024 ReturnComNotImplemented();
1025}
1026
1027HRESULT SystemProperties::setFreeDiskSpacePercentError(ULONG /* aFreeSpacePercent */)
1028{
1029 ReturnComNotImplemented();
1030}
1031
1032HRESULT SystemProperties::getVRDEAuthLibrary(com::Utf8Str &aVRDEAuthLibrary)
1033{
1034 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1035
1036 aVRDEAuthLibrary = m->strVRDEAuthLibrary;
1037
1038 return S_OK;
1039}
1040
1041HRESULT SystemProperties::setVRDEAuthLibrary(const com::Utf8Str &aVRDEAuthLibrary)
1042{
1043 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1044 HRESULT rc = i_setVRDEAuthLibrary(aVRDEAuthLibrary);
1045 alock.release();
1046 if (SUCCEEDED(rc))
1047 {
1048 // VirtualBox::i_saveSettings() needs vbox write lock
1049 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1050 rc = mParent->i_saveSettings();
1051 }
1052
1053 return rc;
1054}
1055
1056HRESULT SystemProperties::getWebServiceAuthLibrary(com::Utf8Str &aWebServiceAuthLibrary)
1057{
1058 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1059
1060 aWebServiceAuthLibrary = m->strWebServiceAuthLibrary;
1061
1062 return S_OK;
1063}
1064
1065HRESULT SystemProperties::setWebServiceAuthLibrary(const com::Utf8Str &aWebServiceAuthLibrary)
1066{
1067 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1068 HRESULT rc = i_setWebServiceAuthLibrary(aWebServiceAuthLibrary);
1069 alock.release();
1070
1071 if (SUCCEEDED(rc))
1072 {
1073 // VirtualBox::i_saveSettings() needs vbox write lock
1074 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1075 rc = mParent->i_saveSettings();
1076 }
1077
1078 return rc;
1079}
1080
1081HRESULT SystemProperties::getDefaultVRDEExtPack(com::Utf8Str &aExtPack)
1082{
1083 HRESULT hrc = S_OK;
1084 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1085 Utf8Str strExtPack(m->strDefaultVRDEExtPack);
1086 if (strExtPack.isNotEmpty())
1087 {
1088 if (strExtPack.equals(VBOXVRDP_KLUDGE_EXTPACK_NAME))
1089 hrc = S_OK;
1090 else
1091#ifdef VBOX_WITH_EXTPACK
1092 hrc = mParent->i_getExtPackManager()->i_checkVrdeExtPack(&strExtPack);
1093#else
1094 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), strExtPack.c_str());
1095#endif
1096 }
1097 else
1098 {
1099#ifdef VBOX_WITH_EXTPACK
1100 hrc = mParent->i_getExtPackManager()->i_getDefaultVrdeExtPack(&strExtPack);
1101#endif
1102 if (strExtPack.isEmpty())
1103 {
1104 /*
1105 * Klugde - check if VBoxVRDP.dll/.so/.dylib is installed.
1106 * This is hardcoded uglyness, sorry.
1107 */
1108 char szPath[RTPATH_MAX];
1109 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
1110 if (RT_SUCCESS(vrc))
1111 vrc = RTPathAppend(szPath, sizeof(szPath), "VBoxVRDP");
1112 if (RT_SUCCESS(vrc))
1113 vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
1114 if (RT_SUCCESS(vrc) && RTFileExists(szPath))
1115 {
1116 /* Illegal extpack name, so no conflict. */
1117 strExtPack = VBOXVRDP_KLUDGE_EXTPACK_NAME;
1118 }
1119 }
1120 }
1121
1122 if (SUCCEEDED(hrc))
1123 aExtPack = strExtPack;
1124
1125 return S_OK;
1126}
1127
1128
1129HRESULT SystemProperties::setDefaultVRDEExtPack(const com::Utf8Str &aExtPack)
1130{
1131 HRESULT hrc = S_OK;
1132 if (aExtPack.isNotEmpty())
1133 {
1134 if (aExtPack.equals(VBOXVRDP_KLUDGE_EXTPACK_NAME))
1135 hrc = S_OK;
1136 else
1137#ifdef VBOX_WITH_EXTPACK
1138 hrc = mParent->i_getExtPackManager()->i_checkVrdeExtPack(&aExtPack);
1139#else
1140 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), aExtPack.c_str());
1141#endif
1142 }
1143 if (SUCCEEDED(hrc))
1144 {
1145 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1146 hrc = i_setDefaultVRDEExtPack(aExtPack);
1147 if (SUCCEEDED(hrc))
1148 {
1149 /* VirtualBox::i_saveSettings() needs the VirtualBox write lock. */
1150 alock.release();
1151 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1152 hrc = mParent->i_saveSettings();
1153 }
1154 }
1155
1156 return hrc;
1157}
1158
1159
1160HRESULT SystemProperties::getDefaultCryptoExtPack(com::Utf8Str &aExtPack)
1161{
1162 HRESULT hrc = S_OK;
1163 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1164 Utf8Str strExtPack(m->strDefaultCryptoExtPack);
1165 if (strExtPack.isNotEmpty())
1166 {
1167 if (strExtPack.equals(VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME))
1168 hrc = S_OK;
1169 else
1170#ifdef VBOX_WITH_EXTPACK
1171 hrc = mParent->i_getExtPackManager()->i_checkCryptoExtPack(&strExtPack);
1172#else
1173 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), strExtPack.c_str());
1174#endif
1175 }
1176 else
1177 {
1178#ifdef VBOX_WITH_EXTPACK
1179 hrc = mParent->i_getExtPackManager()->i_getDefaultCryptoExtPack(&strExtPack);
1180#endif
1181 if (strExtPack.isEmpty())
1182 {
1183 /*
1184 * Klugde - check if VBoxPuelCrypto.dll/.so/.dylib is installed.
1185 * This is hardcoded uglyness, sorry.
1186 */
1187 char szPath[RTPATH_MAX];
1188 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
1189 if (RT_SUCCESS(vrc))
1190 vrc = RTPathAppend(szPath, sizeof(szPath), "VBoxPuelCrypto");
1191 if (RT_SUCCESS(vrc))
1192 vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
1193 if (RT_SUCCESS(vrc) && RTFileExists(szPath))
1194 {
1195 /* Illegal extpack name, so no conflict. */
1196 strExtPack = VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME;
1197 }
1198 }
1199 }
1200
1201 if (SUCCEEDED(hrc))
1202 aExtPack = strExtPack;
1203
1204 return S_OK;
1205}
1206
1207
1208HRESULT SystemProperties::setDefaultCryptoExtPack(const com::Utf8Str &aExtPack)
1209{
1210 HRESULT hrc = S_OK;
1211 if (aExtPack.isNotEmpty())
1212 {
1213 if (aExtPack.equals(VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME))
1214 hrc = S_OK;
1215 else
1216#ifdef VBOX_WITH_EXTPACK
1217 hrc = mParent->i_getExtPackManager()->i_checkCryptoExtPack(&aExtPack);
1218#else
1219 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), aExtPack.c_str());
1220#endif
1221 }
1222 if (SUCCEEDED(hrc))
1223 {
1224 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1225 hrc = i_setDefaultCryptoExtPack(aExtPack);
1226 if (SUCCEEDED(hrc))
1227 {
1228 /* VirtualBox::i_saveSettings() needs the VirtualBox write lock. */
1229 alock.release();
1230 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1231 hrc = mParent->i_saveSettings();
1232 }
1233 }
1234
1235 return hrc;
1236}
1237
1238
1239HRESULT SystemProperties::getLogHistoryCount(ULONG *count)
1240{
1241 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1242
1243 *count = m->uLogHistoryCount;
1244
1245 return S_OK;
1246}
1247
1248
1249HRESULT SystemProperties::setLogHistoryCount(ULONG count)
1250{
1251 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1252 m->uLogHistoryCount = count;
1253 alock.release();
1254
1255 // VirtualBox::i_saveSettings() needs vbox write lock
1256 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1257 HRESULT rc = mParent->i_saveSettings();
1258
1259 return rc;
1260}
1261
1262HRESULT SystemProperties::getDefaultAudioDriver(AudioDriverType_T *aAudioDriver)
1263{
1264 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1265
1266 *aAudioDriver = settings::MachineConfigFile::getHostDefaultAudioDriver();
1267
1268 return S_OK;
1269}
1270
1271HRESULT SystemProperties::getAutostartDatabasePath(com::Utf8Str &aAutostartDbPath)
1272{
1273 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1274
1275 aAutostartDbPath = m->strAutostartDatabasePath;
1276
1277 return S_OK;
1278}
1279
1280HRESULT SystemProperties::setAutostartDatabasePath(const com::Utf8Str &aAutostartDbPath)
1281{
1282 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1283 HRESULT rc = i_setAutostartDatabasePath(aAutostartDbPath);
1284 alock.release();
1285
1286 if (SUCCEEDED(rc))
1287 {
1288 // VirtualBox::i_saveSettings() needs vbox write lock
1289 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1290 rc = mParent->i_saveSettings();
1291 }
1292
1293 return rc;
1294}
1295
1296HRESULT SystemProperties::getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO)
1297{
1298 return i_getDefaultAdditionsISO(aDefaultAdditionsISO);
1299}
1300
1301HRESULT SystemProperties::setDefaultAdditionsISO(const com::Utf8Str &aDefaultAdditionsISO)
1302{
1303 RT_NOREF(aDefaultAdditionsISO);
1304 /** @todo not yet implemented, settings handling is missing */
1305 ReturnComNotImplemented();
1306#if 0 /* not implemented */
1307 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1308 HRESULT rc = i_setDefaultAdditionsISO(aDefaultAdditionsISO);
1309 alock.release();
1310
1311 if (SUCCEEDED(rc))
1312 {
1313 // VirtualBox::i_saveSettings() needs vbox write lock
1314 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1315 rc = mParent->i_saveSettings();
1316 }
1317
1318 return rc;
1319#endif
1320}
1321
1322HRESULT SystemProperties::getDefaultFrontend(com::Utf8Str &aDefaultFrontend)
1323{
1324 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1325 aDefaultFrontend = m->strDefaultFrontend;
1326 return S_OK;
1327}
1328
1329HRESULT SystemProperties::setDefaultFrontend(const com::Utf8Str &aDefaultFrontend)
1330{
1331 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1332 if (m->strDefaultFrontend == aDefaultFrontend)
1333 return S_OK;
1334 HRESULT rc = i_setDefaultFrontend(aDefaultFrontend);
1335 alock.release();
1336
1337 if (SUCCEEDED(rc))
1338 {
1339 // VirtualBox::i_saveSettings() needs vbox write lock
1340 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
1341 rc = mParent->i_saveSettings();
1342 }
1343
1344 return rc;
1345}
1346
1347HRESULT SystemProperties::getScreenShotFormats(std::vector<BitmapFormat_T> &aBitmapFormats)
1348{
1349 aBitmapFormats.push_back(BitmapFormat_BGR0);
1350 aBitmapFormats.push_back(BitmapFormat_BGRA);
1351 aBitmapFormats.push_back(BitmapFormat_RGBA);
1352 aBitmapFormats.push_back(BitmapFormat_PNG);
1353 return S_OK;
1354}
1355
1356HRESULT SystemProperties::getProxyMode(ProxyMode_T *pProxyMode)
1357{
1358 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1359 ProxyMode_T enmMode = *pProxyMode = (ProxyMode_T)m->uProxyMode;
1360 AssertMsgReturn(enmMode == ProxyMode_System || enmMode == ProxyMode_NoProxy || enmMode == ProxyMode_Manual,
1361 ("enmMode=%d\n", enmMode), E_UNEXPECTED);
1362 return S_OK;
1363}
1364
1365HRESULT SystemProperties::setProxyMode(ProxyMode_T aProxyMode)
1366{
1367 /* Validate input. */
1368 switch (aProxyMode)
1369 {
1370 case ProxyMode_System:
1371 case ProxyMode_NoProxy:
1372 case ProxyMode_Manual:
1373 break;
1374 default:
1375 return setError(E_INVALIDARG, tr("Invalid ProxyMode value: %d"), (int)aProxyMode);
1376 }
1377
1378 /* Set and write out settings. */
1379 {
1380 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1381 m->uProxyMode = aProxyMode;
1382 }
1383 AutoWriteLock alock(mParent COMMA_LOCKVAL_SRC_POS); /* required for saving. */
1384 return mParent->i_saveSettings();
1385}
1386
1387HRESULT SystemProperties::getProxyURL(com::Utf8Str &aProxyURL)
1388{
1389 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1390 aProxyURL = m->strProxyUrl;
1391 return S_OK;
1392}
1393
1394HRESULT SystemProperties::setProxyURL(const com::Utf8Str &aProxyURL)
1395{
1396 /*
1397 * Validate input.
1398 */
1399 Utf8Str const *pStrProxyUrl = &aProxyURL;
1400 Utf8Str strTmp;
1401 if (pStrProxyUrl->isNotEmpty())
1402 {
1403 /* RTUriParse requires a scheme, so append 'http://' if none seems present: */
1404 if (pStrProxyUrl->find("://") == RTCString::npos)
1405 {
1406 strTmp.printf("http://%s", aProxyURL.c_str());
1407 pStrProxyUrl = &strTmp;
1408 }
1409
1410 /* Use RTUriParse to check the format. There must be a hostname, but nothing
1411 can follow it and the port. */
1412 RTURIPARSED Parsed;
1413 int vrc = RTUriParse(pStrProxyUrl->c_str(), &Parsed);
1414 if (RT_FAILURE(vrc))
1415 return setErrorBoth(E_INVALIDARG, vrc, tr("Failed to parse proxy URL: %Rrc"), vrc);
1416 if ( Parsed.cchAuthorityHost == 0
1417 && !RTUriIsSchemeMatch(pStrProxyUrl->c_str(), "direct"))
1418 return setError(E_INVALIDARG, tr("Proxy URL must include a hostname"));
1419 if (Parsed.cchPath > 0)
1420 return setError(E_INVALIDARG, tr("Proxy URL must not include a path component (%.*s)"),
1421 Parsed.cchPath, pStrProxyUrl->c_str() + Parsed.offPath);
1422 if (Parsed.cchQuery > 0)
1423 return setError(E_INVALIDARG, tr("Proxy URL must not include a query component (?%.*s)"),
1424 Parsed.cchQuery, pStrProxyUrl->c_str() + Parsed.offQuery);
1425 if (Parsed.cchFragment > 0)
1426 return setError(E_INVALIDARG, tr("Proxy URL must not include a fragment component (#%.*s)"),
1427 Parsed.cchFragment, pStrProxyUrl->c_str() + Parsed.offFragment);
1428 }
1429
1430 /*
1431 * Set and write out settings.
1432 */
1433 {
1434 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1435 m->strProxyUrl = *pStrProxyUrl;
1436 }
1437 AutoWriteLock alock(mParent COMMA_LOCKVAL_SRC_POS); /* required for saving. */
1438 return mParent->i_saveSettings();
1439}
1440
1441HRESULT SystemProperties::getSupportedParavirtProviders(std::vector<ParavirtProvider_T> &aSupportedParavirtProviders)
1442{
1443 static const ParavirtProvider_T aParavirtProviders[] =
1444 {
1445 ParavirtProvider_None,
1446 ParavirtProvider_Default,
1447 ParavirtProvider_Legacy,
1448 ParavirtProvider_Minimal,
1449 ParavirtProvider_HyperV,
1450 ParavirtProvider_KVM,
1451 };
1452 aSupportedParavirtProviders.assign(aParavirtProviders,
1453 aParavirtProviders + RT_ELEMENTS(aParavirtProviders));
1454 return S_OK;
1455}
1456
1457HRESULT SystemProperties::getSupportedClipboardModes(std::vector<ClipboardMode_T> &aSupportedClipboardModes)
1458{
1459 static const ClipboardMode_T aClipboardModes[] =
1460 {
1461 ClipboardMode_Disabled,
1462 ClipboardMode_HostToGuest,
1463 ClipboardMode_GuestToHost,
1464 ClipboardMode_Bidirectional,
1465 };
1466 aSupportedClipboardModes.assign(aClipboardModes,
1467 aClipboardModes + RT_ELEMENTS(aClipboardModes));
1468 return S_OK;
1469}
1470
1471HRESULT SystemProperties::getSupportedDnDModes(std::vector<DnDMode_T> &aSupportedDnDModes)
1472{
1473 static const DnDMode_T aDnDModes[] =
1474 {
1475 DnDMode_Disabled,
1476 DnDMode_HostToGuest,
1477 DnDMode_GuestToHost,
1478 DnDMode_Bidirectional,
1479 };
1480 aSupportedDnDModes.assign(aDnDModes,
1481 aDnDModes + RT_ELEMENTS(aDnDModes));
1482 return S_OK;
1483}
1484
1485HRESULT SystemProperties::getSupportedFirmwareTypes(std::vector<FirmwareType_T> &aSupportedFirmwareTypes)
1486{
1487 static const FirmwareType_T aFirmwareTypes[] =
1488 {
1489 FirmwareType_BIOS,
1490 FirmwareType_EFI,
1491 FirmwareType_EFI32,
1492 FirmwareType_EFI64,
1493 FirmwareType_EFIDUAL,
1494 };
1495 aSupportedFirmwareTypes.assign(aFirmwareTypes,
1496 aFirmwareTypes + RT_ELEMENTS(aFirmwareTypes));
1497 return S_OK;
1498}
1499
1500HRESULT SystemProperties::getSupportedPointingHIDTypes(std::vector<PointingHIDType_T> &aSupportedPointingHIDTypes)
1501{
1502 static const PointingHIDType_T aPointingHIDTypes[] =
1503 {
1504 PointingHIDType_PS2Mouse,
1505#ifdef DEBUG
1506 PointingHIDType_USBMouse,
1507#endif
1508 PointingHIDType_USBTablet,
1509#ifdef DEBUG
1510 PointingHIDType_ComboMouse,
1511#endif
1512 PointingHIDType_USBMultiTouch,
1513 };
1514 aSupportedPointingHIDTypes.assign(aPointingHIDTypes,
1515 aPointingHIDTypes + RT_ELEMENTS(aPointingHIDTypes));
1516 return S_OK;
1517}
1518
1519HRESULT SystemProperties::getSupportedKeyboardHIDTypes(std::vector<KeyboardHIDType_T> &aSupportedKeyboardHIDTypes)
1520{
1521 static const KeyboardHIDType_T aKeyboardHIDTypes[] =
1522 {
1523 KeyboardHIDType_PS2Keyboard,
1524 KeyboardHIDType_USBKeyboard,
1525#ifdef DEBUG
1526 KeyboardHIDType_ComboKeyboard,
1527#endif
1528 };
1529 aSupportedKeyboardHIDTypes.assign(aKeyboardHIDTypes,
1530 aKeyboardHIDTypes + RT_ELEMENTS(aKeyboardHIDTypes));
1531 return S_OK;
1532}
1533
1534HRESULT SystemProperties::getSupportedVFSTypes(std::vector<VFSType_T> &aSupportedVFSTypes)
1535{
1536 static const VFSType_T aVFSTypes[] =
1537 {
1538 VFSType_File,
1539 VFSType_Cloud,
1540 VFSType_S3,
1541#ifdef DEBUG
1542 VFSType_WebDav,
1543#endif
1544 };
1545 aSupportedVFSTypes.assign(aVFSTypes,
1546 aVFSTypes + RT_ELEMENTS(aVFSTypes));
1547 return S_OK;
1548}
1549
1550HRESULT SystemProperties::getSupportedImportOptions(std::vector<ImportOptions_T> &aSupportedImportOptions)
1551{
1552 static const ImportOptions_T aImportOptions[] =
1553 {
1554 ImportOptions_KeepAllMACs,
1555 ImportOptions_KeepNATMACs,
1556 ImportOptions_ImportToVDI,
1557 };
1558 aSupportedImportOptions.assign(aImportOptions,
1559 aImportOptions + RT_ELEMENTS(aImportOptions));
1560 return S_OK;
1561}
1562
1563HRESULT SystemProperties::getSupportedExportOptions(std::vector<ExportOptions_T> &aSupportedExportOptions)
1564{
1565 static const ExportOptions_T aExportOptions[] =
1566 {
1567 ExportOptions_CreateManifest,
1568 ExportOptions_ExportDVDImages,
1569 ExportOptions_StripAllMACs,
1570 ExportOptions_StripAllNonNATMACs,
1571 };
1572 aSupportedExportOptions.assign(aExportOptions,
1573 aExportOptions + RT_ELEMENTS(aExportOptions));
1574 return S_OK;
1575}
1576
1577HRESULT SystemProperties::getSupportedRecordingAudioCodecs(std::vector<RecordingAudioCodec_T> &aSupportedRecordingAudioCodecs)
1578{
1579 static const RecordingAudioCodec_T aRecordingAudioCodecs[] =
1580 {
1581#ifdef DEBUG
1582 RecordingAudioCodec_WavPCM,
1583#endif
1584 RecordingAudioCodec_Opus,
1585 };
1586 aSupportedRecordingAudioCodecs.assign(aRecordingAudioCodecs,
1587 aRecordingAudioCodecs + RT_ELEMENTS(aRecordingAudioCodecs));
1588 return S_OK;
1589}
1590
1591HRESULT SystemProperties::getSupportedRecordingVideoCodecs(std::vector<RecordingVideoCodec_T> &aSupportedRecordingVideoCodecs)
1592{
1593 static const RecordingVideoCodec_T aRecordingVideoCodecs[] =
1594 {
1595 RecordingVideoCodec_VP8,
1596#ifdef DEBUG
1597 RecordingVideoCodec_VP9,
1598 RecordingVideoCodec_AV1,
1599#endif
1600 };
1601 aSupportedRecordingVideoCodecs.assign(aRecordingVideoCodecs,
1602 aRecordingVideoCodecs + RT_ELEMENTS(aRecordingVideoCodecs));
1603 return S_OK;
1604}
1605
1606HRESULT SystemProperties::getSupportedRecordingVSMethods(std::vector<RecordingVideoScalingMethod_T> &aSupportedRecordingVideoScalingMethods)
1607{
1608 static const RecordingVideoScalingMethod_T aRecordingVideoScalingMethods[] =
1609 {
1610 RecordingVideoScalingMethod_None,
1611#ifdef DEBUG
1612 RecordingVideoScalingMethod_NearestNeighbor,
1613 RecordingVideoScalingMethod_Bilinear,
1614 RecordingVideoScalingMethod_Bicubic,
1615#endif
1616 };
1617 aSupportedRecordingVideoScalingMethods.assign(aRecordingVideoScalingMethods,
1618 aRecordingVideoScalingMethods + RT_ELEMENTS(aRecordingVideoScalingMethods));
1619 return S_OK;
1620}
1621
1622HRESULT SystemProperties::getSupportedRecordingVRCModes(std::vector<RecordingVideoRateControlMode_T> &aSupportedRecordingVideoRateControlModes)
1623{
1624 static const RecordingVideoRateControlMode_T aRecordingVideoRateControlModes[] =
1625 {
1626 RecordingVideoRateControlMode_CBR,
1627#ifdef DEBUG
1628 RecordingVideoRateControlMode_VBR,
1629#endif
1630 };
1631 aSupportedRecordingVideoRateControlModes.assign(aRecordingVideoRateControlModes,
1632 aRecordingVideoRateControlModes + RT_ELEMENTS(aRecordingVideoRateControlModes));
1633 return S_OK;
1634}
1635
1636HRESULT SystemProperties::getSupportedGraphicsControllerTypes(std::vector<GraphicsControllerType_T> &aSupportedGraphicsControllerTypes)
1637{
1638 static const GraphicsControllerType_T aGraphicsControllerTypes[] =
1639 {
1640 GraphicsControllerType_VBoxVGA,
1641 GraphicsControllerType_VMSVGA,
1642 GraphicsControllerType_VBoxSVGA,
1643 GraphicsControllerType_Null,
1644 };
1645 aSupportedGraphicsControllerTypes.assign(aGraphicsControllerTypes,
1646 aGraphicsControllerTypes + RT_ELEMENTS(aGraphicsControllerTypes));
1647 return S_OK;
1648}
1649
1650HRESULT SystemProperties::getSupportedCloneOptions(std::vector<CloneOptions_T> &aSupportedCloneOptions)
1651{
1652 static const CloneOptions_T aCloneOptions[] =
1653 {
1654 CloneOptions_Link,
1655 CloneOptions_KeepAllMACs,
1656 CloneOptions_KeepNATMACs,
1657 CloneOptions_KeepDiskNames,
1658 CloneOptions_KeepHwUUIDs,
1659 };
1660 aSupportedCloneOptions.assign(aCloneOptions,
1661 aCloneOptions + RT_ELEMENTS(aCloneOptions));
1662 return S_OK;
1663}
1664
1665HRESULT SystemProperties::getSupportedAutostopTypes(std::vector<AutostopType_T> &aSupportedAutostopTypes)
1666{
1667 static const AutostopType_T aAutostopTypes[] =
1668 {
1669 AutostopType_Disabled,
1670 AutostopType_SaveState,
1671 AutostopType_PowerOff,
1672 AutostopType_AcpiShutdown,
1673 };
1674 aSupportedAutostopTypes.assign(aAutostopTypes,
1675 aAutostopTypes + RT_ELEMENTS(aAutostopTypes));
1676 return S_OK;
1677}
1678
1679HRESULT SystemProperties::getSupportedVMProcPriorities(std::vector<VMProcPriority_T> &aSupportedVMProcPriorities)
1680{
1681 static const VMProcPriority_T aVMProcPriorities[] =
1682 {
1683 VMProcPriority_Default,
1684 VMProcPriority_Flat,
1685 VMProcPriority_Low,
1686 VMProcPriority_Normal,
1687 VMProcPriority_High,
1688 };
1689 aSupportedVMProcPriorities.assign(aVMProcPriorities,
1690 aVMProcPriorities + RT_ELEMENTS(aVMProcPriorities));
1691 return S_OK;
1692}
1693
1694HRESULT SystemProperties::getSupportedNetworkAttachmentTypes(std::vector<NetworkAttachmentType_T> &aSupportedNetworkAttachmentTypes)
1695{
1696 static const NetworkAttachmentType_T aNetworkAttachmentTypes[] =
1697 {
1698 NetworkAttachmentType_NAT,
1699 NetworkAttachmentType_Bridged,
1700 NetworkAttachmentType_Internal,
1701 NetworkAttachmentType_HostOnly,
1702#ifdef VBOX_WITH_VMNET
1703 NetworkAttachmentType_HostOnlyNetwork,
1704#endif /* VBOX_WITH_VMNET */
1705 NetworkAttachmentType_Generic,
1706 NetworkAttachmentType_NATNetwork,
1707#ifdef VBOX_WITH_CLOUD_NET
1708 NetworkAttachmentType_Cloud,
1709#endif
1710 NetworkAttachmentType_Null,
1711 };
1712 aSupportedNetworkAttachmentTypes.assign(aNetworkAttachmentTypes,
1713 aNetworkAttachmentTypes + RT_ELEMENTS(aNetworkAttachmentTypes));
1714 return S_OK;
1715}
1716
1717HRESULT SystemProperties::getSupportedNetworkAdapterTypes(std::vector<NetworkAdapterType_T> &aSupportedNetworkAdapterTypes)
1718{
1719 static const NetworkAdapterType_T aNetworkAdapterTypes[] =
1720 {
1721 NetworkAdapterType_Am79C970A,
1722 NetworkAdapterType_Am79C973,
1723 NetworkAdapterType_I82540EM,
1724 NetworkAdapterType_I82543GC,
1725 NetworkAdapterType_I82545EM,
1726 NetworkAdapterType_Virtio,
1727 };
1728 aSupportedNetworkAdapterTypes.assign(aNetworkAdapterTypes,
1729 aNetworkAdapterTypes + RT_ELEMENTS(aNetworkAdapterTypes));
1730 return S_OK;
1731}
1732
1733HRESULT SystemProperties::getSupportedPortModes(std::vector<PortMode_T> &aSupportedPortModes)
1734{
1735 static const PortMode_T aPortModes[] =
1736 {
1737 PortMode_Disconnected,
1738 PortMode_HostPipe,
1739 PortMode_HostDevice,
1740 PortMode_RawFile,
1741 PortMode_TCP,
1742 };
1743 aSupportedPortModes.assign(aPortModes,
1744 aPortModes + RT_ELEMENTS(aPortModes));
1745 return S_OK;
1746}
1747
1748HRESULT SystemProperties::getSupportedUartTypes(std::vector<UartType_T> &aSupportedUartTypes)
1749{
1750 static const UartType_T aUartTypes[] =
1751 {
1752 UartType_U16450,
1753 UartType_U16550A,
1754 UartType_U16750,
1755 };
1756 aSupportedUartTypes.assign(aUartTypes,
1757 aUartTypes + RT_ELEMENTS(aUartTypes));
1758 return S_OK;
1759}
1760
1761HRESULT SystemProperties::getSupportedUSBControllerTypes(std::vector<USBControllerType_T> &aSupportedUSBControllerTypes)
1762{
1763 static const USBControllerType_T aUSBControllerTypesWithoutExtPack[] =
1764 {
1765 USBControllerType_OHCI,
1766 };
1767 static const USBControllerType_T aUSBControllerTypesWithExtPack[] =
1768 {
1769 USBControllerType_OHCI,
1770 USBControllerType_EHCI,
1771 USBControllerType_XHCI,
1772 };
1773 bool fExtPack = false;
1774# ifdef VBOX_WITH_EXTPACK
1775 static const char *s_pszUsbExtPackName = "Oracle VM VirtualBox Extension Pack";
1776 if (mParent->i_getExtPackManager()->i_isExtPackUsable(s_pszUsbExtPackName))
1777# endif
1778 {
1779 fExtPack = true;
1780 }
1781
1782 if (fExtPack)
1783 aSupportedUSBControllerTypes.assign(aUSBControllerTypesWithExtPack,
1784 aUSBControllerTypesWithExtPack + RT_ELEMENTS(aUSBControllerTypesWithExtPack));
1785 else
1786 aSupportedUSBControllerTypes.assign(aUSBControllerTypesWithoutExtPack,
1787 aUSBControllerTypesWithoutExtPack + RT_ELEMENTS(aUSBControllerTypesWithoutExtPack));
1788 return S_OK;
1789}
1790
1791HRESULT SystemProperties::getSupportedAudioDriverTypes(std::vector<AudioDriverType_T> &aSupportedAudioDriverTypes)
1792{
1793 static const AudioDriverType_T aAudioDriverTypes[] =
1794 {
1795 AudioDriverType_Default,
1796#ifdef RT_OS_WINDOWS
1797# if 0 /* deprecated for many years now */
1798 AudioDriverType_WinMM,
1799# endif
1800 AudioDriverType_WAS,
1801 AudioDriverType_DirectSound,
1802#endif
1803#ifdef RT_OS_DARWIN
1804 AudioDriverType_CoreAudio,
1805#endif
1806#ifdef RT_OS_OS2
1807 AudioDriverType_MMPM,
1808#endif
1809#ifdef RT_OS_SOLARIS
1810# if 0 /* deprecated for many years now */
1811 AudioDriverType_SolAudio,
1812# endif
1813#endif
1814#ifdef VBOX_WITH_AUDIO_ALSA
1815 AudioDriverType_ALSA,
1816#endif
1817#ifdef VBOX_WITH_AUDIO_OSS
1818 AudioDriverType_OSS,
1819#endif
1820#ifdef VBOX_WITH_AUDIO_PULSE
1821 AudioDriverType_Pulse,
1822#endif
1823 AudioDriverType_Null,
1824 };
1825 aSupportedAudioDriverTypes.assign(aAudioDriverTypes,
1826 aAudioDriverTypes + RT_ELEMENTS(aAudioDriverTypes));
1827 return S_OK;
1828}
1829
1830HRESULT SystemProperties::getSupportedAudioControllerTypes(std::vector<AudioControllerType_T> &aSupportedAudioControllerTypes)
1831{
1832 static const AudioControllerType_T aAudioControllerTypes[] =
1833 {
1834 AudioControllerType_AC97,
1835 AudioControllerType_SB16,
1836 AudioControllerType_HDA,
1837 };
1838 aSupportedAudioControllerTypes.assign(aAudioControllerTypes,
1839 aAudioControllerTypes + RT_ELEMENTS(aAudioControllerTypes));
1840 return S_OK;
1841}
1842
1843HRESULT SystemProperties::getSupportedStorageBuses(std::vector<StorageBus_T> &aSupportedStorageBuses)
1844{
1845 static const StorageBus_T aStorageBuses[] =
1846 {
1847 StorageBus_SATA,
1848 StorageBus_IDE,
1849 StorageBus_SCSI,
1850 StorageBus_Floppy,
1851 StorageBus_SAS,
1852 StorageBus_USB,
1853 StorageBus_PCIe,
1854 StorageBus_VirtioSCSI,
1855 };
1856 aSupportedStorageBuses.assign(aStorageBuses,
1857 aStorageBuses + RT_ELEMENTS(aStorageBuses));
1858 return S_OK;
1859}
1860
1861HRESULT SystemProperties::getSupportedStorageControllerTypes(std::vector<StorageControllerType_T> &aSupportedStorageControllerTypes)
1862{
1863 static const StorageControllerType_T aStorageControllerTypes[] =
1864 {
1865 StorageControllerType_IntelAhci,
1866 StorageControllerType_PIIX4,
1867 StorageControllerType_PIIX3,
1868 StorageControllerType_ICH6,
1869 StorageControllerType_LsiLogic,
1870 StorageControllerType_BusLogic,
1871 StorageControllerType_I82078,
1872 StorageControllerType_LsiLogicSas,
1873 StorageControllerType_USB,
1874 StorageControllerType_NVMe,
1875 StorageControllerType_VirtioSCSI,
1876 };
1877 aSupportedStorageControllerTypes.assign(aStorageControllerTypes,
1878 aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes));
1879 return S_OK;
1880}
1881
1882HRESULT SystemProperties::getSupportedChipsetTypes(std::vector<ChipsetType_T> &aSupportedChipsetTypes)
1883{
1884 static const ChipsetType_T aChipsetTypes[] =
1885 {
1886 ChipsetType_PIIX3,
1887 ChipsetType_ICH9,
1888 };
1889 aSupportedChipsetTypes.assign(aChipsetTypes,
1890 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1891 return S_OK;
1892}
1893
1894HRESULT SystemProperties::getSupportedIommuTypes(std::vector<IommuType_T> &aSupportedIommuTypes)
1895{
1896 static const IommuType_T aIommuTypes[] =
1897 {
1898 IommuType_None,
1899 IommuType_Automatic,
1900 IommuType_AMD,
1901 /** @todo Add Intel when it's supported. */
1902 };
1903 aSupportedIommuTypes.assign(aIommuTypes,
1904 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1905 return S_OK;
1906}
1907
1908
1909// public methods only for internal purposes
1910/////////////////////////////////////////////////////////////////////////////
1911
1912HRESULT SystemProperties::i_loadSettings(const settings::SystemProperties &data)
1913{
1914 AutoCaller autoCaller(this);
1915 if (FAILED(autoCaller.rc())) return autoCaller.rc();
1916
1917 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1918 HRESULT rc = S_OK;
1919 rc = i_setDefaultMachineFolder(data.strDefaultMachineFolder);
1920 if (FAILED(rc)) return rc;
1921
1922 rc = i_setLoggingLevel(data.strLoggingLevel);
1923 if (FAILED(rc)) return rc;
1924
1925 rc = i_setDefaultHardDiskFormat(data.strDefaultHardDiskFormat);
1926 if (FAILED(rc)) return rc;
1927
1928 rc = i_setVRDEAuthLibrary(data.strVRDEAuthLibrary);
1929 if (FAILED(rc)) return rc;
1930
1931 rc = i_setWebServiceAuthLibrary(data.strWebServiceAuthLibrary);
1932 if (FAILED(rc)) return rc;
1933
1934 rc = i_setDefaultVRDEExtPack(data.strDefaultVRDEExtPack);
1935 if (FAILED(rc)) return rc;
1936
1937 rc = i_setDefaultCryptoExtPack(data.strDefaultCryptoExtPack);
1938 if (FAILED(rc)) return rc;
1939
1940 m->uLogHistoryCount = data.uLogHistoryCount;
1941 m->fExclusiveHwVirt = data.fExclusiveHwVirt;
1942 m->uProxyMode = data.uProxyMode;
1943 m->strProxyUrl = data.strProxyUrl;
1944
1945 m->strLanguageId = data.strLanguageId;
1946
1947 rc = i_setAutostartDatabasePath(data.strAutostartDatabasePath);
1948 if (FAILED(rc)) return rc;
1949
1950 {
1951 /* must ignore errors signalled here, because the guest additions
1952 * file may not exist, and in this case keep the empty string */
1953 ErrorInfoKeeper eik;
1954 (void)i_setDefaultAdditionsISO(data.strDefaultAdditionsISO);
1955 }
1956
1957 rc = i_setDefaultFrontend(data.strDefaultFrontend);
1958 if (FAILED(rc)) return rc;
1959
1960 return S_OK;
1961}
1962
1963HRESULT SystemProperties::i_saveSettings(settings::SystemProperties &data)
1964{
1965 AutoCaller autoCaller(this);
1966 if (FAILED(autoCaller.rc())) return autoCaller.rc();
1967
1968 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1969
1970 data = *m;
1971
1972 return S_OK;
1973}
1974
1975/**
1976 * Returns a medium format object corresponding to the given format
1977 * identifier or null if no such format.
1978 *
1979 * @param aFormat Format identifier.
1980 *
1981 * @return ComObjPtr<MediumFormat>
1982 */
1983ComObjPtr<MediumFormat> SystemProperties::i_mediumFormat(const Utf8Str &aFormat)
1984{
1985 ComObjPtr<MediumFormat> format;
1986
1987 AutoCaller autoCaller(this);
1988 AssertComRCReturn (autoCaller.rc(), format);
1989
1990 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1991
1992 for (MediumFormatList::const_iterator it = m_llMediumFormats.begin();
1993 it != m_llMediumFormats.end();
1994 ++ it)
1995 {
1996 /* MediumFormat is all const, no need to lock */
1997
1998 if ((*it)->i_getId().compare(aFormat, Utf8Str::CaseInsensitive) == 0)
1999 {
2000 format = *it;
2001 break;
2002 }
2003 }
2004
2005 return format;
2006}
2007
2008/**
2009 * Returns a medium format object corresponding to the given file extension or
2010 * null if no such format.
2011 *
2012 * @param aExt File extension.
2013 *
2014 * @return ComObjPtr<MediumFormat>
2015 */
2016ComObjPtr<MediumFormat> SystemProperties::i_mediumFormatFromExtension(const Utf8Str &aExt)
2017{
2018 ComObjPtr<MediumFormat> format;
2019
2020 AutoCaller autoCaller(this);
2021 AssertComRCReturn (autoCaller.rc(), format);
2022
2023 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
2024
2025 bool fFound = false;
2026 for (MediumFormatList::const_iterator it = m_llMediumFormats.begin();
2027 it != m_llMediumFormats.end() && !fFound;
2028 ++it)
2029 {
2030 /* MediumFormat is all const, no need to lock */
2031 MediumFormat::StrArray aFileList = (*it)->i_getFileExtensions();
2032 for (MediumFormat::StrArray::const_iterator it1 = aFileList.begin();
2033 it1 != aFileList.end();
2034 ++it1)
2035 {
2036 if ((*it1).compare(aExt, Utf8Str::CaseInsensitive) == 0)
2037 {
2038 format = *it;
2039 fFound = true;
2040 break;
2041 }
2042 }
2043 }
2044
2045 return format;
2046}
2047
2048
2049/**
2050 * VD plugin load
2051 */
2052int SystemProperties::i_loadVDPlugin(const char *pszPluginLibrary)
2053{
2054 int vrc = VDPluginLoadFromFilename(pszPluginLibrary);
2055 LogFlowFunc(("pszPluginLibrary='%s' -> %Rrc\n", pszPluginLibrary, vrc));
2056 return vrc;
2057}
2058
2059/**
2060 * VD plugin unload
2061 */
2062int SystemProperties::i_unloadVDPlugin(const char *pszPluginLibrary)
2063{
2064 int vrc = VDPluginUnloadFromFilename(pszPluginLibrary);
2065 LogFlowFunc(("pszPluginLibrary='%s' -> %Rrc\n", pszPluginLibrary, vrc));
2066 return vrc;
2067}
2068
2069/**
2070 * Internally usable version of getDefaultAdditionsISO.
2071 */
2072HRESULT SystemProperties::i_getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO)
2073{
2074 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
2075 if (m->strDefaultAdditionsISO.isNotEmpty())
2076 aDefaultAdditionsISO = m->strDefaultAdditionsISO;
2077 else
2078 {
2079 /* no guest additions, check if it showed up in the mean time */
2080 alock.release();
2081 AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
2082 if (m->strDefaultAdditionsISO.isEmpty())
2083 {
2084 ErrorInfoKeeper eik;
2085 (void)i_setDefaultAdditionsISO("");
2086 }
2087 aDefaultAdditionsISO = m->strDefaultAdditionsISO;
2088 }
2089 return S_OK;
2090}
2091
2092// private methods
2093/////////////////////////////////////////////////////////////////////////////
2094
2095/**
2096 * Returns the user's home directory. Wrapper around RTPathUserHome().
2097 * @param strPath
2098 * @return
2099 */
2100HRESULT SystemProperties::i_getUserHomeDirectory(Utf8Str &strPath)
2101{
2102 char szHome[RTPATH_MAX];
2103 int vrc = RTPathUserHome(szHome, sizeof(szHome));
2104 if (RT_FAILURE(vrc))
2105 return setErrorBoth(E_FAIL, vrc,
2106 tr("Cannot determine user home directory (%Rrc)"),
2107 vrc);
2108 strPath = szHome;
2109 return S_OK;
2110}
2111
2112/**
2113 * Internal implementation to set the default machine folder. Gets called
2114 * from the public attribute setter as well as loadSettings(). With 4.0,
2115 * the "default default" machine folder has changed, and we now require
2116 * a full path always.
2117 * @param strPath
2118 * @return
2119 */
2120HRESULT SystemProperties::i_setDefaultMachineFolder(const Utf8Str &strPath)
2121{
2122 Utf8Str path(strPath); // make modifiable
2123 if ( path.isEmpty() // used by API calls to reset the default
2124 || path == "Machines" // this value (exactly like this, without path) is stored
2125 // in VirtualBox.xml if user upgrades from before 4.0 and
2126 // has not changed the default machine folder
2127 )
2128 {
2129 // new default with VirtualBox 4.0: "$HOME/VirtualBox VMs"
2130 HRESULT rc = i_getUserHomeDirectory(path);
2131 if (FAILED(rc)) return rc;
2132 path += RTPATH_SLASH_STR "VirtualBox VMs";
2133 }
2134
2135 if (!RTPathStartsWithRoot(path.c_str()))
2136 return setError(E_INVALIDARG,
2137 tr("Given default machine folder '%s' is not fully qualified"),
2138 path.c_str());
2139
2140 m->strDefaultMachineFolder = path;
2141
2142 return S_OK;
2143}
2144
2145HRESULT SystemProperties::i_setLoggingLevel(const com::Utf8Str &aLoggingLevel)
2146{
2147 Utf8Str useLoggingLevel(aLoggingLevel);
2148 if (useLoggingLevel.isEmpty())
2149 useLoggingLevel = VBOXSVC_LOG_DEFAULT;
2150 int rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), useLoggingLevel.c_str());
2151 // If failed and not the default logging level - try to use the default logging level.
2152 if (RT_FAILURE(rc))
2153 {
2154 // If failed write message to the release log.
2155 LogRel(("Cannot set passed logging level=%s Error=%Rrc \n", useLoggingLevel.c_str(), rc));
2156 // If attempted logging level not the default one then try the default one.
2157 if (!useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT))
2158 {
2159 rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), VBOXSVC_LOG_DEFAULT);
2160 // If failed report this to the release log.
2161 if (RT_FAILURE(rc))
2162 LogRel(("Cannot set default logging level Error=%Rrc \n", rc));
2163 }
2164 // On any failure - set default level as the one to be stored.
2165 useLoggingLevel = VBOXSVC_LOG_DEFAULT;
2166 }
2167 // Set to passed value or if default used/attempted (even if error condition) use empty string.
2168 m->strLoggingLevel = (useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT) ? "" : useLoggingLevel);
2169 return RT_SUCCESS(rc) ? S_OK : E_FAIL;
2170}
2171
2172HRESULT SystemProperties::i_setDefaultHardDiskFormat(const com::Utf8Str &aFormat)
2173{
2174 if (!aFormat.isEmpty())
2175 m->strDefaultHardDiskFormat = aFormat;
2176 else
2177 m->strDefaultHardDiskFormat = "VDI";
2178
2179 return S_OK;
2180}
2181
2182HRESULT SystemProperties::i_setVRDEAuthLibrary(const com::Utf8Str &aPath)
2183{
2184 if (!aPath.isEmpty())
2185 m->strVRDEAuthLibrary = aPath;
2186 else
2187 m->strVRDEAuthLibrary = "VBoxAuth";
2188
2189 return S_OK;
2190}
2191
2192HRESULT SystemProperties::i_setWebServiceAuthLibrary(const com::Utf8Str &aPath)
2193{
2194 if (!aPath.isEmpty())
2195 m->strWebServiceAuthLibrary = aPath;
2196 else
2197 m->strWebServiceAuthLibrary = "VBoxAuth";
2198
2199 return S_OK;
2200}
2201
2202HRESULT SystemProperties::i_setDefaultVRDEExtPack(const com::Utf8Str &aExtPack)
2203{
2204 m->strDefaultVRDEExtPack = aExtPack;
2205
2206 return S_OK;
2207}
2208
2209HRESULT SystemProperties::i_setDefaultCryptoExtPack(const com::Utf8Str &aExtPack)
2210{
2211 m->strDefaultCryptoExtPack = aExtPack;
2212
2213 return S_OK;
2214}
2215
2216HRESULT SystemProperties::i_setAutostartDatabasePath(const com::Utf8Str &aPath)
2217{
2218 HRESULT rc = S_OK;
2219 AutostartDb *autostartDb = this->mParent->i_getAutostartDb();
2220
2221 if (!aPath.isEmpty())
2222 {
2223 /* Update path in the autostart database. */
2224 int vrc = autostartDb->setAutostartDbPath(aPath.c_str());
2225 if (RT_SUCCESS(vrc))
2226 m->strAutostartDatabasePath = aPath;
2227 else
2228 rc = setErrorBoth(E_FAIL, vrc,
2229 tr("Cannot set the autostart database path (%Rrc)"),
2230 vrc);
2231 }
2232 else
2233 {
2234 int vrc = autostartDb->setAutostartDbPath(NULL);
2235 if (RT_SUCCESS(vrc) || vrc == VERR_NOT_SUPPORTED)
2236 m->strAutostartDatabasePath = "";
2237 else
2238 rc = setErrorBoth(E_FAIL, vrc,
2239 tr("Deleting the autostart database path failed (%Rrc)"),
2240 vrc);
2241 }
2242
2243 return rc;
2244}
2245
2246HRESULT SystemProperties::i_setDefaultAdditionsISO(const com::Utf8Str &aPath)
2247{
2248 com::Utf8Str path(aPath);
2249 if (path.isEmpty())
2250 {
2251 char strTemp[RTPATH_MAX];
2252 int vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));
2253 AssertRC(vrc);
2254 Utf8Str strSrc1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso");
2255
2256 vrc = RTPathExecDir(strTemp, sizeof(strTemp));
2257 AssertRC(vrc);
2258 Utf8Str strSrc2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso");
2259
2260 vrc = RTPathUserHome(strTemp, sizeof(strTemp));
2261 AssertRC(vrc);
2262 Utf8Str strSrc3 = Utf8StrFmt("%s/VBoxGuestAdditions_%s.iso", strTemp, VirtualBox::i_getVersionNormalized().c_str());
2263
2264 /* Check the standard image locations */
2265 if (RTFileExists(strSrc1.c_str()))
2266 path = strSrc1;
2267 else if (RTFileExists(strSrc2.c_str()))
2268 path = strSrc2;
2269 else if (RTFileExists(strSrc3.c_str()))
2270 path = strSrc3;
2271 else
2272 return setError(E_FAIL,
2273 tr("Cannot determine default Guest Additions ISO location. Most likely they are not available"));
2274 }
2275
2276 if (!RTPathStartsWithRoot(path.c_str()))
2277 return setError(E_INVALIDARG,
2278 tr("Given default machine Guest Additions ISO file '%s' is not fully qualified"),
2279 path.c_str());
2280
2281 if (!RTFileExists(path.c_str()))
2282 return setError(E_INVALIDARG,
2283 tr("Given default machine Guest Additions ISO file '%s' does not exist"),
2284 path.c_str());
2285
2286 m->strDefaultAdditionsISO = path;
2287
2288 return S_OK;
2289}
2290
2291HRESULT SystemProperties::i_setDefaultFrontend(const com::Utf8Str &aDefaultFrontend)
2292{
2293 m->strDefaultFrontend = aDefaultFrontend;
2294
2295 return S_OK;
2296}
2297
2298HRESULT SystemProperties::getLanguageId(com::Utf8Str &aLanguageId)
2299{
2300#ifdef VBOX_WITH_MAIN_NLS
2301 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
2302 aLanguageId = m->strLanguageId;
2303 alock.release();
2304
2305 HRESULT hrc = S_OK;
2306 if (aLanguageId.isEmpty())
2307 {
2308 char szLocale[256];
2309 memset(szLocale, 0, sizeof(szLocale));
2310 int vrc = RTLocaleQueryNormalizedBaseLocaleName(szLocale, sizeof(szLocale));
2311 if (RT_SUCCESS(vrc))
2312 aLanguageId = szLocale;
2313 else
2314 hrc = Global::vboxStatusCodeToCOM(vrc);
2315 }
2316 return hrc;
2317#else
2318 aLanguageId = "C";
2319 return S_OK;
2320#endif
2321}
2322
2323HRESULT SystemProperties::setLanguageId(const com::Utf8Str &aLanguageId)
2324{
2325#ifdef VBOX_WITH_MAIN_NLS
2326 VirtualBoxTranslator *pTranslator = VirtualBoxTranslator::instance();
2327 if (!pTranslator)
2328 return E_FAIL;
2329
2330 HRESULT hrc = S_OK;
2331 int vrc = pTranslator->i_loadLanguage(aLanguageId.c_str());
2332 if (RT_SUCCESS(vrc))
2333 {
2334 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
2335 m->strLanguageId = aLanguageId;
2336 alock.release();
2337
2338 // VirtualBox::i_saveSettings() needs vbox write lock
2339 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
2340 hrc = mParent->i_saveSettings();
2341 }
2342 else
2343 hrc = Global::vboxStatusCodeToCOM(vrc);
2344
2345 pTranslator->release();
2346
2347 if (SUCCEEDED(hrc))
2348 mParent->i_onLanguageChanged(aLanguageId);
2349
2350 return hrc;
2351#else
2352 NOREF(aLanguageId);
2353 return E_NOTIMPL;
2354#endif
2355}
2356
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