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