VirtualBox

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

Last change on this file since 67954 was 67754, checked in by vboxsync, 7 years ago

SystemProperties::i_getDefaultAdditionsISO: fixed my locking mess from a few days back.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.3 KB
Line 
1/* $Id: SystemPropertiesImpl.cpp 67754 2017-07-03 12:51:55Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2016 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 setError(E_FAIL,
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 = setError(E_FAIL,
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 = setError(E_FAIL,
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