VirtualBox

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

Last change on this file since 73003 was 73003, checked in by vboxsync, 6 years ago

Main: Use setErrorBoth when we've got a VBox status code handy. (The COM status codes aren't too specfic and this may help us decode error messages and provide an alternative to strstr for API clients. setErrorBoth isn't new, btw.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.4 KB
Line 
1/* $Id: SystemPropertiesImpl.cpp 73003 2018-07-09 11:09:32Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2017 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#include "SystemPropertiesImpl.h"
19#include "VirtualBoxImpl.h"
20#include "MachineImpl.h"
21#ifdef VBOX_WITH_EXTPACK
22# include "ExtPackManagerImpl.h"
23#endif
24#include "AutoCaller.h"
25#include "Global.h"
26#include "Logging.h"
27#include "AutostartDb.h"
28
29// generated header
30#include "SchemaDefs.h"
31
32#include <iprt/dir.h>
33#include <iprt/ldr.h>
34#include <iprt/path.h>
35#include <iprt/string.h>
36#include <iprt/cpp/utils.h>
37
38#include <VBox/err.h>
39#include <VBox/param.h>
40#include <VBox/settings.h>
41#include <VBox/vd.h>
42
43// defines
44/////////////////////////////////////////////////////////////////////////////
45
46// constructor / destructor
47/////////////////////////////////////////////////////////////////////////////
48
49SystemProperties::SystemProperties()
50 : mParent(NULL),
51 m(new settings::SystemProperties)
52{
53}
54
55SystemProperties::~SystemProperties()
56{
57 delete m;
58}
59
60
61HRESULT SystemProperties::FinalConstruct()
62{
63 return BaseFinalConstruct();
64}
65
66void SystemProperties::FinalRelease()
67{
68 uninit();
69 BaseFinalRelease();
70}
71
72// public methods only for internal purposes
73/////////////////////////////////////////////////////////////////////////////
74
75/**
76 * Initializes the system information object.
77 *
78 * @returns COM result indicator
79 */
80HRESULT SystemProperties::init(VirtualBox *aParent)
81{
82 LogFlowThisFunc(("aParent=%p\n", aParent));
83
84 ComAssertRet(aParent, E_FAIL);
85
86 /* Enclose the state transition NotReady->InInit->Ready */
87 AutoInitSpan autoInitSpan(this);
88 AssertReturn(autoInitSpan.isOk(), E_FAIL);
89
90 unconst(mParent) = aParent;
91
92 i_setDefaultMachineFolder(Utf8Str::Empty);
93 i_setLoggingLevel(Utf8Str::Empty);
94 i_setDefaultHardDiskFormat(Utf8Str::Empty);
95
96 i_setVRDEAuthLibrary(Utf8Str::Empty);
97 i_setDefaultVRDEExtPack(Utf8Str::Empty);
98
99 m->ulLogHistoryCount = 3;
100
101
102 /* On Windows, OS X and Solaris, HW virtualization use isn't exclusive
103 * by default so that VT-x or AMD-V can be shared with other
104 * hypervisors without requiring user intervention.
105 * NB: See also SystemProperties constructor in settings.h
106 */
107#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)
108 m->fExclusiveHwVirt = false;
109#else
110 m->fExclusiveHwVirt = true;
111#endif
112
113 HRESULT rc = S_OK;
114
115 /* Fetch info of all available hd backends. */
116
117 /// @todo NEWMEDIA VDBackendInfo needs to be improved to let us enumerate
118 /// any number of backends
119
120 VDBACKENDINFO aVDInfo[100];
121 unsigned cEntries;
122 int vrc = VDBackendInfo(RT_ELEMENTS(aVDInfo), aVDInfo, &cEntries);
123 AssertRC(vrc);
124 if (RT_SUCCESS(vrc))
125 {
126 for (unsigned i = 0; i < cEntries; ++ i)
127 {
128 ComObjPtr<MediumFormat> hdf;
129 rc = hdf.createObject();
130 if (FAILED(rc)) break;
131
132 rc = hdf->init(&aVDInfo[i]);
133 if (FAILED(rc)) break;
134
135 m_llMediumFormats.push_back(hdf);
136 }
137 }
138
139 /* Confirm a successful initialization */
140 if (SUCCEEDED(rc))
141 autoInitSpan.setSucceeded();
142
143 return rc;
144}
145
146/**
147 * Uninitializes the instance and sets the ready flag to FALSE.
148 * Called either from FinalRelease() or by the parent when it gets destroyed.
149 */
150void SystemProperties::uninit()
151{
152 LogFlowThisFunc(("\n"));
153
154 /* Enclose the state transition Ready->InUninit->NotReady */
155 AutoUninitSpan autoUninitSpan(this);
156 if (autoUninitSpan.uninitDone())
157 return;
158
159 unconst(mParent) = NULL;
160}
161
162// wrapped ISystemProperties properties
163/////////////////////////////////////////////////////////////////////////////
164
165HRESULT SystemProperties::getMinGuestRAM(ULONG *minRAM)
166
167{
168 /* no need to lock, this is const */
169 AssertCompile(MM_RAM_MIN_IN_MB >= SchemaDefs::MinGuestRAM);
170 *minRAM = MM_RAM_MIN_IN_MB;
171
172 return S_OK;
173}
174
175HRESULT SystemProperties::getMaxGuestRAM(ULONG *maxRAM)
176{
177 /* no need to lock, this is const */
178 AssertCompile(MM_RAM_MAX_IN_MB <= SchemaDefs::MaxGuestRAM);
179 ULONG maxRAMSys = MM_RAM_MAX_IN_MB;
180 ULONG maxRAMArch = maxRAMSys;
181 *maxRAM = RT_MIN(maxRAMSys, maxRAMArch);
182
183 return S_OK;
184}
185
186HRESULT SystemProperties::getMinGuestVRAM(ULONG *minVRAM)
187{
188 /* no need to lock, this is const */
189 *minVRAM = SchemaDefs::MinGuestVRAM;
190
191 return S_OK;
192}
193
194HRESULT SystemProperties::getMaxGuestVRAM(ULONG *maxVRAM)
195{
196 /* no need to lock, this is const */
197 *maxVRAM = SchemaDefs::MaxGuestVRAM;
198
199 return S_OK;
200}
201
202HRESULT SystemProperties::getMinGuestCPUCount(ULONG *minCPUCount)
203{
204 /* no need to lock, this is const */
205 *minCPUCount = SchemaDefs::MinCPUCount; // VMM_MIN_CPU_COUNT
206
207 return S_OK;
208}
209
210HRESULT SystemProperties::getMaxGuestCPUCount(ULONG *maxCPUCount)
211{
212 /* no need to lock, this is const */
213 *maxCPUCount = SchemaDefs::MaxCPUCount; // VMM_MAX_CPU_COUNT
214
215 return S_OK;
216}
217
218HRESULT SystemProperties::getMaxGuestMonitors(ULONG *maxMonitors)
219{
220
221 /* no need to lock, this is const */
222 *maxMonitors = SchemaDefs::MaxGuestMonitors;
223
224 return S_OK;
225}
226
227
228HRESULT SystemProperties::getInfoVDSize(LONG64 *infoVDSize)
229{
230 /*
231 * The BIOS supports currently 32 bit LBA numbers (implementing the full
232 * 48 bit range is in theory trivial, but the crappy compiler makes things
233 * more difficult). This translates to almost 2 TiBytes (to be on the safe
234 * side, the reported limit is 1 MiByte less than that, as the total number
235 * of sectors should fit in 32 bits, too), which should be enough for the
236 * moment. Since the MBR partition tables support only 32bit sector numbers
237 * and thus the BIOS can only boot from disks smaller than 2T this is a
238 * rather hard limit.
239 *
240 * The virtual ATA/SATA disks support complete LBA48, and SCSI supports
241 * LBA64 (almost, more like LBA55 in practice), so the theoretical maximum
242 * disk size is 128 PiByte/16 EiByte. The GUI works nicely with 6 orders
243 * of magnitude, but not with 11..13 orders of magnitude.
244 */
245 /* no need to lock, this is const */
246 *infoVDSize = 2 * _1T - _1M;
247
248 return S_OK;
249}
250
251
252HRESULT SystemProperties::getSerialPortCount(ULONG *count)
253{
254 /* no need to lock, this is const */
255 *count = SchemaDefs::SerialPortCount;
256
257 return S_OK;
258}
259
260
261HRESULT SystemProperties::getParallelPortCount(ULONG *count)
262{
263 /* no need to lock, this is const */
264 *count = SchemaDefs::ParallelPortCount;
265
266 return S_OK;
267}
268
269
270HRESULT SystemProperties::getMaxBootPosition(ULONG *aMaxBootPosition)
271{
272 /* no need to lock, this is const */
273 *aMaxBootPosition = SchemaDefs::MaxBootPosition;
274
275 return S_OK;
276}
277
278
279HRESULT SystemProperties::getRawModeSupported(BOOL *aRawModeSupported)
280{
281#ifdef VBOX_WITH_RAW_MODE
282 *aRawModeSupported = TRUE;
283#else
284 *aRawModeSupported = FALSE;
285#endif
286 return S_OK;
287}
288
289
290HRESULT SystemProperties::getExclusiveHwVirt(BOOL *aExclusiveHwVirt)
291{
292 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
293
294 *aExclusiveHwVirt = m->fExclusiveHwVirt;
295
296 return S_OK;
297}
298
299HRESULT SystemProperties::setExclusiveHwVirt(BOOL aExclusiveHwVirt)
300{
301 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
302 m->fExclusiveHwVirt = !!aExclusiveHwVirt;
303 alock.release();
304
305 // VirtualBox::i_saveSettings() needs vbox write lock
306 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
307 HRESULT rc = mParent->i_saveSettings();
308
309 return rc;
310}
311
312HRESULT SystemProperties::getMaxNetworkAdapters(ChipsetType_T aChipset, ULONG *aMaxNetworkAdapters)
313{
314 /* no need for locking, no state */
315 uint32_t uResult = Global::getMaxNetworkAdapters(aChipset);
316 if (uResult == 0)
317 AssertMsgFailed(("Invalid chipset type %d\n", aChipset));
318 *aMaxNetworkAdapters = uResult;
319 return S_OK;
320}
321
322HRESULT SystemProperties::getMaxNetworkAdaptersOfType(ChipsetType_T aChipset, NetworkAttachmentType_T aType, ULONG *count)
323{
324 /* no need for locking, no state */
325 uint32_t uResult = Global::getMaxNetworkAdapters(aChipset);
326 if (uResult == 0)
327 AssertMsgFailed(("Invalid chipset type %d\n", aChipset));
328
329 switch (aType)
330 {
331 case NetworkAttachmentType_NAT:
332 case NetworkAttachmentType_Internal:
333 case NetworkAttachmentType_NATNetwork:
334 /* chipset default is OK */
335 break;
336 case NetworkAttachmentType_Bridged:
337 /* Maybe use current host interface count here? */
338 break;
339 case NetworkAttachmentType_HostOnly:
340 uResult = RT_MIN(uResult, 8);
341 break;
342 default:
343 AssertMsgFailed(("Unhandled attachment type %d\n", aType));
344 }
345
346 *count = uResult;
347
348 return S_OK;
349}
350
351
352HRESULT SystemProperties::getMaxDevicesPerPortForStorageBus(StorageBus_T aBus,
353 ULONG *aMaxDevicesPerPort)
354{
355 /* no need to lock, this is const */
356 switch (aBus)
357 {
358 case StorageBus_SATA:
359 case StorageBus_SCSI:
360 case StorageBus_SAS:
361 case StorageBus_USB:
362 case StorageBus_PCIe:
363 {
364 /* SATA and both SCSI controllers only support one device per port. */
365 *aMaxDevicesPerPort = 1;
366 break;
367 }
368 case StorageBus_IDE:
369 case StorageBus_Floppy:
370 {
371 /* The IDE and Floppy controllers support 2 devices. One as master
372 * and one as slave (or floppy drive 0 and 1). */
373 *aMaxDevicesPerPort = 2;
374 break;
375 }
376 default:
377 AssertMsgFailed(("Invalid bus type %d\n", aBus));
378 }
379
380 return S_OK;
381}
382
383HRESULT SystemProperties::getMinPortCountForStorageBus(StorageBus_T aBus,
384 ULONG *aMinPortCount)
385{
386 /* no need to lock, this is const */
387 switch (aBus)
388 {
389 case StorageBus_SATA:
390 case StorageBus_SAS:
391 case StorageBus_PCIe:
392 {
393 *aMinPortCount = 1;
394 break;
395 }
396 case StorageBus_SCSI:
397 {
398 *aMinPortCount = 16;
399 break;
400 }
401 case StorageBus_IDE:
402 {
403 *aMinPortCount = 2;
404 break;
405 }
406 case StorageBus_Floppy:
407 {
408 *aMinPortCount = 1;
409 break;
410 }
411 case StorageBus_USB:
412 {
413 *aMinPortCount = 8;
414 break;
415 }
416 default:
417 AssertMsgFailed(("Invalid bus type %d\n", aBus));
418 }
419
420 return S_OK;
421}
422
423HRESULT SystemProperties::getMaxPortCountForStorageBus(StorageBus_T aBus,
424 ULONG *aMaxPortCount)
425{
426 /* no need to lock, this is const */
427 switch (aBus)
428 {
429 case StorageBus_SATA:
430 {
431 *aMaxPortCount = 30;
432 break;
433 }
434 case StorageBus_SCSI:
435 {
436 *aMaxPortCount = 16;
437 break;
438 }
439 case StorageBus_IDE:
440 {
441 *aMaxPortCount = 2;
442 break;
443 }
444 case StorageBus_Floppy:
445 {
446 *aMaxPortCount = 1;
447 break;
448 }
449 case StorageBus_SAS:
450 case StorageBus_PCIe:
451 {
452 *aMaxPortCount = 255;
453 break;
454 }
455 case StorageBus_USB:
456 {
457 *aMaxPortCount = 8;
458 break;
459 }
460 default:
461 AssertMsgFailed(("Invalid bus type %d\n", aBus));
462 }
463
464 return S_OK;
465}
466
467HRESULT SystemProperties::getMaxInstancesOfStorageBus(ChipsetType_T aChipset,
468 StorageBus_T aBus,
469 ULONG *aMaxInstances)
470{
471 ULONG cCtrs = 0;
472
473 /* no need to lock, this is const */
474 switch (aBus)
475 {
476 case StorageBus_SATA:
477 case StorageBus_SCSI:
478 case StorageBus_SAS:
479 case StorageBus_PCIe:
480 cCtrs = aChipset == ChipsetType_ICH9 ? 8 : 1;
481 break;
482 case StorageBus_USB:
483 case StorageBus_IDE:
484 case StorageBus_Floppy:
485 {
486 cCtrs = 1;
487 break;
488 }
489 default:
490 AssertMsgFailed(("Invalid bus type %d\n", aBus));
491 }
492
493 *aMaxInstances = cCtrs;
494
495 return S_OK;
496}
497
498HRESULT SystemProperties::getDeviceTypesForStorageBus(StorageBus_T aBus,
499 std::vector<DeviceType_T> &aDeviceTypes)
500{
501 aDeviceTypes.resize(0);
502
503 /* no need to lock, this is const */
504 switch (aBus)
505 {
506 case StorageBus_IDE:
507 case StorageBus_SATA:
508 case StorageBus_SCSI:
509 case StorageBus_SAS:
510 case StorageBus_USB:
511 {
512 aDeviceTypes.resize(2);
513 aDeviceTypes[0] = DeviceType_DVD;
514 aDeviceTypes[1] = DeviceType_HardDisk;
515 break;
516 }
517 case StorageBus_Floppy:
518 {
519 aDeviceTypes.resize(1);
520 aDeviceTypes[0] = DeviceType_Floppy;
521 break;
522 }
523 case StorageBus_PCIe:
524 {
525 aDeviceTypes.resize(1);
526 aDeviceTypes[0] = DeviceType_HardDisk;
527 break;
528 }
529 default:
530 AssertMsgFailed(("Invalid bus type %d\n", aBus));
531 }
532
533 return S_OK;
534}
535
536HRESULT SystemProperties::getDefaultIoCacheSettingForStorageController(StorageControllerType_T aControllerType,
537 BOOL *aEnabled)
538{
539 /* no need to lock, this is const */
540 switch (aControllerType)
541 {
542 case StorageControllerType_LsiLogic:
543 case StorageControllerType_BusLogic:
544 case StorageControllerType_IntelAhci:
545 case StorageControllerType_LsiLogicSas:
546 case StorageControllerType_USB:
547 case StorageControllerType_NVMe:
548 *aEnabled = false;
549 break;
550 case StorageControllerType_PIIX3:
551 case StorageControllerType_PIIX4:
552 case StorageControllerType_ICH6:
553 case StorageControllerType_I82078:
554 *aEnabled = true;
555 break;
556 default:
557 AssertMsgFailed(("Invalid controller type %d\n", aControllerType));
558 }
559 return S_OK;
560}
561
562HRESULT SystemProperties::getStorageControllerHotplugCapable(StorageControllerType_T aControllerType,
563 BOOL *aHotplugCapable)
564{
565 switch (aControllerType)
566 {
567 case StorageControllerType_IntelAhci:
568 case StorageControllerType_USB:
569 *aHotplugCapable = true;
570 break;
571 case StorageControllerType_LsiLogic:
572 case StorageControllerType_LsiLogicSas:
573 case StorageControllerType_BusLogic:
574 case StorageControllerType_NVMe:
575 case StorageControllerType_PIIX3:
576 case StorageControllerType_PIIX4:
577 case StorageControllerType_ICH6:
578 case StorageControllerType_I82078:
579 *aHotplugCapable = false;
580 break;
581 default:
582 AssertMsgFailedReturn(("Invalid controller type %d\n", aControllerType), E_FAIL);
583 }
584
585 return S_OK;
586}
587
588HRESULT SystemProperties::getMaxInstancesOfUSBControllerType(ChipsetType_T aChipset,
589 USBControllerType_T aType,
590 ULONG *aMaxInstances)
591{
592 NOREF(aChipset);
593 ULONG cCtrs = 0;
594
595 /* no need to lock, this is const */
596 switch (aType)
597 {
598 case USBControllerType_OHCI:
599 case USBControllerType_EHCI:
600 case USBControllerType_XHCI:
601 {
602 cCtrs = 1;
603 break;
604 }
605 default:
606 AssertMsgFailed(("Invalid bus type %d\n", aType));
607 }
608
609 *aMaxInstances = cCtrs;
610
611 return S_OK;
612}
613
614HRESULT SystemProperties::getDefaultMachineFolder(com::Utf8Str &aDefaultMachineFolder)
615{
616 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
617 aDefaultMachineFolder = m->strDefaultMachineFolder;
618 return S_OK;
619}
620
621HRESULT SystemProperties::setDefaultMachineFolder(const com::Utf8Str &aDefaultMachineFolder)
622{
623 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
624 HRESULT rc = i_setDefaultMachineFolder(aDefaultMachineFolder);
625 alock.release();
626 if (SUCCEEDED(rc))
627 {
628 // VirtualBox::i_saveSettings() needs vbox write lock
629 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
630 rc = mParent->i_saveSettings();
631 }
632
633 return rc;
634}
635
636HRESULT SystemProperties::getLoggingLevel(com::Utf8Str &aLoggingLevel)
637{
638 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
639
640 aLoggingLevel = m->strLoggingLevel;
641
642 if (aLoggingLevel.isEmpty())
643 aLoggingLevel = VBOXSVC_LOG_DEFAULT;
644
645 return S_OK;
646}
647
648
649HRESULT SystemProperties::setLoggingLevel(const com::Utf8Str &aLoggingLevel)
650{
651 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
652 HRESULT rc = i_setLoggingLevel(aLoggingLevel);
653 alock.release();
654
655 if (SUCCEEDED(rc))
656 {
657 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
658 rc = mParent->i_saveSettings();
659 }
660 else
661 LogRel(("Cannot set passed logging level=%s, or the default one - Error=%Rhrc \n", aLoggingLevel.c_str(), rc));
662
663 return rc;
664}
665
666HRESULT SystemProperties::getMediumFormats(std::vector<ComPtr<IMediumFormat> > &aMediumFormats)
667{
668 MediumFormatList mediumFormats(m_llMediumFormats);
669 aMediumFormats.resize(mediumFormats.size());
670 size_t i = 0;
671 for (MediumFormatList::const_iterator it = mediumFormats.begin(); it != mediumFormats.end(); ++it, ++i)
672 (*it).queryInterfaceTo(aMediumFormats[i].asOutParam());
673 return S_OK;
674}
675
676HRESULT SystemProperties::getDefaultHardDiskFormat(com::Utf8Str &aDefaultHardDiskFormat)
677{
678 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
679 aDefaultHardDiskFormat = m->strDefaultHardDiskFormat;
680 return S_OK;
681}
682
683
684HRESULT SystemProperties::setDefaultHardDiskFormat(const com::Utf8Str &aDefaultHardDiskFormat)
685{
686 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
687 HRESULT rc = i_setDefaultHardDiskFormat(aDefaultHardDiskFormat);
688 alock.release();
689 if (SUCCEEDED(rc))
690 {
691 // VirtualBox::i_saveSettings() needs vbox write lock
692 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
693 rc = mParent->i_saveSettings();
694 }
695
696 return rc;
697}
698
699HRESULT SystemProperties::getFreeDiskSpaceWarning(LONG64 *aFreeSpace)
700{
701 NOREF(aFreeSpace);
702 ReturnComNotImplemented();
703}
704
705HRESULT SystemProperties::setFreeDiskSpaceWarning(LONG64 /* aFreeSpace */)
706{
707 ReturnComNotImplemented();
708}
709
710HRESULT SystemProperties::getFreeDiskSpacePercentWarning(ULONG *aFreeSpacePercent)
711{
712 NOREF(aFreeSpacePercent);
713 ReturnComNotImplemented();
714}
715
716HRESULT SystemProperties::setFreeDiskSpacePercentWarning(ULONG /* aFreeSpacePercent */)
717{
718 ReturnComNotImplemented();
719}
720
721HRESULT SystemProperties::getFreeDiskSpaceError(LONG64 *aFreeSpace)
722{
723 NOREF(aFreeSpace);
724 ReturnComNotImplemented();
725}
726
727HRESULT SystemProperties::setFreeDiskSpaceError(LONG64 /* aFreeSpace */)
728{
729 ReturnComNotImplemented();
730}
731
732HRESULT SystemProperties::getFreeDiskSpacePercentError(ULONG *aFreeSpacePercent)
733{
734 NOREF(aFreeSpacePercent);
735 ReturnComNotImplemented();
736}
737
738HRESULT SystemProperties::setFreeDiskSpacePercentError(ULONG /* aFreeSpacePercent */)
739{
740 ReturnComNotImplemented();
741}
742
743HRESULT SystemProperties::getVRDEAuthLibrary(com::Utf8Str &aVRDEAuthLibrary)
744{
745 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
746
747 aVRDEAuthLibrary = m->strVRDEAuthLibrary;
748
749 return S_OK;
750}
751
752HRESULT SystemProperties::setVRDEAuthLibrary(const com::Utf8Str &aVRDEAuthLibrary)
753{
754 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
755 HRESULT rc = i_setVRDEAuthLibrary(aVRDEAuthLibrary);
756 alock.release();
757 if (SUCCEEDED(rc))
758 {
759 // VirtualBox::i_saveSettings() needs vbox write lock
760 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
761 rc = mParent->i_saveSettings();
762 }
763
764 return rc;
765}
766
767HRESULT SystemProperties::getWebServiceAuthLibrary(com::Utf8Str &aWebServiceAuthLibrary)
768{
769 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
770
771 aWebServiceAuthLibrary = m->strWebServiceAuthLibrary;
772
773 return S_OK;
774}
775
776HRESULT SystemProperties::setWebServiceAuthLibrary(const com::Utf8Str &aWebServiceAuthLibrary)
777{
778 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
779 HRESULT rc = i_setWebServiceAuthLibrary(aWebServiceAuthLibrary);
780 alock.release();
781
782 if (SUCCEEDED(rc))
783 {
784 // VirtualBox::i_saveSettings() needs vbox write lock
785 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
786 rc = mParent->i_saveSettings();
787 }
788
789 return rc;
790}
791
792HRESULT SystemProperties::getDefaultVRDEExtPack(com::Utf8Str &aExtPack)
793{
794 HRESULT hrc = S_OK;
795 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
796 Utf8Str strExtPack(m->strDefaultVRDEExtPack);
797 if (strExtPack.isNotEmpty())
798 {
799 if (strExtPack.equals(VBOXVRDP_KLUDGE_EXTPACK_NAME))
800 hrc = S_OK;
801 else
802#ifdef VBOX_WITH_EXTPACK
803 hrc = mParent->i_getExtPackManager()->i_checkVrdeExtPack(&strExtPack);
804#else
805 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), strExtPack.c_str());
806#endif
807 }
808 else
809 {
810#ifdef VBOX_WITH_EXTPACK
811 hrc = mParent->i_getExtPackManager()->i_getDefaultVrdeExtPack(&strExtPack);
812#endif
813 if (strExtPack.isEmpty())
814 {
815 /*
816 * Klugde - check if VBoxVRDP.dll/.so/.dylib is installed.
817 * This is hardcoded uglyness, sorry.
818 */
819 char szPath[RTPATH_MAX];
820 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
821 if (RT_SUCCESS(vrc))
822 vrc = RTPathAppend(szPath, sizeof(szPath), "VBoxVRDP");
823 if (RT_SUCCESS(vrc))
824 vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
825 if (RT_SUCCESS(vrc) && RTFileExists(szPath))
826 {
827 /* Illegal extpack name, so no conflict. */
828 strExtPack = VBOXVRDP_KLUDGE_EXTPACK_NAME;
829 }
830 }
831 }
832
833 if (SUCCEEDED(hrc))
834 aExtPack = strExtPack;
835
836 return S_OK;
837}
838
839
840HRESULT SystemProperties::setDefaultVRDEExtPack(const com::Utf8Str &aExtPack)
841{
842 HRESULT hrc = S_OK;
843 if (aExtPack.isNotEmpty())
844 {
845 if (aExtPack.equals(VBOXVRDP_KLUDGE_EXTPACK_NAME))
846 hrc = S_OK;
847 else
848#ifdef VBOX_WITH_EXTPACK
849 hrc = mParent->i_getExtPackManager()->i_checkVrdeExtPack(&aExtPack);
850#else
851 hrc = setError(E_FAIL, tr("The extension pack '%s' does not exist"), aExtPack.c_str());
852#endif
853 }
854 if (SUCCEEDED(hrc))
855 {
856 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
857 hrc = i_setDefaultVRDEExtPack(aExtPack);
858 if (SUCCEEDED(hrc))
859 {
860 /* VirtualBox::i_saveSettings() needs the VirtualBox write lock. */
861 alock.release();
862 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
863 hrc = mParent->i_saveSettings();
864 }
865 }
866
867 return hrc;
868}
869
870
871HRESULT SystemProperties::getLogHistoryCount(ULONG *count)
872{
873 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
874
875 *count = m->ulLogHistoryCount;
876
877 return S_OK;
878}
879
880
881HRESULT SystemProperties::setLogHistoryCount(ULONG count)
882{
883 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
884 m->ulLogHistoryCount = count;
885 alock.release();
886
887 // VirtualBox::i_saveSettings() needs vbox write lock
888 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
889 HRESULT rc = mParent->i_saveSettings();
890
891 return rc;
892}
893
894HRESULT SystemProperties::getDefaultAudioDriver(AudioDriverType_T *aAudioDriver)
895{
896 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
897
898 *aAudioDriver = settings::MachineConfigFile::getHostDefaultAudioDriver();
899
900 return S_OK;
901}
902
903HRESULT SystemProperties::getAutostartDatabasePath(com::Utf8Str &aAutostartDbPath)
904{
905 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
906
907 aAutostartDbPath = m->strAutostartDatabasePath;
908
909 return S_OK;
910}
911
912HRESULT SystemProperties::setAutostartDatabasePath(const com::Utf8Str &aAutostartDbPath)
913{
914 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
915 HRESULT rc = i_setAutostartDatabasePath(aAutostartDbPath);
916 alock.release();
917
918 if (SUCCEEDED(rc))
919 {
920 // VirtualBox::i_saveSettings() needs vbox write lock
921 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
922 rc = mParent->i_saveSettings();
923 }
924
925 return rc;
926}
927
928HRESULT SystemProperties::getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO)
929{
930 return i_getDefaultAdditionsISO(aDefaultAdditionsISO);
931}
932
933HRESULT SystemProperties::setDefaultAdditionsISO(const com::Utf8Str &aDefaultAdditionsISO)
934{
935 RT_NOREF(aDefaultAdditionsISO);
936 /** @todo not yet implemented, settings handling is missing */
937 ReturnComNotImplemented();
938#if 0 /* not implemented */
939 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
940 HRESULT rc = i_setDefaultAdditionsISO(aDefaultAdditionsISO);
941 alock.release();
942
943 if (SUCCEEDED(rc))
944 {
945 // VirtualBox::i_saveSettings() needs vbox write lock
946 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
947 rc = mParent->i_saveSettings();
948 }
949
950 return rc;
951#endif
952}
953
954HRESULT SystemProperties::getDefaultFrontend(com::Utf8Str &aDefaultFrontend)
955{
956 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
957 aDefaultFrontend = m->strDefaultFrontend;
958 return S_OK;
959}
960
961HRESULT SystemProperties::setDefaultFrontend(const com::Utf8Str &aDefaultFrontend)
962{
963 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
964 if (m->strDefaultFrontend == Utf8Str(aDefaultFrontend))
965 return S_OK;
966 HRESULT rc = i_setDefaultFrontend(aDefaultFrontend);
967 alock.release();
968
969 if (SUCCEEDED(rc))
970 {
971 // VirtualBox::i_saveSettings() needs vbox write lock
972 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
973 rc = mParent->i_saveSettings();
974 }
975
976 return rc;
977}
978
979HRESULT SystemProperties::getScreenShotFormats(std::vector<BitmapFormat_T> &aBitmapFormats)
980{
981 aBitmapFormats.push_back(BitmapFormat_BGR0);
982 aBitmapFormats.push_back(BitmapFormat_BGRA);
983 aBitmapFormats.push_back(BitmapFormat_RGBA);
984 aBitmapFormats.push_back(BitmapFormat_PNG);
985 return S_OK;
986}
987
988// public methods only for internal purposes
989/////////////////////////////////////////////////////////////////////////////
990
991HRESULT SystemProperties::i_loadSettings(const settings::SystemProperties &data)
992{
993 AutoCaller autoCaller(this);
994 if (FAILED(autoCaller.rc())) return autoCaller.rc();
995
996 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
997 HRESULT rc = S_OK;
998 rc = i_setDefaultMachineFolder(data.strDefaultMachineFolder);
999 if (FAILED(rc)) return rc;
1000
1001 rc = i_setLoggingLevel(data.strLoggingLevel);
1002 if (FAILED(rc)) return rc;
1003
1004 rc = i_setDefaultHardDiskFormat(data.strDefaultHardDiskFormat);
1005 if (FAILED(rc)) return rc;
1006
1007 rc = i_setVRDEAuthLibrary(data.strVRDEAuthLibrary);
1008 if (FAILED(rc)) return rc;
1009
1010 rc = i_setWebServiceAuthLibrary(data.strWebServiceAuthLibrary);
1011 if (FAILED(rc)) return rc;
1012
1013 rc = i_setDefaultVRDEExtPack(data.strDefaultVRDEExtPack);
1014 if (FAILED(rc)) return rc;
1015
1016 m->ulLogHistoryCount = data.ulLogHistoryCount;
1017 m->fExclusiveHwVirt = data.fExclusiveHwVirt;
1018
1019 rc = i_setAutostartDatabasePath(data.strAutostartDatabasePath);
1020 if (FAILED(rc)) return rc;
1021
1022 {
1023 /* must ignore errors signalled here, because the guest additions
1024 * file may not exist, and in this case keep the empty string */
1025 ErrorInfoKeeper eik;
1026 (void)i_setDefaultAdditionsISO(data.strDefaultAdditionsISO);
1027 }
1028
1029 rc = i_setDefaultFrontend(data.strDefaultFrontend);
1030 if (FAILED(rc)) return rc;
1031
1032 return S_OK;
1033}
1034
1035HRESULT SystemProperties::i_saveSettings(settings::SystemProperties &data)
1036{
1037 AutoCaller autoCaller(this);
1038 if (FAILED(autoCaller.rc())) return autoCaller.rc();
1039
1040 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1041
1042 data = *m;
1043
1044 return S_OK;
1045}
1046
1047/**
1048 * Returns a medium format object corresponding to the given format
1049 * identifier or null if no such format.
1050 *
1051 * @param aFormat Format identifier.
1052 *
1053 * @return ComObjPtr<MediumFormat>
1054 */
1055ComObjPtr<MediumFormat> SystemProperties::i_mediumFormat(const Utf8Str &aFormat)
1056{
1057 ComObjPtr<MediumFormat> format;
1058
1059 AutoCaller autoCaller(this);
1060 AssertComRCReturn (autoCaller.rc(), format);
1061
1062 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1063
1064 for (MediumFormatList::const_iterator it = m_llMediumFormats.begin();
1065 it != m_llMediumFormats.end();
1066 ++ it)
1067 {
1068 /* MediumFormat is all const, no need to lock */
1069
1070 if ((*it)->i_getId().compare(aFormat, Utf8Str::CaseInsensitive) == 0)
1071 {
1072 format = *it;
1073 break;
1074 }
1075 }
1076
1077 return format;
1078}
1079
1080/**
1081 * Returns a medium format object corresponding to the given file extension or
1082 * null if no such format.
1083 *
1084 * @param aExt File extension.
1085 *
1086 * @return ComObjPtr<MediumFormat>
1087 */
1088ComObjPtr<MediumFormat> SystemProperties::i_mediumFormatFromExtension(const Utf8Str &aExt)
1089{
1090 ComObjPtr<MediumFormat> format;
1091
1092 AutoCaller autoCaller(this);
1093 AssertComRCReturn (autoCaller.rc(), format);
1094
1095 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1096
1097 bool fFound = false;
1098 for (MediumFormatList::const_iterator it = m_llMediumFormats.begin();
1099 it != m_llMediumFormats.end() && !fFound;
1100 ++it)
1101 {
1102 /* MediumFormat is all const, no need to lock */
1103 MediumFormat::StrArray aFileList = (*it)->i_getFileExtensions();
1104 for (MediumFormat::StrArray::const_iterator it1 = aFileList.begin();
1105 it1 != aFileList.end();
1106 ++it1)
1107 {
1108 if ((*it1).compare(aExt, Utf8Str::CaseInsensitive) == 0)
1109 {
1110 format = *it;
1111 fFound = true;
1112 break;
1113 }
1114 }
1115 }
1116
1117 return format;
1118}
1119
1120
1121/**
1122 * VD plugin load
1123 */
1124int SystemProperties::i_loadVDPlugin(const char *pszPluginLibrary)
1125{
1126 return VDPluginLoadFromFilename(pszPluginLibrary);
1127}
1128
1129/**
1130 * VD plugin unload
1131 */
1132int SystemProperties::i_unloadVDPlugin(const char *pszPluginLibrary)
1133{
1134 return VDPluginUnloadFromFilename(pszPluginLibrary);
1135}
1136
1137/**
1138 * Internally usable version of getDefaultAdditionsISO.
1139 */
1140HRESULT SystemProperties::i_getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO)
1141{
1142 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1143 if (m->strDefaultAdditionsISO.isNotEmpty())
1144 aDefaultAdditionsISO = m->strDefaultAdditionsISO;
1145 else
1146 {
1147 /* no guest additions, check if it showed up in the mean time */
1148 alock.release();
1149 AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
1150 if (m->strDefaultAdditionsISO.isEmpty())
1151 {
1152 ErrorInfoKeeper eik;
1153 (void)setDefaultAdditionsISO("");
1154 }
1155 aDefaultAdditionsISO = m->strDefaultAdditionsISO;
1156 }
1157 return S_OK;
1158}
1159
1160// private methods
1161/////////////////////////////////////////////////////////////////////////////
1162
1163/**
1164 * Returns the user's home directory. Wrapper around RTPathUserHome().
1165 * @param strPath
1166 * @return
1167 */
1168HRESULT SystemProperties::i_getUserHomeDirectory(Utf8Str &strPath)
1169{
1170 char szHome[RTPATH_MAX];
1171 int vrc = RTPathUserHome(szHome, sizeof(szHome));
1172 if (RT_FAILURE(vrc))
1173 return setErrorBoth(E_FAIL, vrc,
1174 tr("Cannot determine user home directory (%Rrc)"),
1175 vrc);
1176 strPath = szHome;
1177 return S_OK;
1178}
1179
1180/**
1181 * Internal implementation to set the default machine folder. Gets called
1182 * from the public attribute setter as well as loadSettings(). With 4.0,
1183 * the "default default" machine folder has changed, and we now require
1184 * a full path always.
1185 * @param strPath
1186 * @return
1187 */
1188HRESULT SystemProperties::i_setDefaultMachineFolder(const Utf8Str &strPath)
1189{
1190 Utf8Str path(strPath); // make modifiable
1191 if ( path.isEmpty() // used by API calls to reset the default
1192 || path == "Machines" // this value (exactly like this, without path) is stored
1193 // in VirtualBox.xml if user upgrades from before 4.0 and
1194 // has not changed the default machine folder
1195 )
1196 {
1197 // new default with VirtualBox 4.0: "$HOME/VirtualBox VMs"
1198 HRESULT rc = i_getUserHomeDirectory(path);
1199 if (FAILED(rc)) return rc;
1200 path += RTPATH_SLASH_STR "VirtualBox VMs";
1201 }
1202
1203 if (!RTPathStartsWithRoot(path.c_str()))
1204 return setError(E_INVALIDARG,
1205 tr("Given default machine folder '%s' is not fully qualified"),
1206 path.c_str());
1207
1208 m->strDefaultMachineFolder = path;
1209
1210 return S_OK;
1211}
1212
1213HRESULT SystemProperties::i_setLoggingLevel(const com::Utf8Str &aLoggingLevel)
1214{
1215 Utf8Str useLoggingLevel(aLoggingLevel);
1216 if (useLoggingLevel.isEmpty())
1217 useLoggingLevel = VBOXSVC_LOG_DEFAULT;
1218 int rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), useLoggingLevel.c_str());
1219 // If failed and not the default logging level - try to use the default logging level.
1220 if (RT_FAILURE(rc))
1221 {
1222 // If failed write message to the release log.
1223 LogRel(("Cannot set passed logging level=%s Error=%Rrc \n", useLoggingLevel.c_str(), rc));
1224 // If attempted logging level not the default one then try the default one.
1225 if (!useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT))
1226 {
1227 rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), VBOXSVC_LOG_DEFAULT);
1228 // If failed report this to the release log.
1229 if (RT_FAILURE(rc))
1230 LogRel(("Cannot set default logging level Error=%Rrc \n", rc));
1231 }
1232 // On any failure - set default level as the one to be stored.
1233 useLoggingLevel = VBOXSVC_LOG_DEFAULT;
1234 }
1235 // Set to passed value or if default used/attempted (even if error condition) use empty string.
1236 m->strLoggingLevel = (useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT) ? "" : useLoggingLevel);
1237 return RT_SUCCESS(rc) ? S_OK : E_FAIL;
1238}
1239
1240HRESULT SystemProperties::i_setDefaultHardDiskFormat(const com::Utf8Str &aFormat)
1241{
1242 if (!aFormat.isEmpty())
1243 m->strDefaultHardDiskFormat = aFormat;
1244 else
1245 m->strDefaultHardDiskFormat = "VDI";
1246
1247 return S_OK;
1248}
1249
1250HRESULT SystemProperties::i_setVRDEAuthLibrary(const com::Utf8Str &aPath)
1251{
1252 if (!aPath.isEmpty())
1253 m->strVRDEAuthLibrary = aPath;
1254 else
1255 m->strVRDEAuthLibrary = "VBoxAuth";
1256
1257 return S_OK;
1258}
1259
1260HRESULT SystemProperties::i_setWebServiceAuthLibrary(const com::Utf8Str &aPath)
1261{
1262 if (!aPath.isEmpty())
1263 m->strWebServiceAuthLibrary = aPath;
1264 else
1265 m->strWebServiceAuthLibrary = "VBoxAuth";
1266
1267 return S_OK;
1268}
1269
1270HRESULT SystemProperties::i_setDefaultVRDEExtPack(const com::Utf8Str &aExtPack)
1271{
1272 m->strDefaultVRDEExtPack = aExtPack;
1273
1274 return S_OK;
1275}
1276
1277HRESULT SystemProperties::i_setAutostartDatabasePath(const com::Utf8Str &aPath)
1278{
1279 HRESULT rc = S_OK;
1280 AutostartDb *autostartDb = this->mParent->i_getAutostartDb();
1281
1282 if (!aPath.isEmpty())
1283 {
1284 /* Update path in the autostart database. */
1285 int vrc = autostartDb->setAutostartDbPath(aPath.c_str());
1286 if (RT_SUCCESS(vrc))
1287 m->strAutostartDatabasePath = aPath;
1288 else
1289 rc = setErrorBoth(E_FAIL, vrc,
1290 tr("Cannot set the autostart database path (%Rrc)"),
1291 vrc);
1292 }
1293 else
1294 {
1295 int vrc = autostartDb->setAutostartDbPath(NULL);
1296 if (RT_SUCCESS(vrc) || vrc == VERR_NOT_SUPPORTED)
1297 m->strAutostartDatabasePath = "";
1298 else
1299 rc = setErrorBoth(E_FAIL, vrc,
1300 tr("Deleting the autostart database path failed (%Rrc)"),
1301 vrc);
1302 }
1303
1304 return rc;
1305}
1306
1307HRESULT SystemProperties::i_setDefaultAdditionsISO(const com::Utf8Str &aPath)
1308{
1309 com::Utf8Str path(aPath);
1310 if (path.isEmpty())
1311 {
1312 char strTemp[RTPATH_MAX];
1313 int vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));
1314 AssertRC(vrc);
1315 Utf8Str strSrc1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso");
1316
1317 vrc = RTPathExecDir(strTemp, sizeof(strTemp));
1318 AssertRC(vrc);
1319 Utf8Str strSrc2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso");
1320
1321 vrc = RTPathUserHome(strTemp, sizeof(strTemp));
1322 AssertRC(vrc);
1323 Utf8Str strSrc3 = Utf8StrFmt("%s/VBoxGuestAdditions_%s.iso", strTemp, VirtualBox::i_getVersionNormalized().c_str());
1324
1325 /* Check the standard image locations */
1326 if (RTFileExists(strSrc1.c_str()))
1327 path = strSrc1;
1328 else if (RTFileExists(strSrc2.c_str()))
1329 path = strSrc2;
1330 else if (RTFileExists(strSrc3.c_str()))
1331 path = strSrc3;
1332 else
1333 return setError(E_FAIL,
1334 tr("Cannot determine default Guest Additions ISO location. Most likely they are not available"));
1335 }
1336
1337 if (!RTPathStartsWithRoot(path.c_str()))
1338 return setError(E_INVALIDARG,
1339 tr("Given default machine Guest Additions ISO file '%s' is not fully qualified"),
1340 path.c_str());
1341
1342 if (!RTFileExists(path.c_str()))
1343 return setError(E_INVALIDARG,
1344 tr("Given default machine Guest Additions ISO file '%s' does not exist"),
1345 path.c_str());
1346
1347 m->strDefaultAdditionsISO = path;
1348
1349 return S_OK;
1350}
1351
1352HRESULT SystemProperties::i_setDefaultFrontend(const com::Utf8Str &aDefaultFrontend)
1353{
1354 m->strDefaultFrontend = aDefaultFrontend;
1355
1356 return S_OK;
1357}
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