diff options
Diffstat (limited to 'ShellPkg/Application/Shell/ShellEnvVar.c')
| -rw-r--r-- | ShellPkg/Application/Shell/ShellEnvVar.c | 1202 |
1 files changed, 601 insertions, 601 deletions
diff --git a/ShellPkg/Application/Shell/ShellEnvVar.c b/ShellPkg/Application/Shell/ShellEnvVar.c index b97cfe91b9..b422ec9249 100644 --- a/ShellPkg/Application/Shell/ShellEnvVar.c +++ b/ShellPkg/Application/Shell/ShellEnvVar.c @@ -1,601 +1,601 @@ -/** @file
- function declarations for shell environment functions.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Shell.h"
-
-#define INIT_NAME_BUFFER_SIZE 128
-#define INIT_DATA_BUFFER_SIZE 1024
-
-//
-// The list is used to cache the environment variables.
-//
-ENV_VAR_LIST gShellEnvVarList;
-
-/**
- Reports whether an environment variable is Volatile or Non-Volatile.
-
- @param EnvVarName The name of the environment variable in question
- @param Volatile Return TRUE if the environment variable is volatile
-
- @retval EFI_SUCCESS The volatile attribute is returned successfully
- @retval others Some errors happened.
-**/
-EFI_STATUS
-IsVolatileEnv (
- IN CONST CHAR16 *EnvVarName,
- OUT BOOLEAN *Volatile
- )
-{
- EFI_STATUS Status;
- UINTN Size;
- VOID *Buffer;
- UINT32 Attribs;
-
- ASSERT (Volatile != NULL);
-
- Size = 0;
- Buffer = NULL;
-
- //
- // get the variable
- //
- Status = gRT->GetVariable (
- (CHAR16 *)EnvVarName,
- &gShellVariableGuid,
- &Attribs,
- &Size,
- Buffer
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- Buffer = AllocateZeroPool (Size);
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = gRT->GetVariable (
- (CHAR16 *)EnvVarName,
- &gShellVariableGuid,
- &Attribs,
- &Size,
- Buffer
- );
- FreePool (Buffer);
- }
-
- //
- // not found means volatile
- //
- if (Status == EFI_NOT_FOUND) {
- *Volatile = TRUE;
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // check for the Non Volatile bit
- //
- *Volatile = !(BOOLEAN)((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE);
- return EFI_SUCCESS;
-}
-
-/**
- free function for ENV_VAR_LIST objects.
-
- @param[in] List The pointer to pointer to list.
-**/
-VOID
-FreeEnvironmentVariableList (
- IN LIST_ENTRY *List
- )
-{
- ENV_VAR_LIST *Node;
-
- ASSERT (List != NULL);
- if (List == NULL) {
- return;
- }
-
- for ( Node = (ENV_VAR_LIST *)GetFirstNode (List)
- ; !IsListEmpty (List)
- ; Node = (ENV_VAR_LIST *)GetFirstNode (List)
- )
- {
- ASSERT (Node != NULL);
- RemoveEntryList (&Node->Link);
- if (Node->Key != NULL) {
- FreePool (Node->Key);
- }
-
- if (Node->Val != NULL) {
- FreePool (Node->Val);
- }
-
- FreePool (Node);
- }
-}
-
-/**
- Creates a list of all Shell-Guid-based environment variables.
-
- @param[in, out] ListHead The pointer to pointer to LIST ENTRY object for
- storing this list.
-
- @retval EFI_SUCCESS the list was created successfully.
-**/
-EFI_STATUS
-GetEnvironmentVariableList (
- IN OUT LIST_ENTRY *ListHead
- )
-{
- CHAR16 *VariableName;
- UINTN NameSize;
- UINTN NameBufferSize;
- EFI_STATUS Status;
- EFI_GUID Guid;
- UINTN ValSize;
- UINTN ValBufferSize;
- ENV_VAR_LIST *VarList;
-
- if (ListHead == NULL) {
- return (EFI_INVALID_PARAMETER);
- }
-
- Status = EFI_SUCCESS;
-
- ValBufferSize = INIT_DATA_BUFFER_SIZE;
- NameBufferSize = INIT_NAME_BUFFER_SIZE;
- VariableName = AllocateZeroPool (NameBufferSize);
- if (VariableName == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- *VariableName = CHAR_NULL;
-
- while (!EFI_ERROR (Status)) {
- NameSize = NameBufferSize;
- Status = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);
- if (Status == EFI_NOT_FOUND) {
- Status = EFI_SUCCESS;
- break;
- } else if (Status == EFI_BUFFER_TOO_SMALL) {
- NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;
- SHELL_FREE_NON_NULL (VariableName);
- VariableName = AllocateZeroPool (NameBufferSize);
- if (VariableName == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- break;
- }
-
- NameSize = NameBufferSize;
- Status = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);
- }
-
- if (!EFI_ERROR (Status) && CompareGuid (&Guid, &gShellVariableGuid)) {
- VarList = AllocateZeroPool (sizeof (ENV_VAR_LIST));
- if (VarList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- ValSize = ValBufferSize;
- //
- // We need another CHAR16 to save '\0' in VarList->Val.
- //
- VarList->Val = AllocateZeroPool (ValSize + sizeof (CHAR16));
- if (VarList->Val == NULL) {
- SHELL_FREE_NON_NULL (VarList);
- Status = EFI_OUT_OF_RESOURCES;
- break;
- }
-
- Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (VariableName, &VarList->Atts, &ValSize, VarList->Val);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- ValBufferSize = ValSize > ValBufferSize * 2 ? ValSize : ValBufferSize * 2;
- SHELL_FREE_NON_NULL (VarList->Val);
- //
- // We need another CHAR16 to save '\0' in VarList->Val.
- //
- VarList->Val = AllocateZeroPool (ValBufferSize + sizeof (CHAR16));
- if (VarList->Val == NULL) {
- SHELL_FREE_NON_NULL (VarList);
- Status = EFI_OUT_OF_RESOURCES;
- break;
- }
-
- ValSize = ValBufferSize;
- Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (VariableName, &VarList->Atts, &ValSize, VarList->Val);
- }
-
- if (!EFI_ERROR (Status)) {
- VarList->Key = AllocateCopyPool (StrSize (VariableName), VariableName);
- if (VarList->Key == NULL) {
- SHELL_FREE_NON_NULL (VarList->Val);
- SHELL_FREE_NON_NULL (VarList);
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- InsertTailList (ListHead, &VarList->Link);
- }
- } else {
- SHELL_FREE_NON_NULL (VarList->Val);
- SHELL_FREE_NON_NULL (VarList);
- }
- } // if (VarList == NULL) ... else ...
- } // compare guid
- } // while
-
- SHELL_FREE_NON_NULL (VariableName);
-
- if (EFI_ERROR (Status)) {
- FreeEnvironmentVariableList (ListHead);
- }
-
- return (Status);
-}
-
-/**
- Sets a list of all Shell-Guid-based environment variables. this will
- also eliminate all existing shell environment variables (even if they
- are not on the list).
-
- This function will also deallocate the memory from List.
-
- @param[in] ListHead The pointer to LIST_ENTRY from
- GetShellEnvVarList().
-
- @retval EFI_SUCCESS the list was Set successfully.
-**/
-EFI_STATUS
-SetEnvironmentVariableList (
- IN LIST_ENTRY *ListHead
- )
-{
- ENV_VAR_LIST VarList;
- ENV_VAR_LIST *Node;
- EFI_STATUS Status;
- UINTN Size;
-
- InitializeListHead (&VarList.Link);
-
- //
- // Delete all the current environment variables
- //
- Status = GetEnvironmentVariableList (&VarList.Link);
- ASSERT_EFI_ERROR (Status);
-
- for ( Node = (ENV_VAR_LIST *)GetFirstNode (&VarList.Link)
- ; !IsNull (&VarList.Link, &Node->Link)
- ; Node = (ENV_VAR_LIST *)GetNextNode (&VarList.Link, &Node->Link)
- )
- {
- if (Node->Key != NULL) {
- Status = SHELL_DELETE_ENVIRONMENT_VARIABLE (Node->Key);
- }
-
- ASSERT_EFI_ERROR (Status);
- }
-
- FreeEnvironmentVariableList (&VarList.Link);
-
- //
- // set all the variables from the list
- //
- for ( Node = (ENV_VAR_LIST *)GetFirstNode (ListHead)
- ; !IsNull (ListHead, &Node->Link)
- ; Node = (ENV_VAR_LIST *)GetNextNode (ListHead, &Node->Link)
- )
- {
- Size = StrSize (Node->Val) - sizeof (CHAR16);
- if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) {
- Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV (Node->Key, Size, Node->Val);
- } else {
- Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (Node->Key, Size, Node->Val);
- }
-
- ASSERT_EFI_ERROR (Status);
- }
-
- FreeEnvironmentVariableList (ListHead);
-
- return (Status);
-}
-
-/**
- sets a list of all Shell-Guid-based environment variables.
-
- @param Environment Points to a NULL-terminated array of environment
- variables with the format 'x=y', where x is the
- environment variable name and y is the value.
-
- @retval EFI_SUCCESS The command executed successfully.
- @retval EFI_INVALID_PARAMETER The parameter is invalid.
- @retval EFI_OUT_OF_RESOURCES Out of resources.
-
- @sa SetEnvironmentVariableList
-**/
-EFI_STATUS
-SetEnvironmentVariables (
- IN CONST CHAR16 **Environment
- )
-{
- CONST CHAR16 *CurrentString;
- UINTN CurrentCount;
- ENV_VAR_LIST *VarList;
- ENV_VAR_LIST *Node;
-
- VarList = NULL;
-
- if (Environment == NULL) {
- return (EFI_INVALID_PARAMETER);
- }
-
- //
- // Build a list identical to the ones used for get/set list functions above
- //
- for ( CurrentCount = 0
- ;
- ; CurrentCount++
- )
- {
- CurrentString = Environment[CurrentCount];
- if (CurrentString == NULL) {
- break;
- }
-
- ASSERT (StrStr (CurrentString, L"=") != NULL);
- Node = AllocateZeroPool (sizeof (ENV_VAR_LIST));
- if (Node == NULL) {
- SetEnvironmentVariableList (&VarList->Link);
- return (EFI_OUT_OF_RESOURCES);
- }
-
- Node->Key = AllocateZeroPool ((StrStr (CurrentString, L"=") - CurrentString + 1) * sizeof (CHAR16));
- if (Node->Key == NULL) {
- SHELL_FREE_NON_NULL (Node);
- SetEnvironmentVariableList (&VarList->Link);
- return (EFI_OUT_OF_RESOURCES);
- }
-
- //
- // Copy the string into the Key, leaving the last character allocated as NULL to terminate
- //
- StrnCpyS (
- Node->Key,
- StrStr (CurrentString, L"=") - CurrentString + 1,
- CurrentString,
- StrStr (CurrentString, L"=") - CurrentString
- );
-
- //
- // ValueSize = TotalSize - already removed size - size for '=' + size for terminator (the last 2 items cancel each other)
- //
- Node->Val = AllocateCopyPool (StrSize (CurrentString) - StrSize (Node->Key), CurrentString + StrLen (Node->Key) + 1);
- if (Node->Val == NULL) {
- SHELL_FREE_NON_NULL (Node->Key);
- SHELL_FREE_NON_NULL (Node);
- SetEnvironmentVariableList (&VarList->Link);
- return (EFI_OUT_OF_RESOURCES);
- }
-
- Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS;
-
- if (VarList == NULL) {
- VarList = AllocateZeroPool (sizeof (ENV_VAR_LIST));
- if (VarList == NULL) {
- SHELL_FREE_NON_NULL (Node->Key);
- SHELL_FREE_NON_NULL (Node->Val);
- SHELL_FREE_NON_NULL (Node);
- return (EFI_OUT_OF_RESOURCES);
- }
-
- InitializeListHead (&VarList->Link);
- }
-
- InsertTailList (&VarList->Link, &Node->Link);
- } // for loop
-
- //
- // set this new list as the set of all environment variables.
- // this function also frees the memory and deletes all pre-existing
- // shell-guid based environment variables.
- //
- return (SetEnvironmentVariableList (&VarList->Link));
-}
-
-/**
- Find an environment variable in the gShellEnvVarList.
-
- @param Key The name of the environment variable.
- @param Value The value of the environment variable, the buffer
- shoule be freed by the caller.
- @param ValueSize The size in bytes of the environment variable
- including the tailing CHAR_NELL.
- @param Atts The attributes of the variable.
-
- @retval EFI_SUCCESS The command executed successfully.
- @retval EFI_NOT_FOUND The environment variable is not found in
- gShellEnvVarList.
-
-**/
-EFI_STATUS
-ShellFindEnvVarInList (
- IN CONST CHAR16 *Key,
- OUT CHAR16 **Value,
- OUT UINTN *ValueSize,
- OUT UINT32 *Atts OPTIONAL
- )
-{
- ENV_VAR_LIST *Node;
-
- if ((Key == NULL) || (Value == NULL) || (ValueSize == NULL)) {
- return SHELL_INVALID_PARAMETER;
- }
-
- for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
- ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
- ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
- )
- {
- if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {
- *Value = AllocateCopyPool (StrSize (Node->Val), Node->Val);
- *ValueSize = StrSize (Node->Val);
- if (Atts != NULL) {
- *Atts = Node->Atts;
- }
-
- return EFI_SUCCESS;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Add an environment variable into gShellEnvVarList.
-
- @param Key The name of the environment variable.
- @param Value The value of environment variable.
- @param ValueSize The size in bytes of the environment variable
- including the tailing CHAR_NULL
- @param Atts The attributes of the variable.
-
- @retval EFI_SUCCESS The environment variable was added to list successfully.
- @retval others Some errors happened.
-
-**/
-EFI_STATUS
-ShellAddEnvVarToList (
- IN CONST CHAR16 *Key,
- IN CONST CHAR16 *Value,
- IN UINTN ValueSize,
- IN UINT32 Atts
- )
-{
- ENV_VAR_LIST *Node;
- CHAR16 *LocalKey;
- CHAR16 *LocalValue;
-
- if ((Key == NULL) || (Value == NULL) || (ValueSize == 0)) {
- return EFI_INVALID_PARAMETER;
- }
-
- LocalValue = AllocateCopyPool (ValueSize, Value);
- if (LocalValue == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Update the variable value if it exists in gShellEnvVarList.
- //
- for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
- ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
- ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
- )
- {
- if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {
- Node->Atts = Atts;
- SHELL_FREE_NON_NULL (Node->Val);
- Node->Val = LocalValue;
- return EFI_SUCCESS;
- }
- }
-
- //
- // If the environment variable key doesn't exist in list just insert
- // a new node.
- //
- LocalKey = AllocateCopyPool (StrSize (Key), Key);
- if (LocalKey == NULL) {
- FreePool (LocalValue);
- return EFI_OUT_OF_RESOURCES;
- }
-
- Node = (ENV_VAR_LIST *)AllocateZeroPool (sizeof (ENV_VAR_LIST));
- if (Node == NULL) {
- FreePool (LocalKey);
- FreePool (LocalValue);
- return EFI_OUT_OF_RESOURCES;
- }
-
- Node->Key = LocalKey;
- Node->Val = LocalValue;
- Node->Atts = Atts;
- InsertTailList (&gShellEnvVarList.Link, &Node->Link);
-
- return EFI_SUCCESS;
-}
-
-/**
- Remove a specified environment variable in gShellEnvVarList.
-
- @param Key The name of the environment variable.
-
- @retval EFI_SUCCESS The command executed successfully.
- @retval EFI_NOT_FOUND The environment variable is not found in
- gShellEnvVarList.
-**/
-EFI_STATUS
-ShellRemvoeEnvVarFromList (
- IN CONST CHAR16 *Key
- )
-{
- ENV_VAR_LIST *Node;
-
- if (Key == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
- ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
- ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
- )
- {
- if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {
- SHELL_FREE_NON_NULL (Node->Key);
- SHELL_FREE_NON_NULL (Node->Val);
- RemoveEntryList (&Node->Link);
- SHELL_FREE_NON_NULL (Node);
- return EFI_SUCCESS;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Initialize the gShellEnvVarList and cache all Shell-Guid-based environment
- variables.
-
-**/
-EFI_STATUS
-ShellInitEnvVarList (
- VOID
- )
-{
- EFI_STATUS Status;
-
- InitializeListHead (&gShellEnvVarList.Link);
- Status = GetEnvironmentVariableList (&gShellEnvVarList.Link);
-
- return Status;
-}
-
-/**
- Destructe the gShellEnvVarList.
-
-**/
-VOID
-ShellFreeEnvVarList (
- VOID
- )
-{
- FreeEnvironmentVariableList (&gShellEnvVarList.Link);
- InitializeListHead (&gShellEnvVarList.Link);
-
- return;
-}
+/** @file + function declarations for shell environment functions. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Shell.h" + +#define INIT_NAME_BUFFER_SIZE 128 +#define INIT_DATA_BUFFER_SIZE 1024 + +// +// The list is used to cache the environment variables. +// +ENV_VAR_LIST gShellEnvVarList; + +/** + Reports whether an environment variable is Volatile or Non-Volatile. + + @param EnvVarName The name of the environment variable in question + @param Volatile Return TRUE if the environment variable is volatile + + @retval EFI_SUCCESS The volatile attribute is returned successfully + @retval others Some errors happened. +**/ +EFI_STATUS +IsVolatileEnv ( + IN CONST CHAR16 *EnvVarName, + OUT BOOLEAN *Volatile + ) +{ + EFI_STATUS Status; + UINTN Size; + VOID *Buffer; + UINT32 Attribs; + + ASSERT (Volatile != NULL); + + Size = 0; + Buffer = NULL; + + // + // get the variable + // + Status = gRT->GetVariable ( + (CHAR16 *)EnvVarName, + &gShellVariableGuid, + &Attribs, + &Size, + Buffer + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + Buffer = AllocateZeroPool (Size); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable ( + (CHAR16 *)EnvVarName, + &gShellVariableGuid, + &Attribs, + &Size, + Buffer + ); + FreePool (Buffer); + } + + // + // not found means volatile + // + if (Status == EFI_NOT_FOUND) { + *Volatile = TRUE; + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // check for the Non Volatile bit + // + *Volatile = !(BOOLEAN)((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE); + return EFI_SUCCESS; +} + +/** + free function for ENV_VAR_LIST objects. + + @param[in] List The pointer to pointer to list. +**/ +VOID +FreeEnvironmentVariableList ( + IN LIST_ENTRY *List + ) +{ + ENV_VAR_LIST *Node; + + ASSERT (List != NULL); + if (List == NULL) { + return; + } + + for ( Node = (ENV_VAR_LIST *)GetFirstNode (List) + ; !IsListEmpty (List) + ; Node = (ENV_VAR_LIST *)GetFirstNode (List) + ) + { + ASSERT (Node != NULL); + RemoveEntryList (&Node->Link); + if (Node->Key != NULL) { + FreePool (Node->Key); + } + + if (Node->Val != NULL) { + FreePool (Node->Val); + } + + FreePool (Node); + } +} + +/** + Creates a list of all Shell-Guid-based environment variables. + + @param[in, out] ListHead The pointer to pointer to LIST ENTRY object for + storing this list. + + @retval EFI_SUCCESS the list was created successfully. +**/ +EFI_STATUS +GetEnvironmentVariableList ( + IN OUT LIST_ENTRY *ListHead + ) +{ + CHAR16 *VariableName; + UINTN NameSize; + UINTN NameBufferSize; + EFI_STATUS Status; + EFI_GUID Guid; + UINTN ValSize; + UINTN ValBufferSize; + ENV_VAR_LIST *VarList; + + if (ListHead == NULL) { + return (EFI_INVALID_PARAMETER); + } + + Status = EFI_SUCCESS; + + ValBufferSize = INIT_DATA_BUFFER_SIZE; + NameBufferSize = INIT_NAME_BUFFER_SIZE; + VariableName = AllocateZeroPool (NameBufferSize); + if (VariableName == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + + *VariableName = CHAR_NULL; + + while (!EFI_ERROR (Status)) { + NameSize = NameBufferSize; + Status = gRT->GetNextVariableName (&NameSize, VariableName, &Guid); + if (Status == EFI_NOT_FOUND) { + Status = EFI_SUCCESS; + break; + } else if (Status == EFI_BUFFER_TOO_SMALL) { + NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2; + SHELL_FREE_NON_NULL (VariableName); + VariableName = AllocateZeroPool (NameBufferSize); + if (VariableName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + break; + } + + NameSize = NameBufferSize; + Status = gRT->GetNextVariableName (&NameSize, VariableName, &Guid); + } + + if (!EFI_ERROR (Status) && CompareGuid (&Guid, &gShellVariableGuid)) { + VarList = AllocateZeroPool (sizeof (ENV_VAR_LIST)); + if (VarList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + ValSize = ValBufferSize; + // + // We need another CHAR16 to save '\0' in VarList->Val. + // + VarList->Val = AllocateZeroPool (ValSize + sizeof (CHAR16)); + if (VarList->Val == NULL) { + SHELL_FREE_NON_NULL (VarList); + Status = EFI_OUT_OF_RESOURCES; + break; + } + + Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (VariableName, &VarList->Atts, &ValSize, VarList->Val); + if (Status == EFI_BUFFER_TOO_SMALL) { + ValBufferSize = ValSize > ValBufferSize * 2 ? ValSize : ValBufferSize * 2; + SHELL_FREE_NON_NULL (VarList->Val); + // + // We need another CHAR16 to save '\0' in VarList->Val. + // + VarList->Val = AllocateZeroPool (ValBufferSize + sizeof (CHAR16)); + if (VarList->Val == NULL) { + SHELL_FREE_NON_NULL (VarList); + Status = EFI_OUT_OF_RESOURCES; + break; + } + + ValSize = ValBufferSize; + Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (VariableName, &VarList->Atts, &ValSize, VarList->Val); + } + + if (!EFI_ERROR (Status)) { + VarList->Key = AllocateCopyPool (StrSize (VariableName), VariableName); + if (VarList->Key == NULL) { + SHELL_FREE_NON_NULL (VarList->Val); + SHELL_FREE_NON_NULL (VarList); + Status = EFI_OUT_OF_RESOURCES; + } else { + InsertTailList (ListHead, &VarList->Link); + } + } else { + SHELL_FREE_NON_NULL (VarList->Val); + SHELL_FREE_NON_NULL (VarList); + } + } // if (VarList == NULL) ... else ... + } // compare guid + } // while + + SHELL_FREE_NON_NULL (VariableName); + + if (EFI_ERROR (Status)) { + FreeEnvironmentVariableList (ListHead); + } + + return (Status); +} + +/** + Sets a list of all Shell-Guid-based environment variables. this will + also eliminate all existing shell environment variables (even if they + are not on the list). + + This function will also deallocate the memory from List. + + @param[in] ListHead The pointer to LIST_ENTRY from + GetShellEnvVarList(). + + @retval EFI_SUCCESS the list was Set successfully. +**/ +EFI_STATUS +SetEnvironmentVariableList ( + IN LIST_ENTRY *ListHead + ) +{ + ENV_VAR_LIST VarList; + ENV_VAR_LIST *Node; + EFI_STATUS Status; + UINTN Size; + + InitializeListHead (&VarList.Link); + + // + // Delete all the current environment variables + // + Status = GetEnvironmentVariableList (&VarList.Link); + ASSERT_EFI_ERROR (Status); + + for ( Node = (ENV_VAR_LIST *)GetFirstNode (&VarList.Link) + ; !IsNull (&VarList.Link, &Node->Link) + ; Node = (ENV_VAR_LIST *)GetNextNode (&VarList.Link, &Node->Link) + ) + { + if (Node->Key != NULL) { + Status = SHELL_DELETE_ENVIRONMENT_VARIABLE (Node->Key); + } + + ASSERT_EFI_ERROR (Status); + } + + FreeEnvironmentVariableList (&VarList.Link); + + // + // set all the variables from the list + // + for ( Node = (ENV_VAR_LIST *)GetFirstNode (ListHead) + ; !IsNull (ListHead, &Node->Link) + ; Node = (ENV_VAR_LIST *)GetNextNode (ListHead, &Node->Link) + ) + { + Size = StrSize (Node->Val) - sizeof (CHAR16); + if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) { + Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV (Node->Key, Size, Node->Val); + } else { + Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (Node->Key, Size, Node->Val); + } + + ASSERT_EFI_ERROR (Status); + } + + FreeEnvironmentVariableList (ListHead); + + return (Status); +} + +/** + sets a list of all Shell-Guid-based environment variables. + + @param Environment Points to a NULL-terminated array of environment + variables with the format 'x=y', where x is the + environment variable name and y is the value. + + @retval EFI_SUCCESS The command executed successfully. + @retval EFI_INVALID_PARAMETER The parameter is invalid. + @retval EFI_OUT_OF_RESOURCES Out of resources. + + @sa SetEnvironmentVariableList +**/ +EFI_STATUS +SetEnvironmentVariables ( + IN CONST CHAR16 **Environment + ) +{ + CONST CHAR16 *CurrentString; + UINTN CurrentCount; + ENV_VAR_LIST *VarList; + ENV_VAR_LIST *Node; + + VarList = NULL; + + if (Environment == NULL) { + return (EFI_INVALID_PARAMETER); + } + + // + // Build a list identical to the ones used for get/set list functions above + // + for ( CurrentCount = 0 + ; + ; CurrentCount++ + ) + { + CurrentString = Environment[CurrentCount]; + if (CurrentString == NULL) { + break; + } + + ASSERT (StrStr (CurrentString, L"=") != NULL); + Node = AllocateZeroPool (sizeof (ENV_VAR_LIST)); + if (Node == NULL) { + SetEnvironmentVariableList (&VarList->Link); + return (EFI_OUT_OF_RESOURCES); + } + + Node->Key = AllocateZeroPool ((StrStr (CurrentString, L"=") - CurrentString + 1) * sizeof (CHAR16)); + if (Node->Key == NULL) { + SHELL_FREE_NON_NULL (Node); + SetEnvironmentVariableList (&VarList->Link); + return (EFI_OUT_OF_RESOURCES); + } + + // + // Copy the string into the Key, leaving the last character allocated as NULL to terminate + // + StrnCpyS ( + Node->Key, + StrStr (CurrentString, L"=") - CurrentString + 1, + CurrentString, + StrStr (CurrentString, L"=") - CurrentString + ); + + // + // ValueSize = TotalSize - already removed size - size for '=' + size for terminator (the last 2 items cancel each other) + // + Node->Val = AllocateCopyPool (StrSize (CurrentString) - StrSize (Node->Key), CurrentString + StrLen (Node->Key) + 1); + if (Node->Val == NULL) { + SHELL_FREE_NON_NULL (Node->Key); + SHELL_FREE_NON_NULL (Node); + SetEnvironmentVariableList (&VarList->Link); + return (EFI_OUT_OF_RESOURCES); + } + + Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS; + + if (VarList == NULL) { + VarList = AllocateZeroPool (sizeof (ENV_VAR_LIST)); + if (VarList == NULL) { + SHELL_FREE_NON_NULL (Node->Key); + SHELL_FREE_NON_NULL (Node->Val); + SHELL_FREE_NON_NULL (Node); + return (EFI_OUT_OF_RESOURCES); + } + + InitializeListHead (&VarList->Link); + } + + InsertTailList (&VarList->Link, &Node->Link); + } // for loop + + // + // set this new list as the set of all environment variables. + // this function also frees the memory and deletes all pre-existing + // shell-guid based environment variables. + // + return (SetEnvironmentVariableList (&VarList->Link)); +} + +/** + Find an environment variable in the gShellEnvVarList. + + @param Key The name of the environment variable. + @param Value The value of the environment variable, the buffer + shoule be freed by the caller. + @param ValueSize The size in bytes of the environment variable + including the tailing CHAR_NELL. + @param Atts The attributes of the variable. + + @retval EFI_SUCCESS The command executed successfully. + @retval EFI_NOT_FOUND The environment variable is not found in + gShellEnvVarList. + +**/ +EFI_STATUS +ShellFindEnvVarInList ( + IN CONST CHAR16 *Key, + OUT CHAR16 **Value, + OUT UINTN *ValueSize, + OUT UINT32 *Atts OPTIONAL + ) +{ + ENV_VAR_LIST *Node; + + if ((Key == NULL) || (Value == NULL) || (ValueSize == NULL)) { + return SHELL_INVALID_PARAMETER; + } + + for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link) + ; !IsNull (&gShellEnvVarList.Link, &Node->Link) + ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link) + ) + { + if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) { + *Value = AllocateCopyPool (StrSize (Node->Val), Node->Val); + *ValueSize = StrSize (Node->Val); + if (Atts != NULL) { + *Atts = Node->Atts; + } + + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + Add an environment variable into gShellEnvVarList. + + @param Key The name of the environment variable. + @param Value The value of environment variable. + @param ValueSize The size in bytes of the environment variable + including the tailing CHAR_NULL + @param Atts The attributes of the variable. + + @retval EFI_SUCCESS The environment variable was added to list successfully. + @retval others Some errors happened. + +**/ +EFI_STATUS +ShellAddEnvVarToList ( + IN CONST CHAR16 *Key, + IN CONST CHAR16 *Value, + IN UINTN ValueSize, + IN UINT32 Atts + ) +{ + ENV_VAR_LIST *Node; + CHAR16 *LocalKey; + CHAR16 *LocalValue; + + if ((Key == NULL) || (Value == NULL) || (ValueSize == 0)) { + return EFI_INVALID_PARAMETER; + } + + LocalValue = AllocateCopyPool (ValueSize, Value); + if (LocalValue == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Update the variable value if it exists in gShellEnvVarList. + // + for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link) + ; !IsNull (&gShellEnvVarList.Link, &Node->Link) + ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link) + ) + { + if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) { + Node->Atts = Atts; + SHELL_FREE_NON_NULL (Node->Val); + Node->Val = LocalValue; + return EFI_SUCCESS; + } + } + + // + // If the environment variable key doesn't exist in list just insert + // a new node. + // + LocalKey = AllocateCopyPool (StrSize (Key), Key); + if (LocalKey == NULL) { + FreePool (LocalValue); + return EFI_OUT_OF_RESOURCES; + } + + Node = (ENV_VAR_LIST *)AllocateZeroPool (sizeof (ENV_VAR_LIST)); + if (Node == NULL) { + FreePool (LocalKey); + FreePool (LocalValue); + return EFI_OUT_OF_RESOURCES; + } + + Node->Key = LocalKey; + Node->Val = LocalValue; + Node->Atts = Atts; + InsertTailList (&gShellEnvVarList.Link, &Node->Link); + + return EFI_SUCCESS; +} + +/** + Remove a specified environment variable in gShellEnvVarList. + + @param Key The name of the environment variable. + + @retval EFI_SUCCESS The command executed successfully. + @retval EFI_NOT_FOUND The environment variable is not found in + gShellEnvVarList. +**/ +EFI_STATUS +ShellRemvoeEnvVarFromList ( + IN CONST CHAR16 *Key + ) +{ + ENV_VAR_LIST *Node; + + if (Key == NULL) { + return EFI_INVALID_PARAMETER; + } + + for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link) + ; !IsNull (&gShellEnvVarList.Link, &Node->Link) + ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link) + ) + { + if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) { + SHELL_FREE_NON_NULL (Node->Key); + SHELL_FREE_NON_NULL (Node->Val); + RemoveEntryList (&Node->Link); + SHELL_FREE_NON_NULL (Node); + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + Initialize the gShellEnvVarList and cache all Shell-Guid-based environment + variables. + +**/ +EFI_STATUS +ShellInitEnvVarList ( + VOID + ) +{ + EFI_STATUS Status; + + InitializeListHead (&gShellEnvVarList.Link); + Status = GetEnvironmentVariableList (&gShellEnvVarList.Link); + + return Status; +} + +/** + Destructe the gShellEnvVarList. + +**/ +VOID +ShellFreeEnvVarList ( + VOID + ) +{ + FreeEnvironmentVariableList (&gShellEnvVarList.Link); + InitializeListHead (&gShellEnvVarList.Link); + + return; +} |
