]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Application/Shell/ShellEnvVar.c
ArmPlatformPkg: Fix ARMGCC build
[mirror_edk2.git] / ShellPkg / Application / Shell / ShellEnvVar.c
CommitLineData
a405b86d 1/** @file\r
2 function declarations for shell environment functions.\r
3\r
733f138d 4 Copyright (c) 2009 - 2011, 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
15#include <Uefi.h>\r
8be0ba36 16#include <ShellBase.h>\r
a405b86d 17\r
18#include <Guid/ShellVariableGuid.h>\r
19\r
20#include <Library/BaseLib.h>\r
21#include <Library/UefiRuntimeServicesTableLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/BaseMemoryLib.h>\r
25\r
26#include "ShellEnvVar.h"\r
27\r
a405b86d 28/**\r
29 Reports whether an environment variable is Volatile or Non-Volatile.\r
30\r
31 @param EnvVarName The name of the environment variable in question\r
32\r
33 @retval TRUE This environment variable is Volatile\r
34 @retval FALSE This environment variable is NON-Volatile\r
35**/\r
36BOOLEAN\r
37EFIAPI\r
38IsVolatileEnv (\r
39 IN CONST CHAR16 *EnvVarName\r
40 )\r
41{\r
42 EFI_STATUS Status;\r
43 UINTN Size;\r
44 VOID *Buffer;\r
45 UINT32 Attribs;\r
46\r
47 Size = 0;\r
48 Buffer = NULL;\r
49\r
50 //\r
51 // get the variable\r
52 //\r
53 Status = gRT->GetVariable((CHAR16*)EnvVarName,\r
54 &gShellVariableGuid,\r
55 &Attribs,\r
56 &Size,\r
57 Buffer);\r
58 if (Status == EFI_BUFFER_TOO_SMALL) {\r
733f138d 59 Buffer = AllocateZeroPool(Size);\r
a405b86d 60 ASSERT(Buffer != NULL);\r
61 Status = gRT->GetVariable((CHAR16*)EnvVarName,\r
62 &gShellVariableGuid,\r
63 &Attribs,\r
64 &Size,\r
65 Buffer);\r
66 FreePool(Buffer);\r
67 }\r
68 //\r
69 // not found means volatile\r
70 //\r
71 if (Status == EFI_NOT_FOUND) {\r
72 return (TRUE);\r
73 }\r
74 ASSERT_EFI_ERROR(Status);\r
75\r
76 //\r
77 // check for the Non Volatile bit\r
78 //\r
79 if ((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE) {\r
80 return (FALSE);\r
81 }\r
82\r
83 //\r
84 // everything else is volatile\r
85 //\r
86 return (TRUE);\r
87}\r
88\r
89/**\r
90 free function for ENV_VAR_LIST objects.\r
91\r
92 @param[in] List The pointer to pointer to list.\r
93**/\r
94VOID\r
95EFIAPI\r
96FreeEnvironmentVariableList(\r
97 IN LIST_ENTRY *List\r
98 )\r
99{\r
100 ENV_VAR_LIST *Node;\r
101\r
102 ASSERT (List != NULL);\r
103 if (List == NULL) {\r
104 return;\r
105 }\r
106\r
107 for ( Node = (ENV_VAR_LIST*)GetFirstNode(List)\r
108 ; IsListEmpty(List)\r
109 ; Node = (ENV_VAR_LIST*)GetFirstNode(List)\r
110 ){\r
111 ASSERT(Node != NULL);\r
112 RemoveEntryList(&Node->Link);\r
113 if (Node->Key != NULL) {\r
114 FreePool(Node->Key);\r
115 }\r
116 if (Node->Val != NULL) {\r
117 FreePool(Node->Val);\r
118 }\r
119 FreePool(Node);\r
120 }\r
121}\r
122\r
123/**\r
124 Creates a list of all Shell-Guid-based environment variables.\r
125\r
126 @param[in,out] ListHead The pointer to pointer to LIST ENTRY object for\r
127 storing this list.\r
128\r
129 @retval EFI_SUCCESS the list was created sucessfully.\r
130**/\r
131EFI_STATUS\r
132EFIAPI\r
133GetEnvironmentVariableList(\r
134 IN OUT LIST_ENTRY *ListHead\r
135 )\r
136{\r
137 CHAR16 *VariableName;\r
138 UINTN NameSize;\r
139 UINT64 MaxStorSize;\r
140 UINT64 RemStorSize;\r
141 UINT64 MaxVarSize;\r
142 EFI_STATUS Status;\r
143 EFI_GUID Guid;\r
144 UINTN ValSize;\r
145 ENV_VAR_LIST *VarList;\r
146\r
3c865f20 147 if (ListHead == NULL) {\r
148 return (EFI_INVALID_PARAMETER);\r
149 }\r
a405b86d 150\r
a7a394a4 151 if (gRT->Hdr.Revision >= EFI_2_00_SYSTEM_TABLE_REVISION) {\r
152 Status = gRT->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS, &MaxStorSize, &RemStorSize, &MaxVarSize);\r
153 if (EFI_ERROR(Status)) {\r
154 return (Status);\r
155 }\r
156 } else {\r
157 MaxVarSize = 16384;\r
3c865f20 158 }\r
a405b86d 159\r
160 NameSize = (UINTN)MaxVarSize;\r
733f138d 161 VariableName = AllocateZeroPool(NameSize);\r
3c865f20 162 if (VariableName == NULL) {\r
163 return (EFI_OUT_OF_RESOURCES);\r
164 }\r
a405b86d 165 StrCpy(VariableName, L"");\r
166\r
3c865f20 167 while (!EFI_ERROR(Status)) {\r
a405b86d 168 NameSize = (UINTN)MaxVarSize;\r
169 Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);\r
170 if (Status == EFI_NOT_FOUND){\r
171 Status = EFI_SUCCESS;\r
172 break;\r
173 }\r
3c865f20 174 if (!EFI_ERROR(Status) && CompareGuid(&Guid, &gShellVariableGuid)){\r
a405b86d 175 VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));\r
8be0ba36 176 if (VarList == NULL) {\r
177 Status = EFI_OUT_OF_RESOURCES;\r
178 } else {\r
179 ValSize = 0;\r
a405b86d 180 Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);\r
8be0ba36 181 if (Status == EFI_BUFFER_TOO_SMALL){\r
733f138d 182 VarList->Val = AllocateZeroPool(ValSize);\r
8be0ba36 183 if (VarList->Val == NULL) {\r
184 SHELL_FREE_NON_NULL(VarList);\r
185 Status = EFI_OUT_OF_RESOURCES;\r
186 } else {\r
187 Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);\r
188 }\r
189 }\r
c154b997 190 if (!EFI_ERROR(Status) && VarList != NULL) {\r
733f138d 191 VarList->Key = AllocateZeroPool(StrSize(VariableName));\r
8be0ba36 192 if (VarList->Key == NULL) {\r
193 SHELL_FREE_NON_NULL(VarList->Val);\r
194 SHELL_FREE_NON_NULL(VarList);\r
195 Status = EFI_OUT_OF_RESOURCES;\r
196 } else {\r
197 StrCpy(VarList->Key, VariableName);\r
198 InsertTailList(ListHead, &VarList->Link);\r
199 }\r
200 }\r
3c865f20 201 }\r
a405b86d 202 } // compare guid\r
203 } // while\r
204 FreePool(VariableName);\r
205\r
206 if (EFI_ERROR(Status)) {\r
207 FreeEnvironmentVariableList(ListHead);\r
208 }\r
209\r
210 return (Status);\r
211}\r
212\r
213/**\r
214 Sets a list of all Shell-Guid-based environment variables. this will\r
215 also eliminate all existing shell environment variables (even if they\r
216 are not on the list).\r
217\r
218 This function will also deallocate the memory from List.\r
219\r
220 @param[in] ListHead The pointer to LIST_ENTRY from\r
221 GetShellEnvVarList().\r
222\r
223 @retval EFI_SUCCESS the list was Set sucessfully.\r
224**/\r
225EFI_STATUS\r
226EFIAPI\r
227SetEnvironmentVariableList(\r
228 IN LIST_ENTRY *ListHead\r
229 )\r
230{\r
231 ENV_VAR_LIST VarList;\r
232 ENV_VAR_LIST *Node;\r
233 EFI_STATUS Status;\r
234 UINTN Size;\r
235\r
236 InitializeListHead(&VarList.Link);\r
237\r
238 //\r
239 // Delete all the current environment variables\r
240 //\r
241 Status = GetEnvironmentVariableList(&VarList.Link);\r
242 ASSERT_EFI_ERROR(Status);\r
243\r
244 for ( Node = (ENV_VAR_LIST*)GetFirstNode(&VarList.Link)\r
245 ; !IsNull(&VarList.Link, &Node->Link)\r
246 ; Node = (ENV_VAR_LIST*)GetNextNode(&VarList.Link, &Node->Link)\r
247 ){\r
248 if (Node->Key != NULL) {\r
249 Status = SHELL_DELETE_ENVIRONMENT_VARIABLE(Node->Key);\r
250 }\r
251 ASSERT_EFI_ERROR(Status);\r
252 }\r
253\r
254 FreeEnvironmentVariableList(&VarList.Link);\r
255\r
256 //\r
257 // set all the variables fron the list\r
258 //\r
259 for ( Node = (ENV_VAR_LIST*)GetFirstNode(ListHead)\r
260 ; !IsNull(ListHead, &Node->Link)\r
261 ; Node = (ENV_VAR_LIST*)GetNextNode(ListHead, &Node->Link)\r
262 ){\r
263 Size = StrSize(Node->Val);\r
264 if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) {\r
265 Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(Node->Key, Size, Node->Val);\r
266 } else {\r
267 Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (Node->Key, Size, Node->Val);\r
268 }\r
269 ASSERT_EFI_ERROR(Status);\r
270 }\r
271 FreeEnvironmentVariableList(ListHead);\r
272\r
273 return (Status);\r
274}\r
275\r
276/**\r
277 sets a list of all Shell-Guid-based environment variables.\r
278\r
279 @param Environment Points to a NULL-terminated array of environment\r
280 variables with the format 'x=y', where x is the\r
281 environment variable name and y is the value.\r
282\r
283 @retval EFI_SUCCESS The command executed successfully.\r
284 @retval EFI_INVALID_PARAMETER The parameter is invalid.\r
285 @retval EFI_OUT_OF_RESOURCES Out of resources.\r
286\r
287 @sa SetEnvironmentVariableList\r
288**/\r
289EFI_STATUS\r
290EFIAPI\r
291SetEnvironmentVariables(\r
292 IN CONST CHAR16 **Environment\r
293 )\r
294{\r
295 CONST CHAR16 *CurrentString;\r
296 UINTN CurrentCount;\r
297 ENV_VAR_LIST *VarList;\r
298 ENV_VAR_LIST *Node;\r
299 UINTN NewSize;\r
300\r
301 VarList = NULL;\r
302\r
303 if (Environment == NULL) {\r
304 return (EFI_INVALID_PARAMETER);\r
305 }\r
306\r
307 //\r
308 // Build a list identical to the ones used for get/set list functions above\r
309 //\r
310 for ( CurrentCount = 0\r
311 ;\r
312 ; CurrentCount++\r
313 ){\r
314 CurrentString = Environment[CurrentCount];\r
315 if (CurrentString == NULL) {\r
316 break;\r
317 }\r
318 ASSERT(StrStr(CurrentString, L"=") != NULL);\r
733f138d 319 Node = AllocateZeroPool(sizeof(ENV_VAR_LIST));\r
a405b86d 320 ASSERT(Node != NULL);\r
321 Node->Key = AllocateZeroPool((StrStr(CurrentString, L"=") - CurrentString + 1) * sizeof(CHAR16));\r
322 ASSERT(Node->Key != NULL);\r
323 StrnCpy(Node->Key, CurrentString, StrStr(CurrentString, L"=") - CurrentString);\r
324 NewSize = StrSize(CurrentString);\r
325 NewSize -= StrLen(Node->Key) - 1;\r
326 Node->Val = AllocateZeroPool(NewSize);\r
327 ASSERT(Node->Val != NULL);\r
328 StrCpy(Node->Val, CurrentString + StrLen(Node->Key) + 1);\r
329 Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
330\r
331 if (VarList == NULL) {\r
332 VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));\r
333 ASSERT(VarList != NULL);\r
334 InitializeListHead(&VarList->Link);\r
335 }\r
336 InsertTailList(&VarList->Link, &Node->Link);\r
337\r
338 } // for loop\r
339\r
340 //\r
341 // set this new list as the set of all environment variables.\r
342 // this function also frees the memory and deletes all pre-existing\r
343 // shell-guid based environment variables.\r
344 //\r
345 return (SetEnvironmentVariableList(&VarList->Link));\r
346}\r