mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-10-27 10:50:43 +00:00 
			
		
		
		
	 ba0014b9f8
			
		
	
	
		ba0014b9f8
		
	
	
	
	
		
			
			1. Do not use tab characters 2. No trailing white space in one line 3. All files must end with CRLF Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
		
			
				
	
	
		
			579 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			579 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   function declarations for shell environment functions.
 | |
| 
 | |
|   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
|   This program and the accompanying materials
 | |
|   are licensed and made available under the terms and conditions of the BSD License
 | |
|   which accompanies this distribution.  The full text of the license may be found at
 | |
|   http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
|   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
|   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #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 sucessfully.
 | |
| **/
 | |
| 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 sucessfully.
 | |
| **/
 | |
| 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 fron 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 varialbe 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;
 | |
| }
 | |
| 
 |