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