]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Application/Shell/ShellEnvVar.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Application / Shell / ShellEnvVar.c
CommitLineData
a405b86d 1/** @file\r
2 function declarations for shell environment functions.\r
3\r
ba0014b9 4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
56ba3746 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a405b86d 6\r
7**/\r
8\r
0406a571 9#include "Shell.h"\r
a405b86d 10\r
654a012b
QS
11#define INIT_NAME_BUFFER_SIZE 128\r
12#define INIT_DATA_BUFFER_SIZE 1024\r
13\r
b62bb885
QS
14//\r
15// The list is used to cache the environment variables.\r
16//\r
47d20b54 17ENV_VAR_LIST gShellEnvVarList;\r
b62bb885 18\r
a405b86d 19/**\r
20 Reports whether an environment variable is Volatile or Non-Volatile.\r
21\r
22 @param EnvVarName The name of the environment variable in question\r
31e5b912 23 @param Volatile Return TRUE if the environment variable is volatile\r
a405b86d 24\r
31e5b912
RN
25 @retval EFI_SUCCESS The volatile attribute is returned successfully\r
26 @retval others Some errors happened.\r
a405b86d 27**/\r
31e5b912 28EFI_STATUS\r
a405b86d 29IsVolatileEnv (\r
47d20b54
MK
30 IN CONST CHAR16 *EnvVarName,\r
31 OUT BOOLEAN *Volatile\r
a405b86d 32 )\r
33{\r
34 EFI_STATUS Status;\r
35 UINTN Size;\r
36 VOID *Buffer;\r
37 UINT32 Attribs;\r
38\r
31e5b912
RN
39 ASSERT (Volatile != NULL);\r
40\r
47d20b54 41 Size = 0;\r
a405b86d 42 Buffer = NULL;\r
43\r
44 //\r
45 // get the variable\r
46 //\r
47d20b54
MK
47 Status = gRT->GetVariable (\r
48 (CHAR16 *)EnvVarName,\r
49 &gShellVariableGuid,\r
50 &Attribs,\r
51 &Size,\r
52 Buffer\r
53 );\r
a405b86d 54 if (Status == EFI_BUFFER_TOO_SMALL) {\r
47d20b54 55 Buffer = AllocateZeroPool (Size);\r
31e5b912
RN
56 if (Buffer == NULL) {\r
57 return EFI_OUT_OF_RESOURCES;\r
58 }\r
47d20b54
MK
59\r
60 Status = gRT->GetVariable (\r
61 (CHAR16 *)EnvVarName,\r
62 &gShellVariableGuid,\r
63 &Attribs,\r
64 &Size,\r
65 Buffer\r
66 );\r
67 FreePool (Buffer);\r
a405b86d 68 }\r
47d20b54 69\r
a405b86d 70 //\r
71 // not found means volatile\r
72 //\r
73 if (Status == EFI_NOT_FOUND) {\r
31e5b912
RN
74 *Volatile = TRUE;\r
75 return EFI_SUCCESS;\r
a405b86d 76 }\r
47d20b54 77\r
31e5b912
RN
78 if (EFI_ERROR (Status)) {\r
79 return Status;\r
a405b86d 80 }\r
81\r
82 //\r
31e5b912 83 // check for the Non Volatile bit\r
a405b86d 84 //\r
47d20b54 85 *Volatile = !(BOOLEAN)((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE);\r
31e5b912 86 return EFI_SUCCESS;\r
a405b86d 87}\r
88\r
89/**\r
90 free function for ENV_VAR_LIST objects.\r
91\r
92 @param[in] List The pointer to pointer to list.\r
93**/\r
94VOID\r
47d20b54
MK
95FreeEnvironmentVariableList (\r
96 IN LIST_ENTRY *List\r
a405b86d 97 )\r
98{\r
47d20b54 99 ENV_VAR_LIST *Node;\r
a405b86d 100\r
101 ASSERT (List != NULL);\r
102 if (List == NULL) {\r
103 return;\r
104 }\r
105\r
47d20b54
MK
106 for ( Node = (ENV_VAR_LIST *)GetFirstNode (List)\r
107 ; !IsListEmpty (List)\r
108 ; Node = (ENV_VAR_LIST *)GetFirstNode (List)\r
109 )\r
110 {\r
111 ASSERT (Node != NULL);\r
112 RemoveEntryList (&Node->Link);\r
a405b86d 113 if (Node->Key != NULL) {\r
47d20b54 114 FreePool (Node->Key);\r
a405b86d 115 }\r
47d20b54 116\r
a405b86d 117 if (Node->Val != NULL) {\r
47d20b54 118 FreePool (Node->Val);\r
a405b86d 119 }\r
47d20b54
MK
120\r
121 FreePool (Node);\r
a405b86d 122 }\r
123}\r
124\r
125/**\r
126 Creates a list of all Shell-Guid-based environment variables.\r
127\r
4ff7e37b
ED
128 @param[in, out] ListHead The pointer to pointer to LIST ENTRY object for\r
129 storing this list.\r
a405b86d 130\r
6a5033ca 131 @retval EFI_SUCCESS the list was created successfully.\r
a405b86d 132**/\r
133EFI_STATUS\r
47d20b54
MK
134GetEnvironmentVariableList (\r
135 IN OUT LIST_ENTRY *ListHead\r
a405b86d 136 )\r
137{\r
47d20b54
MK
138 CHAR16 *VariableName;\r
139 UINTN NameSize;\r
140 UINTN NameBufferSize;\r
141 EFI_STATUS Status;\r
142 EFI_GUID Guid;\r
143 UINTN ValSize;\r
144 UINTN ValBufferSize;\r
145 ENV_VAR_LIST *VarList;\r
a405b86d 146\r
3c865f20 147 if (ListHead == NULL) {\r
148 return (EFI_INVALID_PARAMETER);\r
149 }\r
ba0014b9 150\r
654a012b 151 Status = EFI_SUCCESS;\r
ba0014b9 152\r
47d20b54 153 ValBufferSize = INIT_DATA_BUFFER_SIZE;\r
654a012b 154 NameBufferSize = INIT_NAME_BUFFER_SIZE;\r
47d20b54 155 VariableName = AllocateZeroPool (NameBufferSize);\r
3c865f20 156 if (VariableName == NULL) {\r
157 return (EFI_OUT_OF_RESOURCES);\r
158 }\r
47d20b54 159\r
7f79b01e 160 *VariableName = CHAR_NULL;\r
a405b86d 161\r
47d20b54 162 while (!EFI_ERROR (Status)) {\r
654a012b 163 NameSize = NameBufferSize;\r
47d20b54
MK
164 Status = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);\r
165 if (Status == EFI_NOT_FOUND) {\r
a405b86d 166 Status = EFI_SUCCESS;\r
167 break;\r
654a012b
QS
168 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
169 NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;\r
47d20b54
MK
170 SHELL_FREE_NON_NULL (VariableName);\r
171 VariableName = AllocateZeroPool (NameBufferSize);\r
654a012b
QS
172 if (VariableName == NULL) {\r
173 Status = EFI_OUT_OF_RESOURCES;\r
174 break;\r
175 }\r
47d20b54 176\r
654a012b 177 NameSize = NameBufferSize;\r
47d20b54 178 Status = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);\r
a405b86d 179 }\r
ba0014b9 180\r
47d20b54
MK
181 if (!EFI_ERROR (Status) && CompareGuid (&Guid, &gShellVariableGuid)) {\r
182 VarList = AllocateZeroPool (sizeof (ENV_VAR_LIST));\r
8be0ba36 183 if (VarList == NULL) {\r
184 Status = EFI_OUT_OF_RESOURCES;\r
185 } else {\r
654a012b 186 ValSize = ValBufferSize;\r
c5c994c5
CC
187 //\r
188 // We need another CHAR16 to save '\0' in VarList->Val.\r
189 //\r
190 VarList->Val = AllocateZeroPool (ValSize + sizeof (CHAR16));\r
654a012b 191 if (VarList->Val == NULL) {\r
47d20b54
MK
192 SHELL_FREE_NON_NULL (VarList);\r
193 Status = EFI_OUT_OF_RESOURCES;\r
194 break;\r
654a012b 195 }\r
47d20b54
MK
196\r
197 Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (VariableName, &VarList->Atts, &ValSize, VarList->Val);\r
198 if (Status == EFI_BUFFER_TOO_SMALL) {\r
654a012b
QS
199 ValBufferSize = ValSize > ValBufferSize * 2 ? ValSize : ValBufferSize * 2;\r
200 SHELL_FREE_NON_NULL (VarList->Val);\r
c5c994c5
CC
201 //\r
202 // We need another CHAR16 to save '\0' in VarList->Val.\r
203 //\r
204 VarList->Val = AllocateZeroPool (ValBufferSize + sizeof (CHAR16));\r
8be0ba36 205 if (VarList->Val == NULL) {\r
47d20b54 206 SHELL_FREE_NON_NULL (VarList);\r
8be0ba36 207 Status = EFI_OUT_OF_RESOURCES;\r
654a012b 208 break;\r
8be0ba36 209 }\r
ba0014b9 210\r
654a012b 211 ValSize = ValBufferSize;\r
47d20b54 212 Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (VariableName, &VarList->Atts, &ValSize, VarList->Val);\r
8be0ba36 213 }\r
47d20b54
MK
214\r
215 if (!EFI_ERROR (Status)) {\r
216 VarList->Key = AllocateCopyPool (StrSize (VariableName), VariableName);\r
8be0ba36 217 if (VarList->Key == NULL) {\r
47d20b54
MK
218 SHELL_FREE_NON_NULL (VarList->Val);\r
219 SHELL_FREE_NON_NULL (VarList);\r
8be0ba36 220 Status = EFI_OUT_OF_RESOURCES;\r
221 } else {\r
47d20b54 222 InsertTailList (ListHead, &VarList->Link);\r
8be0ba36 223 }\r
654a012b 224 } else {\r
47d20b54
MK
225 SHELL_FREE_NON_NULL (VarList->Val);\r
226 SHELL_FREE_NON_NULL (VarList);\r
8be0ba36 227 }\r
654a012b 228 } // if (VarList == NULL) ... else ...\r
a405b86d 229 } // compare guid\r
230 } // while\r
47d20b54 231\r
654a012b 232 SHELL_FREE_NON_NULL (VariableName);\r
a405b86d 233\r
47d20b54
MK
234 if (EFI_ERROR (Status)) {\r
235 FreeEnvironmentVariableList (ListHead);\r
a405b86d 236 }\r
237\r
238 return (Status);\r
239}\r
240\r
241/**\r
242 Sets a list of all Shell-Guid-based environment variables. this will\r
243 also eliminate all existing shell environment variables (even if they\r
244 are not on the list).\r
245\r
246 This function will also deallocate the memory from List.\r
247\r
248 @param[in] ListHead The pointer to LIST_ENTRY from\r
249 GetShellEnvVarList().\r
250\r
6a5033ca 251 @retval EFI_SUCCESS the list was Set successfully.\r
a405b86d 252**/\r
253EFI_STATUS\r
47d20b54
MK
254SetEnvironmentVariableList (\r
255 IN LIST_ENTRY *ListHead\r
a405b86d 256 )\r
257{\r
47d20b54
MK
258 ENV_VAR_LIST VarList;\r
259 ENV_VAR_LIST *Node;\r
260 EFI_STATUS Status;\r
261 UINTN Size;\r
a405b86d 262\r
47d20b54 263 InitializeListHead (&VarList.Link);\r
a405b86d 264\r
265 //\r
266 // Delete all the current environment variables\r
267 //\r
47d20b54
MK
268 Status = GetEnvironmentVariableList (&VarList.Link);\r
269 ASSERT_EFI_ERROR (Status);\r
270\r
271 for ( Node = (ENV_VAR_LIST *)GetFirstNode (&VarList.Link)\r
272 ; !IsNull (&VarList.Link, &Node->Link)\r
273 ; Node = (ENV_VAR_LIST *)GetNextNode (&VarList.Link, &Node->Link)\r
274 )\r
275 {\r
a405b86d 276 if (Node->Key != NULL) {\r
47d20b54 277 Status = SHELL_DELETE_ENVIRONMENT_VARIABLE (Node->Key);\r
a405b86d 278 }\r
47d20b54
MK
279\r
280 ASSERT_EFI_ERROR (Status);\r
a405b86d 281 }\r
282\r
47d20b54 283 FreeEnvironmentVariableList (&VarList.Link);\r
a405b86d 284\r
285 //\r
6a5033ca 286 // set all the variables from the list\r
a405b86d 287 //\r
47d20b54
MK
288 for ( Node = (ENV_VAR_LIST *)GetFirstNode (ListHead)\r
289 ; !IsNull (ListHead, &Node->Link)\r
290 ; Node = (ENV_VAR_LIST *)GetNextNode (ListHead, &Node->Link)\r
291 )\r
292 {\r
c5c994c5 293 Size = StrSize (Node->Val) - sizeof (CHAR16);\r
a405b86d 294 if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) {\r
47d20b54 295 Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV (Node->Key, Size, Node->Val);\r
a405b86d 296 } else {\r
297 Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (Node->Key, Size, Node->Val);\r
298 }\r
47d20b54
MK
299\r
300 ASSERT_EFI_ERROR (Status);\r
a405b86d 301 }\r
47d20b54
MK
302\r
303 FreeEnvironmentVariableList (ListHead);\r
a405b86d 304\r
305 return (Status);\r
306}\r
307\r
308/**\r
309 sets a list of all Shell-Guid-based environment variables.\r
310\r
311 @param Environment Points to a NULL-terminated array of environment\r
312 variables with the format 'x=y', where x is the\r
313 environment variable name and y is the value.\r
314\r
315 @retval EFI_SUCCESS The command executed successfully.\r
316 @retval EFI_INVALID_PARAMETER The parameter is invalid.\r
317 @retval EFI_OUT_OF_RESOURCES Out of resources.\r
318\r
319 @sa SetEnvironmentVariableList\r
320**/\r
321EFI_STATUS\r
47d20b54
MK
322SetEnvironmentVariables (\r
323 IN CONST CHAR16 **Environment\r
a405b86d 324 )\r
325{\r
326 CONST CHAR16 *CurrentString;\r
327 UINTN CurrentCount;\r
328 ENV_VAR_LIST *VarList;\r
329 ENV_VAR_LIST *Node;\r
a405b86d 330\r
331 VarList = NULL;\r
332\r
333 if (Environment == NULL) {\r
334 return (EFI_INVALID_PARAMETER);\r
335 }\r
336\r
337 //\r
338 // Build a list identical to the ones used for get/set list functions above\r
339 //\r
340 for ( CurrentCount = 0\r
47d20b54
MK
341 ;\r
342 ; CurrentCount++\r
343 )\r
344 {\r
a405b86d 345 CurrentString = Environment[CurrentCount];\r
346 if (CurrentString == NULL) {\r
347 break;\r
348 }\r
47d20b54
MK
349\r
350 ASSERT (StrStr (CurrentString, L"=") != NULL);\r
351 Node = AllocateZeroPool (sizeof (ENV_VAR_LIST));\r
7f79b01e 352 if (Node == NULL) {\r
47d20b54 353 SetEnvironmentVariableList (&VarList->Link);\r
7f79b01e
JC
354 return (EFI_OUT_OF_RESOURCES);\r
355 }\r
356\r
47d20b54 357 Node->Key = AllocateZeroPool ((StrStr (CurrentString, L"=") - CurrentString + 1) * sizeof (CHAR16));\r
7f79b01e 358 if (Node->Key == NULL) {\r
47d20b54
MK
359 SHELL_FREE_NON_NULL (Node);\r
360 SetEnvironmentVariableList (&VarList->Link);\r
7f79b01e
JC
361 return (EFI_OUT_OF_RESOURCES);\r
362 }\r
363\r
364 //\r
365 // Copy the string into the Key, leaving the last character allocated as NULL to terminate\r
366 //\r
47d20b54
MK
367 StrnCpyS (\r
368 Node->Key,\r
369 StrStr (CurrentString, L"=") - CurrentString + 1,\r
370 CurrentString,\r
371 StrStr (CurrentString, L"=") - CurrentString\r
372 );\r
7f79b01e
JC
373\r
374 //\r
375 // ValueSize = TotalSize - already removed size - size for '=' + size for terminator (the last 2 items cancel each other)\r
376 //\r
47d20b54 377 Node->Val = AllocateCopyPool (StrSize (CurrentString) - StrSize (Node->Key), CurrentString + StrLen (Node->Key) + 1);\r
7f79b01e 378 if (Node->Val == NULL) {\r
47d20b54
MK
379 SHELL_FREE_NON_NULL (Node->Key);\r
380 SHELL_FREE_NON_NULL (Node);\r
381 SetEnvironmentVariableList (&VarList->Link);\r
7f79b01e
JC
382 return (EFI_OUT_OF_RESOURCES);\r
383 }\r
384\r
a405b86d 385 Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
386\r
387 if (VarList == NULL) {\r
47d20b54 388 VarList = AllocateZeroPool (sizeof (ENV_VAR_LIST));\r
7f79b01e 389 if (VarList == NULL) {\r
47d20b54
MK
390 SHELL_FREE_NON_NULL (Node->Key);\r
391 SHELL_FREE_NON_NULL (Node->Val);\r
392 SHELL_FREE_NON_NULL (Node);\r
7f79b01e
JC
393 return (EFI_OUT_OF_RESOURCES);\r
394 }\r
47d20b54
MK
395\r
396 InitializeListHead (&VarList->Link);\r
a405b86d 397 }\r
a405b86d 398\r
47d20b54 399 InsertTailList (&VarList->Link, &Node->Link);\r
a405b86d 400 } // for loop\r
401\r
402 //\r
403 // set this new list as the set of all environment variables.\r
404 // this function also frees the memory and deletes all pre-existing\r
405 // shell-guid based environment variables.\r
406 //\r
47d20b54 407 return (SetEnvironmentVariableList (&VarList->Link));\r
a405b86d 408}\r
b62bb885
QS
409\r
410/**\r
411 Find an environment variable in the gShellEnvVarList.\r
412\r
413 @param Key The name of the environment variable.\r
414 @param Value The value of the environment variable, the buffer\r
415 shoule be freed by the caller.\r
416 @param ValueSize The size in bytes of the environment variable\r
417 including the tailing CHAR_NELL.\r
418 @param Atts The attributes of the variable.\r
419\r
420 @retval EFI_SUCCESS The command executed successfully.\r
421 @retval EFI_NOT_FOUND The environment variable is not found in\r
422 gShellEnvVarList.\r
423\r
424**/\r
425EFI_STATUS\r
426ShellFindEnvVarInList (\r
47d20b54
MK
427 IN CONST CHAR16 *Key,\r
428 OUT CHAR16 **Value,\r
429 OUT UINTN *ValueSize,\r
430 OUT UINT32 *Atts OPTIONAL\r
b62bb885
QS
431 )\r
432{\r
47d20b54 433 ENV_VAR_LIST *Node;\r
ba0014b9 434\r
47d20b54 435 if ((Key == NULL) || (Value == NULL) || (ValueSize == NULL)) {\r
b62bb885
QS
436 return SHELL_INVALID_PARAMETER;\r
437 }\r
438\r
47d20b54
MK
439 for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)\r
440 ; !IsNull (&gShellEnvVarList.Link, &Node->Link)\r
441 ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)\r
442 )\r
443 {\r
444 if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {\r
445 *Value = AllocateCopyPool (StrSize (Node->Val), Node->Val);\r
446 *ValueSize = StrSize (Node->Val);\r
b62bb885
QS
447 if (Atts != NULL) {\r
448 *Atts = Node->Atts;\r
449 }\r
47d20b54 450\r
b62bb885
QS
451 return EFI_SUCCESS;\r
452 }\r
453 }\r
454\r
455 return EFI_NOT_FOUND;\r
456}\r
457\r
458/**\r
459 Add an environment variable into gShellEnvVarList.\r
460\r
461 @param Key The name of the environment variable.\r
462 @param Value The value of environment variable.\r
463 @param ValueSize The size in bytes of the environment variable\r
464 including the tailing CHAR_NULL\r
465 @param Atts The attributes of the variable.\r
466\r
ffbc60a0
RN
467 @retval EFI_SUCCESS The environment variable was added to list successfully.\r
468 @retval others Some errors happened.\r
469\r
b62bb885 470**/\r
ffbc60a0 471EFI_STATUS\r
b62bb885 472ShellAddEnvVarToList (\r
47d20b54
MK
473 IN CONST CHAR16 *Key,\r
474 IN CONST CHAR16 *Value,\r
475 IN UINTN ValueSize,\r
476 IN UINT32 Atts\r
b62bb885
QS
477 )\r
478{\r
47d20b54
MK
479 ENV_VAR_LIST *Node;\r
480 CHAR16 *LocalKey;\r
481 CHAR16 *LocalValue;\r
ba0014b9 482\r
47d20b54 483 if ((Key == NULL) || (Value == NULL) || (ValueSize == 0)) {\r
ffbc60a0
RN
484 return EFI_INVALID_PARAMETER;\r
485 }\r
486\r
487 LocalValue = AllocateCopyPool (ValueSize, Value);\r
488 if (LocalValue == NULL) {\r
489 return EFI_OUT_OF_RESOURCES;\r
b62bb885
QS
490 }\r
491\r
492 //\r
493 // Update the variable value if it exists in gShellEnvVarList.\r
494 //\r
47d20b54
MK
495 for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)\r
496 ; !IsNull (&gShellEnvVarList.Link, &Node->Link)\r
497 ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)\r
498 )\r
499 {\r
500 if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {\r
b62bb885 501 Node->Atts = Atts;\r
47d20b54
MK
502 SHELL_FREE_NON_NULL (Node->Val);\r
503 Node->Val = LocalValue;\r
ffbc60a0 504 return EFI_SUCCESS;\r
b62bb885
QS
505 }\r
506 }\r
507\r
508 //\r
6a5033ca 509 // If the environment variable key doesn't exist in list just insert\r
b62bb885
QS
510 // a new node.\r
511 //\r
47d20b54 512 LocalKey = AllocateCopyPool (StrSize (Key), Key);\r
ffbc60a0
RN
513 if (LocalKey == NULL) {\r
514 FreePool (LocalValue);\r
515 return EFI_OUT_OF_RESOURCES;\r
516 }\r
47d20b54
MK
517\r
518 Node = (ENV_VAR_LIST *)AllocateZeroPool (sizeof (ENV_VAR_LIST));\r
ffbc60a0
RN
519 if (Node == NULL) {\r
520 FreePool (LocalKey);\r
521 FreePool (LocalValue);\r
522 return EFI_OUT_OF_RESOURCES;\r
523 }\r
47d20b54
MK
524\r
525 Node->Key = LocalKey;\r
526 Node->Val = LocalValue;\r
b62bb885 527 Node->Atts = Atts;\r
47d20b54 528 InsertTailList (&gShellEnvVarList.Link, &Node->Link);\r
b62bb885 529\r
ffbc60a0 530 return EFI_SUCCESS;\r
b62bb885
QS
531}\r
532\r
533/**\r
534 Remove a specified environment variable in gShellEnvVarList.\r
535\r
536 @param Key The name of the environment variable.\r
ba0014b9 537\r
b62bb885
QS
538 @retval EFI_SUCCESS The command executed successfully.\r
539 @retval EFI_NOT_FOUND The environment variable is not found in\r
540 gShellEnvVarList.\r
541**/\r
542EFI_STATUS\r
543ShellRemvoeEnvVarFromList (\r
47d20b54 544 IN CONST CHAR16 *Key\r
b62bb885
QS
545 )\r
546{\r
47d20b54 547 ENV_VAR_LIST *Node;\r
b62bb885
QS
548\r
549 if (Key == NULL) {\r
550 return EFI_INVALID_PARAMETER;\r
551 }\r
552\r
47d20b54
MK
553 for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)\r
554 ; !IsNull (&gShellEnvVarList.Link, &Node->Link)\r
555 ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)\r
556 )\r
557 {\r
558 if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {\r
559 SHELL_FREE_NON_NULL (Node->Key);\r
560 SHELL_FREE_NON_NULL (Node->Val);\r
561 RemoveEntryList (&Node->Link);\r
562 SHELL_FREE_NON_NULL (Node);\r
b62bb885
QS
563 return EFI_SUCCESS;\r
564 }\r
565 }\r
566\r
567 return EFI_NOT_FOUND;\r
568}\r
569\r
570/**\r
571 Initialize the gShellEnvVarList and cache all Shell-Guid-based environment\r
572 variables.\r
ba0014b9 573\r
b62bb885
QS
574**/\r
575EFI_STATUS\r
576ShellInitEnvVarList (\r
577 VOID\r
578 )\r
579{\r
47d20b54 580 EFI_STATUS Status;\r
b62bb885 581\r
47d20b54 582 InitializeListHead (&gShellEnvVarList.Link);\r
b62bb885
QS
583 Status = GetEnvironmentVariableList (&gShellEnvVarList.Link);\r
584\r
585 return Status;\r
586}\r
587\r
588/**\r
589 Destructe the gShellEnvVarList.\r
590\r
591**/\r
592VOID\r
593ShellFreeEnvVarList (\r
594 VOID\r
595 )\r
596{\r
597 FreeEnvironmentVariableList (&gShellEnvVarList.Link);\r
47d20b54 598 InitializeListHead (&gShellEnvVarList.Link);\r
b62bb885
QS
599\r
600 return;\r
601}\r