VirtualBox

source: vbox/trunk/src/VBox/Main/BIOSSettingsImpl.cpp@ 17669

Last change on this file since 17669 was 17669, checked in by vboxsync, 16 years ago

Main: Rework storage controller handling to allow an arbitrary number of different storage controllers and remove code duplication:

  • XML format changed
  • New StorageController class
  • Removed SATAController (obsolete)
  • Removed the IDE controller code from BIOSSettings, handled in StorageController now
  • Property svn:eol-style set to native
File size: 17.3 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#include "BIOSSettingsImpl.h"
23#include "MachineImpl.h"
24#include "Logging.h"
25#include "GuestOSTypeImpl.h"
26
27#include <iprt/cpputils.h>
28#include <VBox/settings.h>
29
30// constructor / destructor
31/////////////////////////////////////////////////////////////////////////////
32
33HRESULT BIOSSettings::FinalConstruct()
34{
35 return S_OK;
36}
37
38void BIOSSettings::FinalRelease()
39{
40 uninit ();
41}
42
43// public initializer/uninitializer for internal purposes only
44/////////////////////////////////////////////////////////////////////////////
45
46/**
47 * Initializes the audio adapter object.
48 *
49 * @returns COM result indicator
50 */
51HRESULT BIOSSettings::init (Machine *aParent)
52{
53 LogFlowThisFuncEnter();
54 LogFlowThisFunc (("aParent: %p\n", aParent));
55
56 ComAssertRet (aParent, E_INVALIDARG);
57
58 /* Enclose the state transition NotReady->InInit->Ready */
59 AutoInitSpan autoInitSpan (this);
60 AssertReturn (autoInitSpan.isOk(), E_FAIL);
61
62 /* share the parent weakly */
63 unconst (mParent) = aParent;
64
65 mData.allocate();
66
67 autoInitSpan.setSucceeded();
68
69 LogFlowThisFuncLeave();
70 return S_OK;
71}
72
73/**
74 * Initializes the audio adapter object given another audio adapter object
75 * (a kind of copy constructor). This object shares data with
76 * the object passed as an argument.
77 *
78 * @note This object must be destroyed before the original object
79 * it shares data with is destroyed.
80 */
81HRESULT BIOSSettings::init (Machine *aParent, BIOSSettings *that)
82{
83 LogFlowThisFuncEnter();
84 LogFlowThisFunc (("aParent: %p, that: %p\n", aParent, that));
85
86 ComAssertRet (aParent && that, E_INVALIDARG);
87
88 /* Enclose the state transition NotReady->InInit->Ready */
89 AutoInitSpan autoInitSpan (this);
90 AssertReturn (autoInitSpan.isOk(), E_FAIL);
91
92 mParent = aParent;
93 mPeer = that;
94
95 AutoWriteLock thatlock (that);
96 mData.share (that->mData);
97
98 autoInitSpan.setSucceeded();
99
100 LogFlowThisFuncLeave();
101 return S_OK;
102}
103
104/**
105 * Initializes the guest object given another guest object
106 * (a kind of copy constructor). This object makes a private copy of data
107 * of the original object passed as an argument.
108 */
109HRESULT BIOSSettings::initCopy (Machine *aParent, BIOSSettings *that)
110{
111 LogFlowThisFuncEnter();
112 LogFlowThisFunc (("aParent: %p, that: %p\n", aParent, that));
113
114 ComAssertRet (aParent && that, E_INVALIDARG);
115
116 /* Enclose the state transition NotReady->InInit->Ready */
117 AutoInitSpan autoInitSpan (this);
118 AssertReturn (autoInitSpan.isOk(), E_FAIL);
119
120 mParent = aParent;
121 // mPeer is left null
122
123 AutoWriteLock thatlock (that);
124 mData.attachCopy (that->mData);
125
126 autoInitSpan.setSucceeded();
127
128 LogFlowThisFuncLeave();
129 return S_OK;
130}
131
132/**
133 * Uninitializes the instance and sets the ready flag to FALSE.
134 * Called either from FinalRelease() or by the parent when it gets destroyed.
135 */
136void BIOSSettings::uninit()
137{
138 LogFlowThisFuncEnter();
139
140 /* Enclose the state transition Ready->InUninit->NotReady */
141 AutoUninitSpan autoUninitSpan (this);
142 if (autoUninitSpan.uninitDone())
143 return;
144
145 mData.free();
146
147 mPeer.setNull();
148 mParent.setNull();
149
150 LogFlowThisFuncLeave();
151}
152
153// IBIOSSettings properties
154/////////////////////////////////////////////////////////////////////////////
155
156STDMETHODIMP BIOSSettings::COMGETTER(LogoFadeIn)(BOOL *enabled)
157{
158 if (!enabled)
159 return E_POINTER;
160
161 AutoCaller autoCaller (this);
162 CheckComRCReturnRC (autoCaller.rc());
163
164 AutoReadLock alock (this);
165
166 *enabled = mData->mLogoFadeIn;
167
168 return S_OK;
169}
170
171STDMETHODIMP BIOSSettings::COMSETTER(LogoFadeIn)(BOOL enable)
172{
173 AutoCaller autoCaller (this);
174 CheckComRCReturnRC (autoCaller.rc());
175
176 /* the machine needs to be mutable */
177 Machine::AutoMutableStateDependency adep (mParent);
178 CheckComRCReturnRC (adep.rc());
179
180 AutoWriteLock alock (this);
181
182 mData.backup();
183 mData->mLogoFadeIn = enable;
184
185 return S_OK;
186}
187
188STDMETHODIMP BIOSSettings::COMGETTER(LogoFadeOut)(BOOL *enabled)
189{
190 if (!enabled)
191 return E_POINTER;
192
193 AutoCaller autoCaller (this);
194 CheckComRCReturnRC (autoCaller.rc());
195
196 AutoReadLock alock (this);
197
198 *enabled = mData->mLogoFadeOut;
199
200 return S_OK;
201}
202
203STDMETHODIMP BIOSSettings::COMSETTER(LogoFadeOut)(BOOL enable)
204{
205 AutoCaller autoCaller (this);
206 CheckComRCReturnRC (autoCaller.rc());
207
208 /* the machine needs to be mutable */
209 Machine::AutoMutableStateDependency adep (mParent);
210 CheckComRCReturnRC (adep.rc());
211
212 AutoWriteLock alock (this);
213
214 mData.backup();
215 mData->mLogoFadeOut = enable;
216
217 return S_OK;
218}
219
220STDMETHODIMP BIOSSettings::COMGETTER(LogoDisplayTime)(ULONG *displayTime)
221{
222 if (!displayTime)
223 return E_POINTER;
224
225 AutoCaller autoCaller (this);
226 CheckComRCReturnRC (autoCaller.rc());
227
228 AutoReadLock alock (this);
229
230 *displayTime = mData->mLogoDisplayTime;
231
232 return S_OK;
233}
234
235STDMETHODIMP BIOSSettings::COMSETTER(LogoDisplayTime)(ULONG displayTime)
236{
237 AutoCaller autoCaller (this);
238 CheckComRCReturnRC (autoCaller.rc());
239
240 /* the machine needs to be mutable */
241 Machine::AutoMutableStateDependency adep (mParent);
242 CheckComRCReturnRC (adep.rc());
243
244 AutoWriteLock alock (this);
245
246 mData.backup();
247 mData->mLogoDisplayTime = displayTime;
248
249 return S_OK;
250}
251
252STDMETHODIMP BIOSSettings::COMGETTER(LogoImagePath)(BSTR *imagePath)
253{
254 if (!imagePath)
255 return E_POINTER;
256
257 AutoCaller autoCaller (this);
258 CheckComRCReturnRC (autoCaller.rc());
259
260 AutoReadLock alock (this);
261
262 mData->mLogoImagePath.cloneTo(imagePath);
263 return S_OK;
264}
265
266STDMETHODIMP BIOSSettings::COMSETTER(LogoImagePath)(IN_BSTR imagePath)
267{
268 /* empty strings are not allowed as path names */
269 if (imagePath && !(*imagePath))
270 return E_INVALIDARG;
271
272 AutoCaller autoCaller (this);
273 CheckComRCReturnRC (autoCaller.rc());
274
275 /* the machine needs to be mutable */
276 Machine::AutoMutableStateDependency adep (mParent);
277 CheckComRCReturnRC (adep.rc());
278
279 AutoWriteLock alock (this);
280
281 mData.backup();
282 mData->mLogoImagePath = imagePath;
283
284 return S_OK;
285}
286
287STDMETHODIMP BIOSSettings::COMGETTER(BootMenuMode)(BIOSBootMenuMode_T *bootMenuMode)
288{
289 if (!bootMenuMode)
290 return E_POINTER;
291
292 AutoCaller autoCaller (this);
293 CheckComRCReturnRC (autoCaller.rc());
294
295 AutoReadLock alock (this);
296
297 *bootMenuMode = mData->mBootMenuMode;
298 return S_OK;
299}
300
301STDMETHODIMP BIOSSettings::COMSETTER(BootMenuMode)(BIOSBootMenuMode_T bootMenuMode)
302{
303 AutoCaller autoCaller (this);
304 CheckComRCReturnRC (autoCaller.rc());
305
306 /* the machine needs to be mutable */
307 Machine::AutoMutableStateDependency adep (mParent);
308 CheckComRCReturnRC (adep.rc());
309
310 AutoWriteLock alock (this);
311
312 mData.backup();
313 mData->mBootMenuMode = bootMenuMode;
314
315 return S_OK;
316}
317
318STDMETHODIMP BIOSSettings::COMGETTER(ACPIEnabled)(BOOL *enabled)
319{
320 if (!enabled)
321 return E_POINTER;
322
323 AutoCaller autoCaller (this);
324 CheckComRCReturnRC (autoCaller.rc());
325
326 AutoReadLock alock (this);
327
328 *enabled = mData->mACPIEnabled;
329
330 return S_OK;
331}
332
333STDMETHODIMP BIOSSettings::COMSETTER(ACPIEnabled)(BOOL enable)
334{
335 AutoCaller autoCaller (this);
336 CheckComRCReturnRC (autoCaller.rc());
337
338 /* the machine needs to be mutable */
339 Machine::AutoMutableStateDependency adep (mParent);
340 CheckComRCReturnRC (adep.rc());
341
342 AutoWriteLock alock (this);
343
344 mData.backup();
345 mData->mACPIEnabled = enable;
346
347 return S_OK;
348}
349
350STDMETHODIMP BIOSSettings::COMGETTER(IOAPICEnabled)(BOOL *enabled)
351{
352 if (!enabled)
353 return E_POINTER;
354
355 AutoCaller autoCaller (this);
356 CheckComRCReturnRC (autoCaller.rc());
357
358 AutoReadLock alock (this);
359
360 *enabled = mData->mIOAPICEnabled;
361
362 return S_OK;
363}
364
365STDMETHODIMP BIOSSettings::COMSETTER(IOAPICEnabled)(BOOL enable)
366{
367 AutoCaller autoCaller (this);
368 CheckComRCReturnRC (autoCaller.rc());
369
370 /* the machine needs to be mutable */
371 Machine::AutoMutableStateDependency adep (mParent);
372 CheckComRCReturnRC (adep.rc());
373
374 AutoWriteLock alock (this);
375
376 mData.backup();
377 mData->mIOAPICEnabled = enable;
378
379 return S_OK;
380}
381
382STDMETHODIMP BIOSSettings::COMGETTER(PXEDebugEnabled)(BOOL *enabled)
383{
384 if (!enabled)
385 return E_POINTER;
386
387 AutoCaller autoCaller (this);
388 CheckComRCReturnRC (autoCaller.rc());
389
390 AutoReadLock alock (this);
391
392 *enabled = mData->mPXEDebugEnabled;
393
394 return S_OK;
395}
396
397STDMETHODIMP BIOSSettings::COMSETTER(PXEDebugEnabled)(BOOL enable)
398{
399 AutoCaller autoCaller (this);
400 CheckComRCReturnRC (autoCaller.rc());
401
402 /* the machine needs to be mutable */
403 Machine::AutoMutableStateDependency adep (mParent);
404 CheckComRCReturnRC (adep.rc());
405
406 AutoWriteLock alock (this);
407
408 mData.backup();
409 mData->mPXEDebugEnabled = enable;
410
411 return S_OK;
412}
413
414STDMETHODIMP BIOSSettings::COMGETTER(TimeOffset)(LONG64 *offset)
415{
416 if (!offset)
417 return E_POINTER;
418
419 AutoCaller autoCaller (this);
420 CheckComRCReturnRC (autoCaller.rc());
421
422 AutoReadLock alock (this);
423
424 *offset = mData->mTimeOffset;
425
426 return S_OK;
427}
428
429STDMETHODIMP BIOSSettings::COMSETTER(TimeOffset)(LONG64 offset)
430{
431 AutoCaller autoCaller (this);
432 CheckComRCReturnRC (autoCaller.rc());
433
434 /* the machine needs to be mutable */
435 Machine::AutoMutableStateDependency adep (mParent);
436 CheckComRCReturnRC (adep.rc());
437
438 AutoWriteLock alock (this);
439
440 mData.backup();
441 mData->mTimeOffset = offset;
442
443 return S_OK;
444}
445
446
447// IBIOSSettings methods
448/////////////////////////////////////////////////////////////////////////////
449
450// public methods only for internal purposes
451/////////////////////////////////////////////////////////////////////////////
452
453/**
454 * Loads settings from the given machine node.
455 * May be called once right after this object creation.
456 *
457 * @param aMachineNode <Machine> node.
458 *
459 * @note Locks this object for writing.
460 */
461HRESULT BIOSSettings::loadSettings (const settings::Key &aMachineNode)
462{
463 using namespace settings;
464
465 AssertReturn (!aMachineNode.isNull(), E_FAIL);
466
467 AutoCaller autoCaller (this);
468 AssertComRCReturnRC (autoCaller.rc());
469
470 AutoWriteLock alock (this);
471
472 /* Note: we assume that the default values for attributes of optional
473 * nodes are assigned in the Data::Data() constructor and don't do it
474 * here. It implies that this method may only be called after constructing
475 * a new BIOSSettings object while all its data fields are in the default
476 * values. Exceptions are fields whose creation time defaults don't match
477 * values that should be applied when these fields are not explicitly set
478 * in the settings file (for backwards compatibility reasons). This takes
479 * place when a setting of a newly created object must default to A while
480 * the same setting of an object loaded from the old settings file must
481 * default to B. */
482
483 /* BIOS node (required) */
484 Key biosNode = aMachineNode.key ("BIOS");
485
486 /* ACPI (required) */
487 {
488 Key acpiNode = biosNode.key ("ACPI");
489
490 mData->mACPIEnabled = acpiNode.value <bool> ("enabled");
491 }
492
493 /* IOAPIC (optional) */
494 {
495 Key ioapicNode = biosNode.findKey ("IOAPIC");
496 if (!ioapicNode.isNull())
497 mData->mIOAPICEnabled = ioapicNode.value <bool> ("enabled");
498 }
499
500 /* Logo (optional) */
501 {
502 Key logoNode = biosNode.findKey ("Logo");
503 if (!logoNode.isNull())
504 {
505 mData->mLogoFadeIn = logoNode.value <bool> ("fadeIn");
506 mData->mLogoFadeOut = logoNode.value <bool> ("fadeOut");
507 mData->mLogoDisplayTime = logoNode.value <ULONG> ("displayTime");
508 mData->mLogoImagePath = logoNode.stringValue ("imagePath");
509 }
510 }
511
512 /* boot menu (optional) */
513 {
514 Key bootMenuNode = biosNode.findKey ("BootMenu");
515 if (!bootMenuNode.isNull())
516 {
517 mData->mBootMenuMode = BIOSBootMenuMode_MessageAndMenu;
518 const char *modeStr = bootMenuNode.stringValue ("mode");
519
520 if (strcmp (modeStr, "Disabled") == 0)
521 mData->mBootMenuMode = BIOSBootMenuMode_Disabled;
522 else if (strcmp (modeStr, "MenuOnly") == 0)
523 mData->mBootMenuMode = BIOSBootMenuMode_MenuOnly;
524 else if (strcmp (modeStr, "MessageAndMenu") == 0)
525 mData->mBootMenuMode = BIOSBootMenuMode_MessageAndMenu;
526 else
527 ComAssertMsgFailedRet (("Invalid boot menu mode '%s'", modeStr),
528 E_FAIL);
529 }
530 }
531
532 /* PXE debug logging (optional) */
533 {
534 Key pxedebugNode = biosNode.findKey ("PXEDebug");
535 if (!pxedebugNode.isNull())
536 mData->mPXEDebugEnabled = pxedebugNode.value <bool> ("enabled");
537 }
538
539 /* time offset (optional) */
540 {
541 Key timeOffsetNode = biosNode.findKey ("TimeOffset");
542 if (!timeOffsetNode.isNull())
543 mData->mTimeOffset = timeOffsetNode.value <LONG64> ("value");
544 }
545
546 return S_OK;
547}
548
549/**
550 * Saves settings to the given machine node.
551 *
552 * @param aMachineNode <Machine> node.
553 *
554 * @note Locks this object for reading.
555 */
556HRESULT BIOSSettings::saveSettings (settings::Key &aMachineNode)
557{
558 using namespace settings;
559
560 AssertReturn (!aMachineNode.isNull(), E_FAIL);
561
562 AutoCaller autoCaller (this);
563 AssertComRCReturnRC (autoCaller.rc());
564
565 AutoReadLock alock (this);
566
567 Key biosNode = aMachineNode.createKey ("BIOS");
568
569 /* ACPI */
570 {
571 Key acpiNode = biosNode.createKey ("ACPI");
572 acpiNode.setValue <bool> ("enabled", !!mData->mACPIEnabled);
573 }
574
575 /* IOAPIC */
576 {
577 Key ioapicNode = biosNode.createKey ("IOAPIC");
578 ioapicNode.setValue <bool> ("enabled", !!mData->mIOAPICEnabled);
579 }
580
581 /* BIOS logo (optional) **/
582 {
583 Key logoNode = biosNode.createKey ("Logo");
584 logoNode.setValue <bool> ("fadeIn", !!mData->mLogoFadeIn);
585 logoNode.setValue <bool> ("fadeOut", !!mData->mLogoFadeOut);
586 logoNode.setValue <ULONG> ("displayTime", mData->mLogoDisplayTime);
587 logoNode.setValueOr <Bstr> ("imagePath", mData->mLogoImagePath, Bstr::Null);
588 }
589
590 /* boot menu (optional) */
591 {
592 Key bootMenuNode = biosNode.createKey ("BootMenu");
593 const char *modeStr = NULL;
594 switch (mData->mBootMenuMode)
595 {
596 case BIOSBootMenuMode_Disabled:
597 modeStr = "Disabled";
598 break;
599 case BIOSBootMenuMode_MenuOnly:
600 modeStr = "MenuOnly";
601 break;
602 case BIOSBootMenuMode_MessageAndMenu:
603 modeStr = "MessageAndMenu";
604 break;
605 default:
606 ComAssertMsgFailedRet (("Invalid boot menu type: %d",
607 mData->mBootMenuMode),
608 E_FAIL);
609 }
610 bootMenuNode.setStringValue ("mode", modeStr);
611 }
612
613 /* time offset (optional) */
614 {
615 Key timeOffsetNode = biosNode.createKey ("TimeOffset");
616 timeOffsetNode.setValue <LONG64> ("value", mData->mTimeOffset);
617 }
618
619 /* PXE debug flag (optional) */
620 {
621 Key pxedebugNode = biosNode.createKey ("PXEDebug");
622 pxedebugNode.setValue <bool> ("enabled", !!mData->mPXEDebugEnabled);
623 }
624
625 return S_OK;
626}
627
628void BIOSSettings::commit()
629{
630 /* sanity */
631 AutoCaller autoCaller (this);
632 AssertComRCReturnVoid (autoCaller.rc());
633
634 /* sanity too */
635 AutoCaller peerCaller (mPeer);
636 AssertComRCReturnVoid (peerCaller.rc());
637
638 /* lock both for writing since we modify both (mPeer is "master" so locked
639 * first) */
640 AutoMultiWriteLock2 alock (mPeer, this);
641
642 if (mData.isBackedUp())
643 {
644 mData.commit();
645 if (mPeer)
646 {
647 /* attach new data to the peer and reshare it */
648 AutoWriteLock peerlock (mPeer);
649 mPeer->mData.attach (mData);
650 }
651 }
652}
653
654void BIOSSettings::copyFrom (BIOSSettings *aThat)
655{
656 AssertReturnVoid (aThat != NULL);
657
658 /* sanity */
659 AutoCaller autoCaller (this);
660 AssertComRCReturnVoid (autoCaller.rc());
661
662 /* sanity too */
663 AutoCaller thatCaller (aThat);
664 AssertComRCReturnVoid (thatCaller.rc());
665
666 /* peer is not modified, lock it for reading (aThat is "master" so locked
667 * first) */
668 AutoMultiLock2 alock (aThat->rlock(), this->wlock());
669
670 /* this will back up current data */
671 mData.assignCopy (aThat->mData);
672}
673
674void BIOSSettings::applyDefaults (GuestOSType *aOsType)
675{
676 AssertReturnVoid (aOsType != NULL);
677
678 /* sanity */
679 AutoCaller autoCaller (this);
680 AssertComRCReturnVoid (autoCaller.rc());
681
682 AutoWriteLock alock (this);
683
684 /* Initialize default BIOS settings here */
685 mData->mIOAPICEnabled = aOsType->recommendedIOAPIC();
686}
687/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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