]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkPkg/Library/FrameworkIfrSupportLib/IfrVariable.c
Add dependency of MdeModulePkg since HiiLib has been moved to MdeModulePkg.
[mirror_edk2.git] / IntelFrameworkPkg / Library / FrameworkIfrSupportLib / IfrVariable.c
1 /** @file
2 Variable/Map manipulations routines
3
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. 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 "IfrSupportLibInternal.h"
16
17 /**
18 Extracts a variable form a Pack.
19
20 @param Pack - List of variables
21 @param Name - Name of the variable/map
22 @param Guid - GUID of the variable/map
23 @param Id - The index of the variable/map to retrieve
24 @param Var - Pointer to the variable/map
25 @param Size - Size of the variable/map in bytes
26 **/
27 VOID
28 EfiLibHiiVariablePackGetMap (
29 IN EFI_HII_VARIABLE_PACK *Pack,
30 OUT CHAR16 **Name, OPTIONAL
31 OUT EFI_GUID **Guid, OPTIONAL
32 OUT UINT16 *Id, OPTIONAL
33 OUT VOID **Var, OPTIONAL
34 OUT UINTN *Size OPTIONAL
35 )
36
37 {
38 if (NULL != Name) {
39 *Name = (VOID *) (Pack + 1);
40 }
41
42 if (NULL != Guid) {
43 *Guid = (EFI_GUID *)(UINTN)&Pack->VariableGuid;
44 }
45
46
47 if (NULL != Id) {
48 *Id = Pack->VariableId;
49 }
50
51 if (NULL != Var) {
52 *Var = (VOID *) ((CHAR8 *) (Pack + 1) + Pack->VariableNameLength);
53 }
54
55 if (NULL != Size) {
56 *Size = Pack->Header.Length - sizeof (*Pack) - Pack->VariableNameLength;
57 }
58 }
59
60 /**
61 Finds a count of the variables/maps in the List.
62
63 @param List - List of variables
64
65 @return The number of map count.
66 **/
67 UINTN
68 EfiLibHiiVariablePackListGetMapCnt (
69 IN EFI_HII_VARIABLE_PACK_LIST *List
70 )
71 {
72 UINTN Cnt = 0;
73 while (NULL != List) {
74 Cnt++;
75 List = List->NextVariablePack;
76 }
77 return Cnt;
78 }
79
80 /**
81 Will iterate all variable/maps as appearing
82 in List and for each, it will call the Callback.
83
84 @param List - List of variables
85 @param Callback - Routine to be called for each iterated variable.
86
87 **/
88 VOID
89 EfiLibHiiVariablePackListForEachVar (
90 IN EFI_HII_VARIABLE_PACK_LIST *List,
91 IN EFI_LIB_HII_VARIABLE_PACK_LIST_CALLBACK *Callback
92 )
93
94
95 {
96 CHAR16 *MapName;
97 EFI_GUID *MapGuid;
98 UINT16 MapId;
99 VOID *Map;
100 UINTN MapSize;
101
102 while (NULL != List) {
103 EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);
104 //
105 // call the callback
106 //
107 Callback (MapName, MapGuid, MapId, Map, MapSize);
108 List = List->NextVariablePack;
109 }
110 }
111
112 /**
113 Finds a variable form List given
114 the order number as appears in the List.
115
116 @param Idx - The index of the variable/map to retrieve
117 @param List - List of variables
118 @param Name - Name of the variable/map
119 @param Guid - GUID of the variable/map
120 @param Id - Id of the variable/map
121 @param Var - Pointer to the variable/map
122 @param Size - Size of the variable/map in bytes
123
124 @return EFI_SUCCESS - Variable is found, OUT parameters are valid
125 @return EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid
126 **/
127 EFI_STATUS
128 EfiLibHiiVariablePackListGetMapByIdx (
129 IN UINTN Idx,
130 IN EFI_HII_VARIABLE_PACK_LIST *List,
131 OUT CHAR16 **Name, OPTIONAL
132 OUT EFI_GUID **Guid, OPTIONAL
133 OUT UINT16 *Id, OPTIONAL
134 OUT VOID **Var,
135 OUT UINTN *Size
136 )
137
138
139 {
140 CHAR16 *MapName;
141 EFI_GUID *MapGuid;
142 UINT16 MapId;
143 VOID *Map;
144 UINTN MapSize;
145
146 while (NULL != List) {
147 EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);
148 if (0 == Idx--) {
149 *Var = Map;
150 *Size = MapSize;
151
152 if (NULL != Name) {
153 *Name = MapName;
154 }
155
156 if (NULL != Guid) {
157 *Guid = MapGuid;
158 }
159
160 if (NULL != Id) {
161 *Id = MapId;
162 }
163
164 return EFI_SUCCESS; // Map found
165 }
166 List = List->NextVariablePack;
167 }
168 //
169 // If here, the map is not found
170 //
171 return EFI_NOT_FOUND;
172 }
173
174 /**
175 Finds a variable form List given the
176 order number as appears in the List.
177
178 @param Id - The ID of the variable/map to retrieve
179 @param List - List of variables
180 @param Name - Name of the variable/map
181 @param Guid - GUID of the variable/map
182 @param Var - Pointer to the variable/map
183 @param Size - Size of the variable/map in bytes
184
185 @retval EFI_SUCCESS - Variable is found, OUT parameters are valid
186 @retval EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid
187
188 **/
189 EFI_STATUS
190 EfiLibHiiVariablePackListGetMapById (
191 IN UINT16 Id,
192 IN EFI_HII_VARIABLE_PACK_LIST *List,
193 OUT CHAR16 **Name, OPTIONAL
194 OUT EFI_GUID **Guid, OPTIONAL
195 OUT VOID **Var,
196 OUT UINTN *Size
197 )
198 {
199 CHAR16 *MapName;
200 EFI_GUID *MapGuid;
201 UINT16 MapId;
202 VOID *Map;
203 UINTN MapSize;
204
205 while (NULL != List) {
206 EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);
207 if (MapId == Id) {
208 *Var = Map;
209 *Size = MapSize;
210 if (NULL != Name) {
211 *Name = MapName;
212 }
213 if (NULL != Guid) {
214 *Guid = MapGuid;
215 }
216 //
217 // Map found
218 //
219 return EFI_SUCCESS;
220 }
221 List = List->NextVariablePack;
222 }
223 //
224 // If here, the map is not found
225 //
226 return EFI_NOT_FOUND;
227 }
228
229 /**
230 Finds a variable form EFI_HII_VARIABLE_PACK_LIST given name and GUID.
231
232 @param List - List of variables
233 @param Name - Name of the variable/map to be found
234 @param Guid - GUID of the variable/map to be found
235 @param Id - Id of the variable/map to be found
236 @param Var - Pointer to the variable/map found
237 @param Size - Size of the variable/map in bytes found
238
239 @retval EFI_SUCCESS - variable is found, OUT parameters are valid
240 @retval EFI_NOT_FOUND - variable is not found, OUT parameters are not valid
241 **/
242 EFI_STATUS
243 EfiLibHiiVariablePackListGetMap (
244 IN EFI_HII_VARIABLE_PACK_LIST *List,
245 IN CHAR16 *Name,
246 IN EFI_GUID *Guid,
247 OUT UINT16 *Id,
248 OUT VOID **Var,
249 OUT UINTN *Size
250 )
251 {
252 VOID *Map;
253 UINTN MapSize;
254 UINT16 MapId;
255 CHAR16 *MapName;
256 EFI_GUID *MapGuid;
257
258 while (NULL != List) {
259 EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);
260 if ((0 == StrCmp (Name, MapName)) && CompareGuid (Guid, MapGuid)) {
261 *Id = MapId;
262 *Var = Map;
263 *Size = MapSize;
264 return EFI_SUCCESS;
265 }
266 List = List->NextVariablePack;
267 }
268 //
269 // If here, the map is not found
270 //
271 return EFI_NOT_FOUND;
272 }
273
274 /**
275 Finds out if a variable of specific Name/Guid/Size exists in NV.
276 If it does, it will retrieve it into the Var.
277
278 @param Name Parameters of the variable to retrieve. Must match exactly.
279 @param Guid Parameters of the variable to retrieve. Must match exactly.
280 @param Size Parameters of the variable to retrieve. Must match exactly.
281 @param Var Variable will be retrieved into buffer pointed by this pointer.
282 If pointing to NULL, the buffer will be allocated. Caller is responsible for releasing the buffer.
283
284 @retval EFI_SUCCESS - The variable of exact Name/Guid/Size parameters was retrieved and written to Var.
285 @retval EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.
286 @retval EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.
287
288 **/
289 EFI_STATUS
290 EfiLibHiiVariableRetrieveFromNv (
291 IN CHAR16 *Name,
292 IN EFI_GUID *Guid,
293 IN UINTN Size,
294 OUT VOID **Var
295 )
296
297 {
298 EFI_STATUS Status;
299 UINTN SizeNv;
300
301 //
302 // Test for existence of the variable.
303 //
304 SizeNv = 0;
305 Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, NULL);
306 if (EFI_BUFFER_TOO_SMALL != Status) {
307 ASSERT (EFI_SUCCESS != Status);
308 return EFI_NOT_FOUND;
309 }
310 if (SizeNv != Size) {
311 //
312 // The variable is considered corrupt, as it has different size from expected.
313 //
314 return EFI_LOAD_ERROR;
315 }
316
317 if (NULL == *Var) {
318 *Var = AllocatePool (Size);
319 ASSERT (NULL != *Var);
320 }
321 SizeNv = Size;
322 //
323 // Final read into the Var
324 //
325 Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, *Var);
326 //
327 // No tolerance for random failures. Such behavior is undetermined and not validated.
328 //
329 ASSERT_EFI_ERROR (Status);
330 ASSERT (SizeNv == Size);
331 return EFI_SUCCESS;
332 }
333
334 /**
335 Overrrides the variable with NV data if found.
336 But it only does it if the Name ends with specified Suffix.
337 For example, if Suffix="MyOverride" and the Name="XyzSetupMyOverride",
338 the Suffix matches the end of Name, so the variable will be loaded from NV
339 provided the variable exists and the GUID and Size matches.
340
341 @param Suffix Suffix the Name should end with.
342 @param Name, Guid, Size Parameters of the variable to retrieve. Must match exactly.
343 @param Var Variable will be retrieved into this buffer.
344 Caller is responsible for providing storage of exactly Size size in bytes.
345
346 @retval EFI_SUCCESS - The variable was overriden with NV variable of same Name/Guid/Size.
347 @retval EFI_INVALID_PARAMETER - The name of the variable does not end with <Suffix>.
348 @retval EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.
349 @retval EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.
350 **/
351 EFI_STATUS
352 EfiLibHiiVariableOverrideIfSuffix (
353 IN CHAR16 *Suffix,
354 IN CHAR16 *Name,
355 IN EFI_GUID *Guid,
356 IN UINTN Size,
357 OUT VOID *Var
358 )
359 {
360 UINTN StrLength;
361 UINTN StrLenSuffix;
362
363 StrLength = StrLen (Name);
364 StrLenSuffix = StrLen (Suffix);
365 if ((StrLength <= StrLenSuffix) || (0 != StrCmp (Suffix, &Name[StrLength - StrLenSuffix]))) {
366 //
367 // Not ending with <Suffix>.
368 //
369 return EFI_INVALID_PARAMETER;
370 }
371 return EfiLibHiiVariableRetrieveFromNv (Name, Guid, Size, &Var);
372 }
373
374 /**
375 Overrrides the variable with NV data if found.
376 But it only does it if the NV contains the same variable with Name is appended with Suffix.
377 For example, if Suffix="MyOverride" and the Name="XyzSetup",
378 the Suffix will be appended to the end of Name, and the variable with Name="XyzSetupMyOverride"
379 will be loaded from NV provided the variable exists and the GUID and Size matches.
380
381 @param Suffix Suffix the variable will be appended with.
382 @param Name, Guid, Size Parameters of the variable to retrieve. Must match exactly.
383 @param Var Variable will be retrieved into this buffer.
384 Caller is responsible for providing storage of exactly Size size in bytes.
385
386 @retval EFI_SUCCESS - The variable was overriden with NV variable of same Name/Guid/Size.
387 @retval EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.
388 @retval EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.
389
390 --*/
391 EFI_STATUS
392 EfiLibHiiVariableOverrideBySuffix (
393 IN CHAR16 *Suffix,
394 IN CHAR16 *Name,
395 IN EFI_GUID *Guid,
396 IN UINTN Size,
397 OUT VOID *Var
398 )
399
400 {
401 EFI_STATUS Status;
402 CHAR16 *NameSuffixed;
403 UINTN NameLength;
404 UINTN SuffixLength;
405
406 //
407 // enough to concatenate both strings.
408 //
409 NameLength = StrLen (Name);
410 SuffixLength = StrLen (Suffix);
411 NameSuffixed = AllocateZeroPool ((NameLength + SuffixLength + 1) * sizeof (CHAR16));
412
413 StrCpy (NameSuffixed, Name);
414 StrCat (NameSuffixed, Suffix);
415
416 Status = EfiLibHiiVariableRetrieveFromNv (NameSuffixed, Guid, Size, &Var);
417 gBS->FreePool (NameSuffixed);
418
419 return Status;
420 }
421