VirtualBox

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

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

Main: Renamed AutoLock => AutoWriteLock; AutoReaderLock => AutoReadLock.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use