VirtualBox

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

Last change on this file since 43139 was 43133, checked in by vboxsync, 13 years ago

export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.2 KB
Line 
1/* $Id: Nvram.cpp 43133 2012-08-31 12:01:55Z vboxsync $ */
2
3/** @file
4 * VBox NVRAM COM Class implementation
5 */
6
7/*
8 * Copyright (C) 2012 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include "Nvram.h"
23#include "ConsoleImpl.h"
24
25#include <VBox/vmm/pdm.h>
26#include <VBox/vmm/pdmdrv.h>
27#include <VBox/vmm/pdmnvram.h>
28#include <VBox/vmm/cfgm.h>
29#include <VBox/log.h>
30#include <VBox/err.h>
31#include <iprt/assert.h>
32#include <iprt/critsect.h>
33#include <iprt/mem.h>
34#include <iprt/string.h>
35#include <iprt/uuid.h>
36#include <iprt/base64.h>
37#include <VBox/version.h>
38#include <iprt/file.h>
39#include <iprt/semaphore.h>
40
41
42/*******************************************************************************
43* Structures and Typedefs *
44*******************************************************************************/
45typedef struct NVRAM NVRAM;
46typedef struct NVRAM *PNVRAM;
47
48struct NVRAM
49{
50 PCFGMNODE pNvramNode;
51 Nvram *pNvram;
52 PDMINVRAM INvram;
53 int cLoadedVariables;
54};
55
56
57/**
58 * Constructor/destructor
59 */
60Nvram::Nvram(Console *console)
61 : mpDrv(NULL),
62 mParent(console)
63{
64}
65
66Nvram::~Nvram()
67{
68 if (mpDrv)
69 {
70 mpDrv->pNvram = NULL;
71 mpDrv = NULL;
72 }
73}
74
75
76/**
77 * @interface_method_impl(PDMINVRAM,pfnStoreNvramValue)
78 */
79DECLCALLBACK(int) drvNvram_pfnStoreNvramValue(PPDMINVRAM pInterface,
80 int idxVariable,
81 RTUUID *pVendorUuid,
82 const char *pcszVariableName,
83 size_t cbVariableName,
84 uint8_t *pu8Value,
85 size_t cbValue)
86{
87 int rc = VINF_SUCCESS;
88 char szExtraDataKey[256];
89 char szExtraDataValue[1024];
90 LogFlowFunc(("ENTER: pVendorUuid:%RTuuid, pcszVariableName:%s, cbVariableName:%d, pu8Value:%.*Rhxs, cbValue:%d\n",
91 pVendorUuid,
92 pcszVariableName,
93 cbVariableName,
94 cbValue,
95 pu8Value,
96 cbValue));
97 PNVRAM pThis = RT_FROM_MEMBER(pInterface, NVRAM, INvram);
98
99 RT_ZERO(szExtraDataKey);
100 RT_ZERO(szExtraDataValue);
101 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableName", idxVariable);
102 RTStrPrintf(szExtraDataValue, 1024, "%s", pcszVariableName? pcszVariableName: "");
103 pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw());
104
105 RT_ZERO(szExtraDataKey);
106 RT_ZERO(szExtraDataValue);
107 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VendorGuid", idxVariable);
108 if (pVendorUuid)
109 RTUuidToStr(pVendorUuid, szExtraDataValue, 1024);
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/VariableValueLength", idxVariable);
115 if (!cbValue)
116 RTStrPrintf(szExtraDataValue, 1024, "%d", cbValue);
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/VariableValue", idxVariable);
122 size_t cbActualSize;
123 if (pu8Value)
124 rc = RTBase64Encode(pu8Value, cbValue, szExtraDataValue, 1024, &cbActualSize);
125 AssertRCReturn(rc, rc);
126 pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw());
127
128 LogFlowFuncLeaveRC(rc);
129 return rc;
130}
131
132/**
133 * @interface_method_impl(PDMINVRAM,pfnFlushNvramStorage)
134 */
135DECLCALLBACK(int) drvNvram_pfnFlushNvramStorage(PPDMINVRAM pInterface)
136{
137 int rc = VINF_SUCCESS;
138 LogFlowFuncEnter();
139 PNVRAM pThis = RT_FROM_MEMBER(pInterface, NVRAM, INvram);
140 int idxVariable = 0;
141 for (idxVariable = 0; idxVariable < pThis->cLoadedVariables; ++idxVariable)
142 {
143 drvNvram_pfnStoreNvramValue(pInterface, idxVariable, NULL, NULL, 0, NULL, 0);
144 }
145 LogFlowFuncLeaveRC(rc);
146 return rc;
147}
148
149/**
150 * @interface_method_impl(PDMINVRAM,pfnStoreNvramValue)
151 */
152DECLCALLBACK(int) drvNvram_pfnLoadNvramValue(PPDMINVRAM pInterface,
153 int idxVariable,
154 RTUUID *pVendorUuid,
155 char *pcszVariableName,
156 size_t *pcbVariableName,
157 uint8_t *pu8Value,
158 size_t *pcbValue)
159{
160 int rc = VINF_SUCCESS;
161 char szExtraDataKey[256];
162 Bstr bstrValue;
163 HRESULT hrc;
164 LogFlowFunc(("ENTER: idxVariable:%d, *pcbVariableName:%d, *pcbValue:%d\n",
165 idxVariable,
166 *pcbVariableName,
167 *pcbValue));
168 PNVRAM pThis = RT_FROM_MEMBER(pInterface, NVRAM, INvram);
169
170 RT_ZERO(szExtraDataKey);
171 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableName", idxVariable);
172 hrc = pThis->pNvram->getParent()->machine()->GetExtraData(Bstr(szExtraDataKey).raw(), bstrValue.asOutParam());
173 if (!SUCCEEDED(hrc))
174 return VERR_NOT_FOUND;
175 *pcbVariableName = RTStrCopy(pcszVariableName, 1024, Utf8Str(bstrValue).c_str());
176
177 RT_ZERO(szExtraDataKey);
178 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VendorGuid", idxVariable);
179 hrc = pThis->pNvram->getParent()->machine()->GetExtraData(Bstr(szExtraDataKey).raw(), bstrValue.asOutParam());
180 RTUuidFromStr(pVendorUuid, Utf8Str(bstrValue).c_str());
181
182 RT_ZERO(szExtraDataKey);
183 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableValueLength", idxVariable);
184 hrc = pThis->pNvram->getParent()->machine()->GetExtraData(Bstr(szExtraDataKey).raw(), bstrValue.asOutParam());
185 *pcbValue = Utf8Str(bstrValue).toUInt32();
186
187 RT_ZERO(szExtraDataKey);
188 RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableValue", idxVariable);
189 hrc = pThis->pNvram->getParent()->machine()->GetExtraData(Bstr(szExtraDataKey).raw(), bstrValue.asOutParam());
190 rc = RTBase64Decode(Utf8Str(bstrValue).c_str(), pu8Value, 1024, pcbValue, NULL);
191 AssertRCReturn(rc, rc);
192
193 pThis->cLoadedVariables++;
194 LogFlowFuncLeaveRC(rc);
195 return rc;
196}
197
198
199/**
200 * @interface_method_impl(PDMIBASE,pfnQueryInterface)
201 */
202DECLCALLBACK(void *)Nvram::drvNvram_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
203{
204 LogFlow(("%s pInterface:%p, pszIID:%s\n", __FUNCTION__, pInterface, pszIID));
205 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
206 PNVRAM pThis = PDMINS_2_DATA(pDrvIns, PNVRAM);
207
208 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
209 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINVRAM, &pThis->INvram);
210 return NULL;
211}
212
213/**
214 * @interface_method_impl(PDMDRVREG,pfnConstruct)
215 */
216DECLCALLBACK(int) Nvram::drvNvram_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
217{
218 LogFlowFunc(("iInstance/#d, pCfg:%p, fFlags:%x\n", pDrvIns->iInstance, pCfg, fFlags));
219 PNVRAM pThis = PDMINS_2_DATA(pDrvIns, PNVRAM);
220
221 if (!CFGMR3AreValuesValid(pCfg, "Object\0"))
222 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
223 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
224 ("Configuration error: Not possible to attach anything to this driver!\n"),
225 VERR_PDM_DRVINS_NO_ATTACH);
226
227 void *pv;
228 int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
229 AssertMsgRCReturn(rc, ("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc), rc);
230 pThis->pNvram = (Nvram *)pv;
231
232 pThis->pNvramNode = CFGMR3GetChild(pCfg, "NVRAM");
233
234 pDrvIns->IBase.pfnQueryInterface = Nvram::drvNvram_QueryInterface;
235 pThis->INvram.pfnFlushNvramStorage = drvNvram_pfnFlushNvramStorage;
236 pThis->INvram.pfnStoreNvramValue = drvNvram_pfnStoreNvramValue;
237 pThis->INvram.pfnLoadNvramValue = drvNvram_pfnLoadNvramValue;
238 /*
239 DECLR3CALLBACKMEMBER(int, pfnLoadNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, const char *pcszVariableName, size_t *pcbVariableName, uint8_t *pu8Value, size_t *pcbValue));
240 */
241
242 return VINF_SUCCESS;
243}
244
245/**
246 * @interface_method_impl(PDMDRVREG,pfnDestruct)
247 */
248DECLCALLBACK(void) Nvram::drvNvram_Destruct(PPDMDRVINS pDrvIns)
249{
250 LogFlow(("%s: iInstance/#d\n", __FUNCTION__, pDrvIns->iInstance));
251 PNVRAM pThis = PDMINS_2_DATA(pDrvIns, PNVRAM);
252}
253
254const PDMDRVREG Nvram::DrvReg =
255{
256 /* u32Version */
257 PDM_DRVREG_VERSION,
258 /* szName[32] */
259 "NvramStorage",
260 /* szRCMod[32] */
261 "",
262 /* szR0Mod[32] */
263 "",
264 /* pszDescription */
265 "NVRAM Main Driver",
266 /* fFlags */
267 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
268 /* fClass */
269 PDM_DRVREG_CLASS_VMMDEV,
270 /* cMaxInstances */
271 1,
272 /* cbInstance */
273 sizeof(NVRAM),
274 /* pfnConstruct */
275 Nvram::drvNvram_Construct,
276 /* pfnDestruct */
277 Nvram::drvNvram_Destruct,
278 /* pfnRelocate */
279 NULL,
280 /* pfnIOCtl */
281 NULL,
282 /* pfnPowerOn */
283 NULL,
284 /* pfnReset */
285 NULL,
286 /* pfnSuspend */
287 NULL,
288 /* pfnResume */
289 NULL,
290 /* pfnAttach */
291 NULL,
292 /* pfnDetach */
293 NULL,
294 /* pfnPowerOff */
295 NULL,
296 /* pfnSoftReset */
297 NULL,
298 /* u32VersionEnd */
299 PDM_DRVREG_VERSION
300};
301/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette