VirtualBox

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

Last change on this file since 90441 was 87241, checked in by vboxsync, 4 years ago

AMD IOMMU: bugref:9654 Main/API: AMD IOMMU support.

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