]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Application/Shell/ShellEnvVar.c
Refine comments and two code style.
[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 Status = EFI_SUCCESS;
158 MaxVarSize = 16384;
159 }
160
161 NameSize = (UINTN)MaxVarSize;
162 VariableName = AllocateZeroPool(NameSize);
163 if (VariableName == NULL) {
164 return (EFI_OUT_OF_RESOURCES);
165 }
166 StrCpy(VariableName, L"");
167
168 while (!EFI_ERROR(Status)) {
169 NameSize = (UINTN)MaxVarSize;
170 Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);
171 if (Status == EFI_NOT_FOUND){
172 Status = EFI_SUCCESS;
173 break;
174 }
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;
179 } else {
180 ValSize = 0;
181 Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
182 if (Status == EFI_BUFFER_TOO_SMALL){
183 VarList->Val = AllocateZeroPool(ValSize);
184 if (VarList->Val == NULL) {
185 SHELL_FREE_NON_NULL(VarList);
186 Status = EFI_OUT_OF_RESOURCES;
187 } else {
188 Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
189 }
190 }
191 if (!EFI_ERROR(Status) && VarList != NULL) {
192 VarList->Key = AllocateZeroPool(StrSize(VariableName));
193 if (VarList->Key == NULL) {
194 SHELL_FREE_NON_NULL(VarList->Val);
195 SHELL_FREE_NON_NULL(VarList);
196 Status = EFI_OUT_OF_RESOURCES;
197 } else {
198 StrCpy(VarList->Key, VariableName);
199 InsertTailList(ListHead, &VarList->Link);
200 }
201 }
202 }
203 } // compare guid
204 } // while
205 FreePool(VariableName);
206
207 if (EFI_ERROR(Status)) {
208 FreeEnvironmentVariableList(ListHead);
209 }
210
211 return (Status);
212 }
213
214 /**
215 Sets a list of all Shell-Guid-based environment variables. this will
216 also eliminate all existing shell environment variables (even if they
217 are not on the list).
218
219 This function will also deallocate the memory from List.
220
221 @param[in] ListHead The pointer to LIST_ENTRY from
222 GetShellEnvVarList().
223
224 @retval EFI_SUCCESS the list was Set sucessfully.
225 **/
226 EFI_STATUS
227 EFIAPI
228 SetEnvironmentVariableList(
229 IN LIST_ENTRY *ListHead
230 )
231 {
232 ENV_VAR_LIST VarList;
233 ENV_VAR_LIST *Node;
234 EFI_STATUS Status;
235 UINTN Size;
236
237 InitializeListHead(&VarList.Link);
238
239 //
240 // Delete all the current environment variables
241 //
242 Status = GetEnvironmentVariableList(&VarList.Link);
243 ASSERT_EFI_ERROR(Status);
244
245 for ( Node = (ENV_VAR_LIST*)GetFirstNode(&VarList.Link)
246 ; !IsNull(&VarList.Link, &Node->Link)
247 ; Node = (ENV_VAR_LIST*)GetNextNode(&VarList.Link, &Node->Link)
248 ){
249 if (Node->Key != NULL) {
250 Status = SHELL_DELETE_ENVIRONMENT_VARIABLE(Node->Key);
251 }
252 ASSERT_EFI_ERROR(Status);
253 }
254
255 FreeEnvironmentVariableList(&VarList.Link);
256
257 //
258 // set all the variables fron the list
259 //
260 for ( Node = (ENV_VAR_LIST*)GetFirstNode(ListHead)
261 ; !IsNull(ListHead, &Node->Link)
262 ; Node = (ENV_VAR_LIST*)GetNextNode(ListHead, &Node->Link)
263 ){
264 Size = StrSize(Node->Val);
265 if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) {
266 Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(Node->Key, Size, Node->Val);
267 } else {
268 Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (Node->Key, Size, Node->Val);
269 }
270 ASSERT_EFI_ERROR(Status);
271 }
272 FreeEnvironmentVariableList(ListHead);
273
274 return (Status);
275 }
276
277 /**
278 sets a list of all Shell-Guid-based environment variables.
279
280 @param Environment Points to a NULL-terminated array of environment
281 variables with the format 'x=y', where x is the
282 environment variable name and y is the value.
283
284 @retval EFI_SUCCESS The command executed successfully.
285 @retval EFI_INVALID_PARAMETER The parameter is invalid.
286 @retval EFI_OUT_OF_RESOURCES Out of resources.
287
288 @sa SetEnvironmentVariableList
289 **/
290 EFI_STATUS
291 EFIAPI
292 SetEnvironmentVariables(
293 IN CONST CHAR16 **Environment
294 )
295 {
296 CONST CHAR16 *CurrentString;
297 UINTN CurrentCount;
298 ENV_VAR_LIST *VarList;
299 ENV_VAR_LIST *Node;
300 UINTN NewSize;
301
302 VarList = NULL;
303
304 if (Environment == NULL) {
305 return (EFI_INVALID_PARAMETER);
306 }
307
308 //
309 // Build a list identical to the ones used for get/set list functions above
310 //
311 for ( CurrentCount = 0
312 ;
313 ; CurrentCount++
314 ){
315 CurrentString = Environment[CurrentCount];
316 if (CurrentString == NULL) {
317 break;
318 }
319 ASSERT(StrStr(CurrentString, L"=") != NULL);
320 Node = AllocateZeroPool(sizeof(ENV_VAR_LIST));
321 ASSERT(Node != NULL);
322 Node->Key = AllocateZeroPool((StrStr(CurrentString, L"=") - CurrentString + 1) * sizeof(CHAR16));
323 ASSERT(Node->Key != NULL);
324 StrnCpy(Node->Key, CurrentString, StrStr(CurrentString, L"=") - CurrentString);
325 NewSize = StrSize(CurrentString);
326 NewSize -= StrLen(Node->Key) - 1;
327 Node->Val = AllocateZeroPool(NewSize);
328 ASSERT(Node->Val != NULL);
329 StrCpy(Node->Val, CurrentString + StrLen(Node->Key) + 1);
330 Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS;
331
332 if (VarList == NULL) {
333 VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));
334 ASSERT(VarList != NULL);
335 InitializeListHead(&VarList->Link);
336 }
337 InsertTailList(&VarList->Link, &Node->Link);
338
339 } // for loop
340
341 //
342 // set this new list as the set of all environment variables.
343 // this function also frees the memory and deletes all pre-existing
344 // shell-guid based environment variables.
345 //
346 return (SetEnvironmentVariableList(&VarList->Link));
347 }