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