2 Main file for DmpStore shell Debug1 function.
4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2005 - 2015, 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.
56 if ((Atts
& EFI_VARIABLE_NON_VOLATILE
) != 0) {
57 StrnCatGrow (&RetString
, &BufLen
, L
"+NV", 0);
59 if ((Atts
& EFI_VARIABLE_RUNTIME_ACCESS
) != 0) {
60 StrnCatGrow (&RetString
, &BufLen
, L
"+RT+BS", 0);
61 } else if ((Atts
& EFI_VARIABLE_BOOTSERVICE_ACCESS
) != 0) {
62 StrnCatGrow (&RetString
, &BufLen
, L
"+BS", 0);
64 if ((Atts
& EFI_VARIABLE_HARDWARE_ERROR_RECORD
) != 0) {
65 StrnCatGrow (&RetString
, &BufLen
, L
"+HR", 0);
67 if ((Atts
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
68 StrnCatGrow (&RetString
, &BufLen
, L
"+AW", 0);
70 if ((Atts
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
71 StrnCatGrow (&RetString
, &BufLen
, L
"+AT", 0);
74 if (RetString
== NULL
) {
75 RetString
= StrnCatGrow(&RetString
, &BufLen
, L
"Invalid", 0);
78 if ((RetString
!= NULL
) && (RetString
[0] == L
'+')) {
79 CopyMem(RetString
, RetString
+ 1, StrSize(RetString
+ 1));
86 Load the variable data from file and set to variable data base.
88 @param[in] FileHandle The file to be read.
89 @param[in] Name The name of the variables to be loaded.
90 @param[in] Guid The guid of the variables to be loaded.
91 @param[out] Found TRUE when at least one variable was loaded and set.
93 @retval SHELL_DEVICE_ERROR Cannot access the file.
94 @retval SHELL_VOLUME_CORRUPTED The file is in bad format.
95 @retval SHELL_OUT_OF_RESOURCES There is not enough memory to perform the operation.
96 @retval SHELL_SUCCESS Successfully load and set the variables.
99 LoadVariablesFromFile (
100 IN SHELL_FILE_HANDLE FileHandle
,
101 IN CONST CHAR16
*Name
,
102 IN CONST EFI_GUID
*Guid
,
107 SHELL_STATUS ShellStatus
;
115 DMP_STORE_VARIABLE
*Variable
;
121 Status
= ShellGetFileSize (FileHandle
, &FileSize
);
122 if (EFI_ERROR (Status
)) {
123 return SHELL_DEVICE_ERROR
;
126 ShellStatus
= SHELL_SUCCESS
;
128 InitializeListHead (&List
);
131 while (Position
< FileSize
) {
135 BufferSize
= sizeof (NameSize
);
136 Status
= ShellReadFile (FileHandle
, &BufferSize
, &NameSize
);
137 if (EFI_ERROR (Status
) || (BufferSize
!= sizeof (NameSize
))) {
138 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
145 BufferSize
= sizeof (DataSize
);
146 Status
= ShellReadFile (FileHandle
, &BufferSize
, &DataSize
);
147 if (EFI_ERROR (Status
) || (BufferSize
!= sizeof (DataSize
))) {
148 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
153 // Name, Guid, Attributes, Data, Crc32
155 RemainingSize
= NameSize
+ sizeof (EFI_GUID
) + sizeof (UINT32
) + DataSize
+ sizeof (Crc32
);
156 BufferSize
= sizeof (NameSize
) + sizeof (DataSize
) + RemainingSize
;
157 Buffer
= AllocatePool (BufferSize
);
158 if (Buffer
== NULL
) {
159 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
162 BufferSize
= RemainingSize
;
163 Status
= ShellReadFile (FileHandle
, &BufferSize
, (UINT32
*) Buffer
+ 2);
164 if (EFI_ERROR (Status
) || (BufferSize
!= RemainingSize
)) {
165 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
173 * (UINT32
*) Buffer
= NameSize
;
174 * ((UINT32
*) Buffer
+ 1) = DataSize
;
175 BufferSize
= RemainingSize
+ sizeof (NameSize
) + sizeof (DataSize
) - sizeof (Crc32
);
176 gBS
->CalculateCrc32 (
181 if (Crc32
!= * (UINT32
*) (Buffer
+ BufferSize
)) {
183 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
187 Position
+= BufferSize
+ sizeof (Crc32
);
189 Variable
= AllocateZeroPool (sizeof (*Variable
) + NameSize
+ DataSize
);
190 if (Variable
== NULL
) {
192 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
195 Variable
->Signature
= DMP_STORE_VARIABLE_SIGNATURE
;
196 Variable
->Name
= (CHAR16
*) (Variable
+ 1);
197 Variable
->DataSize
= DataSize
;
198 Variable
->Data
= (UINT8
*) Variable
->Name
+ NameSize
;
199 CopyMem (Variable
->Name
, Buffer
+ sizeof (NameSize
) + sizeof (DataSize
), NameSize
);
200 CopyMem (&Variable
->Guid
, Buffer
+ sizeof (NameSize
) + sizeof (DataSize
) + NameSize
, sizeof (EFI_GUID
));
201 CopyMem (&Variable
->Attributes
, Buffer
+ sizeof (NameSize
) + sizeof (DataSize
) + NameSize
+ sizeof (EFI_GUID
), sizeof (UINT32
));
202 CopyMem (Variable
->Data
, Buffer
+ sizeof (NameSize
) + sizeof (DataSize
) + NameSize
+ sizeof (EFI_GUID
) + sizeof (UINT32
), DataSize
);
204 InsertTailList (&List
, &Variable
->Link
);
208 if ((Position
!= FileSize
) || (ShellStatus
!= SHELL_SUCCESS
)) {
209 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE
), gShellDebug1HiiHandle
, L
"dmpstore");
210 if (Position
!= FileSize
) {
211 ShellStatus
= SHELL_VOLUME_CORRUPTED
;
215 for ( Link
= GetFirstNode (&List
)
216 ; !IsNull (&List
, Link
) && (ShellStatus
== SHELL_SUCCESS
)
217 ; Link
= GetNextNode (&List
, Link
)
219 Variable
= CR (Link
, DMP_STORE_VARIABLE
, Link
, DMP_STORE_VARIABLE_SIGNATURE
);
221 if (((Name
== NULL
) || gUnicodeCollation
->MetaiMatch (gUnicodeCollation
, Variable
->Name
, (CHAR16
*) Name
)) &&
222 ((Guid
== NULL
) || CompareGuid (&Variable
->Guid
, Guid
))
224 Attributes
= GetAttrType (Variable
->Attributes
);
226 -1, -1, NULL
, STRING_TOKEN(STR_DMPSTORE_HEADER_LINE
), gShellDebug1HiiHandle
,
227 Attributes
, &Variable
->Guid
, Variable
->Name
, Variable
->DataSize
229 SHELL_FREE_NON_NULL(Attributes
);
232 Status
= gRT
->SetVariable (
235 Variable
->Attributes
,
239 if (EFI_ERROR (Status
)) {
240 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", Variable
->Name
, Status
);
245 for (Link
= GetFirstNode (&List
); !IsNull (&List
, Link
); ) {
246 Variable
= CR (Link
, DMP_STORE_VARIABLE
, Link
, DMP_STORE_VARIABLE_SIGNATURE
);
247 Link
= RemoveEntryList (&Variable
->Link
);
255 Append one variable to file.
257 @param[in] FileHandle The file to be appended.
258 @param[in] Name The variable name.
259 @param[in] Guid The variable GUID.
260 @param[in] Attributes The variable attributes.
261 @param[in] DataSize The variable data size.
262 @param[in] Data The variable data.
264 @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation.
265 @retval EFI_SUCCESS The variable is appended to file successfully.
266 @retval others Failed to append the variable to file.
269 AppendSingleVariableToFile (
270 IN SHELL_FILE_HANDLE FileHandle
,
271 IN CONST CHAR16
*Name
,
272 IN CONST EFI_GUID
*Guid
,
273 IN UINT32 Attributes
,
284 NameSize
= (UINT32
) StrSize (Name
);
285 BufferSize
= sizeof (NameSize
) + sizeof (DataSize
)
287 + sizeof (Attributes
)
288 + NameSize
+ DataSize
291 Buffer
= AllocatePool (BufferSize
);
292 if (Buffer
== NULL
) {
293 return EFI_OUT_OF_RESOURCES
;
298 // NameSize and DataSize
300 * (UINT32
*) Ptr
= NameSize
;
301 Ptr
+= sizeof (NameSize
);
302 *(UINT32
*) Ptr
= DataSize
;
303 Ptr
+= sizeof (DataSize
);
308 CopyMem (Ptr
, Name
, NameSize
);
314 CopyMem (Ptr
, Guid
, sizeof (*Guid
));
315 Ptr
+= sizeof (*Guid
);
320 * (UINT32
*) Ptr
= Attributes
;
321 Ptr
+= sizeof (Attributes
);
326 CopyMem (Ptr
, Data
, DataSize
);
332 gBS
->CalculateCrc32 (Buffer
, (UINTN
) (Ptr
- Buffer
), (UINT32
*) Ptr
);
334 Status
= ShellWriteFile (FileHandle
, &BufferSize
, Buffer
);
337 if (!EFI_ERROR (Status
) &&
338 (BufferSize
!= sizeof (NameSize
) + sizeof (DataSize
) + sizeof (*Guid
) + sizeof (Attributes
) + NameSize
+ DataSize
+ sizeof (UINT32
))
340 Status
= EFI_DEVICE_ERROR
;
347 Recursive function to display or delete variables.
349 This function will call itself to create a stack-based list of allt he variables to process,
350 then fromt he last to the first, they will do either printing or deleting.
352 This is necessary since once a delete happens GetNextVariableName() will work.
354 @param[in] Name The variable name of the EFI variable (or NULL).
355 @param[in] Guid The GUID of the variable set (or NULL).
356 @param[in] Type The operation type.
357 @param[in] FileHandle The file to operate on (or NULL).
358 @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.
359 @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.
360 @param[in] FoundOne If a VariableName or Guid was specified and one was printed or
361 deleted, then set this to TRUE, otherwise ignored.
363 @retval SHELL_SUCCESS The operation was successful.
364 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
365 @retval SHELL_ABORTED The abort message was received.
366 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.
367 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.
371 CascadeProcessVariables (
372 IN CONST CHAR16
*Name OPTIONAL
,
373 IN CONST EFI_GUID
*Guid OPTIONAL
,
374 IN DMP_STORE_TYPE Type
,
375 IN EFI_FILE_PROTOCOL
*FileHandle OPTIONAL
,
376 IN CONST CHAR16
* CONST PrevName
,
377 IN EFI_GUID FoundVarGuid
,
382 CHAR16
*FoundVarName
;
386 SHELL_STATUS ShellStatus
;
390 if (ShellGetExecutionBreakFlag()) {
391 return (SHELL_ABORTED
);
397 if (PrevName
!=NULL
) {
398 StrnCatGrow(&FoundVarName
, &NameSize
, PrevName
, 0);
400 FoundVarName
= AllocateZeroPool(sizeof(CHAR16
));
403 Status
= gRT
->GetNextVariableName (&NameSize
, FoundVarName
, &FoundVarGuid
);
404 if (Status
== EFI_BUFFER_TOO_SMALL
) {
405 SHELL_FREE_NON_NULL(FoundVarName
);
406 FoundVarName
= AllocateZeroPool (NameSize
);
407 if (FoundVarName
!= NULL
) {
408 if (PrevName
!= NULL
) {
409 StrnCpyS(FoundVarName
, NameSize
/sizeof(CHAR16
), PrevName
, NameSize
/sizeof(CHAR16
) - 1);
412 Status
= gRT
->GetNextVariableName (&NameSize
, FoundVarName
, &FoundVarGuid
);
414 Status
= EFI_OUT_OF_RESOURCES
;
421 if (Status
== EFI_NOT_FOUND
) {
422 SHELL_FREE_NON_NULL(FoundVarName
);
423 return (SHELL_SUCCESS
);
424 } else if (EFI_ERROR(Status
)) {
425 SHELL_FREE_NON_NULL(FoundVarName
);
426 return (SHELL_DEVICE_ERROR
);
430 // Recurse to the next iteration. We know "our" variable's name.
432 ShellStatus
= CascadeProcessVariables(Name
, Guid
, Type
, FileHandle
, FoundVarName
, FoundVarGuid
, FoundOne
);
434 if (ShellGetExecutionBreakFlag() || (ShellStatus
== SHELL_ABORTED
)) {
435 SHELL_FREE_NON_NULL(FoundVarName
);
436 return (SHELL_ABORTED
);
440 // No matter what happened we process our own variable
441 // Only continue if Guid and VariableName are each either NULL or a match
444 || gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, FoundVarName
, (CHAR16
*) Name
) )
446 || CompareGuid(&FoundVarGuid
, Guid
) )
451 // do the print or delete
454 Status
= gRT
->GetVariable (FoundVarName
, &FoundVarGuid
, &Atts
, &DataSize
, DataBuffer
);
455 if (Status
== EFI_BUFFER_TOO_SMALL
) {
456 SHELL_FREE_NON_NULL (DataBuffer
);
457 DataBuffer
= AllocatePool (DataSize
);
458 if (DataBuffer
== NULL
) {
459 Status
= EFI_OUT_OF_RESOURCES
;
461 Status
= gRT
->GetVariable (FoundVarName
, &FoundVarGuid
, &Atts
, &DataSize
, DataBuffer
);
464 if ((Type
== DmpStoreDisplay
) || (Type
== DmpStoreSave
)) {
466 // Last error check then print this variable out.
468 if (!EFI_ERROR(Status
) && (DataBuffer
!= NULL
) && (FoundVarName
!= NULL
)) {
469 RetString
= GetAttrType(Atts
);
474 STRING_TOKEN(STR_DMPSTORE_HEADER_LINE
),
475 gShellDebug1HiiHandle
,
480 if (Type
== DmpStoreDisplay
) {
481 DumpHex(2, 0, DataSize
, DataBuffer
);
483 Status
= AppendSingleVariableToFile (
492 SHELL_FREE_NON_NULL(RetString
);
494 } else if (Type
== DmpStoreDelete
) {
496 // We only need name to delete it...
502 STRING_TOKEN(STR_DMPSTORE_DELETE_LINE
),
503 gShellDebug1HiiHandle
,
506 gRT
->SetVariable (FoundVarName
, &FoundVarGuid
, Atts
, 0, NULL
)
509 SHELL_FREE_NON_NULL(DataBuffer
);
512 SHELL_FREE_NON_NULL(FoundVarName
);
514 if (Status
== EFI_DEVICE_ERROR
) {
515 ShellStatus
= SHELL_DEVICE_ERROR
;
516 } else if (Status
== EFI_SECURITY_VIOLATION
) {
517 ShellStatus
= SHELL_SECURITY_VIOLATION
;
518 } else if (EFI_ERROR(Status
)) {
519 ShellStatus
= SHELL_NOT_READY
;
522 return (ShellStatus
);
526 Function to display or delete variables. This will set up and call into the recursive function.
528 @param[in] Name The variable name of the EFI variable (or NULL).
529 @param[in] Guid The GUID of the variable set (or NULL).
530 @param[in] Type The operation type.
531 @param[in] FileHandle The file to save or load variables.
533 @retval SHELL_SUCCESS The operation was successful.
534 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
535 @retval SHELL_ABORTED The abort message was received.
536 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.
537 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.
542 IN CONST CHAR16
*Name OPTIONAL
,
543 IN CONST EFI_GUID
*Guid OPTIONAL
,
544 IN DMP_STORE_TYPE Type
,
545 IN SHELL_FILE_HANDLE FileHandle OPTIONAL
548 SHELL_STATUS ShellStatus
;
550 EFI_GUID FoundVarGuid
;
553 ShellStatus
= SHELL_SUCCESS
;
554 ZeroMem (&FoundVarGuid
, sizeof(EFI_GUID
));
556 if (Type
== DmpStoreLoad
) {
557 ShellStatus
= LoadVariablesFromFile (FileHandle
, Name
, Guid
, &Found
);
559 ShellStatus
= CascadeProcessVariables(Name
, Guid
, Type
, FileHandle
, NULL
, FoundVarGuid
, &Found
);
563 if (ShellStatus
== SHELL_OUT_OF_RESOURCES
) {
564 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellDebug1HiiHandle
, L
"dmpstore");
565 return (ShellStatus
);
566 } else if (Name
!= NULL
&& Guid
== NULL
) {
567 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N
), gShellDebug1HiiHandle
, L
"dmpstore", Name
);
568 } else if (Name
!= NULL
&& Guid
!= NULL
) {
569 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN
), gShellDebug1HiiHandle
, L
"dmpstore", Guid
, Name
);
570 } else if (Name
== NULL
&& Guid
== NULL
) {
571 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND
), gShellDebug1HiiHandle
, L
"dmpstore");
572 } else if (Name
== NULL
&& Guid
!= NULL
) {
573 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G
), gShellDebug1HiiHandle
, L
"dmpstore", Guid
);
575 return (SHELL_NOT_FOUND
);
577 return (ShellStatus
);
580 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
585 {L
"-guid", TypeValue
},
590 Function for 'dmpstore' command.
592 @param[in] ImageHandle Handle to the Image (NULL if Internal).
593 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
597 ShellCommandRunDmpStore (
598 IN EFI_HANDLE ImageHandle
,
599 IN EFI_SYSTEM_TABLE
*SystemTable
604 CHAR16
*ProblemParam
;
605 SHELL_STATUS ShellStatus
;
606 CONST CHAR16
*GuidStr
;
612 SHELL_FILE_HANDLE FileHandle
;
613 EFI_FILE_INFO
*FileInfo
;
615 ShellStatus
= SHELL_SUCCESS
;
619 Type
= DmpStoreDisplay
;
621 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
622 if (EFI_ERROR(Status
)) {
623 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
624 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"dmpstore", ProblemParam
);
625 FreePool(ProblemParam
);
626 ShellStatus
= SHELL_INVALID_PARAMETER
;
631 if (ShellCommandLineGetCount(Package
) > 2) {
632 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"dmpstore");
633 ShellStatus
= SHELL_INVALID_PARAMETER
;
634 } else if (ShellCommandLineGetFlag(Package
, L
"-all") && ShellCommandLineGetFlag(Package
, L
"-guid")) {
635 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CONFLICT
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-all", L
"-guid");
636 ShellStatus
= SHELL_INVALID_PARAMETER
;
637 } else if (ShellCommandLineGetFlag(Package
, L
"-s") && ShellCommandLineGetFlag(Package
, L
"-l")) {
638 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CONFLICT
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-l", L
"-s");
639 ShellStatus
= SHELL_INVALID_PARAMETER
;
640 } else if ((ShellCommandLineGetFlag(Package
, L
"-s") || ShellCommandLineGetFlag(Package
, L
"-l")) && ShellCommandLineGetFlag(Package
, L
"-d")) {
641 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CONFLICT
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-l or -s", L
"-d");
642 ShellStatus
= SHELL_INVALID_PARAMETER
;
645 // Determine the GUID to search for based on -all and -guid parameters
647 if (!ShellCommandLineGetFlag(Package
, L
"-all")) {
648 GuidStr
= ShellCommandLineGetValue(Package
, L
"-guid");
649 if (GuidStr
!= NULL
) {
650 Status
= ConvertStringToGuid(GuidStr
, &GuidData
);
651 if (EFI_ERROR(Status
)) {
652 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellDebug1HiiHandle
, L
"dmpstore", GuidStr
);
653 ShellStatus
= SHELL_INVALID_PARAMETER
;
657 Guid
= &gEfiGlobalVariableGuid
;
664 // Get the Name of the variable to find
666 Name
= ShellCommandLineGetRawValue(Package
, 1);
668 if (ShellStatus
== SHELL_SUCCESS
) {
669 if (ShellCommandLineGetFlag(Package
, L
"-s")) {
671 File
= ShellCommandLineGetValue(Package
, L
"-s");
673 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-s");
674 ShellStatus
= SHELL_INVALID_PARAMETER
;
676 Status
= ShellOpenFileByName (File
, &FileHandle
, EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
677 if (!EFI_ERROR (Status
)) {
679 // Delete existing file, but do not delete existing directory
681 FileInfo
= ShellGetFileInfo (FileHandle
);
682 if (FileInfo
== NULL
) {
683 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
684 Status
= EFI_DEVICE_ERROR
;
686 if ((FileInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
) {
687 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
688 Status
= EFI_INVALID_PARAMETER
;
690 Status
= ShellDeleteFile (&FileHandle
);
691 if (EFI_ERROR (Status
)) {
692 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
697 } else if (Status
== EFI_NOT_FOUND
) {
699 // Good when file doesn't exist
701 Status
= EFI_SUCCESS
;
704 // Otherwise it's bad.
706 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
709 if (!EFI_ERROR (Status
)) {
710 Status
= ShellOpenFileByName (File
, &FileHandle
, EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
711 if (EFI_ERROR (Status
)) {
712 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
716 if (EFI_ERROR (Status
)) {
717 ShellStatus
= SHELL_INVALID_PARAMETER
;
720 } else if (ShellCommandLineGetFlag(Package
, L
"-l")) {
722 File
= ShellCommandLineGetValue(Package
, L
"-l");
724 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"dmpstore", L
"-l");
725 ShellStatus
= SHELL_INVALID_PARAMETER
;
727 Status
= ShellOpenFileByName (File
, &FileHandle
, EFI_FILE_MODE_READ
, 0);
728 if (EFI_ERROR (Status
)) {
729 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
730 ShellStatus
= SHELL_INVALID_PARAMETER
;
732 FileInfo
= ShellGetFileInfo (FileHandle
);
733 if (FileInfo
== NULL
) {
734 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
735 ShellStatus
= SHELL_DEVICE_ERROR
;
737 if ((FileInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
) {
738 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY
), gShellDebug1HiiHandle
, L
"dmpstore", File
);
739 ShellStatus
= SHELL_INVALID_PARAMETER
;
745 } else if (ShellCommandLineGetFlag(Package
, L
"-d")) {
746 Type
= DmpStoreDelete
;
750 if (ShellStatus
== SHELL_SUCCESS
) {
751 if (Type
== DmpStoreSave
) {
752 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_SAVE
), gShellDebug1HiiHandle
, File
);
753 } else if (Type
== DmpStoreLoad
) {
754 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DMPSTORE_LOAD
), gShellDebug1HiiHandle
, File
);
756 ShellStatus
= ProcessVariables (Name
, Guid
, Type
, FileHandle
);
757 if ((Type
== DmpStoreLoad
) || (Type
== DmpStoreSave
)) {
758 ShellCloseFile (&FileHandle
);
764 if (Package
!= NULL
) {
765 ShellCommandLineFreeVarList (Package
);