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