+\r
+/**\r
+ Find an environment variable in the gShellEnvVarList.\r
+\r
+ @param Key The name of the environment variable.\r
+ @param Value The value of the environment variable, the buffer\r
+ shoule be freed by the caller.\r
+ @param ValueSize The size in bytes of the environment variable\r
+ including the tailing CHAR_NELL.\r
+ @param Atts The attributes of the variable.\r
+\r
+ @retval EFI_SUCCESS The command executed successfully.\r
+ @retval EFI_NOT_FOUND The environment variable is not found in\r
+ gShellEnvVarList.\r
+\r
+**/\r
+EFI_STATUS\r
+ShellFindEnvVarInList (\r
+ IN CONST CHAR16 *Key,\r
+ OUT CHAR16 **Value,\r
+ OUT UINTN *ValueSize,\r
+ OUT UINT32 *Atts OPTIONAL\r
+ )\r
+{\r
+ ENV_VAR_LIST *Node;\r
+ \r
+ if (Key == NULL || Value == NULL || ValueSize == NULL) {\r
+ return SHELL_INVALID_PARAMETER;\r
+ }\r
+\r
+ for ( Node = (ENV_VAR_LIST*)GetFirstNode(&gShellEnvVarList.Link)\r
+ ; !IsNull(&gShellEnvVarList.Link, &Node->Link)\r
+ ; Node = (ENV_VAR_LIST*)GetNextNode(&gShellEnvVarList.Link, &Node->Link)\r
+ ){\r
+ if (Node->Key != NULL && StrCmp(Key, Node->Key) == 0) {\r
+ *Value = AllocateCopyPool(StrSize(Node->Val), Node->Val);\r
+ *ValueSize = StrSize(Node->Val);\r
+ if (Atts != NULL) {\r
+ *Atts = Node->Atts;\r
+ }\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ Add an environment variable into gShellEnvVarList.\r
+\r
+ @param Key The name of the environment variable.\r
+ @param Value The value of environment variable.\r
+ @param ValueSize The size in bytes of the environment variable\r
+ including the tailing CHAR_NULL\r
+ @param Atts The attributes of the variable.\r
+\r
+**/\r
+VOID\r
+ShellAddEnvVarToList (\r
+ IN CONST CHAR16 *Key,\r
+ IN CONST CHAR16 *Value,\r
+ IN UINTN ValueSize,\r
+ IN UINT32 Atts\r
+ )\r
+{\r
+ ENV_VAR_LIST *Node;\r
+ \r
+ if (Key == NULL || Value == NULL || ValueSize == 0) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Update the variable value if it exists in gShellEnvVarList.\r
+ //\r
+ for ( Node = (ENV_VAR_LIST*)GetFirstNode(&gShellEnvVarList.Link)\r
+ ; !IsNull(&gShellEnvVarList.Link, &Node->Link)\r
+ ; Node = (ENV_VAR_LIST*)GetNextNode(&gShellEnvVarList.Link, &Node->Link)\r
+ ){\r
+ if (Node->Key != NULL && StrCmp(Key, Node->Key) == 0) {\r
+ Node->Atts = Atts;\r
+ SHELL_FREE_NON_NULL(Node->Val);\r
+ Node->Val = AllocateZeroPool (ValueSize);\r
+ ASSERT (Node->Val != NULL);\r
+ CopyMem(Node->Val, Value, ValueSize);\r
+ return;\r
+ }\r
+ }\r
+\r
+ //\r
+ // If the environment varialbe key doesn't exist in list just insert\r
+ // a new node.\r
+ //\r
+ Node = (ENV_VAR_LIST*)AllocateZeroPool (sizeof(ENV_VAR_LIST));\r
+ ASSERT (Node != NULL);\r
+ Node->Key = AllocateCopyPool(StrSize(Key), Key);\r
+ ASSERT (Node->Key != NULL);\r
+ Node->Val = AllocateCopyPool(ValueSize, Value);\r
+ ASSERT (Node->Val != NULL);\r
+ Node->Atts = Atts;\r
+ InsertTailList(&gShellEnvVarList.Link, &Node->Link);\r
+\r
+ return;\r
+}\r
+\r
+/**\r
+ Remove a specified environment variable in gShellEnvVarList.\r
+\r
+ @param Key The name of the environment variable.\r
+ \r
+ @retval EFI_SUCCESS The command executed successfully.\r
+ @retval EFI_NOT_FOUND The environment variable is not found in\r
+ gShellEnvVarList.\r
+**/\r
+EFI_STATUS\r
+ShellRemvoeEnvVarFromList (\r
+ IN CONST CHAR16 *Key\r
+ )\r
+{\r
+ ENV_VAR_LIST *Node;\r
+\r
+ if (Key == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ for ( Node = (ENV_VAR_LIST*)GetFirstNode(&gShellEnvVarList.Link)\r
+ ; !IsNull(&gShellEnvVarList.Link, &Node->Link)\r
+ ; Node = (ENV_VAR_LIST*)GetNextNode(&gShellEnvVarList.Link, &Node->Link)\r
+ ){\r
+ if (Node->Key != NULL && StrCmp(Key, Node->Key) == 0) {\r
+ SHELL_FREE_NON_NULL(Node->Key);\r
+ SHELL_FREE_NON_NULL(Node->Val);\r
+ RemoveEntryList(&Node->Link);\r
+ SHELL_FREE_NON_NULL(Node);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ Initialize the gShellEnvVarList and cache all Shell-Guid-based environment\r
+ variables.\r
+ \r
+**/\r
+EFI_STATUS\r
+ShellInitEnvVarList (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ InitializeListHead(&gShellEnvVarList.Link);\r
+ Status = GetEnvironmentVariableList (&gShellEnvVarList.Link);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Destructe the gShellEnvVarList.\r
+\r
+**/\r
+VOID\r
+ShellFreeEnvVarList (\r
+ VOID\r
+ )\r
+{\r
+ FreeEnvironmentVariableList (&gShellEnvVarList.Link);\r
+ InitializeListHead(&gShellEnvVarList.Link);\r
+\r
+ return;\r
+}\r
+\r