VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/Nvram.cpp@ 43446

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

Main/EFI: Permanent NVRAM save switched off by default.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.6 KB
Line 
1/* $Id: Nvram.cpp 43256 2012-09-08 03:38:02Z vboxsync $ */
2/** @file
3 * VBox NVRAM COM Class implementation.
4 */
5
6/*
7 * Copyright (C) 2012 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/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#include "Nvram.h"
22#include "ConsoleImpl.h"
23
24#include <VBox/vmm/pdm.h>
25#include <VBox/vmm/pdmdrv.h>
26#include <VBox/vmm/pdmnvram.h>
27#include <VBox/vmm/cfgm.h>
28#include <VBox/log.h>
29#include <VBox/err.h>
30#include <iprt/assert.h>
31#include <iprt/critsect.h>
32#include <iprt/mem.h>
33#include <iprt/string.h>
34#include <iprt/uuid.h>
35#include <iprt/base64.h>
36#include <VBox/version.h>
37#include <iprt/file.h>
38#include <iprt/semaphore.h>
39
40
41/*******************************************************************************
42* Structures and Typedefs *
43*******************************************************************************/
44typedef struct NVRAM NVRAM;
45typedef struct NVRAM *PNVRAM;
46
47struct NVRAM
48{
49 Nvram *pNvram;
50 PDMINVRAM INvram;
51 int cLoadedVariables;
52 bool fPermanentSave;
53};
54
55
56/**
57 * Constructor/destructor
58 */
59Nvram::Nvram(Console *console)
60 : mpDrv(NULL),
61 mParent(console)
62{
63}
64
65Nvram::~Nvram()
66{
67 if (mpDrv)
68 {
69 mpDrv->pNvram = NULL;
70 mpDrv = NULL;
71 }
72}
73
74
75/**
76 * @interface_method_impl(PDMINVRAM,pfnStoreNvramValue)
77 */
78DECLCALLBACK(int) drvNvram_pfnStoreNvramValue(PPDMINVRAM pInterface,
79 int idxVariable,
80 RTUUID *pVendorUuid,
81 const char *pcszVariableName,
82 size_t cbVariableName,
83 uint8_t *pu8Value,
84 size_t cbValue)
85{
86 int rc = VINF_SUCCESS;
87 char szExtraDataKey[256];
88 char szExtraDataValue[1024];
89 LogFlowFunc(("ENTER: pVendorUuid:%RTuuid, pcszVariableName:%s, cbVariableName:%d, pu8Value:%.*Rhxs, cbValue:%d\n",
90 pVendorUuid,
91 pcszVariableName,
92 cbVariableName,
93 cbValue,
94 pu8Value,
95 cbValue));
96 PNVRAM pThis = RT_FROM_MEMBER(pInterface, NVRAM, INvram);
97 if (!pThis->fPermanentSave)
98 {
99 LogFlowFuncLeaveRC(rc);
100 return rc;
101 }
102
103 bool fFlushVariable = (!pu8Value);
104
105 RT_ZERO(szExtraDataKey);
106 RT_ZERO(szExtraDataValue);
107 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableName", idxVariable);
108 if (!fFlushVariable)
109 RTStrPrintf(szExtraDataValue, 1024, "%s", pcszVariableName);
110 pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw());
111
112 RT_ZERO(szExtraDataKey);
113 RT_ZERO(szExtraDataValue);
114 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VendorGuid", idxVariable);
115 if (!fFlushVariable)
116 RTUuidToStr(pVendorUuid, szExtraDataValue, 1024);
117 pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw());
118
119 RT_ZERO(szExtraDataKey);
120 RT_ZERO(szExtraDataValue);
121 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableValueLength", idxVariable);
122 if (!fFlushVariable)
123 RTStrPrintf(szExtraDataValue, 1024, "%d", cbValue);
124 pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw());
125
126 RT_ZERO(szExtraDataKey);
127 RT_ZERO(szExtraDataValue);
128 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableValue", idxVariable);
129 size_t cbActualSize;
130 if (pu8Value)
131 rc = RTBase64Encode(pu8Value, cbValue, szExtraDataValue, 1024, &cbActualSize);
132 AssertRCReturn(rc, rc);
133 pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw());
134
135 LogFlowFuncLeaveRC(rc);
136 return rc;
137}
138
139
140/**
141 * @interface_method_impl(PDMINVRAM,pfnFlushNvramStorage)
142 */
143DECLCALLBACK(int) drvNvram_pfnFlushNvramStorage(PPDMINVRAM pInterface)
144{
145 int rc = VINF_SUCCESS;
146 LogFlowFuncEnter();
147 PNVRAM pThis = RT_FROM_MEMBER(pInterface, NVRAM, INvram);
148 if (!pThis->fPermanentSave)
149 {
150 LogFlowFuncLeaveRC(rc);
151 return rc;
152 }
153
154 for (int idxVariable = 0; idxVariable < pThis->cLoadedVariables; ++idxVariable)
155 {
156 drvNvram_pfnStoreNvramValue(pInterface, idxVariable, NULL, NULL, 0, NULL, 0);
157 }
158 LogFlowFuncLeaveRC(rc);
159 return rc;
160}
161
162
163/**
164 * @interface_method_impl(PDMINVRAM,pfnStoreNvramValue)
165 */
166DECLCALLBACK(int) drvNvram_pfnLoadNvramValue(PPDMINVRAM pInterface,
167 int idxVariable,
168 RTUUID *pVendorUuid,
169 char *pcszVariableName,
170 size_t *pcbVariableName,
171 uint8_t *pu8Value,
172 size_t *pcbValue)
173{
174 int rc = VINF_SUCCESS;
175 char szExtraDataKey[256];
176 Bstr bstrValue;
177 HRESULT hrc;
178 LogFlowFunc(("ENTER: idxVariable:%d, *pcbVariableName:%d, *pcbValue:%d\n",
179 idxVariable,
180 *pcbVariableName,
181 *pcbValue));
182 PNVRAM pThis = RT_FROM_MEMBER(pInterface, NVRAM, INvram);
183 if (!pThis->fPermanentSave)
184 {
185 rc = VERR_NOT_FOUND;
186 LogFlowFuncLeaveRC(rc);
187 return rc;
188 }
189
190
191 RT_ZERO(szExtraDataKey);
192 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableName", idxVariable);
193 hrc = pThis->pNvram->getParent()->machine()->GetExtraData(Bstr(szExtraDataKey).raw(), bstrValue.asOutParam());
194 if (!SUCCEEDED(hrc))
195 return VERR_NOT_FOUND;
196 *pcbVariableName = RTStrCopy(pcszVariableName, 1024, Utf8Str(bstrValue).c_str());
197
198 RT_ZERO(szExtraDataKey);
199 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VendorGuid", idxVariable);
200 hrc = pThis->pNvram->getParent()->machine()->GetExtraData(Bstr(szExtraDataKey).raw(), bstrValue.asOutParam());
201 RTUuidFromStr(pVendorUuid, Utf8Str(bstrValue).c_str());
202
203#if 0
204 RT_ZERO(szExtraDataKey);
205 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableValueLength", idxVariable);
206 hrc = pThis->pNvram->getParent()->machine()->GetExtraData(Bstr(szExtraDataKey).raw(), bstrValue.asOutParam());
207 *pcbValue = Utf8Str(bstrValue).toUInt32();
208#endif
209
210 RT_ZERO(szExtraDataKey);
211 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableValue", idxVariable);
212 hrc = pThis->pNvram->getParent()->machine()->GetExtraData(Bstr(szExtraDataKey).raw(), bstrValue.asOutParam());
213 rc = RTBase64Decode(Utf8Str(bstrValue).c_str(), pu8Value, 1024, pcbValue, NULL);
214 AssertRCReturn(rc, rc);
215
216 pThis->cLoadedVariables++;
217 LogFlowFuncLeaveRC(rc);
218 return rc;
219}
220
221
222/**
223 * @interface_method_impl(PDMIBASE,pfnQueryInterface)
224 */
225DECLCALLBACK(void *) Nvram::drvNvram_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
226{
227 LogFlow(("%s pInterface:%p, pszIID:%s\n", __FUNCTION__, pInterface, pszIID));
228 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
229 PNVRAM pThis = PDMINS_2_DATA(pDrvIns, PNVRAM);
230
231 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
232 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINVRAM, &pThis->INvram);
233 return NULL;
234}
235
236
237/**
238 * @interface_method_impl(PDMDRVREG,pfnDestruct)
239 */
240DECLCALLBACK(void) Nvram::drvNvram_Destruct(PPDMDRVINS pDrvIns)
241{
242 LogFlow(("%s: iInstance/#d\n", __FUNCTION__, pDrvIns->iInstance));
243 PNVRAM pThis = PDMINS_2_DATA(pDrvIns, PNVRAM);
244}
245
246
247/**
248 * @interface_method_impl(PDMDRVREG,pfnConstruct)
249 */
250DECLCALLBACK(int) Nvram::drvNvram_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
251{
252 LogFlowFunc(("iInstance/#d, pCfg:%p, fFlags:%x\n", pDrvIns->iInstance, pCfg, fFlags));
253 PNVRAM pThis = PDMINS_2_DATA(pDrvIns, PNVRAM);
254
255 if (!CFGMR3AreValuesValid(pCfg, "Object\0"
256 "PermanentSave\0"))
257 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
258 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
259 ("Configuration error: Not possible to attach anything to this driver!\n"),
260 VERR_PDM_DRVINS_NO_ATTACH);
261
262 void *pv;
263 int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
264 AssertMsgRCReturn(rc, ("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc), rc);
265 pThis->pNvram = (Nvram *)pv;
266
267 bool fPermanentSave = false;
268 rc = CFGMR3QueryBool(pCfg, "PermanentSave", &fPermanentSave);
269 if ( RT_SUCCESS(rc)
270 || rc == VERR_CFGM_VALUE_NOT_FOUND)
271 pThis->fPermanentSave = fPermanentSave;
272 else
273 AssertRCReturn(rc, rc);
274
275 pDrvIns->IBase.pfnQueryInterface = Nvram::drvNvram_QueryInterface;
276 pThis->INvram.pfnFlushNvramStorage = drvNvram_pfnFlushNvramStorage;
277 pThis->INvram.pfnStoreNvramValue = drvNvram_pfnStoreNvramValue;
278 pThis->INvram.pfnLoadNvramValue = drvNvram_pfnLoadNvramValue;
279
280 return VINF_SUCCESS;
281}
282
283
284const PDMDRVREG Nvram::DrvReg =
285{
286 /* u32Version */
287 PDM_DRVREG_VERSION,
288 /* szName[32] */
289 "NvramStorage",
290 /* szRCMod[32] */
291 "",
292 /* szR0Mod[32] */
293 "",
294 /* pszDescription */
295 "NVRAM Main Driver",
296 /* fFlags */
297 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
298 /* fClass */
299 PDM_DRVREG_CLASS_VMMDEV,
300 /* cMaxInstances */
301 1,
302 /* cbInstance */
303 sizeof(NVRAM),
304 /* pfnConstruct */
305 Nvram::drvNvram_Construct,
306 /* pfnDestruct */
307 Nvram::drvNvram_Destruct,
308 /* pfnRelocate */
309 NULL,
310 /* pfnIOCtl */
311 NULL,
312 /* pfnPowerOn */
313 NULL,
314 /* pfnReset */
315 NULL,
316 /* pfnSuspend */
317 NULL,
318 /* pfnResume */
319 NULL,
320 /* pfnAttach */
321 NULL,
322 /* pfnDetach */
323 NULL,
324 /* pfnPowerOff */
325 NULL,
326 /* pfnSoftReset */
327 NULL,
328 /* u32VersionEnd */
329 PDM_DRVREG_VERSION
330};
331/* 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