VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/BIOSSettingsImpl.cpp@ 81299

Last change on this file since 81299 was 81299, checked in by vboxsync, 5 years ago

Main/Machine+BIOSSettings: simplify NVRAM handling, do everything in backwards c
ompatible way
Frontends/VBoxManage: adapt to API change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1/* $Id: BIOSSettingsImpl.cpp 81299 2019-10-16 19:32:48Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Machine BIOS settings.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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#define LOG_GROUP LOG_GROUP_MAIN_BIOSSETTINGS
19#include "BIOSSettingsImpl.h"
20#include "MachineImpl.h"
21#include "GuestOSTypeImpl.h"
22
23#include <iprt/cpp/utils.h>
24#include <VBox/settings.h>
25
26#include "AutoStateDep.h"
27#include "AutoCaller.h"
28#include "LoggingNew.h"
29
30
31////////////////////////////////////////////////////////////////////////////////
32//
33// BIOSSettings private data definition
34//
35////////////////////////////////////////////////////////////////////////////////
36
37struct BIOSSettings::Data
38{
39 Data()
40 : pMachine(NULL)
41 { }
42
43 Machine * const pMachine;
44 ComObjPtr<BIOSSettings> pPeer;
45
46 // use the XML settings structure in the members for simplicity
47 Backupable<settings::BIOSSettings> bd;
48};
49
50// constructor / destructor
51/////////////////////////////////////////////////////////////////////////////
52
53DEFINE_EMPTY_CTOR_DTOR(BIOSSettings)
54
55HRESULT BIOSSettings::FinalConstruct()
56{
57 return BaseFinalConstruct();
58}
59
60void BIOSSettings::FinalRelease()
61{
62 uninit();
63 BaseFinalRelease();
64}
65
66// public initializer/uninitializer for internal purposes only
67/////////////////////////////////////////////////////////////////////////////
68
69/**
70 * Initializes the BIOS settings object.
71 *
72 * @returns COM result indicator
73 */
74HRESULT BIOSSettings::init(Machine *aParent)
75{
76 LogFlowThisFuncEnter();
77 LogFlowThisFunc(("aParent: %p\n", aParent));
78
79 ComAssertRet(aParent, E_INVALIDARG);
80
81 /* Enclose the state transition NotReady->InInit->Ready */
82 AutoInitSpan autoInitSpan(this);
83 AssertReturn(autoInitSpan.isOk(), E_FAIL);
84
85 m = new Data();
86
87 /* share the parent weakly */
88 unconst(m->pMachine) = aParent;
89
90 m->bd.allocate();
91
92 autoInitSpan.setSucceeded();
93
94 LogFlowThisFuncLeave();
95 return S_OK;
96}
97
98/**
99 * Initializes the BIOS settings object given another BIOS settings object
100 * (a kind of copy constructor). This object shares data with
101 * the object passed as an argument.
102 *
103 * @note This object must be destroyed before the original object
104 * it shares data with is destroyed.
105 */
106HRESULT BIOSSettings::init(Machine *aParent, BIOSSettings *that)
107{
108 LogFlowThisFuncEnter();
109 LogFlowThisFunc(("aParent: %p, that: %p\n", aParent, that));
110
111 ComAssertRet(aParent && that, E_INVALIDARG);
112
113 /* Enclose the state transition NotReady->InInit->Ready */
114 AutoInitSpan autoInitSpan(this);
115 AssertReturn(autoInitSpan.isOk(), E_FAIL);
116
117 m = new Data();
118
119 unconst(m->pMachine) = aParent;
120 m->pPeer = that;
121
122 AutoWriteLock thatlock(that COMMA_LOCKVAL_SRC_POS);
123 m->bd.share(that->m->bd);
124
125 autoInitSpan.setSucceeded();
126
127 LogFlowThisFuncLeave();
128 return S_OK;
129}
130
131/**
132 * Initializes the guest object given another guest object
133 * (a kind of copy constructor). This object makes a private copy of data
134 * of the original object passed as an argument.
135 */
136HRESULT BIOSSettings::initCopy(Machine *aParent, BIOSSettings *that)
137{
138 LogFlowThisFuncEnter();
139 LogFlowThisFunc(("aParent: %p, that: %p\n", aParent, that));
140
141 ComAssertRet(aParent && that, E_INVALIDARG);
142
143 /* Enclose the state transition NotReady->InInit->Ready */
144 AutoInitSpan autoInitSpan(this);
145 AssertReturn(autoInitSpan.isOk(), E_FAIL);
146
147 m = new Data();
148
149 unconst(m->pMachine) = aParent;
150 // mPeer is left null
151
152 AutoWriteLock thatlock(that COMMA_LOCKVAL_SRC_POS);
153 m->bd.attachCopy(that->m->bd);
154
155 autoInitSpan.setSucceeded();
156
157 LogFlowThisFuncLeave();
158 return S_OK;
159}
160
161/**
162 * Uninitializes the instance and sets the ready flag to FALSE.
163 * Called either from FinalRelease() or by the parent when it gets destroyed.
164 */
165void BIOSSettings::uninit()
166{
167 LogFlowThisFuncEnter();
168
169 /* Enclose the state transition Ready->InUninit->NotReady */
170 AutoUninitSpan autoUninitSpan(this);
171 if (autoUninitSpan.uninitDone())
172 return;
173
174 m->bd.free();
175
176 unconst(m->pPeer) = NULL;
177 unconst(m->pMachine) = NULL;
178
179 delete m;
180 m = NULL;
181
182 LogFlowThisFuncLeave();
183}
184
185// IBIOSSettings properties
186/////////////////////////////////////////////////////////////////////////////
187
188
189HRESULT BIOSSettings::getLogoFadeIn(BOOL *enabled)
190{
191 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
192
193 *enabled = m->bd->fLogoFadeIn;
194
195 return S_OK;
196}
197
198HRESULT BIOSSettings::setLogoFadeIn(BOOL enable)
199{
200 /* the machine needs to be mutable */
201 AutoMutableStateDependency adep(m->pMachine);
202 if (FAILED(adep.rc())) return adep.rc();
203
204 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
205
206 m->bd.backup();
207 m->bd->fLogoFadeIn = RT_BOOL(enable);
208
209 alock.release();
210 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
211 m->pMachine->i_setModified(Machine::IsModified_BIOS);
212
213 return S_OK;
214}
215
216
217HRESULT BIOSSettings::getLogoFadeOut(BOOL *enabled)
218{
219 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
220
221 *enabled = m->bd->fLogoFadeOut;
222
223 return S_OK;
224}
225
226HRESULT BIOSSettings::setLogoFadeOut(BOOL enable)
227{
228 /* the machine needs to be mutable */
229 AutoMutableStateDependency adep(m->pMachine);
230 if (FAILED(adep.rc())) return adep.rc();
231
232 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
233
234 m->bd.backup();
235 m->bd->fLogoFadeOut = RT_BOOL(enable);
236
237 alock.release();
238 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
239 m->pMachine->i_setModified(Machine::IsModified_BIOS);
240
241 return S_OK;
242}
243
244
245HRESULT BIOSSettings::getLogoDisplayTime(ULONG *displayTime)
246{
247 if (!displayTime)
248 return E_POINTER;
249
250 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
251
252 *displayTime = m->bd->ulLogoDisplayTime;
253
254 return S_OK;
255}
256
257HRESULT BIOSSettings::setLogoDisplayTime(ULONG displayTime)
258{
259 /* the machine needs to be mutable */
260 AutoMutableStateDependency adep(m->pMachine);
261 if (FAILED(adep.rc())) return adep.rc();
262
263 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
264
265 m->bd.backup();
266 m->bd->ulLogoDisplayTime = displayTime;
267
268 alock.release();
269 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
270 m->pMachine->i_setModified(Machine::IsModified_BIOS);
271
272 return S_OK;
273}
274
275
276HRESULT BIOSSettings::getLogoImagePath(com::Utf8Str &imagePath)
277{
278 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
279
280 imagePath = m->bd->strLogoImagePath;
281 return S_OK;
282}
283
284HRESULT BIOSSettings::setLogoImagePath(const com::Utf8Str &imagePath)
285{
286 /* the machine needs to be mutable */
287 AutoMutableStateDependency adep(m->pMachine);
288 if (FAILED(adep.rc())) return adep.rc();
289
290 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
291
292 m->bd.backup();
293 m->bd->strLogoImagePath = imagePath;
294
295 alock.release();
296 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
297 m->pMachine->i_setModified(Machine::IsModified_BIOS);
298
299 return S_OK;
300}
301
302HRESULT BIOSSettings::getBootMenuMode(BIOSBootMenuMode_T *bootMenuMode)
303{
304 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
305
306 *bootMenuMode = m->bd->biosBootMenuMode;
307 return S_OK;
308}
309
310HRESULT BIOSSettings::setBootMenuMode(BIOSBootMenuMode_T bootMenuMode)
311{
312 /* the machine needs to be mutable */
313 AutoMutableStateDependency adep(m->pMachine);
314 if (FAILED(adep.rc())) return adep.rc();
315
316 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
317
318 m->bd.backup();
319 m->bd->biosBootMenuMode = bootMenuMode;
320
321 alock.release();
322 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
323 m->pMachine->i_setModified(Machine::IsModified_BIOS);
324
325 return S_OK;
326}
327
328
329HRESULT BIOSSettings::getACPIEnabled(BOOL *enabled)
330{
331 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
332
333 *enabled = m->bd->fACPIEnabled;
334
335 return S_OK;
336}
337
338HRESULT BIOSSettings::setACPIEnabled(BOOL enable)
339{
340 /* the machine needs to be mutable */
341 AutoMutableStateDependency adep(m->pMachine);
342 if (FAILED(adep.rc())) return adep.rc();
343
344 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
345
346 m->bd.backup();
347 m->bd->fACPIEnabled = RT_BOOL(enable);
348
349 alock.release();
350 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
351 m->pMachine->i_setModified(Machine::IsModified_BIOS);
352
353 return S_OK;
354}
355
356
357HRESULT BIOSSettings::getIOAPICEnabled(BOOL *aIOAPICEnabled)
358{
359 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
360
361 *aIOAPICEnabled = m->bd->fIOAPICEnabled;
362
363 return S_OK;
364}
365
366HRESULT BIOSSettings::setIOAPICEnabled(BOOL aIOAPICEnabled)
367{
368 /* the machine needs to be mutable */
369 AutoMutableStateDependency adep(m->pMachine);
370 if (FAILED(adep.rc())) return adep.rc();
371
372 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
373
374 m->bd.backup();
375
376 m->bd->fIOAPICEnabled = RT_BOOL(aIOAPICEnabled);
377 alock.release();
378 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
379 m->pMachine->i_setModified(Machine::IsModified_BIOS);
380
381 return S_OK;
382}
383
384
385HRESULT BIOSSettings::getAPICMode(APICMode_T *aAPICMode)
386{
387 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
388
389 *aAPICMode = m->bd->apicMode;
390
391 return S_OK;
392}
393
394HRESULT BIOSSettings::setAPICMode(APICMode_T aAPICMode)
395{
396 /* the machine needs to be mutable */
397 AutoMutableStateDependency adep(m->pMachine);
398 if (FAILED(adep.rc())) return adep.rc();
399
400 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
401
402 m->bd.backup();
403
404 m->bd->apicMode = aAPICMode;
405 alock.release();
406 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
407 m->pMachine->i_setModified(Machine::IsModified_BIOS);
408
409 return S_OK;
410}
411
412
413HRESULT BIOSSettings::getPXEDebugEnabled(BOOL *enabled)
414{
415 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
416
417 *enabled = m->bd->fPXEDebugEnabled;
418
419 return S_OK;
420}
421
422HRESULT BIOSSettings::setPXEDebugEnabled(BOOL enable)
423{
424 /* the machine needs to be mutable */
425 AutoMutableStateDependency adep(m->pMachine);
426 if (FAILED(adep.rc())) return adep.rc();
427
428 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
429
430 m->bd.backup();
431 m->bd->fPXEDebugEnabled = RT_BOOL(enable);
432
433 alock.release();
434 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
435 m->pMachine->i_setModified(Machine::IsModified_BIOS);
436
437 return S_OK;
438}
439
440
441HRESULT BIOSSettings::getTimeOffset(LONG64 *offset)
442{
443 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
444
445 *offset = m->bd->llTimeOffset;
446
447 return S_OK;
448}
449
450HRESULT BIOSSettings::setTimeOffset(LONG64 offset)
451{
452 /* the machine needs to be mutable */
453 AutoMutableStateDependency adep(m->pMachine);
454 if (FAILED(adep.rc())) return adep.rc();
455
456 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
457
458 m->bd.backup();
459 m->bd->llTimeOffset = offset;
460
461 alock.release();
462 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
463 m->pMachine->i_setModified(Machine::IsModified_BIOS);
464
465 return S_OK;
466}
467
468
469HRESULT BIOSSettings::getNonVolatileStorageFile(com::Utf8Str &aNonVolatileStorageFile)
470{
471 Utf8Str strTmp;
472 {
473 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
474 strTmp = m->bd->strNVRAMPath;
475 }
476
477 AutoReadLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
478 if (strTmp.isEmpty())
479 strTmp = m->pMachine->i_getDefaultNVRAMFilename();
480 if (strTmp.isNotEmpty())
481 m->pMachine->i_calculateFullPath(strTmp, aNonVolatileStorageFile);
482
483 return S_OK;
484}
485
486
487
488// IBIOSSettings methods
489/////////////////////////////////////////////////////////////////////////////
490
491// public methods only for internal purposes
492/////////////////////////////////////////////////////////////////////////////
493
494/**
495 * Loads settings from the given machine node.
496 * May be called once right after this object creation.
497 *
498 * @param data Configuration settings.
499 *
500 * @note Locks this object for writing.
501 */
502HRESULT BIOSSettings::i_loadSettings(const settings::BIOSSettings &data)
503{
504 AutoCaller autoCaller(this);
505 AssertComRCReturnRC(autoCaller.rc());
506
507 AutoReadLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
508 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
509
510 // simply copy
511 m->bd.assignCopy(&data);
512
513 Utf8Str strTmp(m->bd->strNVRAMPath);
514 if (strTmp.isNotEmpty())
515 m->pMachine->i_copyPathRelativeToMachine(strTmp, m->bd->strNVRAMPath);
516 if ( m->pMachine->i_getFirmwareType() == FirmwareType_BIOS
517 || m->bd->strNVRAMPath == m->pMachine->i_getDefaultNVRAMFilename())
518 m->bd->strNVRAMPath.setNull();
519
520 return S_OK;
521}
522
523/**
524 * Saves settings to the given machine node.
525 *
526 * @param data Configuration settings.
527 *
528 * @note Locks this object for reading.
529 */
530HRESULT BIOSSettings::i_saveSettings(settings::BIOSSettings &data)
531{
532 AutoCaller autoCaller(this);
533 AssertComRCReturnRC(autoCaller.rc());
534
535 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
536
537 data = *m->bd.data();
538
539 return S_OK;
540}
541
542void BIOSSettings::i_rollback()
543{
544 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
545 m->bd.rollback();
546}
547
548void BIOSSettings::i_commit()
549{
550 /* sanity */
551 AutoCaller autoCaller(this);
552 AssertComRCReturnVoid(autoCaller.rc());
553
554 /* sanity too */
555 AutoCaller peerCaller(m->pPeer);
556 AssertComRCReturnVoid(peerCaller.rc());
557
558 /* lock both for writing since we modify both (mPeer is "master" so locked
559 * first) */
560 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
561
562 if (m->bd.isBackedUp())
563 {
564 m->bd.commit();
565 if (m->pPeer)
566 {
567 /* attach new data to the peer and reshare it */
568 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
569 m->pPeer->m->bd.attach(m->bd);
570 }
571 }
572}
573
574void BIOSSettings::i_copyFrom(BIOSSettings *aThat)
575{
576 AssertReturnVoid(aThat != NULL);
577
578 /* sanity */
579 AutoCaller autoCaller(this);
580 AssertComRCReturnVoid(autoCaller.rc());
581
582 /* sanity too */
583 AutoCaller thatCaller(aThat);
584 AssertComRCReturnVoid(thatCaller.rc());
585
586 /* peer is not modified, lock it for reading (aThat is "master" so locked
587 * first) */
588 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
589 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
590
591 /* this will back up current data */
592 m->bd.assignCopy(aThat->m->bd);
593}
594
595void BIOSSettings::i_applyDefaults(GuestOSType *aOsType)
596{
597 /* sanity */
598 AutoCaller autoCaller(this);
599 AssertComRCReturnVoid(autoCaller.rc());
600
601 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
602
603 /* Initialize default BIOS settings here */
604 if (aOsType)
605 m->bd->fIOAPICEnabled = aOsType->i_recommendedIOAPIC();
606 else
607 m->bd->fIOAPICEnabled = true;
608}
609
610void BIOSSettings::i_updateNonVolatileStorageFile(const Utf8Str &aNonVolatileStorageFile)
611{
612 /* sanity */
613 AutoCaller autoCaller(this);
614 AssertComRCReturnVoid(autoCaller.rc());
615
616 AutoReadLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
617 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
618
619 Utf8Str strTmp(aNonVolatileStorageFile);
620 if (strTmp == m->pMachine->i_getDefaultNVRAMFilename())
621 strTmp.setNull();
622
623 if (strTmp == m->bd->strNVRAMPath)
624 return;
625
626 m->bd.backup();
627 m->bd->strNVRAMPath = strTmp;
628}
629
630/* 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