ShellEnvVar.c revision 3f869579a47a0c48119e256a5309526f41092812
1a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** @file
2a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  function declarations for shell environment functions.
3a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
4733f138d84a25a5993bc32ffe016c364daba686cjcarsey  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
5a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  This program and the accompanying materials
6a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  are licensed and made available under the terms and conditions of the BSD License
7a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  which accompanies this distribution.  The full text of the license may be found at
8a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  http://opensource.org/licenses/bsd-license.php
9a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
10a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
13a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/
14a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
15a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include <Uefi.h>
168be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey#include <ShellBase.h>
17a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
18a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include <Guid/ShellVariableGuid.h>
19a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
20a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include <Library/BaseLib.h>
21a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include <Library/UefiRuntimeServicesTableLib.h>
22a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include <Library/MemoryAllocationLib.h>
23a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include <Library/DebugLib.h>
24a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include <Library/BaseMemoryLib.h>
25a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
26a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include "ShellEnvVar.h"
27a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
28a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/**
29a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  Reports whether an environment variable is Volatile or Non-Volatile.
30a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
31a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @param EnvVarName             The name of the environment variable in question
32a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
33a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @retval TRUE                  This environment variable is Volatile
34a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @retval FALSE                 This environment variable is NON-Volatile
35a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/
36a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyBOOLEAN
37a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI
38a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyIsVolatileEnv (
39a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  IN CONST CHAR16 *EnvVarName
40a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  )
41a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{
42a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  EFI_STATUS  Status;
43a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINTN       Size;
44a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  VOID        *Buffer;
45a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINT32      Attribs;
46a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
47a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  Size = 0;
48a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  Buffer = NULL;
49a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
50a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
51a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // get the variable
52a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
53a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  Status = gRT->GetVariable((CHAR16*)EnvVarName,
54a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                            &gShellVariableGuid,
55a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                            &Attribs,
56a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                            &Size,
57a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                            Buffer);
58a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  if (Status == EFI_BUFFER_TOO_SMALL) {
59733f138d84a25a5993bc32ffe016c364daba686cjcarsey    Buffer = AllocateZeroPool(Size);
60a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    ASSERT(Buffer != NULL);
61a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    Status = gRT->GetVariable((CHAR16*)EnvVarName,
62a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                              &gShellVariableGuid,
63a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                              &Attribs,
64a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                              &Size,
65a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                              Buffer);
66a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    FreePool(Buffer);
67a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
68a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
69a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // not found means volatile
70a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
71a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  if (Status == EFI_NOT_FOUND) {
72a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    return (TRUE);
73a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
74a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ASSERT_EFI_ERROR(Status);
75a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
76a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
77a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // check for the Non Volatile bit
78a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
79a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  if ((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE) {
80a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    return (FALSE);
81a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
82a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
83a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
84a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // everything else is volatile
85a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
86a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  return (TRUE);
87a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey}
88a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
89a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/**
90a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  free function for ENV_VAR_LIST objects.
91a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
92a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @param[in] List               The pointer to pointer to list.
93a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/
94a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyVOID
95a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI
96a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyFreeEnvironmentVariableList(
97a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  IN LIST_ENTRY *List
98a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  )
99a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{
100a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ENV_VAR_LIST *Node;
101a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
102a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ASSERT (List != NULL);
103a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  if (List == NULL) {
104a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    return;
105a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
106a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
107a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  for ( Node = (ENV_VAR_LIST*)GetFirstNode(List)
1083f869579a47a0c48119e256a5309526f41092812jcarsey      ; !IsListEmpty(List)
109a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      ; Node = (ENV_VAR_LIST*)GetFirstNode(List)
110a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey     ){
111a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    ASSERT(Node != NULL);
112a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    RemoveEntryList(&Node->Link);
113a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    if (Node->Key != NULL) {
114a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      FreePool(Node->Key);
115a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    }
116a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    if (Node->Val != NULL) {
117a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      FreePool(Node->Val);
118a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    }
119a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    FreePool(Node);
120a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
121a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey}
122a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
123a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/**
124a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  Creates a list of all Shell-Guid-based environment variables.
125a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
1264ff7e37b4f7e336a8ecb7080b8f48eef4b52d396ydong  @param[in, out] ListHead       The pointer to pointer to LIST ENTRY object for
1274ff7e37b4f7e336a8ecb7080b8f48eef4b52d396ydong                                 storing this list.
128a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
129a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @retval EFI_SUCCESS           the list was created sucessfully.
130a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/
131a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFI_STATUS
132a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI
133a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyGetEnvironmentVariableList(
134a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  IN OUT LIST_ENTRY *ListHead
135a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  )
136a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{
137a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  CHAR16            *VariableName;
138a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINTN             NameSize;
139a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINT64            MaxStorSize;
140a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINT64            RemStorSize;
141a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINT64            MaxVarSize;
142a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  EFI_STATUS        Status;
143a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  EFI_GUID          Guid;
144a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINTN             ValSize;
145a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ENV_VAR_LIST      *VarList;
146a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
1473c865f2064d37eaccd1693b878596d5138b0b38ejcarsey  if (ListHead == NULL) {
1483c865f2064d37eaccd1693b878596d5138b0b38ejcarsey    return (EFI_INVALID_PARAMETER);
1493c865f2064d37eaccd1693b878596d5138b0b38ejcarsey  }
150a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
151a7a394a483a2cd7ea7d696d06f84ac88f987ea3bandrewfish  if (gRT->Hdr.Revision >= EFI_2_00_SYSTEM_TABLE_REVISION) {
152a7a394a483a2cd7ea7d696d06f84ac88f987ea3bandrewfish    Status = gRT->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS, &MaxStorSize, &RemStorSize, &MaxVarSize);
153a7a394a483a2cd7ea7d696d06f84ac88f987ea3bandrewfish    if (EFI_ERROR(Status)) {
154a7a394a483a2cd7ea7d696d06f84ac88f987ea3bandrewfish      return (Status);
155a7a394a483a2cd7ea7d696d06f84ac88f987ea3bandrewfish    }
156a7a394a483a2cd7ea7d696d06f84ac88f987ea3bandrewfish  } else {
157ae69c0473611cd817ca8668db949801307e45dadjcarsey    Status = EFI_SUCCESS;
158a7a394a483a2cd7ea7d696d06f84ac88f987ea3bandrewfish    MaxVarSize = 16384;
1593c865f2064d37eaccd1693b878596d5138b0b38ejcarsey  }
160a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
161a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  NameSize = (UINTN)MaxVarSize;
162733f138d84a25a5993bc32ffe016c364daba686cjcarsey  VariableName = AllocateZeroPool(NameSize);
1633c865f2064d37eaccd1693b878596d5138b0b38ejcarsey  if (VariableName == NULL) {
1643c865f2064d37eaccd1693b878596d5138b0b38ejcarsey    return (EFI_OUT_OF_RESOURCES);
1653c865f2064d37eaccd1693b878596d5138b0b38ejcarsey  }
166a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  StrCpy(VariableName, L"");
167a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
1683c865f2064d37eaccd1693b878596d5138b0b38ejcarsey  while (!EFI_ERROR(Status)) {
169a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    NameSize = (UINTN)MaxVarSize;
170a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);
171a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    if (Status == EFI_NOT_FOUND){
172a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      Status = EFI_SUCCESS;
173a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      break;
174a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    }
1753c865f2064d37eaccd1693b878596d5138b0b38ejcarsey    if (!EFI_ERROR(Status) && CompareGuid(&Guid, &gShellVariableGuid)){
176a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));
1778be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey      if (VarList == NULL) {
1788be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey        Status = EFI_OUT_OF_RESOURCES;
1798be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey      } else {
1808be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey        ValSize = 0;
181a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey        Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
1828be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey        if (Status == EFI_BUFFER_TOO_SMALL){
183733f138d84a25a5993bc32ffe016c364daba686cjcarsey          VarList->Val = AllocateZeroPool(ValSize);
1848be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey          if (VarList->Val == NULL) {
1858be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey            SHELL_FREE_NON_NULL(VarList);
1868be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey            Status = EFI_OUT_OF_RESOURCES;
1878be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey          } else {
1888be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey            Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
1898be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey          }
1908be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey        }
191c154b9970849127546f50481b586d61d78c9bbecjcarsey        if (!EFI_ERROR(Status) && VarList != NULL) {
192733f138d84a25a5993bc32ffe016c364daba686cjcarsey          VarList->Key = AllocateZeroPool(StrSize(VariableName));
1938be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey          if (VarList->Key == NULL) {
1948be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey            SHELL_FREE_NON_NULL(VarList->Val);
1958be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey            SHELL_FREE_NON_NULL(VarList);
1968be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey            Status = EFI_OUT_OF_RESOURCES;
1978be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey          } else {
1988be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey            StrCpy(VarList->Key, VariableName);
1998be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey            InsertTailList(ListHead, &VarList->Link);
2008be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey          }
2018be0ba36fc347bac7199e7dbb8d373ea5e4bf0afjcarsey        }
2023c865f2064d37eaccd1693b878596d5138b0b38ejcarsey      }
203a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    } // compare guid
204a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  } // while
205a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  FreePool(VariableName);
206a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
207a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  if (EFI_ERROR(Status)) {
208a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    FreeEnvironmentVariableList(ListHead);
209a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
210a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
211a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  return (Status);
212a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey}
213a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
214a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/**
215a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  Sets a list of all Shell-Guid-based environment variables.  this will
216a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  also eliminate all existing shell environment variables (even if they
217a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  are not on the list).
218a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
219a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  This function will also deallocate the memory from List.
220a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
221a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @param[in] ListHead           The pointer to LIST_ENTRY from
222a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                                GetShellEnvVarList().
223a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
224a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @retval EFI_SUCCESS           the list was Set sucessfully.
225a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/
226a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFI_STATUS
227a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI
228a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySetEnvironmentVariableList(
229a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  IN LIST_ENTRY *ListHead
230a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  )
231a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{
232a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ENV_VAR_LIST      VarList;
233a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ENV_VAR_LIST      *Node;
234a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  EFI_STATUS        Status;
235a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINTN             Size;
236a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
237a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  InitializeListHead(&VarList.Link);
238a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
239a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
240a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // Delete all the current environment variables
241a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
242a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  Status = GetEnvironmentVariableList(&VarList.Link);
243a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ASSERT_EFI_ERROR(Status);
244a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
245a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  for ( Node = (ENV_VAR_LIST*)GetFirstNode(&VarList.Link)
246a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      ; !IsNull(&VarList.Link, &Node->Link)
247a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      ; Node = (ENV_VAR_LIST*)GetNextNode(&VarList.Link, &Node->Link)
248a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey     ){
249a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    if (Node->Key != NULL) {
250a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      Status = SHELL_DELETE_ENVIRONMENT_VARIABLE(Node->Key);
251a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    }
252a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    ASSERT_EFI_ERROR(Status);
253a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
254a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
255a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  FreeEnvironmentVariableList(&VarList.Link);
256a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
257a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
258a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // set all the variables fron the list
259a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
260a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  for ( Node = (ENV_VAR_LIST*)GetFirstNode(ListHead)
261a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      ; !IsNull(ListHead, &Node->Link)
262a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      ; Node = (ENV_VAR_LIST*)GetNextNode(ListHead, &Node->Link)
263a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey     ){
264a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    Size = StrSize(Node->Val);
265a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) {
266a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(Node->Key, Size, Node->Val);
267a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    } else {
268a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (Node->Key, Size, Node->Val);
269a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    }
270a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    ASSERT_EFI_ERROR(Status);
271a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
272a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  FreeEnvironmentVariableList(ListHead);
273a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
274a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  return (Status);
275a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey}
276a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
277a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/**
278a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  sets a list of all Shell-Guid-based environment variables.
279a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
280a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @param Environment        Points to a NULL-terminated array of environment
281a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                            variables with the format 'x=y', where x is the
282a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey                            environment variable name and y is the value.
283a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
284a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @retval EFI_SUCCESS       The command executed successfully.
285a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @retval EFI_INVALID_PARAMETER The parameter is invalid.
286a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @retval EFI_OUT_OF_RESOURCES Out of resources.
287a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
288a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  @sa SetEnvironmentVariableList
289a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/
290a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFI_STATUS
291a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI
292a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySetEnvironmentVariables(
293a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  IN CONST CHAR16 **Environment
294a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  )
295a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{
296a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  CONST CHAR16  *CurrentString;
297a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINTN         CurrentCount;
298a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ENV_VAR_LIST  *VarList;
299a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  ENV_VAR_LIST  *Node;
300a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  UINTN         NewSize;
301a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
302a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  VarList = NULL;
303a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
304a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  if (Environment == NULL) {
305a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    return (EFI_INVALID_PARAMETER);
306a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  }
307a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
308a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
309a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // Build a list identical to the ones used for get/set list functions above
310a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
311a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  for ( CurrentCount = 0
312a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      ;
313a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      ; CurrentCount++
314a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey     ){
315a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    CurrentString = Environment[CurrentCount];
316a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    if (CurrentString == NULL) {
317a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      break;
318a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    }
319a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    ASSERT(StrStr(CurrentString, L"=") != NULL);
320733f138d84a25a5993bc32ffe016c364daba686cjcarsey    Node = AllocateZeroPool(sizeof(ENV_VAR_LIST));
321a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    ASSERT(Node != NULL);
322a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    Node->Key = AllocateZeroPool((StrStr(CurrentString, L"=") - CurrentString + 1) * sizeof(CHAR16));
323a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    ASSERT(Node->Key != NULL);
324a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    StrnCpy(Node->Key, CurrentString, StrStr(CurrentString, L"=") - CurrentString);
325a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    NewSize = StrSize(CurrentString);
326a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    NewSize -= StrLen(Node->Key) - 1;
327a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    Node->Val = AllocateZeroPool(NewSize);
328a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    ASSERT(Node->Val != NULL);
329a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    StrCpy(Node->Val, CurrentString + StrLen(Node->Key) + 1);
330a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS;
331a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
332a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    if (VarList == NULL) {
333a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));
334a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      ASSERT(VarList != NULL);
335a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey      InitializeListHead(&VarList->Link);
336a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    }
337a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey    InsertTailList(&VarList->Link, &Node->Link);
338a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
339a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  } // for loop
340a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey
341a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
342a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // set this new list as the set of all environment variables.
343a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // this function also frees the memory and deletes all pre-existing
344a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  // shell-guid based environment variables.
345a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  //
346a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey  return (SetEnvironmentVariableList(&VarList->Link));
347a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey}
348