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