VirtualBox

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

Last change on this file since 52585 was 52585, checked in by vboxsync, 10 years ago

Storage/VD + Main/ExtPackManager+VirtualBox+SystemProperties: handle unloading of VD plugin from VBoxSVC when extpack is uninstalled, fixes extpack uninstall problems related to VDPluginCrypt.dll on Windows

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