TianoCore EDK2 master
Loading...
Searching...
No Matches
FsAccess.c
Go to the documentation of this file.
1
9#include "NvVarsFileLib.h"
10
12#include <Library/DebugLib.h>
14
28 IN EFI_HANDLE FsHandle,
29 IN BOOLEAN ReadingFile,
30 OUT EFI_FILE_HANDLE *NvVarsFile
31 )
32{
33 EFI_STATUS Status;
35 EFI_FILE_HANDLE Root;
36
37 //
38 // Get the FileSystem protocol on that handle
39 //
40 Status = gBS->HandleProtocol (
41 FsHandle,
42 &gEfiSimpleFileSystemProtocolGuid,
43 (VOID **)&Fs
44 );
45 if (EFI_ERROR (Status)) {
46 return Status;
47 }
48
49 //
50 // Get the volume (the root directory)
51 //
52 Status = Fs->OpenVolume (Fs, &Root);
53 if (EFI_ERROR (Status)) {
54 return Status;
55 }
56
57 //
58 // Attempt to open the NvVars file in the root directory
59 //
60 Status = Root->Open (
61 Root,
62 NvVarsFile,
63 L"NvVars",
64 ReadingFile ?
65 EFI_FILE_MODE_READ :
66 (
67 EFI_FILE_MODE_CREATE |
68 EFI_FILE_MODE_READ |
69 EFI_FILE_MODE_WRITE
70 ),
71 0
72 );
73
74 return Status;
75}
76
86VOID
89 OUT BOOLEAN *Exists,
90 OUT UINTN *Size
91 )
92{
94
95 *Exists = FALSE;
96 *Size = 0;
97
99 if (FileInfo == NULL) {
100 return;
101 }
102
103 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
105 return;
106 }
107
108 *Exists = TRUE;
109 *Size = (UINTN)FileInfo->FileSize;
110
112}
113
126 )
127{
128 EFI_STATUS Status;
130
131 //
132 // Retrieve the FileInfo structure
133 //
135 if (FileInfo == NULL) {
136 return EFI_INVALID_PARAMETER;
137 }
138
139 //
140 // If the path is a directory, then return an error
141 //
142 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
144 return EFI_INVALID_PARAMETER;
145 }
146
147 //
148 // If the file size is already 0, then it is empty, so
149 // we can return success.
150 //
151 if (FileInfo->FileSize == 0) {
153 return EFI_SUCCESS;
154 }
155
156 //
157 // Set the file size to 0.
158 //
159 FileInfo->FileSize = 0;
160 Status = FileHandleSetInfo (File, FileInfo);
161
163
164 return Status;
165}
166
177VOID *
179 IN EFI_FILE_HANDLE FileHandle,
180 IN UINTN ReadSize
181 )
182{
183 EFI_STATUS Status;
184 UINTN ActualReadSize;
185 VOID *FileContents;
186
187 ActualReadSize = ReadSize;
188 FileContents = AllocatePool (ReadSize);
189 if (FileContents != NULL) {
190 Status = FileHandleRead (
191 FileHandle,
192 &ReadSize,
193 FileContents
194 );
195 if (EFI_ERROR (Status) || (ActualReadSize != ReadSize)) {
196 FreePool (FileContents);
197 return NULL;
198 }
199 }
200
201 return FileContents;
202}
203
214 IN EFI_HANDLE FsHandle
215 )
216{
217 EFI_STATUS Status;
218 EFI_FILE_HANDLE File;
219 UINTN FileSize;
220 BOOLEAN FileExists;
221 VOID *FileContents;
222 EFI_HANDLE SerializedVariables;
223
224 Status = GetNvVarsFile (FsHandle, TRUE, &File);
225 if (EFI_ERROR (Status)) {
226 DEBUG ((DEBUG_INFO, "FsAccess.c: Could not open NV Variables file on this file system\n"));
227 return Status;
228 }
229
230 NvVarsFileReadCheckup (File, &FileExists, &FileSize);
231 if (FileSize == 0) {
232 FileHandleClose (File);
233 return EFI_UNSUPPORTED;
234 }
235
236 FileContents = FileHandleReadToNewBuffer (File, FileSize);
237 if (FileContents == NULL) {
238 FileHandleClose (File);
239 return EFI_UNSUPPORTED;
240 }
241
242 DEBUG ((
243 DEBUG_INFO,
244 "FsAccess.c: Read %Lu bytes from NV Variables file\n",
245 (UINT64)FileSize
246 ));
247
249 &SerializedVariables,
250 FileContents,
251 FileSize
252 );
253 if (!RETURN_ERROR (Status)) {
254 Status = SerializeVariablesSetSerializedVariables (SerializedVariables);
255 }
256
257 FreePool (FileContents);
258 FileHandleClose (File);
259
260 return Status;
261}
262
268STATIC
269VOID
271 VOID
272 )
273{
274 BOOLEAN VarData;
275 UINTN Size;
276
277 //
278 // Write a variable to indicate we've already loaded the
279 // variable data. If it is found, we skip the loading on
280 // subsequent attempts.
281 //
282 Size = sizeof (VarData);
283 VarData = TRUE;
284 gRT->SetVariable (
285 L"NvVars",
286 &gEfiSimpleFileSystemProtocolGuid,
288 EFI_VARIABLE_BOOTSERVICE_ACCESS |
289 EFI_VARIABLE_RUNTIME_ACCESS,
290 Size,
291 (VOID *)&VarData
292 );
293}
294
306 EFI_HANDLE FsHandle
307 )
308{
309 EFI_STATUS Status;
310 BOOLEAN VarData;
311 UINTN Size;
312
313 DEBUG ((DEBUG_INFO, "FsAccess.c: LoadNvVarsFromFs\n"));
314
315 //
316 // We write a variable to indicate we've already loaded the
317 // variable data. If it is found, we skip the loading.
318 //
319 // This is relevant if the non-volatile variable have been
320 // able to survive a reboot operation. In that case, we don't
321 // want to re-load the file as it would overwrite newer changes
322 // made to the variables.
323 //
324 Size = sizeof (VarData);
325 VarData = TRUE;
326 Status = gRT->GetVariable (
327 L"NvVars",
328 &gEfiSimpleFileSystemProtocolGuid,
329 NULL,
330 &Size,
331 (VOID *)&VarData
332 );
333 if (Status == EFI_SUCCESS) {
334 DEBUG ((DEBUG_INFO, "NV Variables were already loaded\n"));
335 return EFI_ALREADY_STARTED;
336 }
337
338 //
339 // Attempt to restore the variables from the NvVars file.
340 //
341 Status = ReadNvVarsFile (FsHandle);
342 if (EFI_ERROR (Status)) {
343 DEBUG ((DEBUG_INFO, "Error while restoring NV variable data\n"));
344 return Status;
345 }
346
347 //
348 // Write a variable to indicate we've already loaded the
349 // variable data. If it is found, we skip the loading on
350 // subsequent attempts.
351 //
353
354 DEBUG ((
355 DEBUG_INFO,
356 "FsAccess.c: Read NV Variables file (size=%Lu)\n",
357 (UINT64)Size
358 ));
359
360 return Status;
361}
362
363STATIC
364RETURN_STATUS
365EFIAPI
366IterateVariablesCallbackAddAllNvVariables (
367 IN VOID *Context,
368 IN CHAR16 *VariableName,
369 IN EFI_GUID *VendorGuid,
370 IN UINT32 Attributes,
371 IN UINTN DataSize,
372 IN VOID *Data
373 )
374{
375 EFI_HANDLE Instance;
376
377 Instance = (EFI_HANDLE)Context;
378
379 //
380 // Only save non-volatile variables
381 //
382 if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
383 return RETURN_SUCCESS;
384 }
385
387 Instance,
388 VariableName,
389 VendorGuid,
390 Attributes,
391 DataSize,
392 Data
393 );
394}
395
407 EFI_HANDLE FsHandle
408 )
409{
410 EFI_STATUS Status;
411 EFI_FILE_HANDLE File;
412 UINTN WriteSize;
413 UINTN VariableDataSize;
414 VOID *VariableData;
415 EFI_HANDLE SerializedVariables;
416
417 SerializedVariables = NULL;
418
419 Status = SerializeVariablesNewInstance (&SerializedVariables);
420 if (EFI_ERROR (Status)) {
421 return Status;
422 }
423
425 IterateVariablesCallbackAddAllNvVariables,
426 (VOID *)SerializedVariables
427 );
428 if (EFI_ERROR (Status)) {
429 return Status;
430 }
431
432 VariableData = NULL;
433 VariableDataSize = 0;
435 SerializedVariables,
436 NULL,
437 &VariableDataSize
438 );
439 if (Status == RETURN_BUFFER_TOO_SMALL) {
440 VariableData = AllocatePool (VariableDataSize);
441 if (VariableData == NULL) {
442 Status = EFI_OUT_OF_RESOURCES;
443 } else {
445 SerializedVariables,
446 VariableData,
447 &VariableDataSize
448 );
449 }
450 }
451
452 SerializeVariablesFreeInstance (SerializedVariables);
453
454 if (EFI_ERROR (Status)) {
455 return Status;
456 }
457
458 //
459 // Open the NvVars file for writing.
460 //
461 Status = GetNvVarsFile (FsHandle, FALSE, &File);
462 if (EFI_ERROR (Status)) {
463 DEBUG ((DEBUG_INFO, "FsAccess.c: Unable to open file to saved NV Variables\n"));
464 return Status;
465 }
466
467 //
468 // Empty the starting file contents.
469 //
470 Status = FileHandleEmpty (File);
471 if (EFI_ERROR (Status)) {
472 FileHandleClose (File);
473 return Status;
474 }
475
476 WriteSize = VariableDataSize;
477 Status = FileHandleWrite (File, &WriteSize, VariableData);
478 if (EFI_ERROR (Status)) {
479 return Status;
480 }
481
482 FileHandleClose (File);
483
484 if (!EFI_ERROR (Status)) {
485 //
486 // Write a variable to indicate we've already loaded the
487 // variable data. If it is found, we skip the loading on
488 // subsequent attempts.
489 //
491
492 DEBUG ((DEBUG_INFO, "Saved NV Variables to NvVars file\n"));
493 }
494
495 return Status;
496}
UINT64 UINTN
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI FileHandleSetInfo(IN EFI_FILE_HANDLE FileHandle, IN CONST EFI_FILE_INFO *FileInfo)
EFI_FILE_INFO *EFIAPI FileHandleGetInfo(IN EFI_FILE_HANDLE FileHandle)
EFI_STATUS EFIAPI FileHandleClose(IN EFI_FILE_HANDLE FileHandle)
EFI_STATUS EFIAPI FileHandleWrite(IN EFI_FILE_HANDLE FileHandle, IN OUT UINTN *BufferSize, IN VOID *Buffer)
EFI_STATUS EFIAPI FileHandleRead(IN EFI_FILE_HANDLE FileHandle, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
VOID * FileHandleReadToNewBuffer(IN EFI_FILE_HANDLE FileHandle, IN UINTN ReadSize)
Definition: FsAccess.c:178
EFI_STATUS FileHandleEmpty(IN EFI_FILE_HANDLE File)
Definition: FsAccess.c:124
STATIC VOID SetNvVarsVariable(VOID)
Definition: FsAccess.c:270
VOID NvVarsFileReadCheckup(IN EFI_FILE_HANDLE File, OUT BOOLEAN *Exists, OUT UINTN *Size)
Definition: FsAccess.c:87
EFI_STATUS GetNvVarsFile(IN EFI_HANDLE FsHandle, IN BOOLEAN ReadingFile, OUT EFI_FILE_HANDLE *NvVarsFile)
Definition: FsAccess.c:27
EFI_STATUS LoadNvVarsFromFs(EFI_HANDLE FsHandle)
Definition: FsAccess.c:305
EFI_STATUS SaveNvVarsToFs(EFI_HANDLE FsHandle)
Definition: FsAccess.c:406
EFI_STATUS ReadNvVarsFile(IN EFI_HANDLE FsHandle)
Definition: FsAccess.c:213
RETURN_STATUS EFIAPI SerializeVariablesIterateSystemVariables(IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, IN VOID *Context)
RETURN_STATUS EFIAPI SerializeVariablesFreeInstance(IN EFI_HANDLE Handle)
RETURN_STATUS EFIAPI SerializeVariablesNewInstanceFromBuffer(OUT EFI_HANDLE *Handle, IN VOID *Buffer, IN UINTN Size)
RETURN_STATUS EFIAPI SerializeVariablesAddVariable(IN EFI_HANDLE Handle, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
RETURN_STATUS EFIAPI SerializeVariablesToBuffer(IN EFI_HANDLE Handle, OUT VOID *Buffer, IN OUT UINTN *Size)
RETURN_STATUS EFIAPI SerializeVariablesNewInstance(OUT EFI_HANDLE *Handle)
RETURN_STATUS EFIAPI SerializeVariablesSetSerializedVariables(IN EFI_HANDLE Handle)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:1093
#define STATIC
Definition: Base.h:264
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
#define EFI_VARIABLE_NON_VOLATILE
UINT64 Attribute
Definition: FileInfo.h:47
UINT64 FileSize
Definition: FileInfo.h:27
Definition: Base.h:213