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.
95 FreeEnvironmentVariableList(
101 ASSERT (List
!= NULL
);
106 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(List
)
108 ; Node
= (ENV_VAR_LIST
*)GetFirstNode(List
)
110 ASSERT(Node
!= NULL
);
111 RemoveEntryList(&Node
->Link
);
112 if (Node
->Key
!= NULL
) {
115 if (Node
->Val
!= NULL
) {
123 Creates a list of all Shell-Guid-based environment variables.
125 @param[in, out] ListHead The pointer to pointer to LIST ENTRY object for
128 @retval EFI_SUCCESS the list was created sucessfully.
132 GetEnvironmentVariableList(
133 IN OUT LIST_ENTRY
*ListHead
136 CHAR16
*VariableName
;
138 UINTN NameBufferSize
;
143 ENV_VAR_LIST
*VarList
;
145 if (ListHead
== NULL
) {
146 return (EFI_INVALID_PARAMETER
);
149 Status
= EFI_SUCCESS
;
151 ValBufferSize
= INIT_DATA_BUFFER_SIZE
;
152 NameBufferSize
= INIT_NAME_BUFFER_SIZE
;
153 VariableName
= AllocateZeroPool(NameBufferSize
);
154 if (VariableName
== NULL
) {
155 return (EFI_OUT_OF_RESOURCES
);
157 *VariableName
= CHAR_NULL
;
159 while (!EFI_ERROR(Status
)) {
160 NameSize
= NameBufferSize
;
161 Status
= gRT
->GetNextVariableName(&NameSize
, VariableName
, &Guid
);
162 if (Status
== EFI_NOT_FOUND
){
163 Status
= EFI_SUCCESS
;
165 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
166 NameBufferSize
= NameSize
> NameBufferSize
* 2 ? NameSize
: NameBufferSize
* 2;
167 SHELL_FREE_NON_NULL(VariableName
);
168 VariableName
= AllocateZeroPool(NameBufferSize
);
169 if (VariableName
== NULL
) {
170 Status
= EFI_OUT_OF_RESOURCES
;
173 NameSize
= NameBufferSize
;
174 Status
= gRT
->GetNextVariableName(&NameSize
, VariableName
, &Guid
);
177 if (!EFI_ERROR(Status
) && CompareGuid(&Guid
, &gShellVariableGuid
)){
178 VarList
= AllocateZeroPool(sizeof(ENV_VAR_LIST
));
179 if (VarList
== NULL
) {
180 Status
= EFI_OUT_OF_RESOURCES
;
182 ValSize
= ValBufferSize
;
183 VarList
->Val
= AllocateZeroPool(ValSize
);
184 if (VarList
->Val
== NULL
) {
185 SHELL_FREE_NON_NULL(VarList
);
186 Status
= EFI_OUT_OF_RESOURCES
;
189 Status
= SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName
, &VarList
->Atts
, &ValSize
, VarList
->Val
);
190 if (Status
== EFI_BUFFER_TOO_SMALL
){
191 ValBufferSize
= ValSize
> ValBufferSize
* 2 ? ValSize
: ValBufferSize
* 2;
192 SHELL_FREE_NON_NULL (VarList
->Val
);
193 VarList
->Val
= AllocateZeroPool(ValBufferSize
);
194 if (VarList
->Val
== NULL
) {
195 SHELL_FREE_NON_NULL(VarList
);
196 Status
= EFI_OUT_OF_RESOURCES
;
200 ValSize
= ValBufferSize
;
201 Status
= SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName
, &VarList
->Atts
, &ValSize
, VarList
->Val
);
203 if (!EFI_ERROR(Status
)) {
204 VarList
->Key
= AllocateCopyPool(StrSize(VariableName
), VariableName
);
205 if (VarList
->Key
== NULL
) {
206 SHELL_FREE_NON_NULL(VarList
->Val
);
207 SHELL_FREE_NON_NULL(VarList
);
208 Status
= EFI_OUT_OF_RESOURCES
;
210 InsertTailList(ListHead
, &VarList
->Link
);
213 SHELL_FREE_NON_NULL(VarList
->Val
);
214 SHELL_FREE_NON_NULL(VarList
);
216 } // if (VarList == NULL) ... else ...
219 SHELL_FREE_NON_NULL (VariableName
);
221 if (EFI_ERROR(Status
)) {
222 FreeEnvironmentVariableList(ListHead
);
229 Sets a list of all Shell-Guid-based environment variables. this will
230 also eliminate all existing shell environment variables (even if they
231 are not on the list).
233 This function will also deallocate the memory from List.
235 @param[in] ListHead The pointer to LIST_ENTRY from
236 GetShellEnvVarList().
238 @retval EFI_SUCCESS the list was Set sucessfully.
242 SetEnvironmentVariableList(
243 IN LIST_ENTRY
*ListHead
246 ENV_VAR_LIST VarList
;
251 InitializeListHead(&VarList
.Link
);
254 // Delete all the current environment variables
256 Status
= GetEnvironmentVariableList(&VarList
.Link
);
257 ASSERT_EFI_ERROR(Status
);
259 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&VarList
.Link
)
260 ; !IsNull(&VarList
.Link
, &Node
->Link
)
261 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&VarList
.Link
, &Node
->Link
)
263 if (Node
->Key
!= NULL
) {
264 Status
= SHELL_DELETE_ENVIRONMENT_VARIABLE(Node
->Key
);
266 ASSERT_EFI_ERROR(Status
);
269 FreeEnvironmentVariableList(&VarList
.Link
);
272 // set all the variables fron the list
274 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(ListHead
)
275 ; !IsNull(ListHead
, &Node
->Link
)
276 ; Node
= (ENV_VAR_LIST
*)GetNextNode(ListHead
, &Node
->Link
)
278 Size
= StrSize(Node
->Val
);
279 if (Node
->Atts
& EFI_VARIABLE_NON_VOLATILE
) {
280 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_NV(Node
->Key
, Size
, Node
->Val
);
282 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V (Node
->Key
, Size
, Node
->Val
);
284 ASSERT_EFI_ERROR(Status
);
286 FreeEnvironmentVariableList(ListHead
);
292 sets a list of all Shell-Guid-based environment variables.
294 @param Environment Points to a NULL-terminated array of environment
295 variables with the format 'x=y', where x is the
296 environment variable name and y is the value.
298 @retval EFI_SUCCESS The command executed successfully.
299 @retval EFI_INVALID_PARAMETER The parameter is invalid.
300 @retval EFI_OUT_OF_RESOURCES Out of resources.
302 @sa SetEnvironmentVariableList
306 SetEnvironmentVariables(
307 IN CONST CHAR16
**Environment
310 CONST CHAR16
*CurrentString
;
312 ENV_VAR_LIST
*VarList
;
317 if (Environment
== NULL
) {
318 return (EFI_INVALID_PARAMETER
);
322 // Build a list identical to the ones used for get/set list functions above
324 for ( CurrentCount
= 0
328 CurrentString
= Environment
[CurrentCount
];
329 if (CurrentString
== NULL
) {
332 ASSERT(StrStr(CurrentString
, L
"=") != NULL
);
333 Node
= AllocateZeroPool(sizeof(ENV_VAR_LIST
));
335 SetEnvironmentVariableList(&VarList
->Link
);
336 return (EFI_OUT_OF_RESOURCES
);
339 Node
->Key
= AllocateZeroPool((StrStr(CurrentString
, L
"=") - CurrentString
+ 1) * sizeof(CHAR16
));
340 if (Node
->Key
== NULL
) {
341 SHELL_FREE_NON_NULL(Node
);
342 SetEnvironmentVariableList(&VarList
->Link
);
343 return (EFI_OUT_OF_RESOURCES
);
347 // Copy the string into the Key, leaving the last character allocated as NULL to terminate
350 StrStr(CurrentString
, L
"=") - CurrentString
+ 1,
352 StrStr(CurrentString
, L
"=") - CurrentString
356 // ValueSize = TotalSize - already removed size - size for '=' + size for terminator (the last 2 items cancel each other)
358 Node
->Val
= AllocateCopyPool(StrSize(CurrentString
) - StrSize(Node
->Key
), CurrentString
+ StrLen(Node
->Key
) + 1);
359 if (Node
->Val
== NULL
) {
360 SHELL_FREE_NON_NULL(Node
->Key
);
361 SHELL_FREE_NON_NULL(Node
);
362 SetEnvironmentVariableList(&VarList
->Link
);
363 return (EFI_OUT_OF_RESOURCES
);
366 Node
->Atts
= EFI_VARIABLE_BOOTSERVICE_ACCESS
;
368 if (VarList
== NULL
) {
369 VarList
= AllocateZeroPool(sizeof(ENV_VAR_LIST
));
370 if (VarList
== NULL
) {
371 SHELL_FREE_NON_NULL(Node
->Key
);
372 SHELL_FREE_NON_NULL(Node
->Val
);
373 SHELL_FREE_NON_NULL(Node
);
374 return (EFI_OUT_OF_RESOURCES
);
376 InitializeListHead(&VarList
->Link
);
378 InsertTailList(&VarList
->Link
, &Node
->Link
);
383 // set this new list as the set of all environment variables.
384 // this function also frees the memory and deletes all pre-existing
385 // shell-guid based environment variables.
387 return (SetEnvironmentVariableList(&VarList
->Link
));
391 Find an environment variable in the gShellEnvVarList.
393 @param Key The name of the environment variable.
394 @param Value The value of the environment variable, the buffer
395 shoule be freed by the caller.
396 @param ValueSize The size in bytes of the environment variable
397 including the tailing CHAR_NELL.
398 @param Atts The attributes of the variable.
400 @retval EFI_SUCCESS The command executed successfully.
401 @retval EFI_NOT_FOUND The environment variable is not found in
406 ShellFindEnvVarInList (
407 IN CONST CHAR16
*Key
,
409 OUT UINTN
*ValueSize
,
410 OUT UINT32
*Atts OPTIONAL
415 if (Key
== NULL
|| Value
== NULL
|| ValueSize
== NULL
) {
416 return SHELL_INVALID_PARAMETER
;
419 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
420 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
421 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
423 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
424 *Value
= AllocateCopyPool(StrSize(Node
->Val
), Node
->Val
);
425 *ValueSize
= StrSize(Node
->Val
);
433 return EFI_NOT_FOUND
;
437 Add an environment variable into gShellEnvVarList.
439 @param Key The name of the environment variable.
440 @param Value The value of environment variable.
441 @param ValueSize The size in bytes of the environment variable
442 including the tailing CHAR_NULL
443 @param Atts The attributes of the variable.
445 @retval EFI_SUCCESS The environment variable was added to list successfully.
446 @retval others Some errors happened.
450 ShellAddEnvVarToList (
451 IN CONST CHAR16
*Key
,
452 IN CONST CHAR16
*Value
,
461 if (Key
== NULL
|| Value
== NULL
|| ValueSize
== 0) {
462 return EFI_INVALID_PARAMETER
;
465 LocalValue
= AllocateCopyPool (ValueSize
, Value
);
466 if (LocalValue
== NULL
) {
467 return EFI_OUT_OF_RESOURCES
;
471 // Update the variable value if it exists in gShellEnvVarList.
473 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
474 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
475 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
477 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
479 SHELL_FREE_NON_NULL(Node
->Val
);
480 Node
->Val
= LocalValue
;
486 // If the environment varialbe key doesn't exist in list just insert
489 LocalKey
= AllocateCopyPool (StrSize(Key
), Key
);
490 if (LocalKey
== NULL
) {
491 FreePool (LocalValue
);
492 return EFI_OUT_OF_RESOURCES
;
494 Node
= (ENV_VAR_LIST
*)AllocateZeroPool (sizeof(ENV_VAR_LIST
));
497 FreePool (LocalValue
);
498 return EFI_OUT_OF_RESOURCES
;
500 Node
->Key
= LocalKey
;
501 Node
->Val
= LocalValue
;
503 InsertTailList(&gShellEnvVarList
.Link
, &Node
->Link
);
509 Remove a specified environment variable in gShellEnvVarList.
511 @param Key The name of the environment variable.
513 @retval EFI_SUCCESS The command executed successfully.
514 @retval EFI_NOT_FOUND The environment variable is not found in
518 ShellRemvoeEnvVarFromList (
525 return EFI_INVALID_PARAMETER
;
528 for ( Node
= (ENV_VAR_LIST
*)GetFirstNode(&gShellEnvVarList
.Link
)
529 ; !IsNull(&gShellEnvVarList
.Link
, &Node
->Link
)
530 ; Node
= (ENV_VAR_LIST
*)GetNextNode(&gShellEnvVarList
.Link
, &Node
->Link
)
532 if (Node
->Key
!= NULL
&& StrCmp(Key
, Node
->Key
) == 0) {
533 SHELL_FREE_NON_NULL(Node
->Key
);
534 SHELL_FREE_NON_NULL(Node
->Val
);
535 RemoveEntryList(&Node
->Link
);
536 SHELL_FREE_NON_NULL(Node
);
541 return EFI_NOT_FOUND
;
545 Initialize the gShellEnvVarList and cache all Shell-Guid-based environment
550 ShellInitEnvVarList (
556 InitializeListHead(&gShellEnvVarList
.Link
);
557 Status
= GetEnvironmentVariableList (&gShellEnvVarList
.Link
);
563 Destructe the gShellEnvVarList.
567 ShellFreeEnvVarList (
571 FreeEnvironmentVariableList (&gShellEnvVarList
.Link
);
572 InitializeListHead(&gShellEnvVarList
.Link
);