diff options
author | Jaben Carsey <jaben.carsey@intel.com> | 2013-12-20 22:33:01 +0000 |
---|---|---|
committer | jcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-12-20 22:33:01 +0000 |
commit | 5bd12b0555989b714d47abe628d846861d350efe (patch) | |
tree | 9f9bfb4f5caef0e4c468ab500a0c4996f957b3ed /ShellPkg | |
parent | 4692bc0b81d822e467435c7a7b9e6470dff1b8d2 (diff) | |
download | edk2-platforms-5bd12b0555989b714d47abe628d846861d350efe.tar.xz |
ShellPkg: fix DmpStore for deleting
This change allows DmpStore command to delete all variables whereas before it would stop after a single deletion due to looping errors. It uses a recursive function and deletes the last item returned from GetNextVariableName() first and then goes "backwards" to the first items.
This can't delete authenticated variables.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jaben Carsey <jaben.carsey@intel.com>
Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15014 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ShellPkg')
-rw-r--r-- | ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c | 252 |
1 files changed, 137 insertions, 115 deletions
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c index 3445b7f7e2..fd10967964 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c @@ -14,10 +14,6 @@ #include "UefiShellDebug1CommandsLib.h"
-
-#define INIT_NAME_BUFFER_SIZE 128
-#define INIT_DATA_BUFFER_SIZE 1024
-
/**
Base on the input attribute value to return the attribute string.
@@ -67,11 +63,20 @@ GetAttrType ( }
/**
- Function to display or delete variables.
+ Recursive function to display or delete variables.
+
+ This function will call itself to create a stack-based list of allt he variables to process,
+ then fromt he last to the first, they will do either printing or deleting.
+
+ This is necessary since once a delete happens GetNextVariableName() will work.
@param[in] VariableName The variable name of the EFI variable (or NULL).
@param[in] Guid The GUID of the variable set (or NULL).
@param[in] Delete TRUE to delete, FALSE otherwise.
+ @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.
+ @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.
+ @param[in] FoundOne If a VariableName or Guid was specified and one was printed or
+ deleted, then set this to TRUE, otherwise ignored.
@retval SHELL_SUCCESS The operation was successful.
@retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
@@ -81,127 +86,112 @@ GetAttrType ( **/
SHELL_STATUS
EFIAPI
-ProcessVariables (
+CascadeProcessVariables (
IN CONST CHAR16 *VariableName OPTIONAL,
IN CONST EFI_GUID *Guid OPTIONAL,
- IN BOOLEAN Delete
+ IN BOOLEAN Delete,
+ IN CONST CHAR16 * CONST PrevName,
+ IN EFI_GUID FoundVarGuid,
+ IN BOOLEAN *FoundOne
)
{
EFI_STATUS Status;
CHAR16 *FoundVarName;
- EFI_GUID FoundVarGuid;
UINT8 *DataBuffer;
UINTN DataSize;
UINT32 Atts;
SHELL_STATUS ShellStatus;
- BOOLEAN Found;
- UINTN NameBufferSize; // Allocated Name buffer size
UINTN NameSize;
- CHAR16 *OldName;
- UINTN OldNameBufferSize;
- UINTN DataBufferSize; // Allocated data buffer size
CHAR16 *RetString;
- Found = FALSE;
- ShellStatus = SHELL_SUCCESS;
- Status = EFI_SUCCESS;
-
- NameBufferSize = INIT_NAME_BUFFER_SIZE;
- DataBufferSize = INIT_DATA_BUFFER_SIZE;
- FoundVarName = AllocateZeroPool (NameBufferSize);
- if (FoundVarName == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
- DataBuffer = AllocatePool (DataBufferSize);
- if (DataBuffer == NULL) {
- FreePool (FoundVarName);
- return (SHELL_OUT_OF_RESOURCES);
+ if (ShellGetExecutionBreakFlag()) {
+ return (SHELL_ABORTED);
}
- for (;;){
- if (ShellGetExecutionBreakFlag()) {
- ShellStatus = SHELL_ABORTED;
- break;
- }
+ NameSize = 0;
+ FoundVarName = NULL;
- NameSize = NameBufferSize;
- Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- OldName = FoundVarName;
- OldNameBufferSize = NameBufferSize;
- //
- // Expand at least twice to avoid reallocate many times
- //
- NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;
- FoundVarName = AllocateZeroPool (NameBufferSize);
- if (FoundVarName == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- FreePool (OldName);
- break;
- }
- //
- // Preserve the original content to get correct iteration for GetNextVariableName() call
- //
- CopyMem (FoundVarName, OldName, OldNameBufferSize);
- FreePool (OldName);
- NameSize = NameBufferSize;
- Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
- }
- if (Status == EFI_NOT_FOUND) {
- break;
+ if (PrevName!=NULL) {
+ StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);
+ } else {
+ FoundVarName = AllocateZeroPool(sizeof(CHAR16));
+ }
+
+ Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ SHELL_FREE_NON_NULL(FoundVarName);
+ FoundVarName = AllocateZeroPool (NameSize);
+ if (PrevName != NULL) {
+ StrCpy(FoundVarName, PrevName);
}
- ASSERT_EFI_ERROR(Status);
+ Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
+ }
+
+ //
+ // No more is fine.
+ //
+ if (Status == EFI_NOT_FOUND) {
+ SHELL_FREE_NON_NULL(FoundVarName);
+ return (SHELL_SUCCESS);
+ } else if (EFI_ERROR(Status)) {
+ SHELL_FREE_NON_NULL(FoundVarName);
+ return (SHELL_DEVICE_ERROR);
+ }
+
+ //
+ // Recurse to the next iteration. We know "our" variable's name.
+ //
+ ShellStatus = CascadeProcessVariables(VariableName, Guid, Delete, FoundVarName, FoundVarGuid, FoundOne);
+
+ //
+ // No matter what happened we process our own variable
+ // Only continue if Guid and VariableName are each either NULL or a match
+ //
+ if ( ( VariableName == NULL
+ || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*)VariableName) )
+ && ( Guid == NULL
+ || CompareGuid(&FoundVarGuid, Guid) )
+ ) {
+ DataSize = 0;
+ DataBuffer = NULL;
//
- // Check if it matches
+ // do the print or delete
//
- if (VariableName != NULL) {
- if (!gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*)VariableName)) {
- continue;
- }
- }
- if (Guid != NULL) {
- if (!CompareGuid(&FoundVarGuid, Guid)) {
- continue;
- }
- }
-
- DataSize = DataBufferSize;
- Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
+ *FoundOne = TRUE;
+ Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
if (Status == EFI_BUFFER_TOO_SMALL) {
- //
- // Expand at least twice to avoid reallocate many times
- //
- FreePool (DataBuffer);
- DataBufferSize = DataSize > DataBufferSize * 2 ? DataSize : DataBufferSize * 2;
- DataBuffer = AllocatePool (DataBufferSize);
+ SHELL_FREE_NON_NULL (DataBuffer);
+ DataBuffer = AllocatePool (DataSize);
if (DataBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
- break;
+ } else {
+ Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
}
- DataSize = DataBufferSize;
- Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
- }
- ASSERT_EFI_ERROR(Status);
-
- //
- // do the print or delete
- //
- Found = TRUE;
- RetString = GetAttrType(Atts);
+ }
if (!Delete) {
- ShellPrintHiiEx(
- -1,
- -1,
- NULL,
- STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),
- gShellDebug1HiiHandle,
- RetString,
- &FoundVarGuid,
- FoundVarName,
- DataSize);
- DumpHex(2, 0, DataSize, DataBuffer);
+ //
+ // Last error check then print this variable out.
+ //
+ if (!EFI_ERROR(Status)) {
+ RetString = GetAttrType(Atts);
+ ShellPrintHiiEx(
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),
+ gShellDebug1HiiHandle,
+ RetString,
+ &FoundVarGuid,
+ FoundVarName,
+ DataSize);
+ DumpHex(2, 0, DataSize, DataBuffer);
+ SHELL_FREE_NON_NULL(RetString);
+ }
} else {
+ //
+ // We only need name to delete it...
+ //
ShellPrintHiiEx(
-1,
-1,
@@ -217,27 +207,59 @@ ProcessVariables ( STRING_TOKEN(STR_DMPSTORE_DELETE_DONE),
gShellDebug1HiiHandle,
gRT->SetVariable(FoundVarName, &FoundVarGuid, Atts, 0, NULL));
- FoundVarName[0] = CHAR_NULL;
- }
-
- if (RetString != NULL) {
- FreePool (RetString);
}
+ SHELL_FREE_NON_NULL(DataBuffer);
}
- if (FoundVarName != NULL) {
- FreePool(FoundVarName);
- }
- if (DataBuffer != NULL) {
- FreePool(DataBuffer);
+ SHELL_FREE_NON_NULL(FoundVarName);
+
+ if (Status == EFI_DEVICE_ERROR) {
+ ShellStatus = SHELL_DEVICE_ERROR;
+ } else if (Status == EFI_SECURITY_VIOLATION) {
+ ShellStatus = SHELL_SECURITY_VIOLATION;
+ } else if (EFI_ERROR(Status)) {
+ ShellStatus = SHELL_NOT_READY;
}
+
+ return (ShellStatus);
+}
+
+/**
+ Function to display or delete variables. This will set up and call into the recursive function.
+
+ @param[in] VariableName The variable name of the EFI variable (or NULL).
+ @param[in] Guid The GUID of the variable set (or NULL).
+ @param[in] Delete TRUE to delete, FALSE otherwise.
+
+ @retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
+ @retval SHELL_ABORTED The abort message was received.
+ @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.
+ @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.
+**/
+SHELL_STATUS
+EFIAPI
+ProcessVariables (
+ IN CONST CHAR16 *VariableName OPTIONAL,
+ IN CONST EFI_GUID *Guid OPTIONAL,
+ IN BOOLEAN Delete
+ )
+{
+ SHELL_STATUS ShellStatus;
+ BOOLEAN Found;
+ EFI_GUID FoundVarGuid;
+
+ Found = FALSE;
+ ShellStatus = SHELL_SUCCESS;
+ ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));
+
+ ShellStatus = CascadeProcessVariables(VariableName, Guid, Delete, NULL, FoundVarGuid, &Found);
+
if (!Found) {
- if (Status == EFI_OUT_OF_RESOURCES) {
+ if (ShellStatus == SHELL_OUT_OF_RESOURCES) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
- return SHELL_OUT_OF_RESOURCES;
- }
-
- if (VariableName != NULL && Guid == NULL) {
+ return (ShellStatus);
+ } else if (VariableName != NULL && Guid == NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, VariableName);
} else if (VariableName != NULL && Guid != NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, Guid, VariableName);
|