2 function declarations for shell environment functions.
4 Copyright (c) 2009 - 2016, 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
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.
17 #define INIT_NAME_BUFFER_SIZE 128
18 #define INIT_DATA_BUFFER_SIZE 1024
21 // The list is used to cache the environment variables.
23 ENV_VAR_LIST gShellEnvVarList
;
26 Reports whether an environment variable is Volatile or Non-Volatile.
28 @param EnvVarName The name of the environment variable in question
30 @retval TRUE This environment variable is Volatile
31 @retval FALSE This environment variable is NON-Volatile
36 IN CONST CHAR16
*EnvVarName
50 Status
= gRT
->GetVariable((CHAR16
*)EnvVarName
,
55 if (Status
== EFI_BUFFER_TOO_SMALL
) {
56 Buffer
= AllocateZeroPool(Size
);
57 ASSERT(Buffer
!= NULL
);
58 Status
= gRT
->GetVariable((CHAR16
*)EnvVarName
,
66 // not found means volatile
68 if (Status
== EFI_NOT_FOUND
) {
71 ASSERT_EFI_ERROR(Status
);
74 // check for the Non Volatile bit
76 if ((Attribs
& EFI_VARIABLE_NON_VOLATILE
) == EFI_VARIABLE_NON_VOLATILE
) {
81 // everything else is volatile
87 free function for ENV_VAR_LIST objects.
89 @param[in] List The pointer to pointer to list.
93 FreeEnvironmentVariableList(
99 ASSERT (List
!= NULL
);
104 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(List
)
106 ; Node
= (ENV_VAR_LIST
*)GetFirstNode(List
)
108 ASSERT(Node
!= NULL
);
109 RemoveEntryList(&Node
->Link
);
110 if (Node
->Key
!= NULL
) {
113 if (Node
->Val
!= NULL
) {
121 Creates a list of all Shell-Guid-based environment variables.
123 @param[in, out] ListHead The pointer to pointer to LIST ENTRY object for
126 @retval EFI_SUCCESS the list was created sucessfully.
130 GetEnvironmentVariableList(
131 IN OUT LIST_ENTRY
*ListHead
134 CHAR16
*VariableName
;
136 UINTN NameBufferSize
;
141 ENV_VAR_LIST
*VarList
;
143 if (ListHead
== NULL
) {
144 return (EFI_INVALID_PARAMETER
);
147 Status
= EFI_SUCCESS
;
149 ValBufferSize
= INIT_DATA_BUFFER_SIZE
;
150 NameBufferSize
= INIT_NAME_BUFFER_SIZE
;
151 VariableName
= AllocateZeroPool(NameBufferSize
);
152 if (VariableName
== NULL
) {
153 return (EFI_OUT_OF_RESOURCES
);
155 *VariableName
= CHAR_NULL
;
157 while (!EFI_ERROR(Status
)) {
158 NameSize
= NameBufferSize
;
159 Status
= gRT
->GetNextVariableName(&NameSize
, VariableName
, &Guid
);
160 if (Status
== EFI_NOT_FOUND
){
161 Status
= EFI_SUCCESS
;
163 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
164 NameBufferSize
= NameSize
> NameBufferSize
* 2 ? NameSize
: NameBufferSize
* 2;
165 SHELL_FREE_NON_NULL(VariableName
);
166 VariableName
= AllocateZeroPool(NameBufferSize
);
167 if (VariableName
== NULL
) {
168 Status
= EFI_OUT_OF_RESOURCES
;
171 NameSize
= NameBufferSize
;
172 Status
= gRT
->GetNextVariableName(&NameSize
, VariableName
, &Guid
);
175 if (!EFI_ERROR(Status
) && CompareGuid(&Guid
, &gShellVariableGuid
)){
176 VarList
= AllocateZeroPool(sizeof(ENV_VAR_LIST
));
177 if (VarList
== NULL
) {
178 Status
= EFI_OUT_OF_RESOURCES
;
180 ValSize
= ValBufferSize
;
181 VarList
->Val
= AllocateZeroPool(ValSize
);
182 if (VarList
->Val
== NULL
) {
183 SHELL_FREE_NON_NULL(VarList
);
184 Status
= EFI_OUT_OF_RESOURCES
;
187 Status
= SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName
, &VarList
->Atts
, &ValSize
, VarList
->Val
);
188 if (Status
== EFI_BUFFER_TOO_SMALL
){
189 ValBufferSize
= ValSize
> ValBufferSize
* 2 ? ValSize
: ValBufferSize
* 2;
190 SHELL_FREE_NON_NULL (VarList
->Val
);
191 VarList
->Val
= AllocateZeroPool(ValBufferSize
);
192 if (VarList
->Val
== NULL
) {
193 SHELL_FREE_NON_NULL(VarList
);
194 Status
= EFI_OUT_OF_RESOURCES
;
198 ValSize
= ValBufferSize
;
199 Status
= SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName
, &VarList
->Atts
, &ValSize
, VarList
->Val
);
201 if (!EFI_ERROR(Status
)) {
202 VarList
->Key
= AllocateCopyPool(StrSize(VariableName
), VariableName
);
203 if (VarList
->Key
== NULL
) {
204 SHELL_FREE_NON_NULL(VarList
->Val
);
205 SHELL_FREE_NON_NULL(VarList
);
206 Status
= EFI_OUT_OF_RESOURCES
;
208 InsertTailList(ListHead
, &VarList
->Link
);
211 SHELL_FREE_NON_NULL(VarList
->Val
);
212 SHELL_FREE_NON_NULL(VarList
);
214 } // if (VarList == NULL) ... else ...
217 SHELL_FREE_NON_NULL (VariableName
);
219 if (EFI_ERROR(Status
)) {
220 FreeEnvironmentVariableList(ListHead
);
227 Sets a list of all Shell-Guid-based environment variables. this will
228 also eliminate all existing shell environment variables (even if they
229 are not on the list).
231 This function will also deallocate the memory from List.
233 @param[in] ListHead The pointer to LIST_ENTRY from
234 GetShellEnvVarList().
236 @retval EFI_SUCCESS the list was Set sucessfully.
240 SetEnvironmentVariableList(
241 IN LIST_ENTRY
*ListHead
244 ENV_VAR_LIST VarList
;
249 InitializeListHead(&VarList
.Link
);
252 // Delete all the current environment variables
254 Status
= GetEnvironmentVariableList(&VarList
.Link
);
255 ASSERT_EFI_ERROR(Status
);
257 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&VarList
.Link
)
258 ; !IsNull(&VarList
.Link
, &Node
->Link
)
259 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&VarList
.Link
, &Node
->Link
)
261 if (Node
->Key
!= NULL
) {
262 Status
= SHELL_DELETE_ENVIRONMENT_VARIABLE(Node
->Key
);
264 ASSERT_EFI_ERROR(Status
);
267 FreeEnvironmentVariableList(&VarList
.Link
);
270 // set all the variables fron the list
272 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(ListHead
)
273 ; !IsNull(ListHead
, &Node
->Link
)
274 ; Node
= (ENV_VAR_LIST
*)GetNextNode(ListHead
, &Node
->Link
)
276 Size
= StrSize(Node
->Val
);
277 if (Node
->Atts
& EFI_VARIABLE_NON_VOLATILE
) {
278 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_NV(Node
->Key
, Size
, Node
->Val
);
280 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V (Node
->Key
, Size
, Node
->Val
);
282 ASSERT_EFI_ERROR(Status
);
284 FreeEnvironmentVariableList(ListHead
);
290 sets a list of all Shell-Guid-based environment variables.
292 @param Environment Points to a NULL-terminated array of environment
293 variables with the format 'x=y', where x is the
294 environment variable name and y is the value.
296 @retval EFI_SUCCESS The command executed successfully.
297 @retval EFI_INVALID_PARAMETER The parameter is invalid.
298 @retval EFI_OUT_OF_RESOURCES Out of resources.
300 @sa SetEnvironmentVariableList
304 SetEnvironmentVariables(
305 IN CONST CHAR16
**Environment
308 CONST CHAR16
*CurrentString
;
310 ENV_VAR_LIST
*VarList
;
315 if (Environment
== NULL
) {
316 return (EFI_INVALID_PARAMETER
);
320 // Build a list identical to the ones used for get/set list functions above
322 for ( CurrentCount
= 0
326 CurrentString
= Environment
[CurrentCount
];
327 if (CurrentString
== NULL
) {
330 ASSERT(StrStr(CurrentString
, L
"=") != NULL
);
331 Node
= AllocateZeroPool(sizeof(ENV_VAR_LIST
));
333 SetEnvironmentVariableList(&VarList
->Link
);
334 return (EFI_OUT_OF_RESOURCES
);
337 Node
->Key
= AllocateZeroPool((StrStr(CurrentString
, L
"=") - CurrentString
+ 1) * sizeof(CHAR16
));
338 if (Node
->Key
== NULL
) {
339 SHELL_FREE_NON_NULL(Node
);
340 SetEnvironmentVariableList(&VarList
->Link
);
341 return (EFI_OUT_OF_RESOURCES
);
345 // Copy the string into the Key, leaving the last character allocated as NULL to terminate
348 StrStr(CurrentString
, L
"=") - CurrentString
+ 1,
350 StrStr(CurrentString
, L
"=") - CurrentString
354 // ValueSize = TotalSize - already removed size - size for '=' + size for terminator (the last 2 items cancel each other)
356 Node
->Val
= AllocateCopyPool(StrSize(CurrentString
) - StrSize(Node
->Key
), CurrentString
+ StrLen(Node
->Key
) + 1);
357 if (Node
->Val
== NULL
) {
358 SHELL_FREE_NON_NULL(Node
->Key
);
359 SHELL_FREE_NON_NULL(Node
);
360 SetEnvironmentVariableList(&VarList
->Link
);
361 return (EFI_OUT_OF_RESOURCES
);
364 Node
->Atts
= EFI_VARIABLE_BOOTSERVICE_ACCESS
;
366 if (VarList
== NULL
) {
367 VarList
= AllocateZeroPool(sizeof(ENV_VAR_LIST
));
368 if (VarList
== NULL
) {
369 SHELL_FREE_NON_NULL(Node
->Key
);
370 SHELL_FREE_NON_NULL(Node
->Val
);
371 SHELL_FREE_NON_NULL(Node
);
372 return (EFI_OUT_OF_RESOURCES
);
374 InitializeListHead(&VarList
->Link
);
376 InsertTailList(&VarList
->Link
, &Node
->Link
);
381 // set this new list as the set of all environment variables.
382 // this function also frees the memory and deletes all pre-existing
383 // shell-guid based environment variables.
385 return (SetEnvironmentVariableList(&VarList
->Link
));
389 Find an environment variable in the gShellEnvVarList.
391 @param Key The name of the environment variable.
392 @param Value The value of the environment variable, the buffer
393 shoule be freed by the caller.
394 @param ValueSize The size in bytes of the environment variable
395 including the tailing CHAR_NELL.
396 @param Atts The attributes of the variable.
398 @retval EFI_SUCCESS The command executed successfully.
399 @retval EFI_NOT_FOUND The environment variable is not found in
404 ShellFindEnvVarInList (
405 IN CONST CHAR16
*Key
,
407 OUT UINTN
*ValueSize
,
408 OUT UINT32
*Atts OPTIONAL
413 if (Key
== NULL
|| Value
== NULL
|| ValueSize
== NULL
) {
414 return SHELL_INVALID_PARAMETER
;
417 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
418 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
419 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
421 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
422 *Value
= AllocateCopyPool(StrSize(Node
->Val
), Node
->Val
);
423 *ValueSize
= StrSize(Node
->Val
);
431 return EFI_NOT_FOUND
;
435 Add an environment variable into gShellEnvVarList.
437 @param Key The name of the environment variable.
438 @param Value The value of environment variable.
439 @param ValueSize The size in bytes of the environment variable
440 including the tailing CHAR_NULL
441 @param Atts The attributes of the variable.
445 ShellAddEnvVarToList (
446 IN CONST CHAR16
*Key
,
447 IN CONST CHAR16
*Value
,
454 if (Key
== NULL
|| Value
== NULL
|| ValueSize
== 0) {
459 // Update the variable value if it exists in gShellEnvVarList.
461 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
462 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
463 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
465 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
467 SHELL_FREE_NON_NULL(Node
->Val
);
468 Node
->Val
= AllocateZeroPool (ValueSize
);
469 ASSERT (Node
->Val
!= NULL
);
470 CopyMem(Node
->Val
, Value
, ValueSize
);
476 // If the environment varialbe key doesn't exist in list just insert
479 Node
= (ENV_VAR_LIST
*)AllocateZeroPool (sizeof(ENV_VAR_LIST
));
480 ASSERT (Node
!= NULL
);
481 Node
->Key
= AllocateCopyPool(StrSize(Key
), Key
);
482 ASSERT (Node
->Key
!= NULL
);
483 Node
->Val
= AllocateCopyPool(ValueSize
, Value
);
484 ASSERT (Node
->Val
!= NULL
);
486 InsertTailList(&gShellEnvVarList
.Link
, &Node
->Link
);
492 Remove a specified environment variable in gShellEnvVarList.
494 @param Key The name of the environment variable.
496 @retval EFI_SUCCESS The command executed successfully.
497 @retval EFI_NOT_FOUND The environment variable is not found in
501 ShellRemvoeEnvVarFromList (
508 return EFI_INVALID_PARAMETER
;
511 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
512 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
513 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
515 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
516 SHELL_FREE_NON_NULL(Node
->Key
);
517 SHELL_FREE_NON_NULL(Node
->Val
);
518 RemoveEntryList(&Node
->Link
);
519 SHELL_FREE_NON_NULL(Node
);
524 return EFI_NOT_FOUND
;
528 Initialize the gShellEnvVarList and cache all Shell-Guid-based environment
533 ShellInitEnvVarList (
539 InitializeListHead(&gShellEnvVarList
.Link
);
540 Status
= GetEnvironmentVariableList (&gShellEnvVarList
.Link
);
546 Destructe the gShellEnvVarList.
550 ShellFreeEnvVarList (
554 FreeEnvironmentVariableList (&gShellEnvVarList
.Link
);
555 InitializeListHead(&gShellEnvVarList
.Link
);