VirtualBox

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

Last change on this file since 44948 was 44948, checked in by vboxsync, 12 years ago

Main/SystemProperties+Machine: new config setting for default VM frontend.
Frontend/VirtualBox+VBoxManage: changes to use the default VM frontend when starting a VM, other minor cleanups
Main/xml/*.xsd: attempt to bring the XML schema close to reality
doc/manual: document the new possibilities, and fix a few long standing inaccuracies

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