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