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