2 Main file for DmpStore shell Debug1 function.
4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UefiShellDebug1CommandsLib.h"
35 #define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's')
38 Base on the input attribute value to return the attribute string.
40 @param[in] Atts The input attribute value
42 @retval The attribute string info.
55 if ((Atts
& EFI_VARIABLE_NON_VOLATILE
) != 0) {
56 StrnCatGrow (&RetString
, &BufLen
, L
"+NV", 0);
58 if ((Atts
& EFI_VARIABLE_RUNTIME_ACCESS
) != 0) {
59 StrnCatGrow (&RetString
, &BufLen
, L
"+RT+BS", 0);
60 } else if ((Atts
& EFI_VARIABLE_BOOTSERVICE_ACCESS
) != 0) {
61 StrnCatGrow (&RetString
, &BufLen
, L
"+BS", 0);
63 if ((Atts
& EFI_VARIABLE_HARDWARE_ERROR_RECORD
) != 0) {
64 StrnCatGrow (&RetString
, &BufLen
, L
"+HR", 0);
66 if ((Atts
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
67 StrnCatGrow (&RetString
, &BufLen
, L
"+AW", 0);
69 if ((Atts
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
70 StrnCatGrow (&RetString
, &BufLen
, L
"+AT", 0);
73 if (RetString
== NULL
) {
74 RetString
= StrnCatGrow(&RetString
, &BufLen
, L
"Invalid", 0);
77 if ((RetString
!= NULL
) && (RetString
[0] == L
'+')) {
78 CopyMem(RetString
, RetString
+ 1, StrSize(RetString
+ 1));
85 Convert binary to hex format string.
87 @param[in] Buffer The binary data.
88 @param[in] BufferSize The size in bytes of the binary data.
89 @param[in, out] HexString Hex format string.
90 @param[in] HexStringSize The size in bytes of the string.
92 @return The hex format string.
98 IN OUT CHAR16
*HexString
,
99 IN UINTN HexStringSize
105 ASSERT (Buffer
!= NULL
);
106 ASSERT ((BufferSize
* 2 + 1) * sizeof (CHAR16
) <= HexStringSize
);
108 for (Index
= 0, StringIndex
= 0; Index
< BufferSize
; Index
+= 1) {
111 &HexString
[StringIndex
],
112 HexStringSize
- StringIndex
* sizeof (CHAR16
),
114 ((UINT8
*) Buffer
)[Index
]
121 Load the variable data from file and set to variable data base.
123 @param[in] FileHandle The file to be read.
124 @param[in] Name The name of the variables to be loaded.
125 @param[in] Guid The guid of the variables to be loaded.
126 @param[out] Found TRUE when at least one variable was loaded and set.
128 @retval SHELL_DEVICE_ERROR Cannot access the file.
129 @retval SHELL_VOLUME_CORRUPTED The file is in bad format.
130 @retval SHELL_OUT_OF_RESOURCES There is not enough memory to perform the operation.
131 @retval SHELL_SUCCESS Successfully load and set the variables.
134 LoadVariablesFromFile (
135 IN SHELL_FILE_HANDLE FileHandle
,
136 IN CONST CHAR16
*Name
,
137 IN CONST EFI_GUID
*Guid
,
142 SHELL_STATUS ShellStatus
;
150 DMP_STORE_VARIABLE
*Variable
;
156 Status
= ShellGetFileSize (FileHandle
, &FileSize
);
157 if (EFI_ERROR (Status
)) {
158 return SHELL_DEVICE_ERROR
;
161 ShellStatus
= SHELL_SUCCESS
;
163 InitializeListHead (&List
);
166 while (Position
< FileSize
) {
170 BufferSize
= sizeof (NameSize
);
171 Status
= ShellReadFile (FileHandle
, &BufferSize
, &NameSize
);
172 if (EFI_ERROR (Status
) || (BufferSize
!= sizeof (NameSize
))) {
173 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
180 BufferSize
= sizeof (DataSize
);
181 Status
= ShellReadFile (FileHandle
, &BufferSize
, &DataSize
);
182 if (EFI_ERROR (Status
) || (BufferSize
!= sizeof (DataSize
))) {
183 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
188 // Name, Guid, Attributes, Data, Crc32
190 RemainingSize
= NameSize
+ sizeof (EFI_GUID
) + sizeof (UINT32
) + DataSize
+ sizeof (Crc32
);
191 BufferSize
= sizeof (NameSize
) + sizeof (DataSize
) + RemainingSize
;
192 Buffer
= AllocatePool (BufferSize
);
193 if (Buffer
== NULL
) {
194 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
197 BufferSize
= RemainingSize
;
198 Status
= ShellReadFile (FileHandle
, &BufferSize
, (UINT32
*) Buffer
+ 2);
199 if (EFI_ERROR (Status
) || (BufferSize
!= RemainingSize
)) {
200 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
208 * (UINT32
*) Buffer
= NameSize
;
209 * ((UINT32
*) Buffer
+ 1) = DataSize
;
210 BufferSize
= RemainingSize
+ sizeof (NameSize
) + sizeof (DataSize
) - sizeof (Crc32
);
211 gBS
->CalculateCrc32 (
216 if (Crc32
!= * (UINT32
*) (Buffer
+ BufferSize
)) {
218 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
222 Position
+= BufferSize
+ sizeof (Crc32
);
224 Variable
= AllocateZeroPool (sizeof (*Variable
) + NameSize
+ DataSize
);
225 if (Variable
== NULL
) {
227 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
230 Variable
->Signature
= DMP_STORE_VARIABLE_SIGNATURE
;
231 Variable
->Name
= (CHAR16
*) (Variable
+ 1);
232 Variable
->DataSize
= DataSize
;
233 Variable
->Data
= (UINT8
*) Variable
->Name
+ NameSize
;
234 CopyMem (Variable
->Name
, Buffer
+ sizeof (NameSize
) + sizeof (DataSize
), NameSize
);
235 CopyMem (&Variable
->Guid
, Buffer
+ sizeof (NameSize
) + sizeof (DataSize
) + NameSize
, sizeof (EFI_GUID
));
236 CopyMem (&Variable
->Attributes
, Buffer
+ sizeof (NameSize
) + sizeof (DataSize
) + NameSize
+ sizeof (EFI_GUID
), sizeof (UINT32
));
237 CopyMem (Variable
->Data
, Buffer
+ sizeof (NameSize
) + sizeof (DataSize
) + NameSize
+ sizeof (EFI_GUID
) + sizeof (UINT32
), DataSize
);
239 InsertTailList (&List
, &Variable
->Link
);
243 if ((Position
!= FileSize
) || (ShellStatus
!= SHELL_SUCCESS
)) {
244 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE
), gShellDebug1HiiHandle
, L
"dmpstore");
245 if (Position
!= FileSize
) {
246 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
250 for ( Link
= GetFirstNode (&List
)
251 ; !IsNull (&List
, Link
) && (ShellStatus
== SHELL_SUCCESS
)
252 ; Link
= GetNextNode (&List
, Link
)
254 Variable
= CR (Link
, DMP_STORE_VARIABLE
, Link
, DMP_STORE_VARIABLE_SIGNATURE
);
256 if (((Name
== NULL
) || gUnicodeCollation
->MetaiMatch (gUnicodeCollation
, Variable
->Name
, (CHAR16
*) Name
)) &&
257 ((Guid
== NULL
) || CompareGuid (&Variable
->Guid
, Guid
))
259 Attributes
= GetAttrType (Variable
->Attributes
);
261 -1, -1, NULL
, STRING_TOKEN(STR_DMPSTORE_HEADER_LINE
), gShellDebug1HiiHandle
,
262 Attributes
, &Variable
->Guid
, Variable
->Name
, Variable
->DataSize
264 SHELL_FREE_NON_NULL(Attributes
);
267 Status
= gRT
->SetVariable (
270 Variable
->Attributes
,
274 if (EFI_ERROR (Status
)) {
275 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", Variable
->Name
, Status
);
280 for (Link
= GetFirstNode (&List
); !IsNull (&List
, Link
); ) {
281 Variable
= CR (Link
, DMP_STORE_VARIABLE
, Link
, DMP_STORE_VARIABLE_SIGNATURE
);
282 Link
= RemoveEntryList (&Variable
->Link
);
290 Append one variable to file.
292 @param[in] FileHandle The file to be appended.
293 @param[in] Name The variable name.
294 @param[in] Guid The variable GUID.
295 @param[in] Attributes The variable attributes.
296 @param[in] DataSize The variable data size.
297 @param[in] Data The variable data.
299 @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation.
300 @retval EFI_SUCCESS The variable is appended to file successfully.
301 @retval others Failed to append the variable to file.
304 AppendSingleVariableToFile (
305 IN SHELL_FILE_HANDLE FileHandle
,
306 IN CONST CHAR16
*Name
,
307 IN CONST EFI_GUID
*Guid
,
308 IN UINT32 Attributes
,
319 NameSize
= (UINT32
) StrSize (Name
);
320 BufferSize
= sizeof (NameSize
) + sizeof (DataSize
)
322 + sizeof (Attributes
)
323 + NameSize
+ DataSize
326 Buffer
= AllocatePool (BufferSize
);
327 if (Buffer
== NULL
) {
328 return EFI_OUT_OF_RESOURCES
;
333 // NameSize and DataSize
335 * (UINT32
*) Ptr
= NameSize
;
336 Ptr
+= sizeof (NameSize
);
337 *(UINT32
*) Ptr
= DataSize
;
338 Ptr
+= sizeof (DataSize
);
343 CopyMem (Ptr
, Name
, NameSize
);
349 CopyMem (Ptr
, Guid
, sizeof (*Guid
));
350 Ptr
+= sizeof (*Guid
);
355 * (UINT32
*) Ptr
= Attributes
;
356 Ptr
+= sizeof (Attributes
);
361 CopyMem (Ptr
, Data
, DataSize
);
367 gBS
->CalculateCrc32 (Buffer
, (UINTN
) Ptr
- (UINTN
) Buffer
, (UINT32
*) Ptr
);
369 Status
= ShellWriteFile (FileHandle
, &BufferSize
, Buffer
);
372 if (!EFI_ERROR (Status
) &&
373 (BufferSize
!= sizeof (NameSize
) + sizeof (DataSize
) + sizeof (*Guid
) + sizeof (Attributes
) + NameSize
+ DataSize
+ sizeof (UINT32
))
375 Status
= EFI_DEVICE_ERROR
;
382 Recursive function to display or delete variables.
384 This function will call itself to create a stack-based list of allt he variables to process,
385 then fromt he last to the first, they will do either printing or deleting.
387 This is necessary since once a delete happens GetNextVariableName() will work.
389 @param[in] Name The variable name of the EFI variable (or NULL).
390 @param[in] Guid The GUID of the variable set (or NULL).
391 @param[in] Type The operation type.
392 @param[in] FileHandle The file to operate on (or NULL).
393 @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.
394 @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.
395 @param[in] FoundOne If a VariableName or Guid was specified and one was printed or
396 deleted, then set this to TRUE, otherwise ignored.
397 @param[in] StandardFormatOutput TRUE indicates Standard-Format Output.
399 @retval SHELL_SUCCESS The operation was successful.
400 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
401 @retval SHELL_ABORTED The abort message was received.
402 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.
403 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.
406 CascadeProcessVariables (
407 IN CONST CHAR16
*Name OPTIONAL
,
408 IN CONST EFI_GUID
*Guid OPTIONAL
,
409 IN DMP_STORE_TYPE Type
,
410 IN EFI_FILE_PROTOCOL
*FileHandle OPTIONAL
,
411 IN CONST CHAR16
* CONST PrevName
,
412 IN EFI_GUID FoundVarGuid
,
413 IN BOOLEAN
*FoundOne
,
414 IN BOOLEAN StandardFormatOutput
418 CHAR16
*FoundVarName
;
422 SHELL_STATUS ShellStatus
;
426 EFI_STATUS SetStatus
;
427 CONST CHAR16
*GuidName
;
429 if (ShellGetExecutionBreakFlag()) {
430 return (SHELL_ABORTED
);
436 if (PrevName
!=NULL
) {
437 StrnCatGrow(&FoundVarName
, &NameSize
, PrevName
, 0);
439 FoundVarName
= AllocateZeroPool(sizeof(CHAR16
));
440 NameSize
= sizeof(CHAR16
);
443 Status
= gRT
->GetNextVariableName (&NameSize
, FoundVarName
, &FoundVarGuid
);
444 if (Status
== EFI_BUFFER_TOO_SMALL
) {
445 SHELL_FREE_NON_NULL(FoundVarName
);
446 FoundVarName
= AllocateZeroPool (NameSize
);
447 if (FoundVarName
!= NULL
) {
448 if (PrevName
!= NULL
) {
449 StrnCpyS(FoundVarName
, NameSize
/sizeof(CHAR16
), PrevName
, NameSize
/sizeof(CHAR16
) - 1);
452 Status
= gRT
->GetNextVariableName (&NameSize
, FoundVarName
, &FoundVarGuid
);
454 Status
= EFI_OUT_OF_RESOURCES
;
461 if (Status
== EFI_NOT_FOUND
) {
462 SHELL_FREE_NON_NULL(FoundVarName
);
463 return (SHELL_SUCCESS
);
464 } else if (EFI_ERROR(Status
)) {
465 SHELL_FREE_NON_NULL(FoundVarName
);
466 return (SHELL_DEVICE_ERROR
);
470 // Recurse to the next iteration. We know "our" variable's name.
472 ShellStatus
= CascadeProcessVariables (Name
, Guid
, Type
, FileHandle
, FoundVarName
, FoundVarGuid
, FoundOne
, StandardFormatOutput
);
474 if (ShellGetExecutionBreakFlag() || (ShellStatus
== SHELL_ABORTED
)) {
475 SHELL_FREE_NON_NULL(FoundVarName
);
476 return (SHELL_ABORTED
);
480 // No matter what happened we process our own variable
481 // Only continue if Guid and VariableName are each either NULL or a match
484 || gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, FoundVarName
, (CHAR16
*) Name
) )
486 || CompareGuid(&FoundVarGuid
, Guid
) )
491 // do the print or delete
494 Status
= gRT
->GetVariable (FoundVarName
, &FoundVarGuid
, &Atts
, &DataSize
, DataBuffer
);
495 if (Status
== EFI_BUFFER_TOO_SMALL
) {
496 SHELL_FREE_NON_NULL (DataBuffer
);
497 DataBuffer
= AllocatePool (DataSize
);
498 if (DataBuffer
== NULL
) {
499 Status
= EFI_OUT_OF_RESOURCES
;
501 Status
= gRT
->GetVariable (FoundVarName
, &FoundVarGuid
, &Atts
, &DataSize
, DataBuffer
);
505 // Last error check then print this variable out.
507 if (Type
== DmpStoreDisplay
) {
508 if (!EFI_ERROR(Status
) && (DataBuffer
!= NULL
) && (FoundVarName
!= NULL
)) {
509 AttrString
= GetAttrType(Atts
);
510 if (StandardFormatOutput
) {
511 HexString
= AllocatePool ((DataSize
* 2 + 1) * sizeof (CHAR16
));
512 if (HexString
!= NULL
) {
514 -1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_VAR_SFO
), gShellDebug1HiiHandle
,
515 FoundVarName
, &FoundVarGuid
, Atts
, DataSize
,
517 DataBuffer
, DataSize
, HexString
, (DataSize
* 2 + 1) * sizeof (CHAR16
)
520 FreePool (HexString
);
522 Status
= EFI_OUT_OF_RESOURCES
;
525 Status
= gEfiShellProtocol
->GetGuidName(&FoundVarGuid
, &GuidName
);
526 if (EFI_ERROR (Status
)) {
528 -1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE
), gShellDebug1HiiHandle
,
529 AttrString
, &FoundVarGuid
, FoundVarName
, DataSize
533 -1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE2
), gShellDebug1HiiHandle
,
534 AttrString
, GuidName
, FoundVarName
, DataSize
537 DumpHex (2, 0, DataSize
, DataBuffer
);
539 SHELL_FREE_NON_NULL (AttrString
);
541 } else if (Type
== DmpStoreSave
) {
542 if (!EFI_ERROR(Status
) && (DataBuffer
!= NULL
) && (FoundVarName
!= NULL
)) {
543 AttrString
= GetAttrType (Atts
);
545 -1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE
), gShellDebug1HiiHandle
,
546 AttrString
, &FoundVarGuid
, FoundVarName
, DataSize
548 Status
= AppendSingleVariableToFile (
556 SHELL_FREE_NON_NULL (AttrString
);
558 } else if (Type
== DmpStoreDelete
) {
560 // We only need name to delete it...
562 SetStatus
= gRT
->SetVariable (FoundVarName
, &FoundVarGuid
, Atts
, 0, NULL
);
563 if (StandardFormatOutput
) {
564 if (SetStatus
== EFI_SUCCESS
) {
566 -1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_NG_SFO
), gShellDebug1HiiHandle
,
567 FoundVarName
, &FoundVarGuid
572 -1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_DELETE_LINE
), gShellDebug1HiiHandle
,
573 &FoundVarGuid
, FoundVarName
, SetStatus
577 SHELL_FREE_NON_NULL(DataBuffer
);
580 SHELL_FREE_NON_NULL(FoundVarName
);
582 if (Status
== EFI_DEVICE_ERROR
) {
583 ShellStatus
= SHELL_DEVICE_ERROR
;
584 } else if (Status
== EFI_SECURITY_VIOLATION
) {
585 ShellStatus
= SHELL_SECURITY_VIOLATION
;
586 } else if (EFI_ERROR(Status
)) {
587 ShellStatus
= SHELL_NOT_READY
;
590 return (ShellStatus
);
594 Function to display or delete variables. This will set up and call into the recursive function.
596 @param[in] Name The variable name of the EFI variable (or NULL).
597 @param[in] Guid The GUID of the variable set (or NULL).
598 @param[in] Type The operation type.
599 @param[in] FileHandle The file to save or load variables.
600 @param[in] StandardFormatOutput TRUE indicates Standard-Format Output.
602 @retval SHELL_SUCCESS The operation was successful.
603 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
604 @retval SHELL_ABORTED The abort message was received.
605 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.
606 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.
610 IN CONST CHAR16
*Name OPTIONAL
,
611 IN CONST EFI_GUID
*Guid OPTIONAL
,
612 IN DMP_STORE_TYPE Type
,
613 IN SHELL_FILE_HANDLE FileHandle OPTIONAL
,
614 IN BOOLEAN StandardFormatOutput
617 SHELL_STATUS ShellStatus
;
619 EFI_GUID FoundVarGuid
;
622 ShellStatus
= SHELL_SUCCESS
;
623 ZeroMem (&FoundVarGuid
, sizeof(EFI_GUID
));
625 if (StandardFormatOutput
) {
626 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_GEN_SFO_HEADER
), gShellDebug1HiiHandle
, L
"dmpstore");
629 if (Type
== DmpStoreLoad
) {
630 ShellStatus
= LoadVariablesFromFile (FileHandle
, Name
, Guid
, &Found
);
632 ShellStatus
= CascadeProcessVariables (Name
, Guid
, Type
, FileHandle
, NULL
, FoundVarGuid
, &Found
, StandardFormatOutput
);
636 if (ShellStatus
== SHELL_OUT_OF_RESOURCES
) {
637 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellDebug1HiiHandle
, L
"dmpstore");
638 return (ShellStatus
);
639 } else if (Name
!= NULL
&& Guid
== NULL
) {
640 if (StandardFormatOutput
) {
641 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N_SFO
), gShellDebug1HiiHandle
, Name
);
643 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N
), gShellDebug1HiiHandle
, L
"dmpstore", Name
);
645 } else if (Name
!= NULL
&& Guid
!= NULL
) {
646 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN
), gShellDebug1HiiHandle
, L
"dmpstore", Guid
, Name
);
647 } else if (Name
== NULL
&& Guid
== NULL
) {
648 if (StandardFormatOutput
) {
649 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_SFO
), gShellDebug1HiiHandle
);
651 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND
), gShellDebug1HiiHandle
, L
"dmpstore");
653 } else if (Name
== NULL
&& Guid
!= NULL
) {
654 if (StandardFormatOutput
) {
655 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G_SFO
), gShellDebug1HiiHandle
, Guid
);
657 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G
), gShellDebug1HiiHandle
, L
"dmpstore", Guid
);
660 return (SHELL_NOT_FOUND
);
662 return (ShellStatus
);
665 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
670 {L
"-guid", TypeValue
},
676 Function for 'dmpstore' command.
678 @param[in] ImageHandle Handle to the Image (NULL if Internal).
679 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
683 ShellCommandRunDmpStore (
684 IN EFI_HANDLE ImageHandle
,
685 IN EFI_SYSTEM_TABLE
*SystemTable
689 RETURN_STATUS RStatus
;
691 CHAR16
*ProblemParam
;
692 SHELL_STATUS ShellStatus
;
693 CONST CHAR16
*GuidStr
;
699 SHELL_FILE_HANDLE FileHandle
;
700 EFI_FILE_INFO
*FileInfo
;
701 BOOLEAN StandardFormatOutput
;
703 ShellStatus
= SHELL_SUCCESS
;
707 Type
= DmpStoreDisplay
;
708 StandardFormatOutput
= FALSE
;
710 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
711 if (EFI_ERROR(Status
)) {
712 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
713 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"dmpstore", ProblemParam
);
714 FreePool(ProblemParam
);
715 ShellStatus
= SHELL_INVALID_PARAMETER
;
720 if (ShellCommandLineGetCount(Package
) > 2) {
721 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"dmpstore");
722 ShellStatus
= SHELL_INVALID_PARAMETER
;
723 } else if (ShellCommandLineGetFlag(Package
, L
"-all") && ShellCommandLineGetFlag(Package
, L
"-guid")) {
724 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CONFLICT
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-all", L
"-guid");
725 ShellStatus
= SHELL_INVALID_PARAMETER
;
726 } else if (ShellCommandLineGetFlag(Package
, L
"-s") && ShellCommandLineGetFlag(Package
, L
"-l")) {
727 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CONFLICT
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-l", L
"-s");
728 ShellStatus
= SHELL_INVALID_PARAMETER
;
729 } else if ((ShellCommandLineGetFlag(Package
, L
"-s") || ShellCommandLineGetFlag(Package
, L
"-l")) && ShellCommandLineGetFlag(Package
, L
"-d")) {
730 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CONFLICT
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-l or -s", L
"-d");
731 ShellStatus
= SHELL_INVALID_PARAMETER
;
732 } else if ((ShellCommandLineGetFlag(Package
, L
"-s") || ShellCommandLineGetFlag(Package
, L
"-l")) && ShellCommandLineGetFlag(Package
, L
"-sfo")) {
733 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CONFLICT
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-l or -s", L
"-sfo");
734 ShellStatus
= SHELL_INVALID_PARAMETER
;
737 // Determine the GUID to search for based on -all and -guid parameters
739 if (!ShellCommandLineGetFlag(Package
, L
"-all")) {
740 GuidStr
= ShellCommandLineGetValue(Package
, L
"-guid");
741 if (GuidStr
!= NULL
) {
742 RStatus
= StrToGuid (GuidStr
, &GuidData
);
743 if (RETURN_ERROR (RStatus
) || (GuidStr
[GUID_STRING_LENGTH
] != L
'\0')) {
744 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellDebug1HiiHandle
, L
"dmpstore", GuidStr
);
745 ShellStatus
= SHELL_INVALID_PARAMETER
;
749 Guid
= &gEfiGlobalVariableGuid
;
756 // Get the Name of the variable to find
758 Name
= ShellCommandLineGetRawValue(Package
, 1);
760 if (ShellStatus
== SHELL_SUCCESS
) {
761 if (ShellCommandLineGetFlag(Package
, L
"-s")) {
763 File
= ShellCommandLineGetValue(Package
, L
"-s");
765 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-s");
766 ShellStatus
= SHELL_INVALID_PARAMETER
;
768 Status
= ShellOpenFileByName (File
, &FileHandle
, EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
769 if (!EFI_ERROR (Status
)) {
771 // Delete existing file, but do not delete existing directory
773 FileInfo
= ShellGetFileInfo (FileHandle
);
774 if (FileInfo
== NULL
) {
775 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
776 Status
= EFI_DEVICE_ERROR
;
778 if ((FileInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
) {
779 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
780 Status
= EFI_INVALID_PARAMETER
;
782 Status
= ShellDeleteFile (&FileHandle
);
783 if (EFI_ERROR (Status
)) {
784 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
789 } else if (Status
== EFI_NOT_FOUND
) {
791 // Good when file doesn't exist
793 Status
= EFI_SUCCESS
;
796 // Otherwise it's bad.
798 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
801 if (!EFI_ERROR (Status
)) {
802 Status
= ShellOpenFileByName (File
, &FileHandle
, EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
803 if (EFI_ERROR (Status
)) {
804 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
808 if (EFI_ERROR (Status
)) {
809 ShellStatus
= SHELL_INVALID_PARAMETER
;
812 } else if (ShellCommandLineGetFlag(Package
, L
"-l")) {
814 File
= ShellCommandLineGetValue(Package
, L
"-l");
816 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-l");
817 ShellStatus
= SHELL_INVALID_PARAMETER
;
819 Status
= ShellOpenFileByName (File
, &FileHandle
, EFI_FILE_MODE_READ
, 0);
820 if (EFI_ERROR (Status
)) {
821 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
822 ShellStatus
= SHELL_INVALID_PARAMETER
;
824 FileInfo
= ShellGetFileInfo (FileHandle
);
825 if (FileInfo
== NULL
) {
826 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
827 ShellStatus
= SHELL_DEVICE_ERROR
;
829 if ((FileInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
) {
830 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
831 ShellStatus
= SHELL_INVALID_PARAMETER
;
837 } else if (ShellCommandLineGetFlag(Package
, L
"-d")) {
838 Type
= DmpStoreDelete
;
841 if (ShellCommandLineGetFlag (Package
,L
"-sfo")) {
842 StandardFormatOutput
= TRUE
;
846 if (ShellStatus
== SHELL_SUCCESS
) {
847 if (Type
== DmpStoreSave
) {
848 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_SAVE
), gShellDebug1HiiHandle
, File
);
849 } else if (Type
== DmpStoreLoad
) {
850 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_LOAD
), gShellDebug1HiiHandle
, File
);
852 ShellStatus
= ProcessVariables (Name
, Guid
, Type
, FileHandle
, StandardFormatOutput
);
853 if ((Type
== DmpStoreLoad
) || (Type
== DmpStoreSave
)) {
854 ShellCloseFile (&FileHandle
);
860 if (Package
!= NULL
) {
861 ShellCommandLineFreeVarList (Package
);