\r
#include "UefiShellDebug1CommandsLib.h"\r
\r
-\r
-#define INIT_NAME_BUFFER_SIZE 128\r
-#define INIT_DATA_BUFFER_SIZE 1024\r
-\r
/**\r
Base on the input attribute value to return the attribute string.\r
\r
}\r
\r
/**\r
- Function to display or delete variables.\r
+ Recursive function to display or delete variables.\r
+\r
+ This function will call itself to create a stack-based list of allt he variables to process, \r
+ then fromt he last to the first, they will do either printing or deleting.\r
+\r
+ This is necessary since once a delete happens GetNextVariableName() will work.\r
\r
@param[in] VariableName The variable name of the EFI variable (or NULL).\r
@param[in] Guid The GUID of the variable set (or NULL).\r
@param[in] Delete TRUE to delete, FALSE otherwise.\r
+ @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.\r
+ @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.\r
+ @param[in] FoundOne If a VariableName or Guid was specified and one was printed or\r
+ deleted, then set this to TRUE, otherwise ignored.\r
\r
@retval SHELL_SUCCESS The operation was successful.\r
@retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
**/\r
SHELL_STATUS\r
EFIAPI\r
-ProcessVariables (\r
+CascadeProcessVariables (\r
IN CONST CHAR16 *VariableName OPTIONAL,\r
IN CONST EFI_GUID *Guid OPTIONAL,\r
- IN BOOLEAN Delete\r
+ IN BOOLEAN Delete,\r
+ IN CONST CHAR16 * CONST PrevName,\r
+ IN EFI_GUID FoundVarGuid,\r
+ IN BOOLEAN *FoundOne\r
)\r
{\r
EFI_STATUS Status;\r
CHAR16 *FoundVarName;\r
- EFI_GUID FoundVarGuid;\r
UINT8 *DataBuffer;\r
UINTN DataSize;\r
UINT32 Atts;\r
SHELL_STATUS ShellStatus;\r
- BOOLEAN Found;\r
- UINTN NameBufferSize; // Allocated Name buffer size\r
UINTN NameSize;\r
- CHAR16 *OldName;\r
- UINTN OldNameBufferSize;\r
- UINTN DataBufferSize; // Allocated data buffer size\r
CHAR16 *RetString;\r
\r
- Found = FALSE;\r
- ShellStatus = SHELL_SUCCESS;\r
- Status = EFI_SUCCESS;\r
-\r
- NameBufferSize = INIT_NAME_BUFFER_SIZE;\r
- DataBufferSize = INIT_DATA_BUFFER_SIZE;\r
- FoundVarName = AllocateZeroPool (NameBufferSize);\r
- if (FoundVarName == NULL) {\r
- return (SHELL_OUT_OF_RESOURCES);\r
- } \r
- DataBuffer = AllocatePool (DataBufferSize);\r
- if (DataBuffer == NULL) {\r
- FreePool (FoundVarName);\r
- return (SHELL_OUT_OF_RESOURCES);\r
+ if (ShellGetExecutionBreakFlag()) {\r
+ return (SHELL_ABORTED);\r
}\r
\r
- for (;;){\r
- if (ShellGetExecutionBreakFlag()) {\r
- ShellStatus = SHELL_ABORTED;\r
- break;\r
- }\r
+ NameSize = 0;\r
+ FoundVarName = NULL;\r
\r
- NameSize = NameBufferSize;\r
- Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- OldName = FoundVarName;\r
- OldNameBufferSize = NameBufferSize;\r
- //\r
- // Expand at least twice to avoid reallocate many times\r
- //\r
- NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;\r
- FoundVarName = AllocateZeroPool (NameBufferSize);\r
- if (FoundVarName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- FreePool (OldName);\r
- break;\r
- }\r
- //\r
- // Preserve the original content to get correct iteration for GetNextVariableName() call\r
- //\r
- CopyMem (FoundVarName, OldName, OldNameBufferSize);\r
- FreePool (OldName);\r
- NameSize = NameBufferSize;\r
- Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
- }\r
- if (Status == EFI_NOT_FOUND) {\r
- break;\r
+ if (PrevName!=NULL) {\r
+ StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);\r
+ } else {\r
+ FoundVarName = AllocateZeroPool(sizeof(CHAR16));\r
+ }\r
+\r
+ Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+ FoundVarName = AllocateZeroPool (NameSize);\r
+ if (PrevName != NULL) {\r
+ StrCpy(FoundVarName, PrevName);\r
}\r
- ASSERT_EFI_ERROR(Status);\r
\r
+ Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
+ }\r
+\r
+ //\r
+ // No more is fine.\r
+ //\r
+ if (Status == EFI_NOT_FOUND) {\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+ return (SHELL_SUCCESS);\r
+ } else if (EFI_ERROR(Status)) {\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+ return (SHELL_DEVICE_ERROR);\r
+ }\r
+\r
+ //\r
+ // Recurse to the next iteration. We know "our" variable's name.\r
+ //\r
+ ShellStatus = CascadeProcessVariables(VariableName, Guid, Delete, FoundVarName, FoundVarGuid, FoundOne);\r
+\r
+ //\r
+ // No matter what happened we process our own variable\r
+ // Only continue if Guid and VariableName are each either NULL or a match\r
+ //\r
+ if ( ( VariableName == NULL \r
+ || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*)VariableName) )\r
+ && ( Guid == NULL \r
+ || CompareGuid(&FoundVarGuid, Guid) )\r
+ ) {\r
+ DataSize = 0;\r
+ DataBuffer = NULL;\r
//\r
- // Check if it matches\r
+ // do the print or delete\r
//\r
- if (VariableName != NULL) {\r
- if (!gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*)VariableName)) {\r
- continue;\r
- }\r
- }\r
- if (Guid != NULL) {\r
- if (!CompareGuid(&FoundVarGuid, Guid)) {\r
- continue;\r
- }\r
- }\r
-\r
- DataSize = DataBufferSize;\r
- Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
+ *FoundOne = TRUE;\r
+ Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
- //\r
- // Expand at least twice to avoid reallocate many times\r
- //\r
- FreePool (DataBuffer);\r
- DataBufferSize = DataSize > DataBufferSize * 2 ? DataSize : DataBufferSize * 2;\r
- DataBuffer = AllocatePool (DataBufferSize);\r
+ SHELL_FREE_NON_NULL (DataBuffer);\r
+ DataBuffer = AllocatePool (DataSize);\r
if (DataBuffer == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
- break;\r
+ } else {\r
+ Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
}\r
- DataSize = DataBufferSize;\r
- Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
- } \r
- ASSERT_EFI_ERROR(Status);\r
-\r
- //\r
- // do the print or delete\r
- //\r
- Found = TRUE;\r
- RetString = GetAttrType(Atts);\r
+ }\r
if (!Delete) {\r
- ShellPrintHiiEx(\r
- -1,\r
- -1,\r
- NULL,\r
- STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),\r
- gShellDebug1HiiHandle,\r
- RetString,\r
- &FoundVarGuid,\r
- FoundVarName,\r
- DataSize);\r
- DumpHex(2, 0, DataSize, DataBuffer);\r
+ //\r
+ // Last error check then print this variable out.\r
+ //\r
+ if (!EFI_ERROR(Status)) {\r
+ RetString = GetAttrType(Atts);\r
+ ShellPrintHiiEx(\r
+ -1,\r
+ -1,\r
+ NULL,\r
+ STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),\r
+ gShellDebug1HiiHandle,\r
+ RetString,\r
+ &FoundVarGuid,\r
+ FoundVarName,\r
+ DataSize);\r
+ DumpHex(2, 0, DataSize, DataBuffer);\r
+ SHELL_FREE_NON_NULL(RetString);\r
+ }\r
} else {\r
+ //\r
+ // We only need name to delete it...\r
+ //\r
ShellPrintHiiEx(\r
-1,\r
-1,\r
STRING_TOKEN(STR_DMPSTORE_DELETE_DONE),\r
gShellDebug1HiiHandle,\r
gRT->SetVariable(FoundVarName, &FoundVarGuid, Atts, 0, NULL));\r
- FoundVarName[0] = CHAR_NULL;\r
- }\r
-\r
- if (RetString != NULL) {\r
- FreePool (RetString);\r
}\r
+ SHELL_FREE_NON_NULL(DataBuffer);\r
}\r
\r
- if (FoundVarName != NULL) {\r
- FreePool(FoundVarName);\r
- }\r
- if (DataBuffer != NULL) {\r
- FreePool(DataBuffer);\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+\r
+ if (Status == EFI_DEVICE_ERROR) {\r
+ ShellStatus = SHELL_DEVICE_ERROR;\r
+ } else if (Status == EFI_SECURITY_VIOLATION) {\r
+ ShellStatus = SHELL_SECURITY_VIOLATION;\r
+ } else if (EFI_ERROR(Status)) {\r
+ ShellStatus = SHELL_NOT_READY;\r
}\r
+\r
+ return (ShellStatus);\r
+}\r
+\r
+/**\r
+ Function to display or delete variables. This will set up and call into the recursive function.\r
+\r
+ @param[in] VariableName The variable name of the EFI variable (or NULL).\r
+ @param[in] Guid The GUID of the variable set (or NULL).\r
+ @param[in] Delete TRUE to delete, FALSE otherwise.\r
+\r
+ @retval SHELL_SUCCESS The operation was successful.\r
+ @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
+ @retval SHELL_ABORTED The abort message was received.\r
+ @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
+ @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ProcessVariables (\r
+ IN CONST CHAR16 *VariableName OPTIONAL,\r
+ IN CONST EFI_GUID *Guid OPTIONAL,\r
+ IN BOOLEAN Delete\r
+ )\r
+{\r
+ SHELL_STATUS ShellStatus;\r
+ BOOLEAN Found;\r
+ EFI_GUID FoundVarGuid;\r
+\r
+ Found = FALSE;\r
+ ShellStatus = SHELL_SUCCESS;\r
+ ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));\r
+\r
+ ShellStatus = CascadeProcessVariables(VariableName, Guid, Delete, NULL, FoundVarGuid, &Found);\r
+\r
if (!Found) {\r
- if (Status == EFI_OUT_OF_RESOURCES) {\r
+ if (ShellStatus == SHELL_OUT_OF_RESOURCES) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);\r
- return SHELL_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (VariableName != NULL && Guid == NULL) {\r
+ return (ShellStatus);\r
+ } else if (VariableName != NULL && Guid == NULL) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, VariableName);\r
} else if (VariableName != NULL && Guid != NULL) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, Guid, VariableName);\r