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
29 @param Volatile Return TRUE if the environment variable is volatile
31 @retval EFI_SUCCESS The volatile attribute is returned successfully
32 @retval others Some errors happened.
36 IN CONST CHAR16
*EnvVarName
,
45 ASSERT (Volatile
!= NULL
);
53 Status
= gRT
->GetVariable((CHAR16
*)EnvVarName
,
58 if (Status
== EFI_BUFFER_TOO_SMALL
) {
59 Buffer
= AllocateZeroPool(Size
);
61 return EFI_OUT_OF_RESOURCES
;
63 Status
= gRT
->GetVariable((CHAR16
*)EnvVarName
,
71 // not found means volatile
73 if (Status
== EFI_NOT_FOUND
) {
77 if (EFI_ERROR (Status
)) {
82 // check for the Non Volatile bit
84 *Volatile
= !(BOOLEAN
) ((Attribs
& EFI_VARIABLE_NON_VOLATILE
) == EFI_VARIABLE_NON_VOLATILE
);
89 free function for ENV_VAR_LIST objects.
91 @param[in] List The pointer to pointer to list.
94 FreeEnvironmentVariableList(
100 ASSERT (List
!= NULL
);
105 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(List
)
107 ; Node
= (ENV_VAR_LIST
*)GetFirstNode(List
)
109 ASSERT(Node
!= NULL
);
110 RemoveEntryList(&Node
->Link
);
111 if (Node
->Key
!= NULL
) {
114 if (Node
->Val
!= NULL
) {
122 Creates a list of all Shell-Guid-based environment variables.
124 @param[in, out] ListHead The pointer to pointer to LIST ENTRY object for
127 @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.
239 SetEnvironmentVariableList(
240 IN LIST_ENTRY
*ListHead
243 ENV_VAR_LIST VarList
;
248 InitializeListHead(&VarList
.Link
);
251 // Delete all the current environment variables
253 Status
= GetEnvironmentVariableList(&VarList
.Link
);
254 ASSERT_EFI_ERROR(Status
);
256 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&VarList
.Link
)
257 ; !IsNull(&VarList
.Link
, &Node
->Link
)
258 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&VarList
.Link
, &Node
->Link
)
260 if (Node
->Key
!= NULL
) {
261 Status
= SHELL_DELETE_ENVIRONMENT_VARIABLE(Node
->Key
);
263 ASSERT_EFI_ERROR(Status
);
266 FreeEnvironmentVariableList(&VarList
.Link
);
269 // set all the variables fron the list
271 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(ListHead
)
272 ; !IsNull(ListHead
, &Node
->Link
)
273 ; Node
= (ENV_VAR_LIST
*)GetNextNode(ListHead
, &Node
->Link
)
275 Size
= StrSize(Node
->Val
);
276 if (Node
->Atts
& EFI_VARIABLE_NON_VOLATILE
) {
277 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_NV(Node
->Key
, Size
, Node
->Val
);
279 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V (Node
->Key
, Size
, Node
->Val
);
281 ASSERT_EFI_ERROR(Status
);
283 FreeEnvironmentVariableList(ListHead
);
289 sets a list of all Shell-Guid-based environment variables.
291 @param Environment Points to a NULL-terminated array of environment
292 variables with the format 'x=y', where x is the
293 environment variable name and y is the value.
295 @retval EFI_SUCCESS The command executed successfully.
296 @retval EFI_INVALID_PARAMETER The parameter is invalid.
297 @retval EFI_OUT_OF_RESOURCES Out of resources.
299 @sa SetEnvironmentVariableList
302 SetEnvironmentVariables(
303 IN CONST CHAR16
**Environment
306 CONST CHAR16
*CurrentString
;
308 ENV_VAR_LIST
*VarList
;
313 if (Environment
== NULL
) {
314 return (EFI_INVALID_PARAMETER
);
318 // Build a list identical to the ones used for get/set list functions above
320 for ( CurrentCount
= 0
324 CurrentString
= Environment
[CurrentCount
];
325 if (CurrentString
== NULL
) {
328 ASSERT(StrStr(CurrentString
, L
"=") != NULL
);
329 Node
= AllocateZeroPool(sizeof(ENV_VAR_LIST
));
331 SetEnvironmentVariableList(&VarList
->Link
);
332 return (EFI_OUT_OF_RESOURCES
);
335 Node
->Key
= AllocateZeroPool((StrStr(CurrentString
, L
"=") - CurrentString
+ 1) * sizeof(CHAR16
));
336 if (Node
->Key
== NULL
) {
337 SHELL_FREE_NON_NULL(Node
);
338 SetEnvironmentVariableList(&VarList
->Link
);
339 return (EFI_OUT_OF_RESOURCES
);
343 // Copy the string into the Key, leaving the last character allocated as NULL to terminate
346 StrStr(CurrentString
, L
"=") - CurrentString
+ 1,
348 StrStr(CurrentString
, L
"=") - CurrentString
352 // ValueSize = TotalSize - already removed size - size for '=' + size for terminator (the last 2 items cancel each other)
354 Node
->Val
= AllocateCopyPool(StrSize(CurrentString
) - StrSize(Node
->Key
), CurrentString
+ StrLen(Node
->Key
) + 1);
355 if (Node
->Val
== NULL
) {
356 SHELL_FREE_NON_NULL(Node
->Key
);
357 SHELL_FREE_NON_NULL(Node
);
358 SetEnvironmentVariableList(&VarList
->Link
);
359 return (EFI_OUT_OF_RESOURCES
);
362 Node
->Atts
= EFI_VARIABLE_BOOTSERVICE_ACCESS
;
364 if (VarList
== NULL
) {
365 VarList
= AllocateZeroPool(sizeof(ENV_VAR_LIST
));
366 if (VarList
== NULL
) {
367 SHELL_FREE_NON_NULL(Node
->Key
);
368 SHELL_FREE_NON_NULL(Node
->Val
);
369 SHELL_FREE_NON_NULL(Node
);
370 return (EFI_OUT_OF_RESOURCES
);
372 InitializeListHead(&VarList
->Link
);
374 InsertTailList(&VarList
->Link
, &Node
->Link
);
379 // set this new list as the set of all environment variables.
380 // this function also frees the memory and deletes all pre-existing
381 // shell-guid based environment variables.
383 return (SetEnvironmentVariableList(&VarList
->Link
));
387 Find an environment variable in the gShellEnvVarList.
389 @param Key The name of the environment variable.
390 @param Value The value of the environment variable, the buffer
391 shoule be freed by the caller.
392 @param ValueSize The size in bytes of the environment variable
393 including the tailing CHAR_NELL.
394 @param Atts The attributes of the variable.
396 @retval EFI_SUCCESS The command executed successfully.
397 @retval EFI_NOT_FOUND The environment variable is not found in
402 ShellFindEnvVarInList (
403 IN CONST CHAR16
*Key
,
405 OUT UINTN
*ValueSize
,
406 OUT UINT32
*Atts OPTIONAL
411 if (Key
== NULL
|| Value
== NULL
|| ValueSize
== NULL
) {
412 return SHELL_INVALID_PARAMETER
;
415 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
416 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
417 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
419 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
420 *Value
= AllocateCopyPool(StrSize(Node
->Val
), Node
->Val
);
421 *ValueSize
= StrSize(Node
->Val
);
429 return EFI_NOT_FOUND
;
433 Add an environment variable into gShellEnvVarList.
435 @param Key The name of the environment variable.
436 @param Value The value of environment variable.
437 @param ValueSize The size in bytes of the environment variable
438 including the tailing CHAR_NULL
439 @param Atts The attributes of the variable.
441 @retval EFI_SUCCESS The environment variable was added to list successfully.
442 @retval others Some errors happened.
446 ShellAddEnvVarToList (
447 IN CONST CHAR16
*Key
,
448 IN CONST CHAR16
*Value
,
457 if (Key
== NULL
|| Value
== NULL
|| ValueSize
== 0) {
458 return EFI_INVALID_PARAMETER
;
461 LocalValue
= AllocateCopyPool (ValueSize
, Value
);
462 if (LocalValue
== NULL
) {
463 return EFI_OUT_OF_RESOURCES
;
467 // Update the variable value if it exists in gShellEnvVarList.
469 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
470 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
471 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
473 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
475 SHELL_FREE_NON_NULL(Node
->Val
);
476 Node
->Val
= LocalValue
;
482 // If the environment varialbe key doesn't exist in list just insert
485 LocalKey
= AllocateCopyPool (StrSize(Key
), Key
);
486 if (LocalKey
== NULL
) {
487 FreePool (LocalValue
);
488 return EFI_OUT_OF_RESOURCES
;
490 Node
= (ENV_VAR_LIST
*)AllocateZeroPool (sizeof(ENV_VAR_LIST
));
493 FreePool (LocalValue
);
494 return EFI_OUT_OF_RESOURCES
;
496 Node
->Key
= LocalKey
;
497 Node
->Val
= LocalValue
;
499 InsertTailList(&gShellEnvVarList
.Link
, &Node
->Link
);
505 Remove a specified environment variable in gShellEnvVarList.
507 @param Key The name of the environment variable.
509 @retval EFI_SUCCESS The command executed successfully.
510 @retval EFI_NOT_FOUND The environment variable is not found in
514 ShellRemvoeEnvVarFromList (
521 return EFI_INVALID_PARAMETER
;
524 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
525 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
526 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
528 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
529 SHELL_FREE_NON_NULL(Node
->Key
);
530 SHELL_FREE_NON_NULL(Node
->Val
);
531 RemoveEntryList(&Node
->Link
);
532 SHELL_FREE_NON_NULL(Node
);
537 return EFI_NOT_FOUND
;
541 Initialize the gShellEnvVarList and cache all Shell-Guid-based environment
546 ShellInitEnvVarList (
552 InitializeListHead(&gShellEnvVarList
.Link
);
553 Status
= GetEnvironmentVariableList (&gShellEnvVarList
.Link
);
559 Destructe the gShellEnvVarList.
563 ShellFreeEnvVarList (
567 FreeEnvironmentVariableList (&gShellEnvVarList
.Link
);
568 InitializeListHead(&gShellEnvVarList
.Link
);