VirtualBox

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

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

Main: Code generator for (xp)com API implementations, including logging and parameter conversion, so far only used by MediumFormat. Next try, needed significant tweaks to work with xpcom (safearray handling fixes in the parameter conversion helpers), different STL implementation (which doesn't support declaring template type parameters as const), missing build dependencies (which didn't show on the dual core system used for writing the code), and finally the duplicate XPCOM classinfo and AddRef/Release/QueryInterface method definitions needed to be removed.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.3 KB
Line 
1/* $Id: SystemPropertiesImpl.cpp 45518 2013-04-12 12:01:02Z 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)->i_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::StrArray aFileList = (*it)->i_getFileExtensions();
1142 for (MediumFormat::StrArray::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