• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*++
2 
3 Copyright (c) 2005, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 Module Name:
13   IfrVariable.c
14 
15 Abstract:
16   Variable/Map manipulations routines
17 
18 --*/
19 
20 #include "IfrLibrary.h"
21 
22 VOID
EfiLibHiiVariablePackGetMap(IN EFI_HII_VARIABLE_PACK * Pack,OUT CHAR16 ** Name,OPTIONAL OUT EFI_GUID ** Guid,OPTIONAL OUT UINT16 * Id,OPTIONAL OUT VOID ** Var,OPTIONAL OUT UINTN * Size OPTIONAL)23 EfiLibHiiVariablePackGetMap (
24   IN    EFI_HII_VARIABLE_PACK       *Pack,
25   OUT   CHAR16                      **Name,  OPTIONAL
26   OUT   EFI_GUID                    **Guid,  OPTIONAL
27   OUT   UINT16                      *Id,     OPTIONAL
28   OUT   VOID                        **Var,   OPTIONAL
29   OUT   UINTN                       *Size    OPTIONAL
30   )
31 /*++
32 
33 Routine Description:
34 
35   Extracts a variable form a Pack.
36 
37 Arguments:
38 
39   Pack - List of variables
40   Name - Name of the variable/map
41   Guid - GUID of the variable/map
42   Var  - Pointer to the variable/map
43   Size - Size of the variable/map in bytes
44 
45 Returns:
46 
47   VOID
48 
49 --*/
50 {
51   if (NULL != Name) {
52     *Name = (VOID *) (Pack + 1);
53   }
54 
55   if (NULL != Guid) {
56     *Guid = &Pack->VariableGuid;
57   }
58 
59 
60   if (NULL != Id) {
61     *Id   = Pack->VariableId;
62   }
63 
64   if (NULL != Var) {
65     *Var  = (VOID *) ((CHAR8 *) (Pack + 1) + Pack->VariableNameLength);
66   }
67 
68   if (NULL != Size) {
69     *Size = Pack->Header.Length - sizeof (*Pack) - Pack->VariableNameLength;
70   }
71 }
72 
73 
74 UINTN
EfiLibHiiVariablePackListGetMapCnt(IN EFI_HII_VARIABLE_PACK_LIST * List)75 EfiLibHiiVariablePackListGetMapCnt (
76   IN    EFI_HII_VARIABLE_PACK_LIST   *List
77   )
78 
79 /*++
80 
81 Routine Description:
82 
83   Finds a count of the variables/maps in the List.
84 
85 Arguments:
86 
87   List - List of variables
88 
89 Returns:
90 
91   UINTN - The number of map count.
92 
93 --*/
94 
95 {
96   UINTN   Cnt = 0;
97   while (NULL != List) {
98     Cnt++;
99     List = List->NextVariablePack;
100   }
101   return Cnt;
102 }
103 
104 
105 VOID
EfiLibHiiVariablePackListForEachVar(IN EFI_HII_VARIABLE_PACK_LIST * List,IN EFI_LIB_HII_VARIABLE_PACK_LIST_CALLBACK * Callback)106 EfiLibHiiVariablePackListForEachVar (
107   IN    EFI_HII_VARIABLE_PACK_LIST               *List,
108   IN    EFI_LIB_HII_VARIABLE_PACK_LIST_CALLBACK  *Callback
109   )
110 /*++
111 
112 Routine Description:
113 
114   Will iterate all variable/maps as appearing
115   in List and for each, it will call the Callback.
116 
117 Arguments:
118 
119   List     - List of variables
120   Callback - Routine to be called for each iterated variable.
121 
122 Returns:
123 
124   VOID
125 
126 --*/
127 
128 {
129   CHAR16    *MapName;
130   EFI_GUID  *MapGuid;
131   UINT16    MapId;
132   VOID      *Map;
133   UINTN     MapSize;
134 
135   while (NULL != List) {
136     EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);
137     //
138     // call the callback
139     //
140     Callback (MapName, MapGuid, MapId, Map, MapSize);
141     List = List->NextVariablePack;
142   }
143 }
144 
145 
146 EFI_STATUS
EfiLibHiiVariablePackListGetMapByIdx(IN UINTN Idx,IN EFI_HII_VARIABLE_PACK_LIST * List,OUT CHAR16 ** Name,OPTIONAL OUT EFI_GUID ** Guid,OPTIONAL OUT UINT16 * Id,OPTIONAL OUT VOID ** Var,OUT UINTN * Size)147 EfiLibHiiVariablePackListGetMapByIdx (
148   IN    UINTN                       Idx,
149   IN    EFI_HII_VARIABLE_PACK_LIST  *List,
150   OUT   CHAR16                      **Name,  OPTIONAL
151   OUT   EFI_GUID                    **Guid,  OPTIONAL
152   OUT   UINT16                      *Id,     OPTIONAL
153   OUT   VOID                        **Var,
154   OUT   UINTN                       *Size
155   )
156 
157 /*++
158 
159 Routine Description:
160 
161   Finds a variable form List given
162   the order number as appears in the List.
163 
164 Arguments:
165 
166   Idx  - The index of the variable/map to retrieve
167   List - List of variables
168   Name - Name of the variable/map
169   Guid - GUID of the variable/map
170   Var  - Pointer to the variable/map
171   Size - Size of the variable/map in bytes
172 
173 Returns:
174 
175   EFI_SUCCESS   - Variable is found, OUT parameters are valid
176   EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid
177 
178 --*/
179 {
180   CHAR16     *MapName;
181   EFI_GUID   *MapGuid;
182   UINT16     MapId;
183   VOID       *Map;
184   UINTN      MapSize;
185 
186   while (NULL != List) {
187     EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);
188     if (0 == Idx--) {
189       *Var  = Map;
190       *Size = MapSize;
191 
192       if (NULL != Name) {
193         *Name = MapName;
194       }
195 
196       if (NULL != Guid) {
197         *Guid = MapGuid;
198       }
199 
200       if (NULL != Id) {
201         *Id   = MapId;
202       }
203 
204       return EFI_SUCCESS; // Map found
205     }
206     List = List->NextVariablePack;
207   }
208   //
209   // If here, the map is not found
210   //
211   return EFI_NOT_FOUND;
212 }
213 
214 
215 EFI_STATUS
EfiLibHiiVariablePackListGetMapById(IN UINT16 Id,IN EFI_HII_VARIABLE_PACK_LIST * List,OUT CHAR16 ** Name,OPTIONAL OUT EFI_GUID ** Guid,OPTIONAL OUT VOID ** Var,OUT UINTN * Size)216 EfiLibHiiVariablePackListGetMapById (
217   IN    UINT16                        Id,
218   IN    EFI_HII_VARIABLE_PACK_LIST    *List,
219   OUT   CHAR16                        **Name,  OPTIONAL
220   OUT   EFI_GUID                      **Guid,  OPTIONAL
221   OUT   VOID                          **Var,
222   OUT   UINTN                         *Size
223   )
224 
225 /*++
226 
227 Routine Description:
228 
229   Finds a variable form List given the
230   order number as appears in the List.
231 
232 Arguments:
233 
234   Id   - The ID of the variable/map to retrieve
235   List - List of variables
236   Name - Name of the variable/map
237   Guid - GUID of the variable/map
238   Var  - Pointer to the variable/map
239   Size - Size of the variable/map in bytes
240 
241 Returns:
242 
243   EFI_SUCCESS   - Variable is found, OUT parameters are valid
244   EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid
245 
246 --*/
247 
248 {
249   CHAR16    *MapName;
250   EFI_GUID  *MapGuid;
251   UINT16    MapId;
252   VOID      *Map;
253   UINTN     MapSize;
254 
255   while (NULL != List) {
256     EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);
257     if (MapId == Id) {
258       *Var  = Map;
259       *Size = MapSize;
260       if (NULL != Name) {
261          *Name = MapName;
262       }
263       if (NULL != Guid) {
264         *Guid = MapGuid;
265       }
266       //
267       // Map found
268       //
269       return EFI_SUCCESS;
270     }
271     List = List->NextVariablePack;
272   }
273   //
274   // If here, the map is not found
275   //
276   return EFI_NOT_FOUND;
277 }
278 
279 
280 EFI_STATUS
EfiLibHiiVariablePackListGetMap(IN EFI_HII_VARIABLE_PACK_LIST * List,IN CHAR16 * Name,IN EFI_GUID * Guid,OUT UINT16 * Id,OUT VOID ** Var,OUT UINTN * Size)281 EfiLibHiiVariablePackListGetMap (
282   IN    EFI_HII_VARIABLE_PACK_LIST   *List,
283   IN    CHAR16                       *Name,
284   IN    EFI_GUID                     *Guid,
285   OUT   UINT16                       *Id,
286   OUT   VOID                         **Var,
287   OUT   UINTN                        *Size
288   )
289 
290 /*++
291 
292 Routine Description:
293 
294   Finds a variable form EFI_HII_VARIABLE_PACK_LIST given name and GUID.
295 
296 Arguments:
297 
298   List - List of variables
299   Name - Name of the variable/map to be found
300   Guid - GUID of the variable/map to be found
301   Var  - Pointer to the variable/map found
302   Size - Size of the variable/map in bytes found
303 
304 Returns:
305 
306   EFI_SUCCESS   - variable is found, OUT parameters are valid
307   EFI_NOT_FOUND - variable is not found, OUT parameters are not valid
308 
309 --*/
310 
311 {
312   VOID      *Map;
313   UINTN     MapSize;
314   UINT16    MapId;
315   CHAR16    *MapName;
316   EFI_GUID  *MapGuid;
317 
318   while (NULL != List) {
319     EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);
320     if ((0 == EfiStrCmp (Name, MapName)) && EfiCompareGuid (Guid, MapGuid)) {
321       *Id   = MapId;
322       *Var  = Map;
323       *Size = MapSize;
324       return EFI_SUCCESS;
325     }
326     List = List->NextVariablePack;
327   }
328   //
329   // If here, the map is not found
330   //
331   return EFI_NOT_FOUND;
332 }
333 
334 EFI_STATUS
EfiLibHiiVariableRetrieveFromNv(IN CHAR16 * Name,IN EFI_GUID * Guid,IN UINTN Size,OUT VOID ** Var)335 EfiLibHiiVariableRetrieveFromNv (
336   IN  CHAR16                 *Name,
337   IN  EFI_GUID               *Guid,
338   IN  UINTN                   Size,
339   OUT VOID                  **Var
340   )
341 /*++
342 
343 Routine Description:
344   Finds out if a variable of specific Name/Guid/Size exists in NV.
345   If it does, it will retrieve it into the Var.
346 
347 Arguments:
348   Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.
349   Var              - Variable will be retrieved into buffer pointed by this pointer.
350                      If pointing to NULL, the buffer will be allocated. Caller is responsible for releasing the buffer.
351 Returns:
352   EFI_SUCCESS    - The variable of exact Name/Guid/Size parameters was retrieved and written to Var.
353   EFI_NOT_FOUND  - The variable of this Name/Guid was not found in the NV.
354   EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.
355 
356 --*/
357 {
358   EFI_STATUS                  Status;
359   UINTN                       SizeNv;
360 
361   //
362   // Test for existence of the variable.
363   //
364   SizeNv = 0;
365   Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, NULL);
366   if (EFI_BUFFER_TOO_SMALL != Status) {
367     ASSERT (EFI_SUCCESS != Status);
368     return EFI_NOT_FOUND;
369   }
370   if (SizeNv != Size) {
371     //
372     // The variable is considered corrupt, as it has different size from expected.
373     //
374     return EFI_LOAD_ERROR;
375   }
376 
377   if (NULL == *Var) {
378     *Var = EfiLibAllocatePool (Size);
379     ASSERT (NULL != *Var);
380   }
381   SizeNv = Size;
382   //
383   // Final read into the Var
384   //
385   Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, *Var);
386   //
387   // No tolerance for random failures. Such behavior is undetermined and not validated.
388   //
389   ASSERT_EFI_ERROR (Status);
390   ASSERT (SizeNv == Size);
391   return EFI_SUCCESS;
392 }
393 
394 
395 
396 EFI_STATUS
EfiLibHiiVariableOverrideIfSuffix(IN CHAR16 * Suffix,IN CHAR16 * Name,IN EFI_GUID * Guid,IN UINTN Size,OUT VOID * Var)397 EfiLibHiiVariableOverrideIfSuffix (
398   IN  CHAR16                 *Suffix,
399   IN  CHAR16                 *Name,
400   IN  EFI_GUID               *Guid,
401   IN  UINTN                   Size,
402   OUT VOID                   *Var
403   )
404 /*++
405 
406 Routine Description:
407   Overrrides the variable with NV data if found.
408   But it only does it if the Name ends with specified Suffix.
409   For example, if Suffix="MyOverride" and the Name="XyzSetupMyOverride",
410   the Suffix matches the end of Name, so the variable will be loaded from NV
411   provided the variable exists and the GUID and Size matches.
412 
413 Arguments:
414   Suffix           - Suffix the Name should end with.
415   Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.
416   Var              - Variable will be retrieved into this buffer.
417                      Caller is responsible for providing storage of exactly Size size in bytes.
418 Returns:
419   EFI_SUCCESS           - The variable was overriden with NV variable of same Name/Guid/Size.
420   EFI_INVALID_PARAMETER - The name of the variable does not end with <Suffix>.
421   EFI_NOT_FOUND         - The variable of this Name/Guid was not found in the NV.
422   EFI_LOAD_ERROR        - The variable in the NV was of different size, or NV API returned error.
423 
424 --*/
425 {
426   UINTN         StrLen;
427   UINTN         StrLenSuffix;
428 
429   StrLen       = EfiStrLen (Name);
430   StrLenSuffix = EfiStrLen (Suffix);
431   if ((StrLen <= StrLenSuffix) || (0 != EfiStrCmp (Suffix, &Name[StrLen - StrLenSuffix]))) {
432     //
433     // Not ending with <Suffix>.
434     //
435     return EFI_INVALID_PARAMETER;
436   }
437   return EfiLibHiiVariableRetrieveFromNv (Name, Guid, Size, &Var);
438 }
439 
440 
441 
442 EFI_STATUS
EfiLibHiiVariableOverrideBySuffix(IN CHAR16 * Suffix,IN CHAR16 * Name,IN EFI_GUID * Guid,IN UINTN Size,OUT VOID * Var)443 EfiLibHiiVariableOverrideBySuffix (
444   IN  CHAR16                 *Suffix,
445   IN  CHAR16                 *Name,
446   IN  EFI_GUID               *Guid,
447   IN  UINTN                   Size,
448   OUT VOID                   *Var
449   )
450 /*++
451 
452 Routine Description:
453   Overrrides the variable with NV data if found.
454   But it only does it if the NV contains the same variable with Name is appended with Suffix.
455   For example, if Suffix="MyOverride" and the Name="XyzSetup",
456   the Suffix will be appended to the end of Name, and the variable with Name="XyzSetupMyOverride"
457   will be loaded from NV provided the variable exists and the GUID and Size matches.
458 
459 Arguments:
460   Suffix           - Suffix the variable will be appended with.
461   Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.
462   Var              - Variable will be retrieved into this buffer.
463                      Caller is responsible for providing storage of exactly Size size in bytes.
464 
465 Returns:
466   EFI_SUCCESS    - The variable was overriden with NV variable of same Name/Guid/Size.
467   EFI_NOT_FOUND  - The variable of this Name/Guid was not found in the NV.
468   EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.
469 
470 --*/
471 {
472   EFI_STATUS    Status;
473   CHAR16       *NameSuffixed;
474   UINTN         NameLength;
475   UINTN         SuffixLength;
476 
477   //
478   // enough to concatenate both strings.
479   //
480   NameLength   = EfiStrLen (Name);
481   SuffixLength = EfiStrLen (Suffix);
482   NameSuffixed = EfiLibAllocateZeroPool ((NameLength + SuffixLength + 1) * sizeof (CHAR16));
483 
484   EfiStrCpy (NameSuffixed, Name);
485   EfiStrCat (NameSuffixed, Suffix);
486 
487   Status = EfiLibHiiVariableRetrieveFromNv (NameSuffixed, Guid, Size, &Var);
488   gBS->FreePool (NameSuffixed);
489 
490   return Status;
491 }
492 
493