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